今天來稍微聊一下自然語言處理(Natural Language Processing - NLP)跟 Python 的應用。
所謂的自然語言,就是我們人類一般使用的語言。不論是英文、中文、日文,都屬於自然語言。為什麼這裡要特別提到自然語言呢?因爲它對電腦而言是不容易消化的資料!
一般而言,電腦擅長處理有規律,或是固定格式的結構化資料(Structured Data)。舉個例子來說,你把一個CSV的檔案給電腦,配合內建(或外加)的軟體它知道怎麼去看 columns 或 rows; 你給它一個JSON的檔案,它知道哪些是 key 以及 values。因為這些資料都有固定的格式,只要循著事先決定好的步驟就可以拿到需要的內容。
但是今天給電腦隨意一篇文章(一堆文字),然後叫它提供你要的資料,就沒這麼簡單了。因為文章這類的資料呈現的型態太過自由,屬於所謂的非結構化資料(Unstructured Data)的一種。
面對這種 Unstructured Data,根據我們的需求,往往要花更多的力氣處理。其實,今天我們看到的許多科技都需要運用自然語言處理, 譬如說 Google 用關鍵字做類似語搜尋,對話機器人(像是網頁上跟你對話的客服機器人)或是 Google 翻譯等,在在都是要求電腦可以某種程度理解自然語言。那是怎麼做到的呢?
當然 NLP 本身是一個又廣又深的領域,涵蓋許多的理論跟實作,所以我們今天就只是稍微介紹一下基本的概念,以及相關的一些 Python 操作。
話不多說,我們跟大家介紹一個處理自然語言的第三方 Library:NLTK
安裝如下:
pip install nltk==3.6.2
坊間有不少處理自然語言的 Python Library,但是 NLTK 絕對是相當具有代表性的一個。
那麼,NLTK 到底是什麼東西呢?或者說目的是什麼呢?
簡單來說最主要的目的,就是它提供一些前置文字處理功能(text preprocessing)讓我們可以把像文章(一長串字)這樣的 Unstructured data 盡量轉換成 Structured data!(當然還有很多其他的功能,像是搭配機器學習的模型,但是不在今天的討論範圍。)
OK,假設有一小篇文章像這樣👇:
我們該怎麼讓電腦處理(想辦法把它轉成 Structured )進而分析這個文章內容呢?
Tokenization
通常第一步,是將文章拆解開來。我們可以以句子為單位,或是單字為單位把文章做分解🛠。
這個動作稱之為 Tokenization。
首先,我們利用 nltk.download 來下載一些所需的資料:
這裡下載的"punkt"資料可以讓 nltk 知道如何區隔標點符號。
接下來就可以去tokenize我們的文字串了:
word_tokenize 將原先的文章拆解成字(word)的單位。這裡看到,各個標點符號也都被認為是一個字。你可以看到 "Python’s" 被拆成 Python,',以及s三個字。所以word_tokenize並不是單純的用空格(space)把字隔開而已喔。
Stop Words
接下來,我們看到了許多像 "is", "as", "for" 這些Be動詞,介系詞,或是 "it"這類代名詞等文法用字,這些字在文章中有它的作用,但是對於整體理解文章內容可能意義不大。
在 NLP,這一類的字被稱為 stop words。
NLTK也提供了這些常見的stop words,首先我們來下載:
稍微來看一下它長什麼樣子:
可以發現它就是一系列我們剛剛講的常見英文 stop words。
我們可以利用它來過濾掉我們不需要的字:
Nice! 現在我們剩下來的字看起來更具意義了。
Stemming & Lemmatization
去除掉 stop words 之後,我們看到剩下的字裡面有包括像 "interpreted","built", "emphasizes" 這一類具有時態的動詞,如果我想把 "interpret","interpreting","interpreted" 全部統一標準,有什麼好方法嗎?
這裡我們會用到的叫做 stemming 以及 lemmatization 的技巧。
Stemming指的對一個字把它轉換成其字根(stem)狀態,看看下面的例子:
這裡使用的 SnowballStemmer 是一種 Stemming 的演算法。嗯...saying是成功的轉成了say,但是 said 怎麼沒變?還有 discover 的結果怎麼怪怪的?
其實 Stemming 的結果常常不如預期,它不見得會給你一個完整的字,因為它著重在字根。
好加在我們還有另外一個方法 - lemmatization!
Lemmatization 跟 Stemming 一樣,可以給你一個單字原本的型態,但是會保留完整英文字的長相。
首先要下載需要的資料:
接下來我們會使用一個叫做WordNetLemmatizer的工具:
看起來是不是好多了!say跟discover都成功的呈現原來的狀態。
OK,那現在我們來limmatize原來的文章看看:
現在所有的動詞都變成他們的基本型態了!這裡,我們同時運用了 string 的 isalpha 功能來移除標點符號。(當然我們也可以針對名詞及形容詞做進一步的處理,不過因為文章有點太長,我們可以下次再討論。)
最後,我們把簡單把這個結果做一個統計,來看看哪些字出現最多次。這裡我們可以利用nltk提供的FreqDist 幫我們做頻率的分佈:
透過這個結果,我們大概可以知道這範例文是關於介紹 Python 身為一個程式語言的特性。
你可能會說:哼,這麼簡單的內容我一看就知道了,哪需要用電腦做這麼麻煩的處理?
想像看看,如果我有上百篇更大篇幅的文章,看都沒時間看,透過這樣的方式是不是可以讓電腦瞬間歸類,並幫忙整理各個文章的主要概念?蠻適合像我這種英文不太好又懶惰的人😅~
甚至也可以把結果轉成圖形:
像這樣,透過視覺化的呈現來快速的抓到主題。
以上,透過我們剛剛看到的這幾個步驟:
tokenization
移除stop words
stemming & lemmatization
從原來的一篇文字,我們最後變成可以用圖形的方式來表現。這些技巧不但讓我們能夠某種程度使文章本身變成結構化的資料,也同時將其複雜程度降低,方便我們接下來做各種進一步的分析!
Comentarios