top of page
Search
Learn with Shin

自然語言處理 - NLP

Updated: Jun 13, 2021



今天來稍微聊一下自然語言處理(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


Post: Blog2_Post
bottom of page