簡單快速上手自然語言處理中的文本分類
本文為用Python3快速實作簡單文本分類之教學
開始前請先使用pip安裝Python3環境以及scikitlearn套件,本文使用 scikit-learn 版本 0.19.1,pandas版本1.0.5
使用其他版本的套件可能會有些許出入
指令如下
pip install scikit-learn==0.21.3
pip install pandas==1.0.5
或是
pip3 install scikit-learn==0.21.3
pip3 install pandas==1.0.5
Qick Start
請先至以下連結下載寫好的Excel語料
並使用Python pandas套件讀取檔案
import pandas as pd
read = pd.read_excel("昕力大學-文本分類.xlsx", index=False).values.tolist()
corpus = [row[0] for row in read]
intents = [row[1] for row in read]
讀取完後可以將語料印出來後看看是否成功
corpus[:15]
向量化
接下來我們載入scikit-learn的Counter Vectorizer,將語句轉換成n元語法(N-gram)向量。
這裡設定的N-gram range 是 1-2,也就是說假設某一個句子"ABCDE",在做feature transform時,會把該句子轉成 "A","B","C","D","E","AB","BC","CD","DE",的形式當成feature。n元語法設定成1到2的方式又被稱為二元語法(Bigram)
詳細Counter Vectorizer使用方法,可以參考這裡
from sklearn.feature_extraction.text import CountVectorizer
feature_extractor = CountVectorizer(
analyzer="word", ngram_range=(1, 2), binary=True,
token_pattern=r'([a-zA-Z]+|\w)')
X = feature_extractor.fit_transform(corpus)
轉成二元語法(Bigram)向量後,我們可以看看總共得到多少數量的特徵,總共有605個這麼多
len(feature_extractor.get_feature_names())
試著將得到的特徵前三十筆印出來看看
feature_extractor.get_feature_names()[:30]
分類
接著我們將剛剛轉成二元語法形式的向量,也就是變數X,和在Excel當中讀取到每個句子所屬於的意圖(Intent),分別當成特徵和標籤送進邏輯回歸(Logistic Regrassion)裡去訓練。
from sklearn.linear_model import LogisticRegression
INTENT_CLASSIFY_REGULARIZATION = "l2"
lr = LogisticRegression(penalty=INTENT_CLASSIFY_REGULARIZATION,
class_weight='balanced')
lr.fit(X, intents)
邏輯回歸的詳細概念可以自行Google。舉個例子,假設你有一群老鼠的身高體重,分別把他們標示成「正常」和「肥胖」
那麼把每個老鼠的數值用個兩個維度的向量(身高, 體重)來表示,也就是把身高放在二維坐標中的X軸,體重放在二維座標的Y軸,在座標平面上就會如下圖所示
邏輯回歸的目標就是找到一條線,這條線通常被稱作超平面(hyperplane),使得肥胖的老鼠和正常體重的老鼠在向量空間中能區隔開來
在得到這條線後,以後有新資料出現,例如一隻超極巨化的皮卡丘,就可以知道牠是屬於肥胖那個區域
預測
在訓練好邏輯回歸得模型後,我們就可以來預測新輸入的句子
例如一句新的句子「查詢明天的降雨量」,這是訓練資料集裡面所沒有的資料,我們來看看訓練好的邏輯回歸模型是否能順利把它歸類為「天氣」,首先我們先把該句子轉換為二元語法(Bigram)向量。
user_input = ['查詢明天的降雨量']
X2 = feature_extractor.transform(user_input)
可以看到轉成向量後的句子就如剛剛所說的,維度也是605
len(X2.toarray()[0])
將得到的測試用的X2向量印出來看看
這裡可以看到從使用者句子中抽取出來的Feature,以index方式呈現,代表該向量在第171, 179, 292, 293....的值為1,其他為0
print(X2)
用得到的index去查找,看看實際上抽取到的feature有哪些。可以看到「查詢明天的降雨量」這句話被抽到Bigram為「天、天的、明、明天、查、查詢、的、詢、詢明、雨」
feature_names = feature_extractor.get_feature_names()
for index in X2.nonzero()[1]:
print(feature_names[index])
預測很簡單,我們用一行程式碼,就可以讓剛訓練好的邏輯回歸模型判斷該句子是屬於哪個類別(意圖)
lr.predict(X2)
想知道該句屬於每個意圖的機率,可以這樣做
probs = lr.predict_proba(X2)[0]
for predict_intent, prob in sorted(zip(lr.classes_, probs), key = lambda x: x[1],reverse = True):
print(predict_intent, prob)
是不是覺得AI裡面的分類(Classfication)問題,就是如此的簡單呢?
大家可以自行編寫Excel表格裡的語句和意圖,就能建構屬於自己的AI文本分類器喔!