当前位置:   article > 正文

自然语言处理_因为文本数据在可用的数据中是非常无结构,它内部会包含很多不同类型的噪,所以要做数据预处理,

因为文本数据在可用的数据中是非常无结构,它内部会包含很多不同类型的噪,所以要做数据预处理,
  1. 自然语言处理(NLP)简介

NLP是数据科学里的一个分支,它的主要覆盖的内容是:以一种智能与高效的方式,对文本数据进行系统化分析、理解与信息提取的过程。通过使用NLP以及它的组件,我们可以管理非常大块的文本数据,或者执行大量的自动化任务,并且解决各式各样的问题,如自动摘要,机器翻译,命名实体识别,关系提取,情感分析,语音识别,以及主题分割等等。

在我们进入下一步之前,我们先解释一下将会在此教程里用到的一些术语:

  1. Tokenization:将文本转化为tokens的过程

  2. Tokens:在文本里的展示的单词或实体

  3. Text object:一个句子、短语、单词或文章

首先安装NLTK以及它的数据:

pip3 install nltk

在python界面里输入以下代码,并根据弹出的界面下载所需要的包:

import nltk

nltk.download()

  1. 文本预处理

因为文本数据在可用的数据中是非常无结构的,它内部会包含很多不同类型的噪点。所以在对文本进行预处理之前,它暂时是不适合被用于做直接分析的。文本预处理过程主要是对 文本数据进行清洗与标准化。这个过程会让我们的数据没有噪声,并可以对它直接做分析。

数据预处理的过程主要包括以下三个部分:

  1. 噪声移除

  2. 词汇规范化

  3. 对象标准化

2.1 噪声移除

任何与数据上下文无关的文本片段以及end-output均可被认为是噪音。例如,语言停顿词(一般是在语言里常用的单词,如:is, am, the, of, in 等等),URL或链接,社交媒体里的实体(如@符号,#标签等),标点符号,以及工业特有词汇等。这个步骤就是为了移除文本里所有类型的噪音实体。

在噪音移除里,一个常见的方法是:准备一个噪音实体的字典,然后对text object进行迭代(以token或单词),去除掉那些存在于噪音字典里的tokens(单词或实体)。

一个例子如下:

sample code to remove noisy words from a text

noise_list = [‘is’, ‘a’, ‘this’, ‘…’]

def _remove_noise(input_text):
words = input_text.split()
noise_free_words = [word for word in words if word not in noise_list]
noise_free_text = ’ '.join(noise_free_words)
return noise_free_text

print(_remove_noise(“this is a sample text”))

sample text

另外一个方法是使用正则表达式处理一些特定模式的噪音。下面是一个使用正则表达式移除噪音的例子:

def _remove_regex(input_text, regex_pattern):

urls = re.finditer(regex_pattern, input_text)

for i in urls:

    input_text = re.sub(i.group().strip(), '', input_text)

return input_text
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

regex_pattern = ‘#[\w]*’

result = _remove_regex(“remove this #hashtag from analytics vidhya”, regex_pattern)

print(result)

remove this from analytics vidhya

2.2 词汇规范化

另外一种文本型的噪音与一个词语的多种表达形式有关。例如,“play”,“player”,“played”,“plays”和“playing”都是单词“play”的变种。尽管它们有不同的意思,但是根据上下文来看,它们是意思是相似的。这个步骤是将一个单词的所有不同形式转换为它的规范形式(也被称为词条(lemma))。规范化在特征工程里,是对文本处理的一个关键步骤。因为它将高维的特征(N个不同的特征)转换到了低维空间(1个特征),这对于机器学习模型来说是非常完美的。

最常见的词汇规范化的实践有:

  1. 词干提取(Stemming):词干提取是一个初级的、基于规则的脱去后缀(如“ing”,“ly”,“es”,“s”等等)的过程

  2. 词元化(Lemmatization):另一方面,词元化,是一个组织好的、一步一步的获取词根的过程。并使用了词汇表(单词在字典里的重要性)和形态学分析(单词结构与语法关系)

下面是一个示例代码,它使用了NLTK来做Stemming与Lemmatization:

from nltk.stem.wordnet import WordNetLemmatizer

lem = WordNetLemmatizer()

from nltk.stem.porter import PorterStemmer

stem = PorterStemmer()

word = “multiplying”

lem.lemmatize(word, “v”)

‘multiply’

stem.stem(word)

‘multipli’

word2 = ‘playing’

stem.stem(word2)

‘play’

2.3 对象标准化
文本数据经常包含一些不存在于标准词汇字典里的单词或短语。这些部分是无法被搜索引擎和模型所识别的。

一些例子如:首字母缩略词,井字标签与它后面的词汇,以及口语俚语等。对此我们可以使用正则表达式和人工准备的数据字典,来修正这些噪音。下面的代码使用了查找字典的方法来修复社交媒体里文本数据的俚语:

lookup_dict = {‘rt’:‘Retweet’, ‘dm’:‘direct message’, ‘awsm’:‘awesome’,‘luv’:‘love’}

def _lookup_words(input_text):

words = input_text.split()

new_words = []

for word in words:

    if word.lower() in lookup_dict:

        word = lookup_dict[word.lower()]

    new_words.append(word)



new_words = ' '.join(new_words)

return new_words
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

result = _lookup_words(‘RT this is a retweeted tweet by Shivam Bansal’)

print(result)

Retweet this is a retweeted tweet by Shivam Bansal

除了以上讨论的三个步骤以外,其他还有一些文本预处理的技术,如:encoding-decoding噪音,语法检查,以及拼写纠正等。

  1. 将文本转化为特征(在文本数据上使用特征工程)
    为了分析一个已经做了预处理的数据,我们需要将它转化为特征。根据使用用途不同,文本特征可以根据各种技术建立而成。如:句法分析(Syntactical Parsing),实体(entities) / N元语法(N-grams) / 基于单词(word-based)特征,统计学(Statistical)特征,以及词向量(word embeddings)。接下来我们会对它们进行逐一介绍。

3.1 句法分析(Syntactic Parsing)
句法分析包括:分析单词在句子里的语法,以及,它们在句子中的位置显示的,在某种程度上,与其他单词之间的关系 。依赖性文法(Depenency Grammar)和词性标注(Part of Speech tags),是文本句法里最重要的属性。

依赖关系树 – 句子是由一些单词组成。在句子里,单词之间的关系是由基本的依赖性文法决定的。依赖性文法是一类句法文本分析,它用于处理两个词项(单词)之间的非对称二元关系。每个关系可以以一个三元项(relation(关系),governor(管理者),dependent(依赖))来表示。例如:考虑这个句子:“Bills on ports and immigration were submitted by Senator Brownback, Republican of Kansas”。在这个句子里,单词之间的关系可以用下面一个树来表示:

从这个树里我们可以看到,“submitted”是这个句子里的根部,并且它由两个子树连接起来(subject-主语子树和object-宾语子树)。每个子树都是它自己的依赖关系树,它们之间的关系例如:(“Bills”<-> “ports” “介词(preposition)”关系),(“ports”<-> “immigration” “连词(conjunction)”关系)

这种类型的树,当以自上到下的方式迭代的进行语法分析时,我们可以得到语法关系三元组作为输出。这些输出可以被当作特征应用于非常多的nlp问题中,如实体情感分析,actor & entity identification,以及文本分类。在python中,StanfordCoreNLP以及NLTK依赖性文法,都可以用于生成依赖关系树。

词性标注 – 除了语法关系,在句子中,每个单词还与它的词性(名次,动词,形容词,副词,等)相关。词性的标签定义了一个单词在句子里的用法以及功能。下面的代码展示了如何用NLTK对输入的文本做词性标注注解。(NLTK提供了多种实现,默认使用的是perceptron tagger)

from nltk import word_tokenize, pos_tag

text = “Hello, I am Zack, I am learning Natural Language Processing online”

tokens = word_tokenize(text)

tokens

[‘Hello’, ‘,’, ‘I’, ‘am’, ‘Zack’, ‘,’, ‘I’, ‘am’, ‘learning’, ‘Natural’, ‘Language’, ‘Processing’, ‘online’]

pos_tag(tokens)

[(‘Hello’, ‘NNP’), (’,’, ‘,’), (‘I’, ‘PRP’), (‘am’, ‘VBP’), (‘Zack’, ‘RB’), (’,’, ‘,’), (‘I’, ‘PRP’), (‘am’, ‘VBP’), (‘learning’, ‘VBG’), (‘Natural’, ‘NNP’), (‘Language’, ‘NNP’), (‘Processing’, ‘NNP’), (‘online’, ‘NN’)]

词性标注在NLP里有很多重要的通途:
A. 词义消歧:一些单词有多重意思,根据它们的使用不同,会有不同意思。例如,下面两个句子:
1.“Please book my flight for Delhi”
2.“I am going to read this book in the flight”

这里 book的单词根据上下文的不同,含义也不同。而词性标注对两个book的词性标注也应不同。在句子1里,book单词是一个动词,而在句子2里是一个名次。(Lesk算法也可以用于相同的目的)

B. 提升基于单词的特征(Improving word-based features):当单词被当作特征使用时,一个学习模型会学习到一个单词的不同上下文。然而如果词性标注被关联进去时,上下文即被保护了,这样便可构造出更优秀的特征。例如:
Sentence – “book my flight, I will read this book”

Tokens – (“book”, 2), (“my”, 1), (“flight”, 1), (“I”, 1), (“will”, 1), (“read”, 1), (“this”, 1)

Tokens with POS – (“book_VB”, 1), (“my_PRP$”, 1), (“flight_NN”, 1), (“I_PRP”, 1), (“will_MD”, 1), (“read_VB”, 1), (“this_DT”, 1), (“book_NN”, 1)

C. 标准化与词元化:在转换一个词到它的基本形式时,词性标签是词元化过程的基础。

D. 高效的停止词移除(Efficient stopword removal):在高效的停止词移除中,词性标注也非常有用

3.2 实体抽取(实体作为特征)
实体被定义为一个句子里最重要的部分,它们一般是名词短语,动词短语或者两者均有。实体检测算法一般是由基于规则的句法分析、词典查找、词性标注以及依存句法分析结合起来的组合模型。实体抽取的应用一般可以在自动聊天机器人、上下文分析器以及消费者洞察(consumer insights)里见到。

主题建模(topic modelling)和命名实体识别(named entity recognition)在NLP里是两个非常关键的实体抽取方法。
A. 命名实体识别(NER)
从一个文本里检测命名的实体(如:人名、地点名、公司名等)的过程叫做NER,例如:

Sentence – Sergey Brin, the manager of Google Inc. is walking in the streets of New York

Named Entities – (“person” : “Sergey Brin”), (“org” : “Google Inc.”), (“location” : “New York”)

一个典型的NER模型包括以下三个部分:

名词短语识别:这个步骤处理的是,使用依存句法分析和词性标记的方法,从一个文本里抽取出所有的名词短语。

短语分类:这个步骤是一个分类操作,它将所有提取出来的名词短语分类到对应的类别中(如地点,名字,等等)。Google Maps API提供了一个很好的办法消除地点的歧义。然后,一般的开源数据库,如dbpedia,Wikipedia等都可以用于识别人名与公司名。除了这以外,我们也可以自己创建一个查找表和字典,将不同来源的数据整合起来。

实体消歧:可能有些时候实体会被错误的分类,所以在输出层之上创建一个验证层将会大有帮助。使用知识图可以实现这个目标。比较流行的知识图有:Google Knowledge Graph,IBM Watson和Wikipedia

B. 主题建模
主题建模是一个从文本语料库里自动化识别主题的过程。它以一种非监督的方式,得到语料库里单词中的隐含模式。主题被定义为“a repeating pattern of co-occurring terms in a corpus”。一个好的主题模型可以得到:“heath”, “doctor”, “patient”, “hospital” 为Healthcare的主题,“farm”, “crops”, “wheat” 对应于“Farming”的主题

隐含狄利克雷分布(Latent Dirichlet Allocation)(LDA)是最流行的主题建模技术。下面的代码使用了LDA实现主题建模。更多与此有关的说明与实现,可以参考这个文档:
https://www.analyticsvidhya.com/blog/2016/08/beginners-guide-to-topic-modeling-in-python/

import gensim

from gensim import corpora

Creating the term dictionary of our corpus, where every term is assigned an index

dictionary = corpora.Dictionary(doc_clean)

Converting list of documents (corpus) into Document Term Matrix using dictionary prepared above

doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean]

Creating the object for LDA model using gensim lib

Lda = gensim.models.ldamodel.LdaModel

Running and Training LDA model on the document term matrix

ldamodel = Lda(doc_term_matrix, num_topics=3, id2word=dictionary, passes=50)

Results

print(ldamodel.print_topics())

[(0, ‘0.030*“driving” + 0.030*“a” + 0.030*“practice” + 0.030*“dance” + 0.030*“lot” + 0.030*“time” + 0.030*“of” + 0.030*“spends” + 0.030*“around” + 0.030*“consume.”’), (1, ‘0.083*“to” + 0.058*“My” + 0.058*“sister” + 0.058*“my” + 0.058*“father” + 0.033*“is” + 0.033*“not” + 0.033*“Sugar” + 0.033*“likes” + 0.033*“have”’), (2, ‘0.061*“driving” + 0.061*“and” + 0.061*“suggest” + 0.061*“stress” + 0.061*“pressure” + 0.061*“may” + 0.061*“that” + 0.061*“increase” + 0.061*“Doctors” + 0.061*“blood”’)]

C. N元语法(N-Grams)作为特征
将N个单词结合在一起叫做N元语法。在作为特征时,N元语法(N>1)一般会比单元语法提供更多的消息。同样,二元语法(bigrams)被认为是其中最重要的特征。下面的代码为一个文本生成了他的二元语法:

def generate_ngrams(text, n):

words = text.split()

output = []

for i in range(len(words)-n+1):

    output.append(words[i:i+n])

return output
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

print(generate_ngrams(‘this is a sample text’, 2))

[[‘this’, ‘is’], [‘is’, ‘a’], [‘a’, ‘sample’], [‘sample’, ‘text’]]

3.3 统计特征(Statistical Features)
通过使用以下提到的几个技术,文本数据可以被直接量化为数量值:
A. 词频 – 逆文档频率(Term Frequency – Inverse Document Frequency)(TF– IDF)
TF-IDF是一个有权重的模型,它常被用于信息检索(information retrieval)问题。它的目的是在于:基于单词在文档里出现的频率(不考虑严格的排序),将文档转化为向量模型。例如:假设这里有个数据库,里面有N个文档。对于每个文档“D”来说,TF和IDF被定义为:

Term Frequency(TF):对于一个术语(term)“t”来说,它在“D”里的TF为“t”在“D”里出现的次数

Inverse Document Frequency(IDF):IDF对于一个术语(term)来说,它被定义为:在语料库里所有文档数,与,包含术语T文档的数,的一个比率的对数

TF . IDF:TF IDF的公式(如下所示)给出了一个术语(term)在语料库(文档的集合)里的相对重要性。

下面的代码展示了使用python的scikit learn包将一个文本转化为tf-idf向量:

from sklearn.feature_extraction.text import TfidfVectorizer

obj = TfidfVectorizer()

corpus = [‘This is a sample document.’, ‘another random document.’, ‘third sample document text’]

X = obj.fit_transform(corpus)

(0, 7) 0.58448290102
(0, 2) 0.58448290102
(0, 4) 0.444514311537
(0, 1) 0.345205016865
(1, 1) 0.385371627466
(1, 0) 0.652490884513
(1, 3) 0.652490884513
(2, 4) 0.444514311537
(2, 1) 0.345205016865
(2, 6) 0.58448290102
(2, 5) 0.58448290102

这个模型创建了一个词汇字典,并且给每个单词分配了一个索引。在输出结果里,每一行包含一个元祖(i, j),以及index为j的单词在文档i里的tf-idf值

B. 计数 / 密度 / 可读性特征(Count / Density / Readability Features)
基于特征的计数与密度特征也可以被用于模型与分析。这些特征可能看起来是不重要的,但是在训练模型时显示出了巨大的影响。其中一些特征包括:单词数(Word Count),句子数(Sentence Count),标点数(Punctuation Counts)和行业特定词数(Industry specific word)。其他类型的衡量方法(包括可读性衡量)如音节数,smog index和易读性指数。可以参考以下文档创建这些特征:
https://github.com/shivam5992/textstat

3.4 词向量(Word Embedding)(text vectors)
Word embedding是一种非常现代的用向量表示单词的方式。它的目标是为了将高维的词特征重新定义为低维的特征向量,主要通过保留语料库里的上下文相关性完成。它已经被广泛应用于如卷积神经网络,循环神经网络等深度学习模型中

Word2Vec 和 GloVe是两个非常流行的为文本创建词向量的模型。这些模型使用文本语料库作为输入,并生成词向量作为输出。

Word2Vec模型由预处理模块、被称为连续词袋(Continuous Bag of Words)的一个浅神经网络模块以及另一个名叫skip-gram的浅神经网络模型组成。这些模型已经被广泛的用于其他各种nlp问题。它首先从训练语料库建立一个词汇表,然后学习词向量的表现方式。下面的代码使用了gensim包实现词向量:

from gensim.models import Word2Vec

sentences = [[‘data’, ‘science’], [‘online’, ‘science’, ‘data’, ‘analytics’],[‘machine’, ‘learning’], [‘deep’, ‘learning’]]

train the model on your corpus

model = Word2Vec(sentences, min_count=1)

print(model.similarity(‘data’, ‘science’))

-0.204396587715

print(model[‘learning’])

[ 4.16955026e-03 -2.37376429e-03 -2.78551341e-03 3.92724760e-03
7.43532903e-04 7.26812170e-04 4.44857636e-03 3.75635154e-03
-1.43383816e-03 4.24796832e-04 -3.50184389e-03 4.13319934e-03
-2.44115014e-03 1.11951970e-03 1.82436092e-03 -4.80600866e-03
4.72195214e-03 -7.03078258e-05 1.24959322e-03 -4.79448866e-03

… ]

它们可以作为特征向量使用在机器学习模型中,也可以用于衡量文本相似度(使用余弦相似技术),还可以适用于词聚类以及文本分类等技术中。

  1. NLP的重要任务
    这个板块会讨论在自然语言处理领域下的不同的应用场景与问题

4.1文本分类
文本分类经典的NLP问题之一。众所周知的例子包括:垃圾邮件识别,新闻主题分类,情感分析,以及搜索引擎的页面组织。

文本分类,简单来说,它就是一种将文本对象(文档或句子)分类到一个固定的类别的技术。当数据量非常大时,它在数据的组织、信息过滤,以及数据存储等方面起到非常大的作用。

一个典型的自然语言分类器包含两部分:1. 训练;2. 预测。如下图所示:

首先,文本在输入后,它的特征会被创建。然后机器学习算法从这些特征学习一组参数。之后使用学习到的机器学习模型对新文本做预测。

下面是一个朴素贝叶斯分类器的例子(使用了textblob库):

from textblob.classifiers import NaiveBayesClassifier as NBC

from textblob import TextBlob

training_corpus = [

                ('I am exhausted of this work.', 'Class_B'),

                ("I can't cooperate with this", 'Class_B'),

                ('He is my badest enemy!', 'Class_B'),

                ('My management is poor.', 'Class_B'),

                ('I love this burger.', 'Class_A'),

                ('This is an brilliant place!', 'Class_A'),

                ('I feel very good about these dates.', 'Class_A'),

                ('This is my best work.', 'Class_A'),

                ("What an awesome view", 'Class_A'),

                ('I do not like this dish', 'Class_B')]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

test_corpus = [

            ("I am not feeling well today.", 'Class_B'),

            ("I feel brilliant!", 'Class_A'),

            ('Gary is a friend of mine.', 'Class_A'),

            ("I can't believe I'm doing this.", 'Class_B'),

            ('The date was good.', 'Class_A'), ('I do not enjoy my job', 'Class_B')]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

model = NBC(training_corpus)

print(model.classify(“Their codes are amazing.”))

Class_A

print(model.classify(“I don’t like their computer.”))

Class_B

print(model.accuracy(test_corpus))

0.833

Scikit.Learn也提供了做文本分类的管道框架:

from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.metrics import classification_report

from sklearn import svm

preparing data for SVM model (using the same training corpus, test corpus from naive bayes example)

train_data = []

train_labels = []

for row in training_corpus:

train_data.append(row[0])

train_labels.append(row[1])
  • 1
  • 2
  • 3

test_data = []

test_labels = []

for row in test_corpus:

test_data.append(row[0])

test_labels.append(row[1])
  • 1
  • 2
  • 3

create feature vectors

vectorizer = TfidfVectorizer(min_df=4, max_df=0.9)

train the feature vectors

train_vectors = vectorizer.fit_transform(train_data)

Apply model on test data

test_vectors = vectorizer.transform(test_data)

perform classification with SVM, kernel=linear

model = svm.SVC(kernel=‘linear’)

model.fit(train_vectors, train_labels)

prediction = model.predict(test_vectors)

print(prediction)

[‘Class_A’ ‘Class_A’ ‘Class_B’ ‘Class_B’ ‘Class_A’ ‘Class_A’]

print(classification_report(test_labels, prediction))

         precision    recall  f1-score   support

Class_A       0.50      0.67      0.57         3
Class_B       0.50      0.33      0.40         3
  • 1
  • 2
  • 3
  • 4

avg / total 0.50 0.50 0.49 6

文本分类很大程度上依赖于特征的质量与数量。当然,在使用任何机器学习训练模型时,一般来说,引入越多的训练数据总会是一个比较好的事。

4.3 指代消解(Coreference Resolution)
指代消解是一个在句子里寻找单词(或短语)之间关系连接的过程。考虑这个句子“Donald went to John’s office to see the new table. He looked at it for an hour.”

人们可以很快的指出“he”指代的是Donald(而不是John),并且“it”指代的是table(而不是John’s office)。指代消解是NLP的一个组成部分,它会自动的完成这个工作。这个技术常被用于文件摘要,问答系统,以及信息提取。Stanford CoreNLP

提供了一个python wrapper:
https://github.com/Wordseer/stanford-corenlp-python

4.4 其他NLP问题 / 任务

  1. 文本摘要:给出一个文本文章或段落,自动对它做总结,并根据重要性、相关性的程度,按次序输出句子(依次输出最重要并最相关的句子)。

  2. 机器翻译:通过处理语法、语义学以及真实世界的信息,自动将一个文本的语言翻译为另外一个语言的文本。

  3. 自然语言的生成与理解:将计算机数据库里的信息或语义意图转化为人类可读的语言叫做自然语言生成。为了更方便计算机程序处理,而将文本块转换为更逻辑化的结构的操作叫做自然语言理解

  4. 视觉字符识别:给出一打印后的文本图,识别与之对应的文本

  5. 文档信息化:对文档(网站,文件,pdf和图片)里文本数据的进行语法分析,将它们处理为干净、可分析的格式

  6. NLP相关的重要库
    · scikit-learn:python里的机器学习库
    · Natural Language Toolkit(NLTK):包含所有NLP技术的完整工具
    · Pattern:一个web mining模块,用于NLP和机器学习
    · TextBlob:操作简单的nlp工具API,构建于NLTK和Pattern
    · spaCy:Industrial strength NLP with Python and Cython
    · Gensim:主题建模
    · Stanford Core NLP:Stanford NLP group提供的NLP服务包

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/394509
推荐阅读
相关标签
  

闽ICP备14008679号