博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

机器学习作业13--垃圾邮件分类2

Posted on 2020-05-21 14:42  马淳丰  阅读(355)  评论(0编辑  收藏  举报

1.读取

 1 # 1、导入数据
 2 file_path = r"C:\Users\23625\Desktop\机器学习\项目\data\SMSSpamCollection"
 3 sms = open(file_path, 'r', encoding='utf-8')
 4 sms_data = []
 5 sms_lable = []
 6 csv_reader = csv.reader(sms, delimiter='\t')
 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

https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html?highlight=sklearn%20feature_extraction%20text%20tfidfvectorizer

sklearn.feature_extraction.text.TfidfVectorizer

https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html?highlight=sklearn%20feature_extraction%20text%20tfidfvectorizer#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("混淆矩阵:\n", m_cm)
6 m_cr = classification_report(y_test, y_m_pre)
7 print("分类报告:\n", m_cr)
8 print("模型准确率:", (m_cm[0][0] + m_cm[1][1]) / np.sum(m_cm))

 

6.比较与总结

如果用CountVectorizer进行文本特征生成,与TfidfVectorizer相比,效果如何?

答:TfidfVectorizer除了考量某词汇文本出现的频率,还关注包含这个词汇的其他文本的数量,而CountVectorizer只考虑词汇文本出现的频率,所以最后模型的准确率会降低。