日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Python結(jié)合spaCy?進(jìn)行簡(jiǎn)易自然語(yǔ)言處理_python

作者:lsvih ? 更新時(shí)間: 2022-08-06 編程語(yǔ)言
  • 原文地址:Natural Language Processing Made Easy – using SpaCy (in Python)
  • 原文作者:Shivam Bansal
  • 譯文出自:https://github.com/xitu/gold-miner
  • 本文永久鏈接:github.com/xitu/gold-m…
  • 譯者:lsvih
  • 校對(duì)者:yzgyyang,sqrthree

簡(jiǎn)介

自然語(yǔ)言處理(NLP)是人工智能領(lǐng)域最重要的部分之一。它在許多智能應(yīng)用中擔(dān)任了關(guān)鍵的角色,例如聊天機(jī)器人、正文提取、多語(yǔ)翻譯以及觀點(diǎn)識(shí)別等應(yīng)用。業(yè)界 NLP 相關(guān)的公司都意識(shí)到了,處理非結(jié)構(gòu)文本數(shù)據(jù)時(shí),不僅要看正確率,還需要注意是否能快速得到想要的結(jié)果。

NLP 是一個(gè)很寬泛的領(lǐng)域,它包括了文本分類、實(shí)體識(shí)別、機(jī)器翻譯、問(wèn)答系統(tǒng)、概念識(shí)別等子領(lǐng)域。在我最近的一篇文章中,我探討了許多用于實(shí)現(xiàn) NLP 的工具與組件。在那篇文章中,我更多的是在描述NLTK(Natural Language Toolkit)這個(gè)偉大的庫(kù)。

在這篇文章中,我會(huì)將 spaCy —— 這個(gè)現(xiàn)在最強(qiáng)大、最先進(jìn)的 NLP python 庫(kù)分享給你們。

1. spaCy 簡(jiǎn)介及安裝方法

1.1 簡(jiǎn)介

spaCy 由 cython(Python 的 C 語(yǔ)言拓展,旨在讓 python 程序達(dá)到如同 C 程序一樣的性能)編寫(xiě),因此它的運(yùn)行效率非常高。spaCy 提供了一系列簡(jiǎn)潔的 API 方便用戶使用,并基于已經(jīng)訓(xùn)練好的機(jī)器學(xué)習(xí)與深度學(xué)習(xí)模型實(shí)現(xiàn)底層。

1.2 安裝

spaCy 及其數(shù)據(jù)和模型可以通過(guò) pip 和安裝工具輕松地完成安裝。使用下面的命令在電腦中安裝 spaCy:

sudo pip install spacy

如果你使用的是 Python3,請(qǐng)用 “pip3” 代替 “pip”。

或者你也可以在?這兒?下載源碼,解壓后運(yùn)行下面的命令安裝:

python setup.py install

在安裝好 spacy 之后,請(qǐng)運(yùn)行下面的命令以下載所有的數(shù)據(jù)集和模型:

python -m spacy.en.download all

2. spaCy 的管道(Pipeline)與屬性(Properties)

spaCy 的使用,以及其各種屬性,是通過(guò)創(chuàng)建管道實(shí)現(xiàn)的。在加載模型的時(shí)候,spaCy 會(huì)將管道創(chuàng)建好。在 spaCy 包中,提供了各種各樣的模塊,這些模塊中包含了各種關(guān)于詞匯、訓(xùn)練向量、語(yǔ)法和實(shí)體等用于語(yǔ)言處理的信息。

下面,我們會(huì)加載默認(rèn)的模塊(english-core-web 模塊)。

import spacy
nlp = spacy.load(“en”)

“nlp” 對(duì)象用于創(chuàng)建 document、獲得 linguistic annotation 及其它的 nlp 屬性。首先我們要?jiǎng)?chuàng)建一個(gè) document,將文本數(shù)據(jù)加載進(jìn)管道中。我使用了來(lái)自貓途鷹網(wǎng)的旅店評(píng)論數(shù)據(jù)。這個(gè)數(shù)據(jù)文件可以在這兒下載。

document = unicode(open(filename).read().decode('utf8'))
document = nlp(document)

這個(gè) document 現(xiàn)在是 spacy.english 模型的一個(gè) class,并關(guān)聯(lián)上了許多的屬性。可以使用下面的命令列出所有 document(或 token)的屬性:

dir(document)
>> [ 'doc', 'ents', … 'mem']

它會(huì)輸出 document 中各種各樣的屬性,例如:token、token 的 index、詞性標(biāo)注、實(shí)體、向量、情感、單詞等。下面讓我們會(huì)對(duì)其中的一些屬性進(jìn)行一番探究。

2.1 Tokenization

spaCy 的 document 可以在 tokenized 過(guò)程中被分割成單句,這些單句還可以進(jìn)一步分割成單詞。你可以通過(guò)遍歷文檔來(lái)讀取這些單詞:

# document 的首個(gè)單詞
document[0]
>> Nice
# document 的最后一個(gè)單詞  
document[len(document)-5]
>> boston
# 列出 document 中的句子
list(document.sents)
>> [ Nice place Better than some reviews give it credit for.,
 Overall, the rooms were a bit small but nice.,
...
Everything was clean, the view was wonderful and it is very well located (the Prudential Center makes shopping and eating easy and the T is nearby for jaunts out and about the city).]

2.2 詞性標(biāo)注(POS Tag)

詞性標(biāo)注即標(biāo)注語(yǔ)法正確的句子中的詞語(yǔ)的詞性。這些標(biāo)注可以用于信息過(guò)濾、統(tǒng)計(jì)模型,或者基于某些規(guī)則進(jìn)行文本解析。

來(lái)看看我們的 document 中所有的詞性標(biāo)注:

# 獲得所有標(biāo)注
all_tags = {w.pos: w.pos_ for w in document}
>> {97:  u'SYM', 98: u'VERB', 99: u'X', 101: u'SPACE', 82: u'ADJ', 83: u'ADP', 84: u'ADV', 87: u'CCONJ', 88: u'DET', 89: u'INTJ', 90: u'NOUN', 91: u'NUM', 92: u'PART', 93: u'PRON', 94: u'PROPN', 95: u'PUNCT'}
# document 中第一個(gè)句子的詞性標(biāo)注
for word in list(document.sents)[0]:  
    print word, word.tag_
>> ( Nice, u'JJ') (place, u'NN') (Better, u'NNP') (than, u'IN') (some, u'DT') (reviews, u'NNS') (give, u'VBP') (it, u'PRP') (creit, u'NN') (for, u'IN') (., u'.')

來(lái)看一看 document 中的最常用詞匯。我已經(jīng)事先寫(xiě)好了預(yù)處理和文本數(shù)據(jù)清洗的函數(shù)。

#一些參數(shù)定義
noisy_pos_tags = [“PROP”]
min_token_length = 2
#檢查 token 是不是噪音的函數(shù)
def isNoise(token):     
    is_noise = False
    if token.pos_ in noisy_pos_tags:
        is_noise = True
    elif token.is_stop == True:
        is_noise = True
    elif len(token.string) <= min_token_length:
        is_noise = True
    return is_noise
def cleanup(token, lower = True):
    if lower:
       token = token.lower()
    return token.strip()
# 評(píng)論中最常用的單詞
from collections import Counter
cleaned_list = [cleanup(word.string) for word in document if not isNoise(word)]
Counter(cleaned_list) .most_common(5)
>> [( u'hotel', 683), (u'room', 652), (u'great', 300),  (u'sheraton', 285), (u'location', 271)]

2.3 實(shí)體識(shí)別

spaCy 擁有一個(gè)快速實(shí)體識(shí)別模型,這個(gè)實(shí)體識(shí)別模型能夠從 document 中找出實(shí)體短語(yǔ)。它能識(shí)別各種類型的實(shí)體,例如人名、位置、機(jī)構(gòu)、日期、數(shù)字等。你可以通過(guò)“.ents”屬性來(lái)讀取這些實(shí)體。

下面讓我們來(lái)獲取我們 document 中所有類型的命名實(shí)體:

labels = set([w.label_ for w in document.ents])
for label in labels:
    entities = [cleanup(e.string, lower=False) for e in document.ents if label==e.label_]
    entities = list(set(entities))
    print label,entities

2.4 依存句法分析

spaCy 最強(qiáng)大的功能之一就是它可以通過(guò)調(diào)用輕量級(jí)的 API 來(lái)實(shí)現(xiàn)又快又準(zhǔn)確的依存分析。這個(gè)分析器也可以用于句子邊界檢測(cè)以及區(qū)分短語(yǔ)塊。依存關(guān)系可以通過(guò)“.children”、“.root”、“.ancestor”等屬性讀取。

# 取出所有句中包含“hotel”單詞的評(píng)論
hotel = [sent for sent in document.sents if 'hotel' in sent.string.lower()]
# 創(chuàng)建依存樹(shù)
sentence = hotel[2] for word in sentence:
print word, ': ', str(list(word.children))
>> A :  []  cab :  [A, from]
from :  [airport, to]
the :  []
airport :  [the]
to :  [hotel]
the :  [] hotel :  
[the] can :  []
be :  [cab, can, cheaper, .]
cheaper :  [than] than :  
[shuttles]
the :  []
shuttles :  [the, depending]
depending :  [time] what :  []
time :  [what, of] of :  [day]
the :  [] day :  
[the, go] you :  
[]
go :  [you]
. :  []

解析所有居中包含“hotel”單詞的句子的依存關(guān)系,并檢查對(duì)于 hotel 人們用了哪些形容詞。我創(chuàng)建了一個(gè)自定義函數(shù),用于分析依存關(guān)系并進(jìn)行相關(guān)的詞性標(biāo)注。

# 檢查修飾某個(gè)單詞的所有形容詞
def pos_words (sentence, token, ptag):
    sentences = [sent for sent in sentence.sents if token in sent.string]     
    pwrds = []
    for sent in sentences:
        for word in sent:
            if character in word.string:
                   pwrds.extend([child.string.strip() for child in word.children
                                                      if child.pos_ == ptag] )
    return Counter(pwrds).most_common(10)
pos_words(document, 'hotel', “ADJ”)
>> [(u'other', 20), (u'great', 10), (u'good', 7), (u'better', 6), (u'nice', 6), (u'different', 5), (u'many', 5), (u'best', 4), (u'my', 4), (u'wonderful', 3)]

2.5 名詞短語(yǔ)(NP)

依存樹(shù)也可以用來(lái)生成名詞短語(yǔ):

# 生成名詞短語(yǔ)
doc = nlp(u'I love data science on analytics vidhya')
for np in doc.noun_chunks:
    print np.text, np.root.dep_, np.root.head.text
>> I nsubj love
   data science dobj love
   analytics pobj on

3. 集成詞向量

spaCy 提供了內(nèi)置整合的向量值算法,這些向量值可以反映詞中的真正表達(dá)信息。它使用?GloVe?來(lái)生成向量。GloVe 是一種用于獲取表示單詞的向量的無(wú)監(jiān)督學(xué)習(xí)算法。

讓我們創(chuàng)建一些詞向量,然后對(duì)其做一些有趣的操作吧:

from numpy import dot
from numpy.linalg import norm
from spacy.en import English
parser = English()
# 生成“apple”的詞向量 
apple = parser.vocab[u'apple']
# 余弦相似性計(jì)算函數(shù)
cosine = lambda v1, v2: dot(v1, v2) / (norm(v1) * norm(v2))
others = list({w for w in parser.vocab if w.has_vector and w.orth_.islower() and w.lower_ != unicode("apple")})
# 根據(jù)相似性值進(jìn)行排序
others.sort(key=lambda w: cosine(w.vector, apple.vector))
others.reverse()
print "top most similar words to apple:"
for word in others[:10]:
    print word.orth_
>> apples iphone f ruit juice cherry lemon banana pie mac orange

4. 使用 spaCy 對(duì)文本進(jìn)行機(jī)器學(xué)習(xí)

將 spaCy 集成進(jìn)機(jī)器學(xué)習(xí)模型是非常簡(jiǎn)單、直接的。讓我們使用 sklearn 做一個(gè)自定義的文本分類器。我們將使用 cleaner、tokenizer、vectorizer、classifier 組件來(lái)創(chuàng)建一個(gè) sklearn 管道。其中的 tokenizer 和 vectorizer 會(huì)使用我們用 spaCy 自定義的模塊構(gòu)建。

from sklearn.feature_extraction.stop_words import ENGLISH_STOP_WORDS as stopwords
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics import accuracy_score
from sklearn.base import TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.svm import LinearSVC
import string
punctuations = string.punctuation
from spacy.en import English
parser = English()
# 使用 spaCy 自定義 transformer
class predictors(TransformerMixin):
    def transform(self, X, **transform_params):
        return [clean_text(text) for text in X]
    def fit(self, X, y=None, **fit_params):
        return self
    def get_params(self, deep=True):
        return {}
# 進(jìn)行文本清洗的實(shí)用的基本函數(shù)
def clean_text(text):     
    return text.strip().lower()

現(xiàn)在讓我們使用 spaCy 的解析器和一些基本的數(shù)據(jù)清洗函數(shù)來(lái)創(chuàng)建一個(gè)自定義的 tokenizer 函數(shù)。值得一提的是,你可以用詞向量來(lái)代替文本特征(使用深度學(xué)習(xí)模型效果會(huì)有較大的提升)

#創(chuàng)建 spaCy tokenizer,解析句子并生成 token
#也可以用詞向量函數(shù)來(lái)代替它
def spacy_tokenizer(sentence):
    tokens = parser(sentence)
    tokens = [tok.lemma_.lower().strip() if tok.lemma_ != "-PRON-" else tok.lower_ for tok in tokens]
    tokens = [tok for tok in tokens if (tok not in stopwords and tok not in punctuations)]     return tokens
#創(chuàng)建 vectorizer 對(duì)象,生成特征向量,以此可以自定義 spaCy 的 tokenizer
vectorizer = CountVectorizer(tokenizer = spacy_tokenizer, ngram_range=(1,1)) classifier = LinearSVC()

現(xiàn)在可以創(chuàng)建管道,加載數(shù)據(jù),然后運(yùn)行分類模型了。

# 創(chuàng)建管道,進(jìn)行文本清洗、tokenize、向量化、分類操作
pipe = Pipeline([("cleaner", predictors()),
                 ('vectorizer', vectorizer),
                 ('classifier', classifier)])
# Load sample data
train = [('I love this sandwich.', 'pos'),          
         ('this is an amazing place!', 'pos'),
         ('I feel very good about these beers.', 'pos'),
         ('this is my best work.', 'pos'),
         ("what an awesome view", 'pos'),
         ('I do not like this restaurant', 'neg'),
         ('I am tired of this stuff.', 'neg'),
         ("I can't deal with this", 'neg'),
         ('he is my sworn enemy!', 'neg'),          
         ('my boss is horrible.', 'neg')]
test =   [('the beer was good.', 'pos'),     
         ('I do not enjoy my job', 'neg'),
         ("I ain't feelin dandy today.", 'neg'),
         ("I feel amazing!", 'pos'),
         ('Gary is a good friend of mine.', 'pos'),
         ("I can't believe I'm doing this.", 'neg')]
# 創(chuàng)建模型并計(jì)算準(zhǔn)確率
pipe.fit([x[0] for x in train], [x[1] for x in train])
pred_data = pipe.predict([x[0] for x in test])
for (sample, pred) in zip(test, pred_data):
    print sample, pred
print "Accuracy:", accuracy_score([x[1] for x in test], pred_data)
>>    ('the beer was good.', 'pos') pos
      ('I do not enjoy my job', 'neg') neg
      ("I ain't feelin dandy today.", 'neg') neg
      ('I feel amazing!', 'pos') pos
      ('Gary is a good friend of mine.', 'pos') pos
      ("I can't believe I'm doing this.", 'neg') neg
      Accuracy: 1.0

5. 和其它庫(kù)的對(duì)比

Spacy 是一個(gè)非常強(qiáng)大且具備工業(yè)級(jí)能力的 NLP 包,它能滿足大多數(shù) NLP 任務(wù)的需求。可能你會(huì)思考:為什么會(huì)這樣呢?

讓我們把 Spacy 和另外兩個(gè) python 中有名的實(shí)現(xiàn) NLP 的工具 —— CoreNLP 和 NLTK 進(jìn)行對(duì)比吧!

支持功能表

功能 Spacy NLTK Core NLP
簡(jiǎn)易的安裝方式 Y Y Y
Python API Y Y N
多語(yǔ)種支持 N Y Y
分詞 Y Y Y
詞性標(biāo)注 Y Y Y
分句 Y Y Y
依存性分析 Y N Y
實(shí)體識(shí)別 Y Y Y
詞向量計(jì)算集成 Y N N
情感分析 Y Y Y
共指消解 N N Y

速度:主要功能(Tokenizer、Tagging、Parsing)速度

庫(kù) Tokenizer Tagging Parsing
spaCy 0.2ms 1ms 19ms
CoreNLP 2ms 10ms 49ms
NLTK 4ms 443ms

準(zhǔn)確性:實(shí)體抽取結(jié)果

庫(kù) 準(zhǔn)確率 Recall F-Score
spaCy 0.72 0.65 0.69
CoreNLP 0.79 0.73 0.76
NLTK 0.51 0.65 0.58

結(jié)束語(yǔ)

本文討論了 spaCy —— 這個(gè)基于 python,完全用于實(shí)現(xiàn) NLP 的庫(kù)。我們通過(guò)許多用例展示了 spaCy 的可用性、速度及準(zhǔn)確性。最后我們還將其余其它幾個(gè)著名的 NLP 庫(kù) —— CoreNLP 與 NLTK 進(jìn)行了對(duì)比。

如果你能真正理解這篇文章要表達(dá)的內(nèi)容,那你一定可以去實(shí)現(xiàn)各種有挑戰(zhàn)的文本數(shù)據(jù)與 NLP 問(wèn)題。

原文鏈接:https://juejin.cn/post/6844903488149782535

欄目分類
最近更新