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

    1.读取

    sms = open("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.数据预处理

    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 = []
        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]
    
        # 词性标注
        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)

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

    观察邮件与向量的关系

    向量还原为邮件

    ##向量化
    def tfidf(x_train, x_test):
        tfidf2 = TfidfVectorizer()
        # 将邮件内容转换为向量
        x_train = tfidf2.fit_transform(x_train)
        x_test = tfidf2.transform(x_test)
        # 转成数组后查看测试集维度
        print('训练集维度:
    ', x_train.toarray().shape)
        print('测试集维度:
    ', x_test.toarray().shape)
        # tfidf2.vocabulary_  # 词袋的词语的统计字典,(单词,单词位置)
    
        # 将向量还原成邮件
        a = np.flatnonzero(x_train.toarray()[0])  # 获取x_train中第一行非0的值的位置列表
        print("非零元素的位置", a)
        print("向量的非零元素:", x_train.toarray()[0][a])
        b = tfidf2.vocabulary_  #词汇表
        key_list = []
        for key, value in b.items():
            if value in a:
                key_list.append(key)
    
        print("非零元素对应的单词", key_list)
        print("向量化之前的邮件", x_traincp )
        return x_train, x_test

    结果为:

      

    4.模型选择

    from sklearn.naive_bayes import GaussianNB

    from sklearn.naive_bayes import MultinomialNB

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

    def model_choose(x_train, y_train, x_test, y_test):
        mnb = MultinomialNB()
        mnb.fit(x_train, y_train)
        y_mnb = mnb.predict(x_test)
        print("预测准确率为:", sum(y_mnb == y_test) / len(y_test))
        return y_mnb  

    结果为:  

      

      选择模型应该通过模型数据的特点来进行选择。因为用高斯贝叶斯模型进行处理的数据,基本是符合正态分布的,而我们处理的数据是单词出现的频率(单词对文档的重要性),是概率性的数据,并不符合正态分布的规则,所以选择多项式贝叶斯模型。

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

    from sklearn.metrics import confusion_matrix

    confusion_matrix = confusion_matrix(y_test, y_predict)

    说明混淆矩阵的含义

    from sklearn.metrics import classification_report

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

    def classify(y_mnb, y_test):
        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))

    结果为:

      

      (1)混淆矩阵:混淆矩阵(Confusion Matrix):

         通过这四个指标,我们可以得出混淆矩阵,这四个指标分别是:

        · 真实值是positive,模型认为是positive的数量(True Positive=TP) (966)

        · 真实值是positive,模型认为是negative的数量(False Negative=FN):这就是统计学上的第二类错误(Type II Error)(49)

        · 真实值是negative,模型认为是positive的数量(False Positive=FP):这就是统计学上的第一类错误(Type I Error)(0)

        · 真实值是negative,模型认为是negative的数量(True Negative=TN)(109)

      (2)准确率:被分对的样本数除以所有的样本数,通常来说,正确率越高,分类器越好。(TP+TN)/总

      (3)精确率:表示被分为正例的示例中实际为正例的比例。 TP/(TP+FP)

        (4)召回率 :召回率是覆盖面的度量,度量有多个正例被分为正例。TP/(TP+FN)

        (5)F值 : 精确率 * 召回率 * 2 / ( 精确率 + 召回率) 。F值就是准确率(P)和召回率(R)的加权调和平均。

    6.比较与总结

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

     CountVectorizer:只考虑每个单词出现的频率;然后构成一个特征矩阵,每一行表示一个训练文本的词频统计结果。

     TfidfVectorizer:除了考量某词汇在本文本出现的频率,还关注包含这个词汇的其它文本的数量。

     相比之下,训练文本的数量越多,TfidfVectorizer这种特征量化方式就更有优势,而且TfidfVectorizer可以削减高频没有意义的词汇,应用于实际更有意义,实际效果也会更好。

  • 相关阅读:
    克如斯卡尔 P1546
    真正的spfa
    第四课 最小生成树 要点
    关于vscode中nullptr未定义
    cmake学习笔记
    python学习笔记
    (BFS 图的遍历) 2906. kotori和迷宫
    (图论基础题) leetcode 997. Find the Town Judge
    (BFS DFS 并查集) leetcode 547. Friend Circles
    (BFS DFS 图的遍历) leetcode 841. Keys and Rooms
  • 原文地址:https://www.cnblogs.com/jwwzone/p/12940506.html
Copyright © 2011-2022 走看看