【NLP】利用維基百科促進(jìn)自然語(yǔ)言處理
編譯 | VK
來(lái)源 | Towards Data Science

介紹
自然語(yǔ)言處理(NLP)正在興起。計(jì)算語(yǔ)言學(xué)和人工智能正在聯(lián)手促進(jìn)新的突破。
雖然研究的重點(diǎn)是大幅改善自然語(yǔ)言處理技術(shù),但企業(yè)正將這項(xiàng)技術(shù)視為一項(xiàng)戰(zhàn)略資產(chǎn)。主要原因是存在著大量文本數(shù)據(jù)。談到數(shù)字化,尤其是對(duì)企業(yè)而言,重要的是要記住,文檔本身就是數(shù)字化的,因此,文本數(shù)據(jù)是知識(shí)的主要來(lái)源。
然而,當(dāng)我們?cè)噲D磨練一個(gè)自然語(yǔ)言處理任務(wù)時(shí),最大的瓶頸之一是數(shù)據(jù)的訓(xùn)練。當(dāng)涉及到實(shí)際的應(yīng)用程序時(shí),例如在特定領(lǐng)域中,我們面臨著低資源數(shù)據(jù)的問(wèn)題。訓(xùn)練數(shù)據(jù)有兩個(gè)主要問(wèn)題:(i)獲取大量數(shù)據(jù)的困難;(ii)為訓(xùn)練和測(cè)試注釋可用數(shù)據(jù)的過(guò)程非常耗時(shí)。
面對(duì)這些問(wèn)題,計(jì)算機(jī)科學(xué)界給予了極大的關(guān)注。特別是,最新的計(jì)算進(jìn)展提出了兩種方法來(lái)克服低資源數(shù)據(jù)問(wèn)題:
微調(diào)預(yù)訓(xùn)練的語(yǔ)言模型,如BERT或GPT-3;
利用高質(zhì)量的開(kāi)放數(shù)據(jù)存儲(chǔ)庫(kù),如Wikipedia或ConceptNet。
目前大多數(shù)計(jì)算語(yǔ)言學(xué)開(kāi)放庫(kù)都提供了基于這兩種方法之一的NLP工具開(kāi)發(fā)架構(gòu)。我們現(xiàn)在演示如何利用Wikipedia提高兩個(gè)NLP任務(wù)的性能:命名實(shí)體識(shí)別和主題模型。
從句子中提取維基百科信息
有幾種工具可用于處理來(lái)自維基百科的信息。對(duì)于文本數(shù)據(jù)的自動(dòng)處理,我們使用了一個(gè)名為SpikeX的spaCy開(kāi)放項(xiàng)目。
SpikeX是一個(gè)spaCy管道的管道集合,spaCy管道是一個(gè)用于NLP的python庫(kù)。SpikeX由一家意大利公司(Erre Quadro Srl)開(kāi)發(fā),旨在幫助構(gòu)建知識(shí)提取工具。
pip install --no-cache -U git+https://github.com/erre-quadro/spikex.git@develop
spikex download-wikigraph enwiki_core
spacy download en_core_web_sm
SpikeX有兩個(gè)主要功能:
1.給定一個(gè)Wikipedia頁(yè)面,它會(huì)提取所有相應(yīng)的類(lèi)別。
from wasabi import msg
from time import process_time as time
page = "Natural_Language_Processing"
print(f"Categories for `{page}`:")
t = time()
for c in wg.get_categories(page):
print("\t", c)
for cc in wg.get_categories(c):
print("\t\t->", cc)
msg.good(f"Success in {time() - t:.2f}s")
“Natural_Language_Processing”的類(lèi)別:
Categories for `Natural_Language_Processing`:
Category:Artificial_intelligence
-> Category:Emerging_technologies
-> Category:Cybernetics
-> Category:Subfields_of_computer_science
-> Category:Computational_neuroscience
-> Category:Futures_studies
-> Category:Cognitive_science
-> Category:Personhood
-> Category:Formal_sciences
Category:Speech_recognition
-> Category:Artificial_intelligence_applications
-> Category:Computational_linguistics
-> Category:Human–computer_interaction
-> Category:Digital_signal_processing
-> Category:Speech
Category:Natural_language_processing
-> Category:Artificial_intelligence_applications
-> Category:Computational_linguistics
Category:Computational_linguistics
-> Category:Computational_social_science
2.給定一個(gè)句子,它會(huì)在文本中找到與維基百科頁(yè)面標(biāo)題匹配的塊。
from spacy import load as spacy_load
from spikex.wikigraph import load as wg_load
from spikex.pipes import WikiPageX
# 加載一個(gè)spacy模型,然后獲取doc對(duì)象
nlp = spacy_load('en_core_web_sm')
doc = nlp('Elon Musk runs Tesla Motors')
# 加載WikiGraph
wg = wg_load('enwiki_core')
# 獲取WikiPageX并提取所有頁(yè)面
wikipagex = WikiPageX(wg)
doc = wikipagex(doc)
# 查看從文檔中提取的所有頁(yè)面
for span in doc._.wiki_spans:
print(span)
print(span._.wiki_pages)
print('------')
Elon Musk
('Elon_Musk', 'Elon_musk', 'Elon_Musk_(book)', 'Elon_Musk_(2015_book)', 'Elon_Musk_(2015)', 'Elon_Musk_(biography)', 'Elon_Musk_(2015_biography)', 'Elon_Musk_(Ashlee_Vance)')
------
Elon
('Elon_(Judges)', 'Elon_(name)', 'Elon_(Hebrew_Judge)', 'Elon_(Ilan)', 'Elon_(disambiguation)', 'Elon_(biblical_judge)', 'Elon_(chemical)', 'Elon')
------
Musk
('Musk', 'MuSK', 'Musk_(wine)', 'Musk_(song)', 'Musk_(Tash_Sultana_song)', 'Musk_(disambiguation)')
------
runs
('Runs_(baseball_statistics)', 'Runs', 'Runs_(cricket)', 'Runs_(music)', 'Runs_(baseball)', 'Runs_(Baseball)', 'Runs_(musical)')
------
Tesla Motors
('Tesla_motors', 'Tesla_Motors')
------
Tesla
('Tesla_(band)', 'Tesla_(unit)', 'Tesla_(Czechoslovak_company)', 'Tesla_(crater)', 'Tesla_(microarchitecture)', 'Tesla_(2020_film)', 'Tesla_(car)', 'Tesla_(GPU)', 'TESLA', 'Tesla_(physicist)', 'Tesla_(group)', 'Tesla_(opera)', 'Tesla_(Bleach)', 'Tesla_(company)', 'Tesla_(disambiguation)', 'Tesla_(2016_film)', 'TESLA_(Czechoslovak_company)', 'Tesla_(unit_of_measure)', 'Tesla_(vehicles)', 'Tesla_(vehicle)', 'Tesla_(film)', 'Tesla_(album)', 'Tesla_(Flux_Pavilion_album)', 'Tesla_(surname)', 'Tesla')
------
Motors ('Motors')
如我們所見(jiàn),在第一個(gè)示例中,SpikeX提取Wikipedia頁(yè)面“Natural_Language_Processing”所屬的所有類(lèi)別。例如,“Natural_Language_Processing/`”屬于“人工智能”、“語(yǔ)音識(shí)別”和“計(jì)算語(yǔ)言學(xué)”的范疇。
在第二個(gè)例子中,對(duì)于“Elon Musk runs Tesla Motors”這句話(huà),SpikeX提取了該句中可能在Wikipedia上有一個(gè)頁(yè)面的所有頁(yè)面。
我們現(xiàn)在了解如何使用這兩個(gè)特性來(lái)執(zhí)行命名實(shí)體識(shí)別和主題模型。
命名實(shí)體識(shí)別
命名實(shí)體識(shí)別(Named Entity Recognition,NER)是一項(xiàng)NLP任務(wù),它試圖將文本中提到的實(shí)體定位并分類(lèi)為預(yù)定義的類(lèi)別(如人名、組織、位置等)。
有不同的方法處理這項(xiàng)任務(wù):基于規(guī)則的系統(tǒng),訓(xùn)練深層神經(jīng)網(wǎng)絡(luò)的方法,或是訓(xùn)練語(yǔ)言模型的方法。例如,Spacy嵌入了一個(gè)預(yù)訓(xùn)練過(guò)的命名實(shí)體識(shí)別系統(tǒng),該系統(tǒng)能夠從文本中識(shí)別常見(jiàn)的類(lèi)別。
我們現(xiàn)在著手構(gòu)建一個(gè)能夠識(shí)別屬于某個(gè)維基百科類(lèi)別的文本片段的NER系統(tǒng)。讓我們考慮下面的例句:
“Named Entity Recognition and Topic Modeling are two tasks of Natural Language Processing”
這個(gè)句子可能包含三個(gè)實(shí)體:“命名實(shí)體識(shí)別”,“主題模型”和“自然語(yǔ)言處理”。這三個(gè)實(shí)體各自有屬于特定類(lèi)別的維基百科頁(yè)面。

在這幅圖中,我們可以看到不同的類(lèi)別是如何在三個(gè)實(shí)體之間傳播的。在這種情況下,類(lèi)別可以看作是我們要從文本中提取的實(shí)體的標(biāo)簽。我們現(xiàn)在可以利用SpikeX的兩個(gè)特性來(lái)構(gòu)建一個(gè)定制的NER系統(tǒng),它接受兩個(gè)變量的輸入:(i)句子的文本和(ii)我們想要檢測(cè)的類(lèi)別。
from wasabi import msg
from spacy import load as spacy_load
from spikex.wikigraph import load as wg_load
from spikex.pipes import WikiPageX
def wiki_entity_recognition(text, entity_root):
entities = []
wg = wg_load("enwiki_core") # 加載WikiGraph
wikipagex = WikiPageX(wg) # 創(chuàng)建wikipagex
nlp = spacy_load("en_core_web_sm")
doc = wikipagex(nlp(text)) # get doc with wiki pages extracted 獲取doc文檔
entity_root = entity_root.replace(" ", "_") # 修復(fù)空格,只是以防萬(wàn)一
# 獲取距離為2的根目錄的上下文
context = set(wg.get_categories(entity_root, distance=2))
for span in doc._.wiki_spans:
page_seen = set()
for page in span._.wiki_pages:
# 避免重復(fù)
pageid = wg.get_pageid(page)
if pageid in page_seen:
continue
page_seen.add(pageid)
# 檢查與上下文的交集
categories = set(wg.get_categories(page))
if len(set.intersection(categories, context)) == 0:
continue
# 實(shí)體
entities.append((span, page))
return entities
# 定義文本
text = "Named Entity Recognition and Topic Modeling are two tasks of Natural Language Processing"
# 定義類(lèi)別
entity_root = "Computational linguistic"
for ent in wiki_entity_recognition(text, entity_root):
print("%s - %s"%(ent[0],ent[1].upper()))
Named Entity Recognition - COMPUTATIONAL LINGUISTIC
Topic Modeling - COMPUTATIONAL LINGUISTIC
Natural Language Processing - COMPUTATIONAL LINGUISTIC
將維基百科的類(lèi)別定義為NER任務(wù)的標(biāo)簽提供了定義NER系統(tǒng)的可能性,從而避免了數(shù)據(jù)訓(xùn)練問(wèn)題。進(jìn)一步的例子是使用display表示基于維基百科類(lèi)別的NER系統(tǒng)提取的實(shí)體。

在這個(gè)例子中,“Programming Language”和“Computational Linguistics”作為輸入給出,然后在文本中搜索。
主題模型
當(dāng)談到主題模型時(shí),我們通常指的是能夠發(fā)現(xiàn)文本體的“隱藏語(yǔ)義結(jié)構(gòu)”的NLP工具。
最近,有人討論“為了自動(dòng)文本分析的目的,主題的定義在某種程度上取決于所采用的方法”[1]。潛Dirichlet分配(LDA)是一種流行的主題模型方法,它使用概率模型在文檔集合中提取主題。
另一個(gè)著名的方法是TextRank,它使用網(wǎng)絡(luò)分析來(lái)檢測(cè)單個(gè)文檔中的主題。近年來(lái),自然語(yǔ)言處理領(lǐng)域的研究也引入了一些能夠在句子水平上提取主題的方法。一個(gè)例子是語(yǔ)義超圖,這是一種“結(jié)合機(jī)器學(xué)習(xí)和符號(hào)方法的優(yōu)點(diǎn),從句子的意義推斷主題的新技術(shù)”[1]。
我們現(xiàn)在看到如何使用Wikipedia在句子和文檔級(jí)別執(zhí)行主題模型。
讓我們考慮專(zhuān)利US20130097769A1的以下文本。
Encapsulated protective suits may be worn in contaminated areas to protect the wearer of the suit. For example, workers may wear an encapsulated protective suit while working inside of a nuclear powered electrical generating plant or in the presence of radioactive materials. An encapsulated protective suit may be a one-time use type of system, wherein after a single use the suit is disposed of. An encapsulated protective suit may receive breathing air during normal operating conditions via an external air flow hose connected to the suit. The air may be supplied, for example, by a power air purifying respirator (PAPR) that may be carried by the user.
topics = Counter()
for sent in doc.sents:
topics = Counter()
sent = nlp(sent.text)
sent = wikipagex(sent)
print(sent)
print('Topics in the sentence:')
for span in sent._.wiki_spans:
if (
len(span._.wiki_pages) > 1
or span[0].pos_ not in good_pos
or span[-1].pos_ not in good_pos
):
continue
topics.update(wg.get_categories(span._.wiki_pages[0], distance=2))
for topic, count in topics.most_common():
print('\t',topic.replace('Category:',''), "->", count)
print('----')
Sentence:
Encapsulated protective suits may be worn in contaminated areas to protect the wearer of the suit.
Topics in the sentence:
Safety -> 1
Euthenics -> 1
----
Sentence:
For example, workers may wear an encapsulated protective suit while working inside of a nuclear powered electrical generating plant or in the presence of radioactive materials.
Topics in the sentence:
Safety -> 1
Euthenics -> 1
Electricity -> 1
Electromagnetism -> 1
Locale_(geographic) -> 1
Electric_power_generation -> 1
Power_stations -> 1
Infrastructure -> 1
Energy_conversion -> 1
Chemistry -> 1
Radioactivity -> 1
----
Sentence:
An encapsulated protective suit may be a one-time use type of system, wherein after a single use the suit is disposed of.
Topics in the sentence:
Safety -> 1
Euthenics -> 1
Transportation_planning -> 1
Feminist_economics -> 1
Schools_of_economic_thought -> 1
Land_management -> 1
Architecture -> 1
Planning -> 1
Transport -> 1
Feminism -> 1
Urban_planning -> 1
Feminist_theory -> 1
Urbanization -> 1
Spatial_planning -> 1
Social_sciences -> 1
----
Sentence:
An encapsulated protective suit may receive breathing air during normal operating conditions via an external air flow hose connected to the suit.
Topics in the sentence:
Safety -> 1
Euthenics -> 1
Chemical_industry -> 1
Gases -> 1
Industrial_gases -> 1
Breathing_gases -> 1
Diving_equipment -> 1
Respiration -> 1
Electromechanical_engineering -> 1
Heat_transfer -> 1
Home_appliances -> 1
Engineering_disciplines -> 1
Automation -> 1
Building_engineering -> 1
Temperature -> 1
Heating,_ventilation,_and_air_conditioning -> 1
----
Sentence:
The air may be supplied, for example, by a power air purifying respirator (PAPR) that may be carried by the user.
Topics in the sentence:
Personal_protective_equipment -> 1
Air_filters -> 1
Respirators -> 1
Protective_gear -> 1
----
專(zhuān)利文本的每一句話(huà)都用SpikeX進(jìn)行處理,并從句子中檢測(cè)到的相應(yīng)Wikipedia頁(yè)面中提取類(lèi)別。我們把話(huà)題作為維基百科的分類(lèi)。這樣我們就有了第一個(gè)簡(jiǎn)單的話(huà)題檢測(cè)。
這種方法不同于語(yǔ)義超圖、文本秩或LDA,它在不直接引用術(shù)語(yǔ)的情況下查找句子主題的標(biāo)簽。提取的主題的標(biāo)簽是指與SpikeX匹配的Wikipedia頁(yè)面的類(lèi)別。如果我們使用這種方法聚合每個(gè)句子的主題,我們就可以更好地表示整個(gè)文檔。

在句子中劃分類(lèi)別的頻率可以更廣泛地了解文本的主題分布?!薄鞍踩焙汀鞍矘?lè)死”比其他類(lèi)別出現(xiàn)得更頻繁。
我們現(xiàn)在使用整個(gè)專(zhuān)利文本(可在Google專(zhuān)利中獲得)來(lái)查找分類(lèi)分布。

如我們所見(jiàn),我們可以自動(dòng)檢測(cè)整個(gè)文檔的主題(或類(lèi)別)(在本例中是專(zhuān)利)??纯辞?個(gè)類(lèi)別,我們可以推斷出這項(xiàng)專(zhuān)利是關(guān)于什么的。這是在沒(méi)有任何訓(xùn)練的情況下完成的。
結(jié)論
Wikipedia作為知識(shí)的來(lái)源已經(jīng)被開(kāi)發(fā)了十多年,并且在各種應(yīng)用中被反復(fù)使用:文本注釋、分類(lèi)、索引、聚類(lèi)、搜索和自動(dòng)分類(lèi)生成。事實(shí)上,Wikipedia的結(jié)構(gòu)有許多有用的特性,使其成為這些應(yīng)用程序的良好候選。
這篇文章演示了如何使用這個(gè)強(qiáng)大的源代碼來(lái)改進(jìn)NLP的簡(jiǎn)單任務(wù)。然而,并不是說(shuō)這種方法優(yōu)于其他最先進(jìn)的方法。評(píng)估自然語(yǔ)言處理任務(wù)準(zhǔn)確性的精確度和召回率的典型測(cè)量方法,在這篇文章中沒(méi)有顯示。
此外,這種方法也有優(yōu)點(diǎn)和缺點(diǎn)。其主要優(yōu)點(diǎn)在于避免了訓(xùn)練,從而減少了耗時(shí)的注釋任務(wù)。可以將維基百科視為一個(gè)龐大的訓(xùn)練機(jī)構(gòu),其貢獻(xiàn)者來(lái)自世界各地。
這對(duì)于有監(jiān)督的任務(wù)(如NER)和無(wú)監(jiān)督的任務(wù)(如主題模型)都是如此。這種方法的缺點(diǎn)是雙重的。首先,維基百科是一個(gè)公共服務(wù),作為一個(gè)由專(zhuān)家和非專(zhuān)家貢獻(xiàn)的知識(shí)庫(kù)。其次,從主題模型的結(jié)果可以看出,自然語(yǔ)言的歧義性會(huì)導(dǎo)致偏誤表現(xiàn)。詞義消歧和非專(zhuān)家驅(qū)動(dòng)的數(shù)據(jù)整理明顯影響整個(gè)系統(tǒng)的可靠性。
參考引用
[1] Menezes, Telmo, and Camille Roth. “Semantic hypergraphs.” arXiv preprint arXiv:1908.10784 (2019).
往期精彩回顧 本站qq群851320808,加入微信群請(qǐng)掃碼:
