sklearn垃圾郵件識別

垃圾郵件識別,算是一個二分類問題,也是一個相對簡單的文本分類問題。

本文數據來自UCI機器學習倉庫中的垃圾信息數據集,從http://archive.ics.uci.edu/ml/datasets/sms+spam+collection下載。

文件中每一行由兩部分組成,行首是標籤 spam/ham(spam 代表垃圾郵件),中間空一格,之後是郵件內容。

以下代碼是一個整體,如需複製,將除了函數部分的代碼按順序複製,函數需要放在庫和其它代碼之間


需要用到的庫:

import nltk
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB

數據提取

源文件無類型後綴,就當作普通文本文件讀取:

sms_data = open('.\SMSSpamCollection', 'r', encoding='utf-8')
x = []
y = []
for line in sms_data.readlines():
    data = line.split('\t')
    y.append(data[0])
    x.append(data[1].split('\n')[0])
sms_data.close()

數據預處理

上面倒數第二行裏面使用了一個自定義函數,把與郵件內容關係不大的單詞(停用詞等)去除,這樣做能減少特徵數量但對訓練精度沒什麼影響

因爲數據集中的內容爲英文,這裏我使用 NLTK 庫進行處理,如果選擇中文數據更推薦使用 jieba 庫

def text_dispose(text):
	# 將每個單詞和符號分開
    sentences = nltk.sent_tokenize(text)
    words = [word for sent in sentences for word in nltk.word_tokenize(sent)]
    stops = stopwords.words('english')
    # 去除停用詞
    words = [word for word in words if words not in stops]
    words = [words.lower() for words in words if len(words) >= 3]
    # 詞彙化
    lemmatizer = WordNetLemmatizer()
    words = [lemmatizer.lemmatize(words) for  words in words]
    dispose_text = ' '.join(words)
    return dispose_text

數據拆分及文本特徵處理

數據拆分成常見的三七開

特徵處理是文本分類的關鍵部分,因爲我們不可能把整個文本內容直接放進模型中訓練,所以需要將文本表示爲計算機可以識別的、能夠代表該文檔特徵的特徵矩陣

# 拆分
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=1)
# 特徵處理
vectorizer = TfidfVectorizer(min_df=2, ngram_range=(1,2), stop_words='english', strip_accents='unicode',norm='l2')
X_train = vectorizer.fit_transform(x_train)
X_test = vectorizer.transform(x_test)

TfidfVectorizer 可以把原始文本轉化爲 TF-IDF 的特徵矩陣


選擇模型並訓練

這裏使用樸素貝葉斯分類器

model = MultinomialNB()
model.fit(X_train,y_train)
score = model.score(X_test, y_test)
print(score)

因爲 sklearn 的高度封裝,只需幾行代碼就可以使用特定算法。我們不需要寫出算法的流程,只要知道其功能即可,所以 sklearn 適用於快速構建模型。當然如果想讓算法定製性更強,則需要自行構建

看評分結果:

0.9689181111775254

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章