zoukankan      html  css  js  c++  java
  • 机器学习11贝叶斯处理邮件分类问题------后续

    1.读取

    import csv
    path = r'C:UsersChen ZhenruiPycharmProjectsuntitled机器学习SMSSpamCollection'
    sms = open(path, 'r', encoding='utf-8')
    csv_reader = csv.reader(sms, delimiter='	')

    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中第一行向量对应的邮件内容: ',key_list) #第一行向量对应的邮件内容 print('x_train中第一行邮件的原始内容为: ',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('训练集维度:
    ',x_train.toarray().shape)  # 训练集维度
    print('测试集维度:
    ', 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中第一行向量对应的邮件内容:
    ', key_list)  # 第一行向量对应的邮件内容
    print('x_train中第一行邮件的原始内容为:
    ', 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("模型的混淆矩阵:
    ",confusion_matrix(y_test,y_mnb))
    from sklearn.metrics import classification_report
    print("输出模型的分类报告 :
    ", 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这种特征量化方式就更有优势。

  • 相关阅读:
    Python类的继承(进阶5)
    面向对象编程基础(进阶4)
    Python模块(进阶3)
    Python函数式编程(进阶2)
    python多线程
    Ternary Search Tree Java实现
    Trie和Ternary Search Tree介绍
    索引时利用K-邻近算法过滤重复歌曲
    Sql排名和分组排名
    Lucene和jackson冲突
  • 原文地址:https://www.cnblogs.com/renshenbenzuig/p/12973271.html
Copyright © 2011-2022 走看看