Python結(jié)合spaCy?進(jìn)行簡(jiǎn)易自然語(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)題。
以上就是Python結(jié)合spaCy 進(jìn)行簡(jiǎn)易自然語(yǔ)言處理的詳細(xì)內(nèi)容,更多關(guān)于Python spaCy自然語(yǔ)言處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python使用爬蟲(chóng)爬取貴陽(yáng)房?jī)r(jià)的方法詳解
這篇文章主要為大家詳細(xì)介紹了Python爬蟲(chóng)爬取貴陽(yáng)房?jī)r(jià)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-02-02Python中def()函數(shù)的實(shí)戰(zhàn)練習(xí)題
def是define的縮寫(xiě),用來(lái)自定義函數(shù),下面這篇文章主要給大家介紹了關(guān)于Python中def()函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07python使用分治法實(shí)現(xiàn)求解最大值的方法
這篇文章主要介紹了python使用分治法實(shí)現(xiàn)求解最大值的方法,較為詳細(xì)的分析了分治法的原理與實(shí)現(xiàn)求最大值的方法,需要的朋友可以參考下2015-05-05Python正則替換字符串函數(shù)re.sub用法示例
這篇文章主要介紹了Python正則替換字符串函數(shù)re.sub用法,結(jié)合實(shí)例形式分析了正則替換字符串函數(shù)re.sub的功能及簡(jiǎn)單使用方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01解決pyinstaller打包發(fā)布后的exe文件打開(kāi)控制臺(tái)閃退的問(wèn)題
今天小編就為大家分享一篇解決pyinstaller打包發(fā)布后的exe文件打開(kāi)控制臺(tái)閃退的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06Python3 pandas.concat的用法說(shuō)明
這篇文章主要介紹了Python3 pandas.concat的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03剛學(xué)完怎么用Python實(shí)現(xiàn)定時(shí)任務(wù),轉(zhuǎn)頭就跑去撩妹!
朋友問(wèn)我有沒(méi)有定時(shí)任務(wù)的模塊,并且越簡(jiǎn)單越好.剛好前今天就研究了一下定時(shí)任務(wù)模塊,于是就告訴他使用方式,令我沒(méi)有想到的是,這貨他學(xué)會(huì)了之后,居然買了一個(gè)服務(wù)器給女朋友發(fā)消息,發(fā)消息,發(fā)消息……重要的事情說(shuō)三遍,需要的朋友可以參考下2021-06-06