1.读取
1 # 1、导入数据 2 file_path = r"C:Users23625Desktop机器学习项目dataSMSSpamCollection" 3 sms = open(file_path, 'r', encoding='utf-8') 4 sms_data = [] 5 sms_lable = [] 6 csv_reader = csv.reader(sms, delimiter=' ') 7 for r in csv_reader: 8 sms_lable.append(r[0]) 9 sms_data.append(preprocessing(r[1])) # 对每封邮件做预处理 10 sms.close()
2.数据预处理
1 # 2、预处理 2 def preprocessing(text): 3 tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)] # 将所有单词形成列表 4 stops = stopwords.words('english') # 停用词 5 tokens = [token for token in tokens if token not in stops] # 去掉停用词 6 tokens = [token.lower() for token in tokens if len(token) >= 3] # 去掉短的词 7 8 lemmatizer = WordNetLemmatizer() 9 tag = nltk.pos_tag(tokens) # 词性标注,标出是不是形容词等等 10 tokens = [lemmatizer.lemmatize(token, pos=get_wordnet_pos(tag[i][1])) for i, token in enumerate(tokens)] # 词形还原 11 preprocessing_text = ''.join(tokens) 12 return preprocessing_text
3.数据划分—训练集和测试集数据划分
from sklearn.model_selection import train_test_split
x_train,x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0, stratify=y_train)
1 # 3、划分数据集 2 x_train, x_test, y_train, y_test = train_test_split(sms_data, sms_lable, test_size=0.2, random_state=0, 3 stratify=sms_lable)
4.文本特征提取
sklearn.feature_extraction.text.CountVectorizer
sklearn.feature_extraction.text.TfidfVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf2 = TfidfVectorizer()
观察邮件与向量的关系
向量还原为邮件
1 # 4、文本特征提取(向量) 2 tfidf = TfidfVectorizer() 3 X_train = tfidf.fit_transform(x_train).toarray() 4 X_test = tfidf.transform(x_test).toarray() 5 # 向量还原文件 6 import numpy as np 7 8 a = np.flatnonzero(X_train[0]) # 输入一个矩阵,返回非零元素的下标 9 # 非零元素对应的单词 10 b = tfidf.vocabulary_ 11 key_list = [] 12 for key, value in b.items(): 13 if value in a: 14 key_list.append(key) 15 print("非零元素对应的单词:", key_list)
4.模型选择
from sklearn.naive_bayes import MultinomialNB
from sklearn.naive_bayes import MultinomialNB
说明为什么选择这个模型?
1 # 5、模型的构建、训练、预测 2 3 m_model = MultinomialNB() 4 m_model.fit(X_train, y_train) 5 y_m_pre = m_model.predict(X_test)
垃圾邮件是离散的,所以采用朴素贝叶斯的分类方法。如果采用高斯贝叶斯,准确率低。
5.模型评价:混淆矩阵,分类报告
from sklearn.metrics import confusion_matrix
confusion_matrix = confusion_matrix(y_test, y_predict)
说明混淆矩阵的含义
from sklearn.metrics import classification_report
说明准确率、精确率、召回率、F值分别代表的意义
混淆矩阵就是一张表,展示预测值各类归对、归错的个数。
精确度:precision,正确预测为正的,占全部预测为正的比例,TP / (TP+FP)
召回率:recall,正确预测为正的,占全部实际为正的比例,TP / (TP+FN)
F1-score:精确率和召回率的调和平均数,2 * precision*recall / (precision+recall)
同时还会给出总体的微平均值,宏平均值和加权平均值。
微平均值:micro average,所有数据结果的平均值
宏平均值:macro average,所有标签结果的平均值
加权平均值:weighted average,所有标签结果的加权平均值
1 # 模型评价 2 # 朴素贝叶斯 3 print("朴素贝叶斯") 4 m_cm = confusion_matrix(y_test, y_m_pre) 5 print("混淆矩阵: ", m_cm) 6 m_cr = classification_report(y_test, y_m_pre) 7 print("分类报告: ", m_cr) 8 print("模型准确率:", (m_cm[0][0] + m_cm[1][1]) / np.sum(m_cm))
6.比较与总结
如果用CountVectorizer进行文本特征生成,与TfidfVectorizer相比,效果如何?
答:TfidfVectorizer除了考量某词汇文本出现的频率,还关注包含这个词汇的其他文本的数量,而CountVectorizer只考虑词汇文本出现的频率,所以最后模型的准确率会降低。