詞 [Word]
詞彙是能獨立使用,構成句子的最小單位。當我們想利用電腦來進行語言識別等任務時,首先需要將一個句子拆分成詞彙序列,因為以詞彙為單位,無論是進行搜尋匹配,索引以及統計分析,都能夠有統一且有意義的操作對象。
舉例來說,對於句子「今天天氣真好」,需要轉換成「今天/天氣/真好」而非「今/天天氣/真/好」。這個任務實際上是一個大腦的認知歷程(Cognition),當我們日常看到這句話時,會自動轉換成正確的詞彙序列,另外在溝通時,也因為詞彙和詞彙之間會有短暫的語氣上的停頓,因此大腦更能夠輕易的進行意義的擷取。
在語言學(Linguistics)上,詞彙還能再拆分成詞素(Morpheme),是構成音義上的最小獨立單位。例如「天氣」,含有「天」與「氣」兩個獨立意義的詞素,兩者結合之後構成「天氣」這個概念。但像是「葡萄」,只含有「葡萄」一個詞素,單獨看「葡」和「萄」不具有任何意義。不過由於不同詞素之間互相結合後,會產生不同的意義,因此一般在人工智慧應用上,我們會只看詞,而不看詞素,就像「今天天氣真好」,操作「天氣」會比操作「天」&「氣」更具有一般性的意義,在這裡需要特別指出,在語言學其他研究上,就有可能會有以詞素為單位的統計分析。
斷詞 [Segmentation]
自然語言處理的基本分析,是利用電腦程式將詞彙從句子中正確的切分出來。這樣的操作稱為Segmentation,中文翻譯為斷詞,或分詞。在中文自然語言處理中,這個問題特別重要,因為中文書寫上詞之間並沒有以空白做為天然邊界,因此我們需要利用程式來達成。
這邊就以Python語言,以及最常見的中文斷詞技術結巴(jieba)作為範例,安裝Jieba
pip install git+https://github.com/APCLab/jieba-tw.git
範例:
import jieba # 引入結巴斷詞器
str = "今天天氣真好"# 要斷詞的句子
words = jieba.cut(str) # 呼叫結巴斷詞api
# 輸出
for w in words:
print(w)
可以看到實驗結果words輸出為「今天/天氣/真好」的詞彙序列。分析出詞彙之後,以統計學的觀點而言,就能夠對一篇文章進行頻率統計,進行後續的分析研究。
斷詞演算法
為了避免過於艱澀,這邊僅列出常見的斷詞演算法,將在後續詳細介紹細節:
斷詞技術的困難點在於以下幾點:
- 未登錄詞識別:這類型的程式通常是依賴已經訓練好的模型來斷詞,對於不在系統辭典紀錄的詞彙,難以估計參數,容易影響斷詞效果。未出現的詞彙並不一定是使用率過低的詞彙,也有可能是蒐集訓練斷詞程式的語料和應用場景不匹配,相關程度低所致。
- 切分歧義:切分結果往往出現語義上都合理的情況,例如「喜歡上一個人」可切分成:「喜歡上/一個人」(喜歡獨處)「喜歡/上/一個/人」(喜歡了某個人)。這類型的切分錯誤相當難處理,需要引入更多上下文的語境才能判斷。
詞形還原 [Lemmatization]
在中文當中,是以詞序表示句法Syntax,而非改變詞形。而印歐語系當中,會改變詞彙的形態來表示句法,見形態句法學Morphosyntax。這對於電腦程式處理會出現不統一的情況,例如”playing”和”play”除了時間表達上的差異,意義幾乎相同,為了有利於電腦程式統計分析,我們一般會需要進行詞形還原lemmatization,像是把”playing”轉換回較簡易,原始的”play”。
這邊就以Python語言,以及最常見NLTK套件提供的API作為範例,安裝nltk
pip install nltk
範例程式:
from nltk import word_tokenize, pos_tag
from nltk.corpus import wordnet as wn
from nltk.stem import WordNetLemmatizer # 引入詞形還原
import nltk
# 詞性對應 cite from : https://github.com/pararthshah/qa-memnn/blob/master/nltk_utils.py
def is_noun(tag):
return tag in ['NN', 'NNS', 'NNP', 'NNPS']
def is_verb(tag):
return tag in ['VB', 'VBD', 'VBG', 'VBN', 'VBP', 'VBZ']
def is_adverb(tag):
return tag in ['RB', 'RBR', 'RBS']
def is_adjective(tag):
return tag in ['JJ', 'JJR', 'JJS']
def penn_to_wn(tag):
if is_adjective(tag):
return wn.ADJ
elif is_noun(tag):
return wn.NOUN
elif is_adverb(tag):
return wn.ADV
elif is_verb(tag):
return wn.VERB
return 'n' #defult pos tag
# 下載數據
nltk.download('punkt')
nltk.download('averaged_perceptron_tagger')
nltk.download('wordnet')
lemmatizer = WordNetLemmatizer() # 建立詞形還原物件
str = "we are playing video games"
words = list(str.split(" ")) # 利用空白斷詞
tagged=pos_tag(word_tokenize(str))
for w, pos in tagged:
print(lemmatizer.lemmatize(w,pos=penn_to_wn(pos)))# 詞形還原
可以發現輸出的句子當中,”are” 被轉換成”be” ,”playing” 被轉換成”play”,”game” 被轉換成”games”
本文允許重製、散布、傳輸以及修改,但不得為商業目的之使用
使用時必須註明出處自:楊明翰 , 台灣人工智慧與資料科學研究室 https://aistudio.tw