1. 程式人生 > >基於NaiveBayse SVM KNN的Python垃圾簡訊過濾系統 附程式碼

基於NaiveBayse SVM KNN的Python垃圾簡訊過濾系統 附程式碼

垃圾簡訊過濾系統

一個課程的結課設計,挺好玩的。

資料處理:

簡訊資料來源於UCI machine learning repository,可以到以下網址去下載:https://archive.ics.uci.edu/ml/datasets/SMS+Spam+Collection 計算機不可能直接識別文字,並在其基礎上進行計算,因此,我們的文字將要轉換成可計算的數字,比如,向量。


步驟:

比如:原句My name is jerry,my name is Tom. 1.原句轉化成單個詞彙的列表,因為我並不需要知道詞彙之間的關係,我只需要找到這條資訊中是什麼把它變的傾向於垃圾簡訊或是正常簡訊。['my','name','is','jerry'],['my','name','is','Tom'] 2.建立詞彙表,記錄所有出現詞彙,並去除重複詞彙。['my','name','is','jerry','Tom'] 3.現在,根據原句可建立對應的向量並可用於計算。 以下所有機器學習演算法,都統一使用如此處理的資料進行訓練。


Naive Bayse 樸素貝葉斯:

基於貝葉斯定理: 籠統點,可以理解為是一種條件概率,在這個系統中可以表示為,這個單詞出現時,是垃圾簡訊的概率有多少。

具體步驟:

1.基於上面資料處理步驟2中的詞彙列表,進行頻率的統計,例如,出現了幾個‘My’,並且是垃圾簡訊時有幾個‘My’,非垃圾簡訊時有幾個‘My’。 2.建立概率表,基於步驟1的統計進行相應的概率計算,能得到每個詞彙的垃圾概率和非垃圾概率。另外,此步驟需要加上拉普拉斯平滑,防止0進入計算。此步驟建議使用Log()方法,防止計算機計算過小值導致損失精度。 3.句子的向量與概率表進行計算,得出該句子的垃圾概率與非垃圾概率,選取較大的那個。 基於隨機選取的60訓練資料與20測試資料,進行10次執行。 MaxRecall: 0.8
MaxPrecision: 1.0
MinError: 0.2
AveRecall(平均召回率): 0.7068421052631579
AvePrecision(平均精確度): 0.9854166666666666
AveError(平均錯誤率): 0.3
AveTime(平均執行時間): 0.028286582971390355
看起來還不算差,起碼AvePrecision不低,不會有太多的正常簡訊被誤認為垃圾簡訊。


SVM (Support Vector Machine)支援向量機:

我有文章詳細介紹過,這裡就不多講了。這裡使用的是Sklearn的package來實現的。


預設狀態:

C=1 Kernel=‘rbf’
MaxRecall: 1.0
MaxPrecision: 1.0
MinError: 0.05
AveRecall: 0.6505847953216375
AvePrecision: 0.9140598290598291
AveError: 0.425
AveTime: 0.06084513318737096

提高懲戒指數:

C=10.0 Kernel=‘rbf’ MaxRecall: 0.9444444444444444
MaxPrecision: 1.0
MinError: 0.1
AveRecall: 0.8248402869919899
AvePrecision: 0.9303405572755418
AveError: 0.23500000000000004
AveTime: 0.04786081637264809
就提升到10.0,後面優化的就不明顯了,而且還有過擬合的風險。

更換核函式:

C=10.0 Kernel='linear'
MaxRecall: 0.9
MaxPrecision: 1.0
MinError: 0.1
AveRecall: 0.8122222222222222
AvePrecision: 0.977124183006536
AveError: 0.205
AveTime: 0.04208579490100922
測試了幾個核函式,這個的資料是最滿意的。 Simple Example

KNN(k-NearestNeighbor):

最簡單的機器學習演算法之一,我的文章也有涉及。這個是順手就做了一個,依舊使用了Sklearn的包。


預設狀態:

n_neighbors=5
MaxRecall: 0.6
MaxPrecision: 1.0
MinError: 0.4
AveRecall: 0.495
AvePrecision: 1.0
AveError: 0.505
AveTime: 0.060209280330714585
不如隨機系列。

嘗試優化:

n_neighbors=3, algorithm='ball_tree'
MaxRecall: 0.65
MaxPrecision: 1.0
MinError: 0.35
AveRecall: 0.5499999999999999
AvePrecision: 1.0
AveError: 0.45000000000000007 AveTime: 0.05553739146649517
依舊不盡人意,訓練資料量相同,都是30個,不會出現容易被歸納為例項多的樣本的情況。可能是分佈實在是不太有規律,可以試著使用樸素貝葉斯的概率表,根據概率表排序後可能就會好很多。不過,KNN有點就是正常簡訊永遠都不會被誤認為垃圾。

結論:

Conclusion
樸素貝葉斯用時最短,Recall和Precision也不錯。 SVM用時略長,但是Recall特別高,Precision也不低。 KNN,雖然Recall和用時都不怎麼樣,但是Precision永遠是100%。 附上Github原始碼:https://github.com/jerry81333/SpamSMSFiltering