• 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="	")
    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("矩阵:
    ",cm)
    cr = classification_report(y_test,y_mnb)
    print("报告:
    ",cr)
    print("模型准确率为:", (cm[0][0] + cm[1][1]) / np.sum(cm))

    截图:

    6.比较与总结

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

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

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

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

  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/q1uj1e/p/12952591.html
Copyright © 2020-2023  润新知