新聞中心
進(jìn)一步學(xué)習(xí)自然語(yǔ)言處理的基本概念
在 之前的文章 里,我介紹了自然語(yǔ)言處理natural language processing(NLP)和賓夕法尼亞大學(xué)研發(fā)的自然語(yǔ)言處理工具包Natural Language Toolkit (NLTK)。我演示了用 Python 解析文本和定義停頓詞stopword的方法,并介紹了語(yǔ)料庫(kù)corpus的概念。語(yǔ)料庫(kù)是由文本構(gòu)成的數(shù)據(jù)集,通過(guò)提供現(xiàn)成的文本數(shù)據(jù)來(lái)輔助文本處理。在這篇文章里,我將繼續(xù)用各種語(yǔ)料庫(kù)對(duì)文本進(jìn)行對(duì)比和分析。
這篇文章主要包括以下部分:
- 詞網(wǎng)WordNet和同義詞集synset
- 相似度比較Similarity comparison
- 樹Tree和樹庫(kù)treebank
- 命名實(shí)體識(shí)別Named entity recognition
詞網(wǎng)和同義詞集
詞網(wǎng)WordNet 是 NLTK 里的一個(gè)大型詞匯數(shù)據(jù)庫(kù)語(yǔ)料庫(kù)。詞網(wǎng)包含各單詞的諸多認(rèn)知同義詞cognitive synonyms(認(rèn)知同義詞常被稱作“同義詞集synset”)。在詞網(wǎng)里,名詞、動(dòng)詞、形容詞和副詞,各自被組織成一個(gè)同義詞的網(wǎng)絡(luò)。
詞網(wǎng)是一個(gè)很有用的文本分析工具。它有面向多種語(yǔ)言的版本(漢語(yǔ)、英語(yǔ)、日語(yǔ)、俄語(yǔ)和西班牙語(yǔ)等),也使用多種許可證(從開源許可證到商業(yè)許可證都有)。初代版本的詞網(wǎng)由普林斯頓大學(xué)研發(fā),面向英語(yǔ),使用類 MIT 許可證MIT-like license。
因?yàn)橐粋€(gè)詞可能有多個(gè)意義或多個(gè)詞性,所以可能與多個(gè)同義詞集相關(guān)聯(lián)。每個(gè)同義詞集通常提供下列屬性:
< 如顯示不全,請(qǐng)左右滑動(dòng) >
| 屬性 | 定義 | 例子 |
|---|---|---|
| 名稱Name | 此同義詞集的名稱 | 單詞 code 有 5 個(gè)同義詞集,名稱分別是 code.n.01、 code.n.02、 code.n.03、code.v.01 和 code.v.02 |
| 詞性POS | 此同義詞集的詞性 | 單詞 code 有 3 個(gè)名詞詞性的同義詞集和 2 個(gè)動(dòng)詞詞性的同義詞集 |
| 定義Definition | 該詞作對(duì)應(yīng)詞性時(shí)的定義 | 動(dòng)詞 code 的一個(gè)定義是:(計(jì)算機(jī)科學(xué))數(shù)據(jù)或計(jì)算機(jī)程序指令的象征性排列symbolic arrangement |
| 例子Example | 使用該詞的例子 | code 一詞的例子:We should encode the message for security reasons |
| 詞元Lemma | 與該詞相關(guān)聯(lián)的其他同義詞集(包括那些不一定嚴(yán)格地是該詞的同義詞,但可以大體看作同義詞的);詞元直接與其他詞元相關(guān)聯(lián),而不是直接與單詞word相關(guān)聯(lián) | code.v.02 的詞元是 code.v.02.encipher、code.v.02.cipher、code.v.02.cypher、code.v.02.encrypt、code.v.02.inscribe 和 code.v.02.write_in_code |
| 反義詞Antonym | 意思相反的詞 | 詞元 encode.v.01.encode 的反義詞是 decode.v.01.decode |
| 上義詞Hypernym | 該詞所屬的一個(gè)范疇更大的詞 | code.v.01 的一個(gè)上義詞是 tag.v.01 |
| 分項(xiàng)詞Meronym | 屬于該詞組成部分的詞 | computer 的一個(gè)分項(xiàng)詞是 chip |
| 總項(xiàng)詞Holonym | 該詞作為組成部分所屬的詞 | window 的一個(gè)總項(xiàng)詞是 computer screen |
同義詞集還有一些其他屬性,在 <你的 Python 安裝路徑>/Lib/site-packages 下的 nltk/corpus/reader/wordnet.py,你可以找到它們。
下面的代碼或許可以幫助理解。
這個(gè)函數(shù):
from nltk.corpus import wordnetdef synset_info(synset):print("Name", synset.name())print("POS:", synset.pos())print("Definition:", synset.definition())print("Examples:", synset.examples())print("Lemmas:", synset.lemmas())print("Antonyms:", [lemma.antonyms() for lemma in synset.lemmas() if len(lemma.antonyms()) > 0])print("Hypernyms:", synset.hypernyms())print("Instance Hypernyms:", synset.instance_hypernyms())print("Part Holonyms:", synset.part_holonyms())print("Part Meronyms:", synset.part_meronyms())print()synsets = wordnet.synsets('code')print(len(synsets), "synsets:")for synset in synsets:synset_info(synset)
將會(huì)顯示:
5 synsets:Name code.n.01POS: nDefinition: a set of rules or principles or laws (especially written ones)Examples: []Lemmas: [Lemma('code.n.01.code'), Lemma('code.n.01.codification')]Antonyms: []Hypernyms: [Synset('written_communication.n.01')]Instance Hpernyms: []Part Holonyms: []Part Meronyms: []...Name code.n.03POS: nDefinition: (computer science) the symbolic arrangement of data or instructions in a computer program or the set of such instructionsExamples: []Lemmas: [Lemma('code.n.03.code'), Lemma('code.n.03.computer_code')]Antonyms: []Hypernyms: [Synset('coding_system.n.01')]Instance Hpernyms: []Part Holonyms: []Part Meronyms: []...Name code.v.02POS: vDefinition: convert ordinary language into codeExamples: ['We should encode the message for security reasons']Lemmas: [Lemma('code.v.02.code'), Lemma('code.v.02.encipher'), Lemma('code.v.02.cipher'), Lemma('code.v.02.cypher'), Lemma('code.v.02.encrypt'), Lemma('code.v.02.inscribe'), Lemma('code.v.02.write_in_code')]Antonyms: []Hypernyms: [Synset('encode.v.01')]Instance Hpernyms: []Part Holonyms: []Part Meronyms: []
同義詞集synset和詞元lemma在詞網(wǎng)里是按照樹狀結(jié)構(gòu)組織起來(lái)的,下面的代碼會(huì)給出直觀的展現(xiàn):
def hypernyms(synset):return synset.hypernyms()synsets = wordnet.synsets('soccer')for synset in synsets:print(synset.name() + " tree:")pprint(synset.tree(rel=hypernyms))print()
code.n.01 tree:[Synset('code.n.01'),[Synset('written_communication.n.01'),...code.n.02 tree:[Synset('code.n.02'),[Synset('coding_system.n.01'),...code.n.03 tree:[Synset('code.n.03'),...code.v.01 tree:[Synset('code.v.01'),[Synset('tag.v.01'),...code.v.02 tree:[Synset('code.v.02'),[Synset('encode.v.01'),...
詞網(wǎng)并沒(méi)有涵蓋所有的單詞和其信息(現(xiàn)今英語(yǔ)有約 17,0000 個(gè)單詞,最新版的 詞網(wǎng) 涵蓋了約 15,5000 個(gè)),但它開了個(gè)好頭。掌握了“詞網(wǎng)”的各個(gè)概念后,如果你覺(jué)得它詞匯少,不能滿足你的需要,可以轉(zhuǎn)而使用其他工具。或者,你也可以打造自己的“詞網(wǎng)”!
自主嘗試
使用 Python 庫(kù),下載維基百科的 “open source” 頁(yè)面,并列出該頁(yè)面所有單詞的同義詞集synset和詞元lemma。
相似度比較
相似度比較的目的是識(shí)別出兩篇文本的相似度,在搜索引擎、聊天機(jī)器人等方面有很多應(yīng)用。
比如,相似度比較可以識(shí)別 football 和 soccer 是否有相似性。
syn1 = wordnet.synsets('football')syn2 = wordnet.synsets('soccer')# 一個(gè)單詞可能有多個(gè) 同義詞集,需要把 word1 的每個(gè)同義詞集和 word2 的每個(gè)同義詞集分別比較for s1 in syn1:for s2 in syn2:print("Path similarity of: ")print(s1, '(', s1.pos(), ')', '[', s1.definition(), ']')print(s2, '(', s2.pos(), ')', '[', s2.definition(), ']')print(" is", s1.path_similarity(s2))print()
Path similarity of:Synset('football.n.01') ( n ) [ any of various games played with a ball (round or oval) in which two teams try to kick or carry or propel the ball into each other's goal ]Synset('soccer.n.01') ( n ) [ a football game in which two teams of 11 players try to kick or head a ball into the opponents' goal ]is 0.5Path similarity of:Synset('football.n.02') ( n ) [ the inflated oblong ball used in playing American football ]Synset('soccer.n.01') ( n ) [ a football game in which two teams of 11 players try to kick or head a ball into the opponents' goal ]is 0.05
兩個(gè)詞各個(gè)同義詞集之間路徑相似度path similarity最大的是 0.5,表明它們關(guān)聯(lián)性很大(路徑相似度path similarity指兩個(gè)詞的意義在上下義關(guān)系的詞匯分類結(jié)構(gòu)hypernym/hypnoym taxonomy中的最短距離)。
那么 code 和 bug 呢?這兩個(gè)計(jì)算機(jī)領(lǐng)域的詞的相似度是:
Path similarity of:Synset('code.n.01') ( n ) [ a set of rules or principles or laws (especially written ones) ]Synset('bug.n.02') ( n ) [ a fault or defect in a computer program, system, or machine ]is 0.1111111111111111...Path similarity of:Synset('code.n.02') ( n ) [ a coding system used for transmitting messages requiring brevity or secrecy ]Synset('bug.n.02') ( n ) [ a fault or defect in a computer program, system, or machine ]is 0.09090909090909091...Path similarity of:Synset('code.n.03') ( n ) [ (computer science) the symbolic arrangement of data or instructions in a computer program or the set of such instructions ]Synset('bug.n.02') ( n ) [ a fault or defect in a computer program, system, or machine ]is 0.09090909090909091
這些是這兩個(gè)詞各同義詞集之間路徑相似度path similarity的最大值,這些值表明兩個(gè)詞是有關(guān)聯(lián)性的。
NLTK 提供多種相似度計(jì)分器similarity scorers,比如:
- path_similarity
- lch_similarity
- wup_similarity
- res_similarity
- jcn_similarity
- lin_similarity
要進(jìn)一步了解這些相似度計(jì)分器similarity scorers,請(qǐng)查看 WordNet Interface 的 Similarity 部分。
自主嘗試
使用 Python 庫(kù),從維基百科的 Category: Lists of computer terms 生成一個(gè)術(shù)語(yǔ)列表,然后計(jì)算各術(shù)語(yǔ)之間的相似度。
樹和樹庫(kù)
使用 NLTK,你可以把文本表示成樹狀結(jié)構(gòu)以便進(jìn)行分析。
這里有一個(gè)例子:
這是一份簡(jiǎn)短的文本,對(duì)其做預(yù)處理和詞性標(biāo)注:
import nltktext = "I love open source"# Tokenize to wordswords = nltk.tokenize.word_tokenize(text)# POS tag the wordswords_tagged = nltk.pos_tag(words)
要把文本轉(zhuǎn)換成樹狀結(jié)構(gòu),你必須定義一個(gè)語(yǔ)法grammar。這個(gè)例子里用的是一個(gè)基于 Penn Treebank tags 的簡(jiǎn)單語(yǔ)法。
# A simple grammar to create treegrammar = "NP: {<JJ><NN>}"
然后用這個(gè)語(yǔ)法grammar創(chuàng)建一顆樹tree:
# Create treeparser = nltk.RegexpParser(grammar)tree = parser.parse(words_tagged)pprint(tree)
運(yùn)行上面的代碼,將得到:
Tree('S', [('I', 'PRP'), ('love', 'VBP'), Tree('NP', [('open', 'JJ'), ('source', 'NN')])])
你也可以圖形化地顯示結(jié)果。
tree.draw()
NLTK Tree
這個(gè)樹狀結(jié)構(gòu)有助于準(zhǔn)確解讀文本的意思。比如,用它可以找到文本的 主語(yǔ):
subject_tags = ["NN", "NNS", "NP", "NNP", "NNPS", "PRP", "PRP$"]def subject(sentence_tree):for tagged_word in sentence_tree:# A crude logic for this case - first word with these tags is considered subjectif tagged_word[1] in subject_tags:return tagged_word[0]print("Subject:", subject(tree))
結(jié)果顯示主語(yǔ)是 I:
Subject: I
這是一個(gè)比較基礎(chǔ)的文本分析步驟,可以用到更廣泛的應(yīng)用場(chǎng)景中。 比如,在聊天機(jī)器人方面,如果用戶告訴機(jī)器人:“給我媽媽 Jane 預(yù)訂一張機(jī)票,1 月 1 號(hào)倫敦飛紐約的”,機(jī)器人可以用這種分析方法解讀這個(gè)指令:
動(dòng)作: 預(yù)訂
動(dòng)作的對(duì)象: 機(jī)票
乘客: Jane
出發(fā)地: 倫敦
目的地: 紐約
日期: (明年)1 月 1 號(hào)
樹庫(kù)treebank指由許多預(yù)先標(biāo)注好的樹tree構(gòu)成的語(yǔ)料庫(kù)?,F(xiàn)在已經(jīng)有面向多種語(yǔ)言的樹庫(kù),既有開源的,也有限定條件下才能免費(fèi)使用的,以及商用的。其中使用最廣泛的是面向英語(yǔ)的賓州樹庫(kù)。賓州樹庫(kù)取材于華爾街日?qǐng)?bào)Wall Street Journal。NLTK 也包含了賓州樹庫(kù)作為一個(gè)子語(yǔ)料庫(kù)。下面是一些使用樹庫(kù)treebank的方法:
words = nltk.corpus.treebank.words()print(len(words), "words:")print(words)tagged_sents = nltk.corpus.treebank.tagged_sents()print(len(tagged_sents), "sentences:")print(tagged_sents)
100676 words:['Pierre', 'Vinken', ',', '61', 'years', 'old', ',', ...]3914 sentences:[[('Pierre', 'NNP'), ('Vinken', 'NNP'), (',', ','), ('61', 'CD'), ('years', 'NNS'), ('old', 'JJ'), (',', ','), ('will', 'MD'), ('join', 'VB'), ('the', 'DT'), ('board', 'NN'), ('as', 'IN'), ('a', 'DT'), ('nonexecutive', 'JJ'), ('director', 'NN'), ...]
查看一個(gè)句子里的各個(gè)標(biāo)簽tags:
sent0 = tagged_sents[0]pprint(sent0)
[('Pierre', 'NNP'),('Vinken', 'NNP'),(',', ','),('61', 'CD'),('years', 'NNS'),...
定義一個(gè)語(yǔ)法grammar來(lái)把這個(gè)句子轉(zhuǎn)換成樹狀結(jié)構(gòu):
grammar = '''Subject: {} SubjectInfo: {} Action: {} Object: {} Stopwords: {- }
ObjectInfo: {} When: {} '''parser = nltk.RegexpParser(grammar)tree = parser.parse(sent0)print(tree)
(S(Subject Pierre/NNP Vinken/NNP),/,(SubjectInfo 61/CD years/NNS old/JJ),/,(Action will/MD join/VB)(Object the/DT board/NN)as/INa/DT(ObjectInfo nonexecutive/JJ director/NN)(Subject Nov./NNP)29/CD./.)
圖形化地顯示:
tree.draw()
NLP Treebank image
樹trees和樹庫(kù)treebanks的概念是文本分析的一個(gè)強(qiáng)大的組成部分。
自主嘗試
使用 Python 庫(kù),下載維基百科的 “open source” 頁(yè)面,將得到的文本以圖形化的樹狀結(jié)構(gòu)展現(xiàn)出來(lái)。
命名實(shí)體識(shí)別
無(wú)論口語(yǔ)還是書面語(yǔ)都包含著重要數(shù)據(jù)。文本處理的主要目標(biāo)之一,就是提取出關(guān)鍵數(shù)據(jù)。幾乎所有應(yīng)用場(chǎng)景所需要提取關(guān)鍵數(shù)據(jù),比如航空公司的訂票機(jī)器人或者問(wèn)答機(jī)器人。 NLTK 為此提供了一個(gè)命名實(shí)體識(shí)別named entity recognition的功能。
這里有一個(gè)代碼示例:
sentence = 'Peterson first suggested the name "open source" at Palo Alto, California'
驗(yàn)證這個(gè)句子里的人名name和地名place有沒(méi)有被識(shí)別出來(lái)。照例先預(yù)處理:
import nltkwords = nltk.word_tokenize(sentence)pos_tagged = nltk.pos_tag(words)
運(yùn)行命名實(shí)體標(biāo)注器named-entity tagger:
ne_tagged = nltk.ne_chunk(pos_tagged)print("NE tagged text:")print(ne_tagged)print()
NE tagged text:(S(PERSON Peterson/NNP)first/RBsuggested/VBDthe/DTname/NN``/``open/JJsource/NN''/''at/IN(FACILITY Palo/NNP Alto/NNP),/,(GPE California/NNP))
上面的結(jié)果里,命名實(shí)體被識(shí)別出來(lái)并做了標(biāo)注;只提取這個(gè)樹tree里的命名實(shí)體:
print("Recognized named entities:")for ne in ne_tagged:if hasattr(ne, "label"):print(ne.label(), ne[0:])
Recognized named entities:PERSON [('Peterson', 'NNP')]FACILITY [('Palo', 'NNP'), ('Alto', 'NNP')]GPE [('California', 'NNP')]
圖形化地顯示:
ne_tagged.draw()
NLTK Treebank tree
NLTK 內(nèi)置的命名實(shí)體標(biāo)注器named-entity tagger,使用的是賓州法尼亞大學(xué)的 Automatic Content Extraction(ACE)程序。該標(biāo)注器能夠識(shí)別組織機(jī)構(gòu)ORGANIZATION、人名PERSON、地名LOCATION、設(shè)施FACILITY和地緣政治實(shí)體geopolitical entity等常見(jiàn)實(shí)體entites。
NLTK 也可以使用其他標(biāo)注器tagger,比如 Stanford Named Entity Recognizer. 這個(gè)經(jīng)過(guò)訓(xùn)練的標(biāo)注器用 Java 寫成,但 NLTK 提供了一個(gè)使用它的接口(詳情請(qǐng)查看 nltk.parse.stanford 或 nltk.tag.stanford)。
自主嘗試
使用 Python 庫(kù),下載維基百科的 “open source” 頁(yè)面,并識(shí)別出對(duì)開源open source有影響力的人的名字,以及他們?yōu)殚_源open source做貢獻(xiàn)的時(shí)間和地點(diǎn)。
高級(jí)實(shí)踐
如果你準(zhǔn)備好了,嘗試用這篇文章以及此前的文章介紹的知識(shí)構(gòu)建一個(gè)超級(jí)結(jié)構(gòu)superstructure。
使用 Python 庫(kù),下載維基百科的 “Category: Computer science page”,然后:
- 找出其中頻率最高的單詞unigrams、二元搭配bigrams和三元搭配trigrams,將它們作為一個(gè)關(guān)鍵詞列表或者技術(shù)列表。相關(guān)領(lǐng)域的學(xué)生或者工程師需要了解這樣一份列表里的內(nèi)容。
- 圖形化地顯示這個(gè)領(lǐng)域里重要的人名、技術(shù)、日期和地點(diǎn)。這會(huì)是一份很棒的信息圖。
- 構(gòu)建一個(gè)搜索引擎。你的搜索引擎性能能夠超過(guò)維基百科嗎?
下一步?
自然語(yǔ)言處理是應(yīng)用構(gòu)建application building的典型支柱。NLTK 是經(jīng)典、豐富且強(qiáng)大的工具集,提供了為現(xiàn)實(shí)世界構(gòu)建有吸引力、目標(biāo)明確的應(yīng)用的工作坊。
在這個(gè)系列的文章里,我用 NLTK 作為例子,展示了自然語(yǔ)言處理可以做什么。自然語(yǔ)言處理和 NLTK 還有太多東西值得探索,這個(gè)系列的文章只是幫助你探索它們的切入點(diǎn)。
如果你的需求增長(zhǎng)到 NLTK 已經(jīng)滿足不了了,你可以訓(xùn)練新的模型或者向 NLTK 添加新的功能?;?NLTK 構(gòu)建的新的自然語(yǔ)言處理庫(kù)正在不斷涌現(xiàn),機(jī)器學(xué)習(xí)也正被深度用于自然語(yǔ)言處理。
分享標(biāo)題:進(jìn)階教程:用Python和NLTK進(jìn)行NLP分析
本文來(lái)源:http://www.5511xx.com/article/copodgc.html


咨詢
建站咨詢

