zoukankan      html  css  js  c++  java
  • 垃圾邮件分类2

    1.读取

    # 1、读取数据集
    def read_dataset():
         file_path = r'SMSSpamCollection'
         sms = open(file_path, 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()
         return sms_data, sms_label

    2.数据预处理

    # 2、数据预处理
    def preprocess(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]  # 大小写,短词
         wnl = WordNetLemmatizer()
         tag = nltk.pos_tag(tokens)  # 词性
         tokens = [wnl.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、划分数据集
    def split_dataset(data, label):
         x_train, x_test, y_train, y_test = train_test_split(data, label, test_size=0.2, random_state=0, stratify=label)
         return x_train, x_test, y_train, 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、文本特征提取
    # 把文本转化为tf-idf的特征矩阵
    def tfidf_dataset(x_train,x_test):
         tfidf = TfidfVectorizer()
         X_train = tfidf.fit_transform(x_train)  
         X_test = tfidf.transform(x_test)
         return X_train, X_test, tfidf
    
    # 向量还原成邮件
    def revert_mail(x_train, X_train, model):
        s = X_train.toarray()[0]
        print("第一封邮件向量表示为:", s)
        a = np.flatnonzero(X_train.toarray()[0])  # 非零元素的位置(index)
        print("非零元素的位置:", a)
        print("向量的非零元素的值:", s[a])
        b = model.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])

    5.模型选择

    from sklearn.naive_bayes import GaussianNB

    from sklearn.naive_bayes import MultinomialNB

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

    # 5、模型选择
    def mnb_model(x_train, x_test, y_train, y_test):
        mnb = MultinomialNB()
        mnb.fit(x_train, y_train)
        pre = mnb.predict(x_test)
        print("总数:", len(y_test))
        print("预测正确数:", (pre == y_test).sum())
        print("预测准确率:",sum(pre == y_test) / len(y_test))
        return pre

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

    from sklearn.metrics import confusion_matrix

    confusion_matrix = confusion_matrix(y_test, y_predict)

    说明混淆矩阵的含义

    from sklearn.metrics import classification_report

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

    # 6、模型评价
    def class_report(pre, y_test):
        conf_matrix = confusion_matrix(y_test, pre)
        print("=====================================================")
        print("混淆矩阵:
    ", conf_matrix)
        c = classification_report(y_test, pre)
        print("分类报告:
    ", c)
        print("模型准确率:", (conf_matrix[0][0] + conf_matrix[1][1]) / np.sum(conf_matrix))

    完整代码:

    # -*- coding:utf-8 -*-
    from sklearn.model_selection import train_test_split
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.naive_bayes import MultinomialNB
    from sklearn.metrics import confusion_matrix, classification_report
    import numpy as np
     
    import nltk
    from nltk.corpus import stopwords
    from nltk.stem import WordNetLemmatizer
    import csv
    def get_wordnet_pos(treebank_tag):# 根据词性,生成还原参数pos
         if treebank_tag.startswith('J'):  # adj
            return nltk.corpus.wordnet.ADJ
         elif treebank_tag.startswith('V'):  # v
            return nltk.corpus.wordnet.VERB
         elif treebank_tag.startswith('N'):  # n
             return nltk.corpus.wordnet.NOUN
         elif treebank_tag.startswith('R'):  # adv
            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]  # 大小写,短词
         lmtzr = WordNetLemmatizer()
         tag = nltk.pos_tag(tokens)  # 词性
         tokens = [lmtzr.lemmatize(token, pos=get_wordnet_pos(tag[i][1])) for i, token in enumerate(tokens)]  # 词性还原
         preprocessed_text = ' '.join(tokens)
         return preprocessed_text
     
    # 读取数据集
    def read_dataset():
         file_path =r'SMSSpamCollection'
         sms = open(file_path, encoding='utf-8')#读取数据
         sms_label = []  # 存储标题
         sms_data = []#存储数据
         csv_reader = csv.reader(sms, delimiter='	')
         for line in csv_reader:
            sms_label.append(line[0])  # 提取出标签
            sms_data.append(preprocessing(line[1]))  # 对每封邮件做预处理
         sms.close()
         return sms_data, sms_label
     
    # 划分数据集
    def split_dataset(data, label):
         x_train, x_test, y_train, y_test = train_test_split(data, label, test_size=0.2, random_state=0, stratify=label)
         return x_train, x_test, y_train, y_test
     
    # 把原始文本转化为tf-idf的特征矩阵
    def tfidf_dataset(x_train,x_test):
         tfidf = TfidfVectorizer()
         X_train = tfidf.fit_transform(x_train)  # X_train用fit_transform生成词汇表
         X_test = tfidf.transform(x_test)  # X_test要与X_train词汇表相同,因此在X_train进行fit_transform基础上进行transform操作
         return X_train, X_test, tfidf
     
    # 向量还原邮件
    def revert_mail(x_train, X_train, model):
        s = X_train.toarray()[0]
        print("第一封邮件向量表示为:", s)
        # 该函数输入一个矩阵,返回扁平化后矩阵中非零元素的位置(index)
        a = np.flatnonzero(X_train.toarray()[0])  # 非零元素的位置(index)
        print("非零元素的位置:", a)
        print("向量的非零元素的值:", s[a])
        b = model.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])
     
    # 模型选择(根据数据特点选择多项式分布)
    def mnb_model(x_train, x_test, y_train, y_test):
        mnb = MultinomialNB()
        mnb.fit(x_train, y_train)
        ypre_mnb = mnb.predict(x_test)
        print("总数:", len(y_test))
        print("预测正确数:", (ypre_mnb == y_test).sum())
        return ypre_mnb
     
    # 模型评价:混淆矩阵,分类报告
    def class_report(ypre_mnb, y_test):
        conf_matrix = confusion_matrix(y_test, ypre_mnb)
        print("混淆矩阵:
    ", conf_matrix)
        c = classification_report(y_test, ypre_mnb)
        print("------------------------------------------")
        print("分类报告:
    ", c)
        print("模型准确率:", (conf_matrix[0][0] + conf_matrix[1][1]) / np.sum(conf_matrix))
     
    if __name__ == '__main__':
        sms_data, sms_label = read_dataset() # 读取数据集
        x_train, x_test, y_train, y_test = split_dataset(sms_data, sms_label) # 划分数据集
        X_train, X_test,tfidf = tfidf_dataset(x_train, x_test) # 把原始文本转化为tf-idf的特征矩阵
        revert_mail(x_train, X_train, tfidf) # 向量还原成邮件
        y_mnb = mnb_model(X_train, X_test, y_train,y_test) # 模型选择
        class_report(y_mnb, y_test) # 模型评价

    6.比较与总结

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

    • CountVectorizer:只考虑词汇在文本中出现的频率,属于词袋模型特征。
    • TfidfVectorizer: 除了考量某词汇在文本出现的频率,还关注包含这个词汇的所有文本的数量,能够削减高频没有意义的词汇出现带来的影响, 挖掘更有意义的特征。属于Tfidf特征。
    • CountVectorizer与TfidfVectorizer相比,对于负类的预测更加准确,而正类的预测则稍逊色。但总体预测正确率也比TfidfVectorizer稍高,相比之下似乎CountVectorizer更适合进行预测。
  • 相关阅读:
    pandas Dataframe filter
    process xlsx with pandas
    data manipulate in excel with easyExcel class
    modify registry in user environment
    add number line in vim
    java import webservice
    ctypes MessageBoxA
    music 163 lyrics
    【python实例】自动贩卖机
    【python基础】sys模块(库)方法汇总
  • 原文地址:https://www.cnblogs.com/lzhdonald/p/12957116.html
Copyright © 2011-2022 走看看