朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证

转自https://blog.****.net/Eastmount/article/details/79128235


中文文本数据集预处理


假设现在需要判断一封邮件是不是垃圾邮件,其步骤如下:

  • 数据集拆分成单词,中文分词技术
  • 计算句子中总共多少单词,确定词向量大小
  • 句子中的单词转换成向量,BagofWordsVec
  • 计算P(Ci),P(Ci|w)=P(w|Ci)P(Ci)/P(w),表示w特征出现时,该样本被分为Ci类的条件概率
  • 判断P(w[i]C[0])和P(w[i]C[1])概率大小,两个集合中概率高的为分类类标
下面讲解一个具体的实例。


内容 评价
这是一本非常优秀的书籍,值得读者购买 好评
Python技术非常火热,这也是一本很好的数据,读者很开心 好评
数据逻辑比较混乱,差评 差评
这是我见过最差的一本Python数据分析书籍 差评
好评,非常好的一本书籍,值得大家学习。 好评
差评,简直是误人子弟。 差评
书籍作者还是写的比较认真的,但是思路有点乱,需优化下。 差评
强烈推荐大家购买这本书籍,这么多年难得一见的好书。 好评
一本优秀的书籍,值得读者拥有。 好评
很差,不建议买,准备退货 差评
这是一本非常优秀的书籍 好评
Python技术非常火热,很开心 好评
数据逻辑混乱,差评 差评
这是我见过最差的一本Python书籍 差评
值得大家学习。 好评
差评。 差评
作者写的比较认真,但是思路有点乱。 差评
强烈推荐大家购买这本书籍。 好评
值得读者拥有。 好评
很差,不建议买,准备退货 差评
准备退货 差评

data.csv的数据

完整代码

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import jieba

# http://blog.****.net/eastmount/article/details/50323063
# http://blog.****.net/eastmount/article/details/50256163
# http://blog.****.net/lsldd/article/details/41542107

####################################
#         第一步 读取数据及分词
#

delimiter="\t"

data = pd.read_csv("D:\Users\WANGBIN505\PycharmProjects\data\data.csv", encoding='gbk',delimiter="\t")
print data

# 取表中的第1列的所有值
print u"获取第一列内容"
col = data.iloc[:, 0]
# 取表中所有值
arrs = col.values

# 去除停用词
stopwords = {}.fromkeys([',', '。', '!', '这', '我', '非常'])

print u"\n中文分词后结果:"
corpus = []
for a in arrs:
    # print a
    seglist = jieba.cut(a, cut_all=False)  # 精确模式
    final = ''
    for seg in seglist:
        seg = seg.encode('utf-8')
        if seg not in stopwords:  # 不是停用词的保留
            final += seg
    seg_list = jieba.cut(final, cut_all=False)
    output = ' '.join(list(seg_list))  # 空格拼接
    print output
    corpus.append(output)

####################################
#         第二步 计算词频
#
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

vectorizer = CountVectorizer()  # 将文本中的词语转换为词频矩阵
X = vectorizer.fit_transform(corpus)  # 计算个词语出现的次数
word = vectorizer.get_feature_names()  # 获取词袋中所有文本关键词
for w in word:  # 查看词频结果
    print w,
print ''
print X.toarray()

####################################
#         第三步 数据分析
#
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import classification_report

# 使用前8行数据集进行训练,最后两行数据集用于预测
print u"\n\n数据分析:"
X = X.toarray()
x_train = X[:8]
x_test = X[8:]
# 1表示好评 0表示差评
y_train = [1, 1, 0, 0, 1, 0, 0, 1]
y_test = [1,0,1,1,0,0,1,0,0,1,1,0,0]

# 调用MultinomialNB分类器
clf = MultinomialNB().fit(x_train, y_train)
pre = clf.predict(x_test)
print u"预测结果:", pre
print u"真实结果:", y_test

from sklearn.metrics import classification_report

print(classification_report(y_test, pre))

# 降维绘制图形
from sklearn.decomposition import PCA

pca = PCA(n_components=2)
newData = pca.fit_transform(X)
print newData

pre = clf.predict(X)
Y = [1, 1, 0, 0, 1, 0, 0, 1, 1, 0]
import matplotlib.pyplot as plt

L1 = [n[0] for n in newData]
L2 = [n[1] for n in newData]
plt.scatter(L1, L2, c=pre, s=200)
plt.show()


运行结果:

Building prefix dict from the default dictionary ...
                               内容,评价
0              这是一本非常优秀的书籍,值得读者购买,好评
1   Python技术非常火热,这也是一本很好的数据,读者很开心,好评
2                     数据逻辑比较混乱,差评,差评
3          这是我见过最差的一本Python数据分析书籍,差评
4             好评,非常好的一本书籍,值得大家学习。,好评
5                     差评,简直是误人子弟。,差评
6     书籍作者还是写的比较认真的,但是思路有点乱,需优化下。,差评
7       强烈推荐大家购买这本书籍,这么多年难得一见的好书。,好评
8                 一本优秀的书籍,值得读者拥有。,好评
9                    很差,不建议买,准备退货,差评
10                    这是一本非常优秀的书籍,好评
11               Python技术非常火热,很开心,好评
12                      数据逻辑混乱,差评,差评
13             这是我见过最差的一本Python书籍,差评
14                        值得大家学习。,好评
15                            差评。,差评
16              作者写的比较认真,但是思路有点乱。,差评
17                  强烈推荐大家购买这本书籍。,好评
18                        值得读者拥有。,好评
19                   很差,不建议买,准备退货,差评
20                           准备退货,差评
获取第一列内容


中文分词后结果:
Loading model from cache d:\users\wangbi~1\appdata\local\temp\jieba.cache
Loading model cost 0.657 seconds.
Prefix dict has been built succesfully.
这是 一本 优秀 的 书籍 值得 读者 购买 , 好评
Python 技术 火热 也 是 一本 很 好 的 数据 读者 很 开心 , 好评
数据 逻辑 比较 混乱 差评 , 差评
是 见 过 最差 的 一本 Python 数据分析 书籍 , 差评
好评 好 的 一本 书籍 值得 大家 学习 , 好评
差评 简直 是 误人子弟 , 差评
书籍 作者 还是 写 的 比较 认真 的 但是 思路 有点 乱 需 优化 下 , 差评
强烈推荐 大家 购买 这本 书籍 这么 多年 难得一见 的 好书 , 好评
一本 优秀 的 书籍 值得 读者 拥有 , 好评
很差 不 建议 买 准备 退货 , 差评
这是 一本 优秀 的 书籍 , 好评
Python 技术 火热 很 开心 , 好评
数据 逻辑 混乱 差评 , 差评
是 见 过 最差 的 一本 Python 书籍 , 差评
值得 大家 学习 , 好评
差评 , 差评
作者 写 的 比较 认真 但是 思路 有点 乱 , 差评
强烈推荐 大家 购买 这本 书籍 , 好评
值得 读者 拥有 , 好评
很差 不 建议 买 准备 退货 , 差评
准备 退货 , 差评
python 一本 书籍 优化 优秀 但是 作者 值得 准备 多年 大家 好书 好评 学习 差评 建议 开心 强烈推荐 很差 思路 技术 拥有 数据 数据分析 最差 有点 比较 混乱 火热 简直 认真 误人子弟 读者 购买 还是 这么 这是 这本 退货 逻辑 难得一见 
[[0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
  1 0 0 0 0]
 [1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0
  0 0 0 1 0]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0]
 [0 1 1 0 0 0 0 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0
  0 0 0 0 0]
 [0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0
  0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
  0 1 0 0 1]
 [0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 1 0 0]
 [0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  1 0 0 0 0]
 [1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0
  0 0 0 1 0]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0
  0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
  0 1 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  0 0 0 0 0]
 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 1 0 0]
 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 1 0 0]]




数据分析:
预测结果: [1 0 1 1 0 0 1 0 0 1 1 0 0]
真实结果: [1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0]
             precision    recall  f1-score   support


          0       1.00      1.00      1.00         7
          1       1.00      1.00      1.00         6


avg / total       1.00      1.00      1.00        13


[[ 1.61136613  0.0127816 ]
 [ 0.87360242 -1.15966155]
 [-1.72827646 -0.21210257]
 [-0.20098345 -0.28551402]
 [ 1.79730282  0.16195999]
 [-1.37334975 -0.28237494]
 [-1.02917836  2.2230535 ]
 [ 1.27335696  1.06956399]
 [ 1.46122138 -0.16765108]
 [-1.01711281 -0.63229683]
 [ 1.08056231  0.01680808]
 [ 0.57062864 -0.75710301]
 [-1.59196315 -0.49387849]
 [-0.19405367 -0.26325436]
 [ 0.87921493  0.03487481]
 [-1.27864536 -0.23834509]
 [-1.19602308  1.60325407]
 [ 1.09773892  0.73601637]
 [ 0.85853971 -0.29872101]
 [-1.01711281 -0.63229683]
 [-0.87683529 -0.43511264]]


Process finished with exit code 0

生成的图表:

朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证



讲解:



1.数据集读取

假设存在如下所示10条Python书籍订单评价信息,每条评价信息对应一个结果(好评和差评),如下图所示:


朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证

数据存储至CSV文件中,如下图所示。

朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证

下面采用pandas扩展包读取数据集。代码如下所示:

[python] view plain copy
  1. # -*- coding: utf-8 -*-  
  2. import numpy as np  
  3. import pandas as pd  
  4.   
  5. data = pd.read_csv("data.csv",encoding='gbk')  
  6. print data  
  7.   
  8. #取表中的第1列的所有值  
  9. print u"获取第一列内容"  
  10. col = data.iloc[:,0]    
  11. #取表中所有值    
  12. arrs = col.values  
  13. for a in arrs:  
  14.     print a  

输出结果如下图所示,同时可以通过data.iloc[:,0]获取第一列的内容。

朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证



2.中文分词及过滤停用词
接下来作者采用jieba工具进行分词,并定义了停用词表,即:
    stopwords = {}.fromkeys([',', '。', '!', '这', '我', '非常'])
完整代码如下所示:

[python] view plain copy
  1. # -*- coding: utf-8 -*-  
  2. import numpy as np  
  3. import pandas as pd  
  4. import jieba  
  5.   
  6. data = pd.read_csv("data.csv",encoding='gbk')  
  7. print data  
  8.   
  9. #取表中的第1列的所有值  
  10. print u"获取第一列内容"  
  11. col = data.iloc[:,0]    
  12. #取表中所有值    
  13. arrs = col.values  
  14. #去除停用词    
  15. stopwords = {}.fromkeys([',''。''!''这''我''非常'])  
  16.   
  17. print u"\n中文分词后结果:"  
  18. for a in arrs:  
  19.     #print a  
  20.     seglist = jieba.cut(a,cut_all=False)     #精确模式    
  21.     final = ''  
  22.     for seg in seglist:  
  23.         seg = seg.encode('utf-8')  
  24.         if seg not in stopwords: #不是停用词的保留  
  25.             final += seg  
  26.     seg_list = jieba.cut(final, cut_all=False)   
  27.     output = ' '.join(list(seg_list))         #空格拼接  
  28.     print output  

然后分词后的数据如下所示,可以看到标点符号及“这”、“我”等词已经过滤。

朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证


3.词频统计
接下来需要将分词后的语句转换为向量的形式,这里使用CountVectorizer实现转换为词频。如果需要转换为TF-IDF值可以使用TfidfTransformer类。词频统计完整代码如下所示:

[python] view plain copy
  1. # -*- coding: utf-8 -*-  
  2. import numpy as np  
  3. import pandas as pd  
  4. import jieba  
  5.   
  6. data = pd.read_csv("data.csv",encoding='gbk')  
  7. print data  
  8.   
  9. #取表中的第1列的所有值  
  10. print u"获取第一列内容"  
  11. col = data.iloc[:,0]    
  12. #取表中所有值    
  13. arrs = col.values  
  14. #去除停用词    
  15. stopwords = {}.fromkeys([',''。''!''这''我''非常'])  
  16.   
  17. print u"\n中文分词后结果:"  
  18. corpus = []  
  19. for a in arrs:  
  20.     #print a  
  21.     seglist = jieba.cut(a,cut_all=False)     #精确模式    
  22.     final = ''  
  23.     for seg in seglist:  
  24.         seg = seg.encode('utf-8')  
  25.         if seg not in stopwords: #不是停用词的保留  
  26.             final += seg  
  27.     seg_list = jieba.cut(final, cut_all=False)   
  28.     output = ' '.join(list(seg_list))         #空格拼接  
  29.     print output  
  30.     corpus.append(output)  
  31.   
  32. #计算词频  
  33. from sklearn.feature_extraction.text import CountVectorizer  
  34. from sklearn.feature_extraction.text import TfidfTransformer  
  35.     
  36. vectorizer = CountVectorizer() #将文本中的词语转换为词频矩阵    
  37. X = vectorizer.fit_transform(corpus) #计算个词语出现的次数      
  38. word = vectorizer.get_feature_names() #获取词袋中所有文本关键词    
  39. for w in word: #查看词频结果  
  40.     print w,  
  41. print ''  
  42. print X.toarray()    

输出结果如下所示,包括特征词及对应的10行数据的向量,这就将中文文本数据集转换为了数学向量的形式,接下来就是对应的数据分析了。

朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证


如下所示得到一个词频矩阵,每行数据集对应一个分类类标,可以预测新的文档属于哪一类。


朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证

TF-IDF相关知识推荐我的文章: [python] 使用scikit-learn工具计算文本TF-IDF值





朴素贝叶斯中文文本舆情分析


最后给出朴素贝叶斯分类算法分析中文文本数据集的完整代码。

[python] view plain copy
  1. # -*- coding: utf-8 -*-  
  2. import numpy as np  
  3. import pandas as pd  
  4. import jieba  
  5.   
  6. #http://blog.****.net/eastmount/article/details/50323063  
  7. #http://blog.****.net/eastmount/article/details/50256163  
  8. #http://blog.****.net/lsldd/article/details/41542107  
  9.   
  10. ####################################  
  11. #         第一步 读取数据及分词  
  12. #  
  13. data = pd.read_csv("data.csv",encoding='gbk')  
  14. print data  
  15.   
  16. #取表中的第1列的所有值  
  17. print u"获取第一列内容"  
  18. col = data.iloc[:,0]    
  19. #取表中所有值    
  20. arrs = col.values  
  21.   
  22. #去除停用词    
  23. stopwords = {}.fromkeys([',''。''!''这''我''非常'])  
  24.   
  25. print u"\n中文分词后结果:"  
  26. corpus = []  
  27. for a in arrs:  
  28.     #print a  
  29.     seglist = jieba.cut(a,cut_all=False)     #精确模式    
  30.     final = ''  
  31.     for seg in seglist:  
  32.         seg = seg.encode('utf-8')  
  33.         if seg not in stopwords: #不是停用词的保留  
  34.             final += seg  
  35.     seg_list = jieba.cut(final, cut_all=False)   
  36.     output = ' '.join(list(seg_list))         #空格拼接  
  37.     print output  
  38.     corpus.append(output)  
  39.   
  40. ####################################  
  41. #         第二步 计算词频  
  42. #  
  43. from sklearn.feature_extraction.text import CountVectorizer  
  44. from sklearn.feature_extraction.text import TfidfTransformer  
  45.     
  46. vectorizer = CountVectorizer() #将文本中的词语转换为词频矩阵    
  47. X = vectorizer.fit_transform(corpus) #计算个词语出现的次数      
  48. word = vectorizer.get_feature_names() #获取词袋中所有文本关键词    
  49. for w in word: #查看词频结果  
  50.     print w,  
  51. print ''  
  52. print X.toarray()    
  53.   
  54.   
  55. ####################################  
  56. #         第三步 数据分析  
  57. #  
  58. from sklearn.naive_bayes import MultinomialNB    
  59. from sklearn.metrics import precision_recall_curve    
  60. from sklearn.metrics import classification_report  
  61.   
  62. #使用前8行数据集进行训练,最后两行数据集用于预测  
  63. print u"\n\n数据分析:"  
  64. X = X.toarray()  
  65. x_train = X[:8]  
  66. x_test = X[8:]  
  67. #1表示好评 0表示差评  
  68. y_train = [1,1,0,0,1,0,0,1]  
  69. y_test = [1,0]  
  70.   
  71. #调用MultinomialNB分类器    
  72. clf = MultinomialNB().fit(x_train, y_train)  
  73. pre = clf.predict(x_test)  
  74. print u"预测结果:",pre  
  75. print u"真实结果:",y_test  
  76.   
  77. from sklearn.metrics import classification_report  
  78. print(classification_report(y_test, pre))  

输出结果如下所示,可以看到预测的两个值都是正确的。即“一本优秀的书籍,值得读者拥有。”预测结果为好评(类标1),“很差,不建议买,准备退货。”结果为差评(类标0)。

[python] view plain copy
  1. 数据分析:  
  2. 预测结果: [1 0]  
  3. 真实结果: [10]  
  4.              precision    recall  f1-score   support  
  5.   
  6.           0       1.00      1.00      1.00         1  
  7.           1       1.00      1.00      1.00         1  
  8.   
  9. avg / total       1.00      1.00      1.00         2  

但存在一个问题,由于数据量较小不具备代表性,而真实分析中会使用海量数据进行舆情分析,预测结果肯定页不是100%的正确,但是需要让实验结果尽可能的好。最后补充一段降维绘制图形的代码,如下:

[python] view plain copy
  1. #降维绘制图形  
  2. from sklearn.decomposition import PCA  
  3. pca = PCA(n_components=2)  
  4. newData = pca.fit_transform(X)  
  5. print newData  
  6.   
  7. pre = clf.predict(X)  
  8. Y = [1,1,0,0,1,0,0,1,1,0]  
  9. import matplotlib.pyplot as plt  
  10. L1 = [n[0for n in newData]  
  11. L2 = [n[1for n in newData]  
  12. plt.scatter(L1,L2,c=pre,s=200)  
  13. plt.show()  

输出结果如图所示,预测结果和真实结果都是一样的,即[1,1,0,0,1,0,0,1,1,0]。

朴素贝叶斯分类器详解及中文文本舆情分析(转载)验证