如何用Python處理自然語言?(Spacy與Word Embedding)

王樹義發表於2018-06-27

本文教你用簡單易學的工業級Python自然語言處理軟體包Spacy,對自然語言文字做詞性分析、命名實體識別、依賴關係刻畫,以及詞嵌入向量的計算和視覺化。

如何用Python處理自然語言?(Spacy與Word Embedding)

盲維

我總愛重複一句芒格愛說的話:

To the one with a hammer, everything looks like a nail. (手中有錘,看什麼都像釘)

這句話是什麼意思呢?

就是你不能只掌握數量很少的方法、工具。

否則你的認知會被自己能力框住。不只是存在盲點,而是存在“盲維”。

你會嘗試用不合適的方法解決問題(還自詡“一招鮮,吃遍天”),卻對原本合適的工具視而不見。

結果可想而知。

所以,你得在自己的工具箱裡面,多放一些兵刃。

最近我又對自己的學生,唸叨芒格這句話。

因為他們開始做實際研究任務的時候,一遇到自然語言處理(Natural Language Processing, NLP),腦子裡想到的就是詞雲情感分析LDA主題建模

為什麼?

因為我的專欄和公眾號裡,自然語言處理部分,只寫過這些內容。

你如果認為,NLP只能做這些事,就大錯特錯了。

看看這段視訊,你大概就能感受到目前自然語言處理的前沿,已經到了哪裡。

如何用Python處理自然語言?(Spacy與Word Embedding)

當然,你手頭擁有的工具和資料,尚不能做出Google展示的黑科技效果。

但是,現有的工具,也足可以讓你對自然語言文字,做出更豐富的處理結果。

科技的發展,蓬勃迅速。

除了我們們之前文章中已介紹過的結巴分詞、SnowNLP和TextBlob,基於Python的自然語言處理工具還有很多,例如 NLTK 和 gensim 等。

我無法幫你一一熟悉,你可能用到的所有自然語言處理工具。

但是我們們不妨開個頭,介紹一款叫做 Spacy 的 Python 工具包。

剩下的,自己舉一反三。

工具

Spacy 的 Slogan,是這樣的:

Industrial-Strength Natural Language Processing. (工業級別的自然語言處理)

如何用Python處理自然語言?(Spacy與Word Embedding)

這句話聽上去,是不是有些狂妄啊?

不過人家還是用資料說話的。

資料採自同行評議(Peer-reviewed)學術論文:

如何用Python處理自然語言?(Spacy與Word Embedding)

看完上述的資料分析,我們大致對於Spacy的效能有些瞭解。

但是我選用它,不僅僅是因為它“工業級別”的效能,更是因為它提供了便捷的使用者呼叫介面,以及豐富、詳細的文件。

僅舉一例。

如何用Python處理自然語言?(Spacy與Word Embedding)

上圖是Spacy上手教程的第一頁。

可以看到,左側有簡明的樹狀導航條,中間是詳細的文件,右側是重點提示。

僅安裝這一項,你就可以點選選擇作業系統、Python包管理工具、Python版本、虛擬環境和語言支援等標籤。網頁會動態為你生成安裝的語句。

如何用Python處理自然語言?(Spacy與Word Embedding)

這種設計,對新手使用者,很有幫助吧?

Spacy的功能有很多。

從最簡單的詞性分析,到高階的神經網路模型,五花八門。

篇幅所限,本文只為你展示以下內容:

  • 詞性分析
  • 命名實體識別
  • 依賴關係刻畫
  • 詞嵌入向量的近似度計算
  • 詞語降維和視覺化

學完這篇教程,你可以按圖索驥,利用Spacy提供的詳細文件,自學其他自然語言處理功能。

我們開始吧。

環境

請點選這個連結(http://t.cn/R35fElv),直接進入我們們的實驗環境。

對,你沒看錯。

不需要在本地計算機安裝任何軟體包。只要有一個現代化瀏覽器(包括Google Chrome, Firefox, Safari和Microsoft Edge等)就可以了。全部的依賴軟體,我都已經為你準備好了。

開啟連結之後,你會看見這個頁面。

如何用Python處理自然語言?(Spacy與Word Embedding)

不同於之前的 Jupyter Notebook,這個介面來自 Jupyter Lab。

你可以將它理解為 Jupyter Notebook 的增強版,它具備以下特徵:

  • 程式碼單元直接滑鼠拖動;
  • 一個瀏覽器標籤,可開啟多個Notebook,而且分別使用不同的Kernel;
  • 提供實時渲染的Markdown編輯器;
  • 完整的檔案瀏覽器;
  • CSV資料檔案快速瀏覽
  • ……

圖中左側分欄,是工作目錄下的全部檔案。

右側開啟的,是我們們要使用的ipynb檔案。

根據我們們的講解,請你逐條執行,觀察結果。

我們說一說樣例文字資料的來源。

如果你之前讀過我的其他自然語言處理方面的教程,應該記得這部電視劇。

如何用Python處理自然語言?(Spacy與Word Embedding)

對,就是"Yes, Minister"。

出於對這部80年代英國喜劇的喜愛,我還是用維基百科上"Yes, Minister"的介紹內容,作為文字分析樣例。

如何用Python處理自然語言?(Spacy與Word Embedding)

下面,我們就正式開始,一步步執行程式程式碼了。

我建議你先完全按照教程跑一遍,執行出結果。

如果一切正常,再將其中的資料,替換為你自己感興趣的內容

之後,嘗試開啟一個空白 ipynb 檔案,根據教程和文件,自己敲程式碼,並且嘗試做調整。

這樣會有助於你理解工作流程和工具使用方法。

實踐

我們從維基百科頁面的第一自然段中,摘取部分語句,放到text變數裡面。

text = "The sequel, Yes, Prime Minister, ran from 1986 to 1988. In total there were 38 episodes, of which all but one lasted half an hour. Almost all episodes ended with a variation of the title of the series spoken as the answer to a question posed by the same character, Jim Hacker. Several episodes were adapted for BBC Radio, and a stage play was produced in 2010, the latter leading to a new television series on UKTV Gold in 2013."
複製程式碼

顯示一下,看是否正確儲存。

text
複製程式碼
'The sequel, Yes, Prime Minister, ran from 1986 to 1988. In total there were 38 episodes, of which all but one lasted half an hour. Almost all episodes ended with a variation of the title of the series spoken as the answer to a question posed by the same character, Jim Hacker. Several episodes were adapted for BBC Radio, and a stage play was produced in 2010, the latter leading to a new television series on UKTV Gold in 2013.'
複製程式碼

沒問題了。

下面我們讀入Spacy軟體包。

import spacy
複製程式碼

我們讓Spacy使用英語模型,將模型儲存到變數nlp中。

nlp = spacy.load('en')
複製程式碼

下面,我們用nlp模型分析我們們的文字段落,將結果命名為doc。

doc = nlp(text)
複製程式碼

我們看看doc的內容。

doc
複製程式碼
The sequel, Yes, Prime Minister, ran from 1986 to 1988. In total there were 38 episodes, of which all but one lasted half an hour. Almost all episodes ended with a variation of the title of the series spoken as the answer to a question posed by the same character, Jim Hacker. Several episodes were adapted for BBC Radio, and a stage play was produced in 2010, the latter leading to a new television series on UKTV Gold in 2013.
複製程式碼

好像跟剛才的text內容沒有區別呀?不還是這段文字嗎?

彆著急,Spacy只是為了讓我們看著舒服,所以只列印出來文字內容。

其實,它在後臺,已經對這段話進行了許多層次的分析。

不信?

我們來試試,讓Spacy幫我們分析這段話中出現的全部詞例(token)。

for token in doc:
    print('"' + token.text + '"')
複製程式碼

你會看到,Spacy為我們輸出了一長串列表。

"The"
"sequel"
","
"Yes"
","
"Prime"
"Minister"
","
"ran"
"from"
"1986"
"to"
"1988"
"."
"In"
"total"
"there"
"were"
"38"
"episodes"
","
"of"
"which"
"all"
"but"
"one"
"lasted"
"half"
"an"
"hour"
"."
"Almost"
"all"
"episodes"
"ended"
"with"
"a"
"variation"
"of"
"the"
"title"
"of"
"the"
"series"
"spoken"
"as"
"the"
"answer"
"to"
"a"
"question"
"posed"
"by"
"the"
"same"
"character"
","
"Jim"
"Hacker"
"."
"Several"
"episodes"
"were"
"adapted"
"for"
"BBC"
"Radio"
","
"and"
"a"
"stage"
"play"
"was"
"produced"
"in"
"2010"
","
"the"
"latter"
"leading"
"to"
"a"
"new"
"television"
"series"
"on"
"UKTV"
"Gold"
"in"
"2013"
"."
複製程式碼

你可能不以為然——這有什麼了不起?

英語本來就是空格分割的嘛!我自己也能編個小程式,以空格分段,依次列印出這些內容來!

別忙,除了詞例內容本身,Spacy還把每個詞例的一些屬性資訊,進行了處理。

下面,我們只對前10個詞例(token),輸出以下內容:

  • 文字
  • 索引值(即在原文中的定位)
  • 詞元(lemma)
  • 是否為標點符號
  • 是否為空格
  • 詞性
  • 標記
for token in doc[:10]:
    print("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}".format(
        token.text,
        token.idx,
        token.lemma_,
        token.is_punct,
        token.is_space,
        token.shape_,
        token.pos_,
        token.tag_
    ))
複製程式碼

結果為:

The 0   the False   False   Xxx DET DT
sequel  4   sequel  False   False   xxxx    NOUN    NN
,   10  ,   True    False   ,   PUNCT   ,
Yes 12  yes False   False   Xxx INTJ    UH
,   15  ,   True    False   ,   PUNCT   ,
Prime   17  prime   False   False   Xxxxx   PROPN   NNP
Minister    23  minister    False   False   Xxxxx   PROPN   NNP
,   31  ,   True    False   ,   PUNCT   ,
ran 33  run False   False   xxx VERB    VBD
from    37  from    False   False   xxxx    ADP IN
複製程式碼

看到Spacy在後臺默默為我們做出的大量工作了吧?

下面我們不再考慮全部詞性,只關注文字中出現的實體(entity)詞彙。

for ent in doc.ents:
    print(ent.text, ent.label_)
複製程式碼
1986 to 1988 DATE
38 CARDINAL
one CARDINAL
half an hour TIME
Jim Hacker PERSON
BBC Radio ORG
2010 DATE
UKTV Gold ORG
2013 DATE
複製程式碼

在這一段文字中,出現的實體包括日期、時間、基數(Cardinal)……Spacy不僅自動識別出了Jim Hacker為人名,還正確判定BBC Radio和UKTV Gold為機構名稱。

如果你平時的工作,需要從海量評論裡篩選潛在競爭產品或者競爭者,那看到這裡,有沒有一點兒靈感呢?

執行下面這段程式碼,看看會發生什麼:

from spacy import displacy
displacy.render(doc, style='ent', jupyter=True)
複製程式碼

如何用Python處理自然語言?(Spacy與Word Embedding)

如上圖所示,Spacy幫我們把實體識別的結果,進行了直觀的視覺化。不同類別的實體,還採用了不同的顏色加以區分。

把一段文字拆解為語句,對Spacy而言,也是小菜一碟。

for sent in doc.sents:
    print(sent)
複製程式碼
The sequel, Yes, Prime Minister, ran from 1986 to 1988.
In total there were 38 episodes, of which all but one lasted half an hour.
Almost all episodes ended with a variation of the title of the series spoken as the answer to a question posed by the same character, Jim Hacker.
Several episodes were adapted for BBC Radio, and a stage play was produced in 2010, the latter leading to a new television series on UKTV Gold in 2013.
複製程式碼

注意這裡,doc.sents並不是個列表型別。

doc.sents
複製程式碼
<generator at 0x116e95e18>
複製程式碼

所以,假設我們需要從中篩選出某一句話,需要先將其轉化為列表。

list(doc.sents)
複製程式碼
[The sequel, Yes, Prime Minister, ran from 1986 to 1988.,
 In total there were 38 episodes, of which all but one lasted half an hour.,
 Almost all episodes ended with a variation of the title of the series spoken as the answer to a question posed by the same character, Jim Hacker.,
 Several episodes were adapted for BBC Radio, and a stage play was produced in 2010, the latter leading to a new television series on UKTV Gold in 2013.]
複製程式碼

下面要展示的功能,分析範圍侷限在第一句話。

我們將其抽取出來,並且重新用nlp模型處理,存入到新的變數newdoc中。

newdoc = nlp(list(doc.sents)[0].text)
複製程式碼

對這一句話,我們想要搞清其中每一個詞例(token)之間的依賴關係。

for token in newdoc:
    print("{0}/{1} <--{2}-- {3}/{4}".format(
        token.text, token.tag_, token.dep_, token.head.text, token.head.tag_))
複製程式碼
The/DT <--det-- sequel/NN
sequel/NN <--nsubj-- ran/VBD
,/, <--punct-- sequel/NN
Yes/UH <--intj-- sequel/NN
,/, <--punct-- sequel/NN
Prime/NNP <--compound-- Minister/NNP
Minister/NNP <--appos-- sequel/NN
,/, <--punct-- sequel/NN
ran/VBD <--ROOT-- ran/VBD
from/IN <--prep-- ran/VBD
1986/CD <--pobj-- from/IN
to/IN <--prep-- from/IN
1988/CD <--pobj-- to/IN
./. <--punct-- ran/VBD
複製程式碼

很清晰,但是列表的方式,似乎不大直觀。

那就讓Spacy幫我們視覺化吧。

displacy.render(newdoc, style='dep', jupyter=True, options={'distance': 90})
複製程式碼

結果如下:

如何用Python處理自然語言?(Spacy與Word Embedding)

這些依賴關係連結上的詞彙,都代表什麼?

如果你對語言學比較瞭解,應該能看懂。

不懂?查查字典嘛。

跟語法書對比一下,看看Spacy分析得是否準確。

前面我們分析的,屬於語法層級。

下面我們看語義。

我們利用的工具,叫做詞嵌入(word embedding)模型。

之前的文章《如何用Python從海量文字抽取主題?》中,我們提到過如何把文字表達成電腦可以看懂的資料。

如何用Python處理自然語言?(Spacy與Word Embedding)

文中處理的每一個單詞,都僅僅對應著詞典裡面的一個編號而已。你可以把它看成你去營業廳辦理業務時領取的號碼。

它只提供了先來後到的順序資訊,跟你的職業、學歷、性別統統沒有關係。

我們將這樣過於簡化的資訊輸入,計算機對於詞義的瞭解,也必然少得可憐。

例如給你下面這個式子:

? - woman = king - queen
複製程式碼

只要你學過英語,就不難猜到這裡大概率應該填寫“man”。

但是,如果你只是用了隨機的序號來代表詞彙,又如何能夠猜到這裡正確的填詞結果呢?

幸好,在深度學習領域,我們可以使用更為順手的單詞向量化工具——詞嵌入(word embeddings )。

如何用Python處理自然語言?(Spacy與Word Embedding)

如上圖這個簡化示例,詞嵌入把單詞變成多維空間上面的向量。

這樣,詞語就不再是冷冰冰的字典編號,而是具有了意義。

使用詞嵌入模型,我們需要Spacy讀取一個新的檔案。

nlp = spacy.load('en_core_web_lg')
複製程式碼

為測試讀取結果,我們讓Spacy列印“minister”這個單詞對應的向量取值。

print(nlp.vocab['minister'].vector)
複製程式碼

如何用Python處理自然語言?(Spacy與Word Embedding)

可以看到,每個單詞,用總長度為300的浮點陣列成向量來表示。

順便說一句,Spacy讀入的這個模型,是採用word2vec,在海量語料上訓練的結果。

我們來看看,此時Spacy的語義近似度判別能力。

這裡,我們將4個變數,賦值為對應單詞的向量表達結果。

dog = nlp.vocab["dog"]
cat = nlp.vocab["cat"]
apple = nlp.vocab["apple"]
orange = nlp.vocab["orange"]
複製程式碼

我們看看“狗”和“貓”的近似度:

dog.similarity(cat)
複製程式碼
0.80168545
複製程式碼

嗯,都是寵物,近似度高,可以接受。

下面看看“狗”和“蘋果”。

dog.similarity(apple)
複製程式碼
0.26339027
複製程式碼

一個動物,一個水果,近似度一下子就跌落下來了。

“狗”和“橘子”呢?

dog.similarity(orange)
複製程式碼
0.2742508
複製程式碼

可見,相似度也不高。

那麼“蘋果”和“橘子”之間呢?

apple.similarity(orange)
複製程式碼
0.5618917
複製程式碼

水果間近似度,遠遠超過水果與動物的相似程度。

測試通過。

看來Spacy利用詞嵌入模型,對語義有了一定的理解。

下面為了好玩,我們來考考它。

這裡,我們需要計算詞典中可能不存在的向量,因此Spacy自帶的similarity()函式,就顯得不夠用了。

我們從scipy中,找到相似度計算需要用到的餘弦函式。

from scipy.spatial.distance import cosine
複製程式碼

對比一下,我們直接代入“狗”和“貓”的向量,進行計算。

1 - cosine(dog.vector, cat.vector)
複製程式碼
0.8016855120658875
複製程式碼

除了保留數字外,計算結果與Spacy自帶的similarity()執行結果沒有差別。

我們把它做成一個小函式,專門處理向量輸入。

def vector_similarity(x, y):
    return 1 - cosine(x, y)
複製程式碼

用我們自編的相似度函式,測試一下“狗”和“蘋果”。

vector_similarity(dog.vector, apple.vector)
複製程式碼
0.2633902430534363
複製程式碼

與剛才的結果對比,也是一致的。

我們要表達的,是這個式子:

? - woman = king - queen
複製程式碼

我們把問號,稱為 guess_word

所以

guess_word = king - queen + woman
複製程式碼

我們把右側三個單詞,一般化記為 words。編寫下面函式,計算guess_word取值。

def make_guess_word(words):
    [first, second, third] = words
    return nlp.vocab[first].vector - nlp.vocab[second].vector + nlp.vocab[third].vector
複製程式碼

下面的函式就比較暴力了,它其實是用我們計算的 guess_word 取值,和字典中全部詞語一一核對近似性。把最為近似的10個候選單詞列印出來。

def get_similar_word(words, scope=nlp.vocab):

    guess_word = make_guess_word(words)

    similarities = []

    for word in scope:
        if not word.has_vector:
            continue

        similarity = vector_similarity(guess_word, word.vector)
        similarities.append((word, similarity))


    similarities = sorted(similarities, key=lambda item: -item[1])
    print([word[0].text for word in similarities[:10]])
複製程式碼

好了,遊戲時間開始。

我們先看看:

? - woman = king - queen
複製程式碼

即:

guess_word = king - queen + woman
複製程式碼

輸入右側詞序列:

words = ["king", "queen", "woman"]
複製程式碼

然後執行對比函式:

get_similar_word(words)
複製程式碼

這個函式執行起來,需要一段時間。請保持耐心。

執行結束之後,你會看到如下結果:

['MAN', 'Man', 'mAn', 'MAn', 'MaN', 'man', 'mAN', 'WOMAN', 'womAn', 'WOman']
複製程式碼

原來字典裡面,“男人”(man)這個詞彙有這麼多的變形啊。

但是這個例子太經典了,我們嘗試個新鮮一些的:

? - England = Paris - London
複製程式碼

即:

guess_word = Paris - London + England
複製程式碼

對你來講,絕對是簡單的題目。左側國別,右側首都,對應來看,自然是巴黎所在的法國(France)。

問題是,Spacy能猜對嗎?

我們把這幾個單詞輸入。

words = ["Paris", "London", "England"]
複製程式碼

讓Spacy來猜:

get_similar_word(words)
複製程式碼
['france', 'FRANCE', 'France', 'Paris', 'paris', 'PARIS', 'EUROPE', 'EUrope', 'europe', 'Europe']
複製程式碼

結果很令人振奮,前三個都是“法國”(France)。

下面我們做一個更有趣的事兒,把詞向量的300維的高空間維度,壓縮到一張紙(二維)上,看看詞語之間的相對位置關係。

首先我們需要讀入numpy軟體包。

import numpy as np
複製程式碼

我們把詞嵌入矩陣先設定為空。一會兒慢慢填入。

embedding = np.array([])
複製程式碼

需要演示的單詞列表,也先空著。

word_list = []
複製程式碼

我們再次讓Spacy遍歷“Yes, Minister”維基頁面中摘取的那段文字,加入到單詞列表中。注意這次我們要進行判斷:

  • 如果是標點,丟棄;
  • 如果詞彙已經在詞語列表中,丟棄。
for token in doc:
    if not(token.is_punct) and not(token.text in word_list):
        word_list.append(token.text)
複製程式碼

看看生成的結果:

word_list
複製程式碼
['The',
 'sequel',
 'Yes',
 'Prime',
 'Minister',
 'ran',
 'from',
 '1986',
 'to',
 '1988',
 'In',
 'total',
 'there',
 'were',
 '38',
 'episodes',
 'of',
 'which',
 'all',
 'but',
 'one',
 'lasted',
 'half',
 'an',
 'hour',
 'Almost',
 'ended',
 'with',
 'a',
 'variation',
 'the',
 'title',
 'series',
 'spoken',
 'as',
 'answer',
 'question',
 'posed',
 'by',
 'same',
 'character',
 'Jim',
 'Hacker',
 'Several',
 'adapted',
 'for',
 'BBC',
 'Radio',
 'and',
 'stage',
 'play',
 'was',
 'produced',
 'in',
 '2010',
 'latter',
 'leading',
 'new',
 'television',
 'on',
 'UKTV',
 'Gold',
 '2013']
複製程式碼

檢查了一下,一長串(63個)詞語列表中,沒有出現標點。一切正常。

下面,我們把每個詞彙對應的空間向量,追加到詞嵌入矩陣中。

for word in word_list:
    embedding = np.append(embedding, nlp.vocab[word].vector)
複製程式碼

看看此時詞嵌入矩陣的維度。

embedding.shape
複製程式碼
(18900,)
複製程式碼

可以看到,所有的向量內容,都被放在了一個長串上面。這顯然不符合我們的要求,我們將不同的單詞對應的詞向量,拆解到不同行上面去。

embedding = embedding.reshape(len(word_list), -1)
複製程式碼

再看看變換後詞嵌入矩陣的維度。

embedding.shape
複製程式碼
(63, 300)
複製程式碼

63個詞彙,每個長度300,這就對了。

下面我們從scikit-learn軟體包中,讀入TSNE模組。

from sklearn.manifold import TSNE
複製程式碼

我們建立一個同名小寫的tsne,作為呼叫物件。

tsne = TSNE()
複製程式碼

tsne的作用,是把高維度的詞向量(300維)壓縮到二維平面上。我們執行這個轉換過程:

low_dim_embedding = tsne.fit_transform(embedding)
複製程式碼

現在,我們手裡擁有的 low_dim_embedding ,就是63個詞彙降低到二維的向量表示了。

我們讀入繪圖工具包。

import matplotlib.pyplot as plt
%pylab inline
複製程式碼

下面這個函式,用來把二維向量的集合,繪製出來。

如果你對該函式內容細節不理解,沒關係。因為我還沒有給你係統介紹過Python下的繪圖功能。

好在這裡我們只要會呼叫它,就可以了。

def plot_with_labels(low_dim_embs, labels, filename='tsne.pdf'):
    assert low_dim_embs.shape[0] >= len(labels), "More labels than embeddings"
    plt.figure(figsize=(18, 18))  # in inches
    for i, label in enumerate(labels):
        x, y = low_dim_embs[i, :]
        plt.scatter(x, y)
        plt.annotate(label,
                 xy=(x, y),
                 xytext=(5, 2),
                 textcoords='offset points',
                 ha='right',
                 va='bottom')
    plt.savefig(filename)
複製程式碼

終於可以進行降維後的詞向量視覺化了。

請執行下面這條語句:

plot_with_labels(low_dim_embedding, word_list)
複製程式碼

你會看到這樣一個圖形。

如何用Python處理自然語言?(Spacy與Word Embedding)

請注意觀察圖中的幾個部分:

  • 年份
  • 同一單詞的大小寫形式
  • Radio 和 television
  • a 和 an

看看有什麼規律沒有?

我發現了一個有意思的現象——每次執行tsne,產生的二維視覺化圖都不一樣!

不過這也正常,因為這段話之中出現的單詞,並非都有預先訓練好的向量。

這樣的單詞,被Spacy進行了隨機化等處理。

因此,每一次生成高維向量,結果都不同。不同的高維向量,壓縮到二維,結果自然也會有區別。

問題來了,如果我希望每次執行的結果都一致,該如何處理呢?

這個問題,作為課後思考題,留給你自行解答。

細心的你可能發現了,執行完最後一條語句後,頁面左側邊欄檔案列表中,出現了一個新的pdf檔案。

如何用Python處理自然語言?(Spacy與Word Embedding)

這個pdf,就是你剛剛生成的視覺化結果。你可以雙擊該檔名稱,在新的標籤頁中檢視。

如何用Python處理自然語言?(Spacy與Word Embedding)

看,就連pdf檔案,Jupyter Lab也能正確顯示。

下面,是練習時間。

請把ipynb出現的文字內容,替換為你感興趣的段落和詞彙,再嘗試執行一次吧。

原始碼

執行了全部程式碼,並且嘗試替換了自己需要分析的文字,成功執行後,你是不是很有成就感?

你可能想要更進一步挖掘Spacy的功能,並且希望在本地復現執行環境與結果。

沒問題,請使用這個連結t.cn/R35MIKh)下載本文用到的全部原始碼和執行環境配置檔案(Pipenv)壓縮包。

如果你知道如何使用github,也歡迎用這個連結t.cn/R35MEqk)訪問對應的github repo,進行clone或者fork等操作。

如何用Python處理自然語言?(Spacy與Word Embedding)

當然,要是能給我的repo加一顆星,就更好了。

謝謝!

小結

本文利用Python自然語言處理工具包Spacy,非常簡要地為你演示了以下NLP功能:

  • 詞性分析
  • 命名實體識別
  • 依賴關係刻畫
  • 詞嵌入向量的近似度計算
  • 詞語降維和視覺化

希望學過之後,你成功地在工具箱裡又新增了一件趁手的兵器。

願它在以後的研究和工作中,助你披荊斬棘,馬到成功。

加油!

討論

你之前做過自然語言處理專案嗎?使用過哪些工具包?除了本文介紹的這些基本功能外,你覺得還有哪些NLP功能是非常基礎而重要的?你是如何學習它們的呢?歡迎留言,把你的經驗和思考分享給大家,我們一起交流討論。

喜歡請點贊。還可以微信關注和置頂我的公眾號“玉樹芝蘭”(nkwangshuyi)

如果你對資料科學感興趣,不妨閱讀我的系列教程索引貼《如何高效入門資料科學?》,裡面還有更多的有趣問題及解法。

相關文章