午安~昨天介紹了貝式分類器的原理之後,今天就要在python裡面實際操作一次看看,也順便把之前還沒講解怎麼實作的詞袋模型當成特徵一起示範。事不宜遲我們馬上開始!
說到機器學習的實作,就一定要提到Scikit Learn
這個套件還有Kaggle這個網站。Scikit Learn
是python裡面專門用來輔助機器學習實作的套件,裡面不只提供很多示範用的資料庫、特徵萃取的輔助工具,還幫我們把最經典常用的機器學習模型都建立好了。基本上就是完整的機器學習一條龍服務啦,所以之後我們也會一直用到它。Kaggle則是當我們想要找一些特定種類資料的時候可以造訪的網站。因為它是數據建模跟數據分析競賽的平台,所以上面提供了各式各樣從日常生活中收集到的真實材料讓我們可以使用。
今天要用到的資料是從這邊下載下來的垃圾訊息資料。我們要做的事情就是藉由這些資料做出詞袋模型,再以詞袋模型來訓練單純貝式分類器看它能多有成效地找出垃圾訊息。所以首先要做的事情就是在colab上面下載Scikit Learn
跟把資料匯進colab。
!pip install scikit-learn
import pandas as pd
raw_data = pd.read_csv("/content/SMSCollection.csv")
這個部分大家應該都很熟悉了,不會有什麼問題。接下來我們要利用Scikit Learn
裡面的feature_extraction
套件來把資料裡面的詞向量化之後做出詞袋模型。首先要做的事情是初始化這個向量工具。
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
接下來因為他需要的參數是放在串列中的字串,所以我們要對dataframe裡面的資料做過處理再丟進去。
raw_text = []
for rows in range(len(raw_data["sms"])):
text = raw_data.at[rows, "sms"]
raw_text.append(text)
arr = vectorizer.fit_transform(raw_text)
使用fit_transform()
這個功能之後,它就幫我們建立好詞袋模型了,接著我們要分別從裡面取出所有type作為特徵的行名,再把轉換完畢的向量取出來作為特徵標籤。然後才能把它們組成新的dataframe。
feature_arr = vectorizer.get_feature_names_out() # 取出type
feature_data = arr.toarray() # 把向量轉換結果變成陣列
feature_df = pd.DataFrame(feature_data, columns=[feature_arr]) # 建立模型訓練用的特徵dataframe
label_df = raw_data[["Class"]] # 建立模型訓練用的標籤(正解)dataframe
做好前置工作以後,我們可以用Scikit Learn
提供的工具來分出訓練集跟測試集。裡面需要放置的第一個參數是特徵資料,接著是正解資料,然後是我們希望測試集占整體資料的比例,最後是用來確保每次訓練結果相同的random_state
。因為區分訓練及跟測試集是一個隨機執行的動作,但我們通常需要跟別人核對訓練資料,所以可以透過設定random_state
來確保他每次的隨機結果都是一樣的(開心用什麼數字就用什麼數字,統一就好)。
from sklearn.model_selection import train_test_split
data_train, data_test, label_train, label_test = train_test_split(feature_df, label_df, test_size=0.2, random_state=24)
接著就可以開始訓練模型了。因為我們的資料都是類別變數,所以這邊選用的是多項式貝氏分類器(MultinomialNB)。我們先初始化一個多項式貝式分類器,接著把訓練集放進去訓練。fit()
裡面的第一個參數要放特徵,第二個則是正確答案。然後就結束了,驚不驚喜,意不意外?因為套件人家都已經寫好了,所以訓練過程真的是比前處理過程短太多了,非常輕鬆又方便。
from sklearn.naive_bayes import MultinomialNB
model = MultinomialNB()
model.fit(data_train, label_train)
既然模型都訓練完了,我們就可以讓他幫測試集分類,再透過分類結果畫出混淆矩陣(confusion matrix)並進一步評量模型的表現。score()
是用來計算accuracy的值,然後precision_recall_fscore_support
則是幫我們計算剩下的三個評量方式。
label_predict = model.predict(data_test)
from sklearn.metrics import confusion_matrix, precision_recall_fscore_support
print(confusion_matrix(label_test, label_predict))
evaluation = precision_recall_fscore_support(label_test, label_predict, average='macro')
accuracy = model.score(data_test, label_test)
print("accuracy: " + str(accuracy) + "\nprecision: " + str(evaluation[0]) + "\nrecall: " + str(evaluation[1]) + "\nfscore: " + str(evaluation[2]))
# 輸出
[[954 13]
[ 10 138]]
accuracy: 0.979372197309417
precision: 0.9517669203924047
recall: 0.9594943961541686
fscore: 0.9555829980480421
這樣就完成我們的單純貝式分類器訓練了,可以看到出來的結果還是滿不錯的,各項指標都有達到0.95的水準。但其實今天為了示範詞袋模型跟單純貝式分類器的實作,省略了資料清洗的步驟,所以如果仔細去看詞袋模型取出來的type,會發現裡面有很多數字跟不是詞的東西。大家如果自己想要完整練習的模型訓練的話,可以先進行資料清洗的步驟再建立詞袋模型,這樣或許可以得到更好的訓練結果喔~今天就到這邊,明天見!