0%

机器学习实战 — 朴素贝叶斯

作业

根据给定的 20-News Group 数据集,设计Naïve Bayes 算法进行文本分类的研究。
讨论和使用不同的预处理方法,并讨论各种预处理对于算法性能的影响。

步骤

  1. 加载数据集
  2. 提取 TF-IDF 特征
  3. 生成文档的 TF-IDF 矩阵
  4. 训练多项式朴素贝叶斯模型
  5. 评价模型

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from sklearn.datasets import fetch_20newsgroups
from pprint import pprint
from sklearn.feature_extraction.text import TfidfVectorizer

# sklearn twenty_newsgroups document
# http://sklearn.apachecn.org/cn/0.19.0/datasets/twenty_newsgroups.html
fetch_20newsgroups(data_home='/Users/ljp/Codes/ivy_plan/naive_bayes/20_newsgroups', # 文件下载的路径
subset='train', # 加载那一部分数据集 train/test
categories=None, # 选取哪一类数据集[类别列表],默认20类
shuffle=True, # 将数据集随机排序
random_state=42, # 随机数生成器
remove=(), # ('headers','footers','quotes') 去除部分文本
download_if_missing=True # 如果没有下载过,重新下载
)

# 加载数据集
newsgroups_train = fetch_20newsgroups(subset='train')

# Bunch
# load_*和 fetch_* 函数返回的数据类型是 datasets.base.Bunch,本质上是一个 dict,它的键值对可用通过对象的属性方式访问。
# 主要包含以下属性:
# data:特征数据数组,type 是 list,是 n_samples * n_features 的二维 numpy.ndarray 数组
# filenames:文件数组,是文件路径,是 n_samples 的一维 numpy.ndarray 数组
# target:标签数组,是类别的整数索引,是 n_samples 的一维 numpy.ndarray 数组,与 filenames 一一对应
# DESCR:数据描述
# feature_names:特征名
# target_names:标签名
# print(type(newsgroups_train)) # <class 'sklearn.utils.Bunch'>
# print(list(newsgroups_train)) # ['data', 'filenames', 'target_names', 'target', 'DESCR', 'description']

# 提取tfidf特征
vectorizer = TfidfVectorizer() # vectorizer type is <class 'sklearn.feature_extraction.text.TfidfVectorizer'>

# vectors type is <class 'scipy.sparse.csr.csr_matrix'>
# 数据格式为:(文档序号, 单词序号), tf-idf值
# 文档序号是该文档在 newsgroups_train.filenames 里的索引(位置)
# 单词序号是该单词在所有单词所构成的一维向量(也称为词袋,Bag of words)里的索引(位置)
# 例如:
# (0, 11071) 0.02879840104494835
# (0, 19516) 0.15199951710440102
# (0, 24556) 0.36446543134314724
vectors = vectorizer.fit_transform(newsgroups_train.data)

# MultinomialNB实现文本分类
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score,f1_score

# 训练
clf=MultinomialNB(alpha=0.1)
clf.fit(vectors,newsgroups_train.target)

# 加载测试集
newsgroups_test=fetch_20newsgroups(subset='test')

# 提取测试集tfidf特征
vectors_test=vectorizer.transform(newsgroups_test.data)

# 模型评价
from sklearn.metrics import classification_report
pred=clf.predict(vectors_test)
print('accuracy_score: ' + str(accuracy_score(newsgroups_test.target,pred)))

print("classification report on test set for classifier:")
print(clf)
X_test = vectorizer.transform((d for d in newsgroups_test.data))
pred = clf.predict(X_test)
y_test = newsgroups_test.target
print(classification_report(y_test, pred, target_names=newsgroups_test.target_names))

## 生成混淆矩阵,观察每种类别被错误分类的情况
from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_test, pred)
print("confusion matrix:")
print(cm)
# Show confusion matrix
import matplotlib.pyplot as plt

plt.figure(figsize=(8, 8), dpi=144)
plt.title('Confusion matrix of the classifier')
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('none')
ax.spines['left'].set_color('none')
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.matshow(cm, fignum=1, cmap='gray')
plt.colorbar()
plt.show()

输出如下:
naive_bayes_auc.jpg

naive_bayes_cross_matrix.png

参考文档

5.6.2. 20个新闻组文本数据集 — scikit-learn 0.19.0 中文文档 - ApacheCN
利用朴素贝叶斯算法进行文档分类 - 简书
https://www.cs.waikato.ac.nz/ml/publications/2004/kibriya_et_al_cr.pdf

觉得不错,就打赏一下吧