13-垃圾邮件分类2

1.读取

代码:

#1.读取数据
import csv
sms = open("venv/data/SMSSpamCollection","r",encoding="utf-8")      #读取数据集
sms_data = []   #提取邮件内容
sms_label = []  #提取邮件标签
csv_reader = csv.reader(sms,delimiter="\t")
for line in csv_reader:
    sms_label.append(line[0])
    sms_data.append(preprocessing(line[1]))   #对每封邮件做预处理
sms.close()

 

2.数据预处理

代码:

#2.数据预处理
import nltk
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer

def get_wordnet_pos(treebank_tag):          # 根据词性,生成还原参数pos
    if treebank_tag.startswith('J'):        #还原形容词
        return nltk.corpus.wordnet.ADJ
    elif treebank_tag.startswith('V'):      #还原动词
        return nltk.corpus.wordnet.VERB
    elif treebank_tag.startswith('N'):      #还原名词
        return nltk.corpus.wordnet.NOUN
    elif treebank_tag.startswith('R'):      #还原副词
        return nltk.corpus.wordnet.ADV
    else:
        return nltk.corpus.wordnet.NOUN

def preprocessing(text):
    # 划分多个句子,对每个句子进行划分,并对每个分词放到列表里面
    tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]

    #去掉停用词(停用器)
    stops = stopwords.words("english")
    tokens = [token for token in tokens if token not in stops]

    tokens = [token.lower() for token in tokens if len(token) >= 3]  # 大小写,长度3

    #词性标注
    tag = nltk.pos_tag(tokens)

    #词性还原
    lmtzr = WordNetLemmatizer()     #定义还原对象
    tokens = [lmtzr.lemmatize(token, pos=get_wordnet_pos(tag[i][1])) for i, token in enumerate(tokens)]    # 词性还原
    preprocessed_text = ' '.join(tokens)

    return preprocessed_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)

 

代码:

# 3.数据划分—训练集和测试集数据划分
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=0, stratify=sms_label)
len(sms_label)    #总数
len(x_train)      #训练集数量
len(y_test)       #测试集数量

 

截图:

 

 

 

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

观察邮件与向量的关系

向量还原为邮件

 

代码:

# 4.文本特征提取
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf2 = TfidfVectorizer()
X_train = tfidf2.fit_transform(x_train)
X_test = tfidf2.transform(x_test)
tfidf2.vocabulary_    #(单词、位置)

#向量还原为邮件
import numpy as np
s = X_train.toarray()[0]  #邮件0的向量
a = np.flatnonzero(s)  # 非零元素的位置(index)
# print("非零元素的位置:", a)
print("向量的非0元素:", s[a])
b = tfidf2.vocabulary_  # 词汇表
key_list = []
for key, value in b.items():
    if value in a:
        key_list.append(key)     # key非0元素对应的单词
print("向量非零元素对应的单词:", key_list)
print("向量化之前的邮件:", x_train[0])

 

截图:

 

 

 

 

 

 

 

4.模型选择

from sklearn.naive_bayes import GaussianNB

from sklearn.naive_bayes import MultinomialNB

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

选择原因:由于实验数据的事件属于从多个词仲提取,且数据属于离散,不适合正态分布,而多项式分布模型又适合这种离散的文本数据,因此我选择的是多项式贝叶斯模型。

 

代码:

from sklearn.naive_bayes import MultinomialNB
mnb = MultinomialNB()
mnb.fit(X_train,y_train)
y_mnb = mnb_model.predict(X_test)
print("准确率:",(y_mnb == y_test).sum())

 

截图:

 

 

 

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

from sklearn.metrics import confusion_matrix

confusion_matrix = confusion_matrix(y_test, y_predict)

说明混淆矩阵的含义

from sklearn.metrics import classification_report

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

 

 混淆矩阵的含义:

①TP(True Positive):真实为0 ,预测也为0

②FN(False Negative):真实为0 ,预测为1

③FP(False Positive):真实为1 , 预测为0

④TN(True Negative):真实为1 ,预测也为1

 

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

 准确率(正确率)=所有预测正确的样本/总的样本  (TP+TN)/总

 精确率=  将正类预测为正类 / 所有预测为正类 TP/(TP+FP)

 召回率 = 将正类预测为正类 / 所有正真的正类 TP/(TP+FN)

 F值 = 精确率 * 召回率 * 2 / ( 精确率 + 召回率) (F 值即为精确率和召回率的调和平均值)

代码:

# 5.模型评价:混淆矩阵,分类报告
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
cm = confusion_matrix(y_test,y_mnb)
print("矩阵:\n",cm)
cr = classification_report(y_test,y_mnb)
print("报告:\n",cr)
print("模型准确率为:", (cm[0][0] + cm[1][1]) / np.sum(cm))

 

截图:

 

 

 

6.比较与总结

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

CountVectorizer:特征数值计算类,文本特征提取方法。它于每一个训练文本,CountVectorizer会将文本中的词语转换为词频矩阵,它通过fit_transform函数计算各个词语在该训练文本出现的次数。而它只考虑词汇在文本中出现的频率。

TfidfVectorizer:它不仅考量某词汇在文本出现的频率,还关注包含这个词汇的所有文本的数量,能够削减高频没有意义的词汇出现带来的影响, 挖掘更有意义的特征。

因此两者相比之下,文本条目越多,TfidfVectorizer的效果会越显著。

posted on 2020-05-24 20:49  He11o  阅读(172)  评论(0编辑  收藏  举报

导航