机器学习11贝叶斯处理邮件分类问题------后续

1.读取

import csv
path = r'C:\Users\Chen Zhenrui\PycharmProjects\untitled\机器学习\SMSSpamCollection'
sms = open(path, 'r', encoding='utf-8')
csv_reader = csv.reader(sms, delimiter='\t')

 

2.数据预处理

#文本预处理自定义函数
def preprocessing(text):
text=text.lower() #将大学字符转成小写字符 seq = string.punctuation # string.punctuation 是python内置的标点符号的合集 # 去除符号 for ch in seq: text = text.replace(ch, '') # 用空格代替去掉的符号 tokens = [] # 定义一个空列表 # 分词 for set in nltk.sent_tokenize(text): # 分句 for word in nltk.word_tokenize(set): # 分词 tokens.append(word) # 将分词结果追加进列表 # 去除停用词 stops = stopwords.words("english") # 获取停用词 tokens = [token for token in tokens if token not in stops] # 删掉长度为一的单词 for i in tokens: if (len(i) == 1): tokens.remove(i) # 还原词性 lemmatizer = WordNetLemmatizer() # 定义还原对象 tokens = [lemmatizer.lemmatize(token, pos='n') for token in tokens] # 还原成名词 tokens = [lemmatizer.lemmatize(token, pos='v') for token in tokens] # 还原成动词 tokens = [lemmatizer.lemmatize(token, pos='a') for token in tokens] # 还原成形容词 # 将列表中的字符合为一条字符串,以空格隔开 tokens = " ".join(tokens) return tokens
#开始预处理
sms_data = []#存放标签(x)
sms_label = []#存放期望值(y)
for line in csv_reader:
    sms_label.append(line[0])
    sms_data.append(preprocessing(line[1]))

 

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)

#划分训练集与测测试集
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(sms_data, sms_label, test_size=0.2, random_state=5,stratify=sms_label)

 

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()

观察邮件与向量的关系

向量还原为邮件

 

TfidfVectorizer方式转换

# 把原始文本转化为tf-idf的特征矩阵
x_traincp=x_train[0]
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf
= TfidfVectorizer() X_train = tfidf.fit_transform(x_train) # X_train用fit_transform生成词汇表 X_test = tfidf.transform(x_test) # rX_test要与X_train词汇表相同,因此在X_train进行fit_transform基础上进行transform操作 # 向量还原成邮件 import numpy as np a=np.flatnonzero(X_train.toarray()[0]) #获取x_train中第一行非0的值的位置列表 X_train.toarray()[0][a] #第一行中非零向量对应的值 b=tfidf.vocabulary_ key_list=[] for key,value in b.items(): if value in a: key_list.append(key) print('x_train中第一行向量对应的邮件内容:\n',key_list) #第一行向量对应的邮件内容 print('x_train中第一行邮件的原始内容为:\n',x_traincp) #第一行向量对应的邮件内容

 

 

CountVectorizer方式转换

# 使用CountVectorizer将单词向量化
from sklearn.feature_extraction.text import CountVectorizer
countv = CountVectorizer()
X_train = countv.fit_transform(x_train)
X_test = countv.transform(x_test)  # 沿用x_train的词袋来转化向量
# 转成数组后查看一下测试集的维度
print('训练集维度:\n',x_train.toarray().shape)  # 训练集维度
print('测试集维度:\n', x_test.toarray().shape)  # 测试集维度
countv.vocabulary_  # 词袋的词语的统计字典,(单词,单词的所在位置)
#    讲向量还原成邮件
import numpy as np
a = np.flatnonzero(x_train.toarray()[0])  # 获取x_train中第一行非0的值的位置列表
x_train.toarray()[0][a]  # 第一行中非零向量对应的值
b = countv.vocabulary_
key_list = []
for key, value in b.items():
    if value in a:
        key_list.append(key)
print('x_train中第一行向量对应的邮件内容:\n', key_list)  # 第一行向量对应的邮件内容
print('x_train中第一行邮件的原始内容为:\n', x_traincp)  # 第一行向量对应的邮件内容

 

 

 

4.模型选择

from sklearn.naive_bayes import GaussianNB

from sklearn.naive_bayes import MultinomialNB

说明为什么选择这个模型?

答:因为高斯贝叶斯适用于正态分布数据,而从词袋中抽出单词,统计某一单词出现的频率属于n次独立重复试验,属于多项式分布概率,应该用多项式贝叶斯,所以选择MultinomialNB模型

from sklearn.naive_bayes import MultinomialNB
mnb_model=MultinomialNB()
mnb_model.fit(X_train,y_train)
y_mnb=mnb_model.predict(X_test) # 预测结果
print("准确率:",mnb_model.score(X_test,y_test))

 

 

5.模型评价:混淆矩阵,分类报告

from sklearn.metrics import confusion_matrix

confusion_matrix = confusion_matrix(y_test, y_predict)

说明混淆矩阵的含义

from sklearn.metrics import classification_report

说明准确率、精确率、召回率、F值分别代表的意义 

 

from sklearn.metrics import confusion_matrix
print("模型的混淆矩阵:\n",confusion_matrix(y_test,y_mnb))
from sklearn.metrics import classification_report
print("输出模型的分类报告 :\n", classification_report( y_test,y_mnb))

 

 

 混淆矩阵:

TP(True Positive):将正类预测为正类数,真实为0,预测也为0

FN(False Negative):将正类预测为负类数,真实为0,预测为1

FP(False Positive):将负类预测为正类数, 真实为1,预测为0

TN(True Negative):将负类预测为负类数,真实为1,预测也为1

分类报告:

准确率:对于给定的测试数据集,分类器正确分类的样本数与总样本数之比。(TP + TN) / 总样本

精确率:针对预测结果,在被所有预测为正的样本中实际为正样本的概率。TP / (TP + FP)

召回率:在实际为正的样本中被预测为正样本的概率。TP / (TP + FN)

F值:同时考虑精确率和召回率,让两者同时达到最高,取得平衡。F值=正确率 * 召回率  * 2 / (正确率 + 召回率 )

6.比较与总结

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

答:

CountVectorizer只考虑每种词汇在该训练文本中出现的频率,而TfidfVectorizer除了考量某一词汇在当前训练文本中出现的频率之外,同时关注包含这个词汇的其它训练文本数目的倒数。在少数据的情况下CountVectorizer有更好的表现,但是在有大量训练数据时TfidfVectorizer这种特征量化方式就更有优势。

posted @ 2020-05-27 15:17  renshenbenzuig  阅读(284)  评论(0编辑  收藏  举报