数据挖掘 文本分类 知乎问题单分类(四):分类
数据挖掘 文本分类 知乎问题单分类(四):分类
- Naive Bayes
-
Bayes' Theorem [^1]
-
Bayesian classification
-
Naive Bayes classifier (Naive Bayes)
-
(Naive Bayes classifier)
- (Naive Bayes-based text classification examples)
- Instance analysis: Naive Bayes-based text classification algorithm
- Instance analysis: Text classification algorithm based on Naive Bayes
- Instance analysis: Naive Bayes-based text classification algorithm
- (Naive Bayes-based text classification examples)
-
朴素贝叶斯如何利用向量空间模型进行分类计算?
-
代码实现
-
-
SVM
-
- 参考
-
在完成了前面几个阶段的工作之后,我们将即将进入最后阶段进行模型分类的过程。使用多项式朴素贝叶斯模型以及支持向量机模型来进行分类。
朴素贝叶斯
贝叶斯定理1
贝叶斯定理是关于随机事件A和B的条件概率的一则定理。


贝叶斯分类
贝叶斯分类器的新实例分类目标是基于描述实例属性 <a1,a2…an> 确定最可能的目标值VMAP。

在该公式中存在两个待估计的数据项:
(1)P(v_j) 通常采用计算每个目标值 v_j 在训练样本集中出现的频次作为其概率估算值。
(2)P(a_1,\dots,a_n|v_j) 仅当存在一个庞大且充分的训练数据集时才能较为可靠地估算其概率;否则直接应用频率方法将导致不可靠的结果。
朴素贝叶斯分类器(Naive Bayes)
为了应对上述第二个数据项所需的庞大训练数据集及计算资源极为庞大问题, 我们采用了朴素贝叶斯方法
朴素贝叶斯分类器的基本假设是:当给定目标值时,在其他条件下各属性之间的关系是互相独立的。具体来说,在某个实例的目标值已知的情况下,则观察到这一实例的所有属性a1, a2…an同时出现的概率等于各个单独属性出现概率的乘积

利用频率方法可以从训练数据中估算不同P(ai|vj)项所需的样本量与估算P(a1,…,an|vj)项所需的样本量相比大为减少 。因此我们能获得如下的朴素贝叶斯分类器定义
朴素贝叶斯分类器的定义:

其中vNB表示朴素贝叶斯分类器输出的目标值。
朴素贝叶斯文本分类例子
假设共有1,000份待分类的训练文档,在这之中有7成的数据被标记归类为 dislike 类别,在剩下的约3成样本中则属于 like 类别。现需要将以下新增的测试样本进行分类处理:
The following is a sample text designed to illustrate the concept of the naive Bayes classifier. The text comprises either a single paragraph or two concise sentences.

朴素贝叶斯进行文本分类就如上面所示,但是有几点需要说明:
- 贝叶斯分类器所暗含的独立性假设有待商榷。
- 尽管此处的独立性假设有待商榷, 但别无他法, 否则计算的概率项将变得无比庞大学术
- 此外, 实践中, 朴素贝叶斯学习器在多数文本分类问题上均展现出卓越的效果
朴素贝叶斯文本分类算法
训练算法:

学习算法:

朴素贝叶斯如何利用向量空间模型进行分类计算?
为每个文档生成类别标签后,计算某个文档属于某个类别的概率值由公式P(v_j)给出。具体来说,则可以通过训练集中对应的标签y_{train}来确定这些概率值的具体分布情况。例如,在上述示例中可以看到:{0:0.1, 1:0.9}表示当类别为0时有10%的文档属于该类;而类别为1时则有90%的文档属于此类别。
通过将训练集TF-IDF矩阵中的同一类别文档向量进行叠加得到一个m×n大小的矩阵(其中m表示类别数量而n表示词典大小)。为了避免后续运算时出现乘零的问题,在该矩阵的基础上对每个位置上的数值均增加1
计算每一类词在该分类中所占的比例。(值得注意的是,在这种情况下,“总权重”实际上还包含了|vocabulary|这一项(即词袋模型中的词汇总数)。对应的矩阵元素则表示条件概率P(wk|vj),例如:
[[2⁄6, 3⁄6, 1⁄6]
[1⁄5, 2⁄5, 2⁄5]]
在这一阶段(即为训练阶段),随后进入该环节(即为测试阶段)。对于测试集中的每一则文本而言,请计算其对应的TF-IDF特征向量,并评估其表现。

在本方法中,vNB代表模型输出结果的预测值,在分类任务中可以直接用于判断文本所属类别。然而,在直接应用上述公式时存在一个挑战:当所有条件概率P(ai|vj)均小于1时,直接相乘会导致数值过小到无法有效表示。因此,在计算过程中我们通常会对每个条件概率取自然对数以解决这一问题。具体而言,通过对数变换后有:ln(P(vj|ai)) = ln(∏ P(vk=jk|ai)) = ∑ ln(P(vk=jk|ai)) ,从而避免了数值下溢的问题,并且由于自然对数函数是单调递增的函数性质得以保留最终分类结果的一致性。
代码实现
这里我们使用了sklearn多项式朴素贝叶斯进行分类,具体代码如下:
data = pd.read_csv("data/data_seg.csv")
x_train, x_test, y_train, y_test = train_test_split(data['seg'], data['type'], test_size = 0.5, shuffle=True, random_state=1)
tfidf_vec = TfidfVectorizer( stop_words=stop_words, max_features=1000)
cv_fit = tfidf_vec.fit_transform(data['seg'].astype(str))
train_vec = tfidf_vec.transform(x_train.astype(str))
test_vec = tfidf_vec.transform(x_test.astype(str))
# 贝叶斯模型训练
nb_clf = MultinomialNB()
nb_clf.fit(train_vec, y_train)
# 贝叶斯模型测试
print(nb_clf.score(test_vec, y_test))
python

分类结果:

SVM
SVM的基本原理在此不做详细讲解。如对相关内容感兴趣的同学,请参考《统计学习方法》中的相关内容, 上述讨论已较为深入。
我们继续采用sklearn库中的C-SVM支持向量分类器(SVC),具体的代码实现见下文。
svc_clf = SVC(kernel='rbf', class_weight='balanced', gamma="scale")
svc_clf.fit(train_vec, y_train)
# 输出测试结果
print(svc_clf.score(test_vec, y_test))
python
其实我们使用了GridSearchCV进行超参数选择,具体代码如下:
svc = SVC(kernel='rbf', class_weight='balanced',)
c_range = np.logspace(-5, 15, 11, base=2)
gamma_range = np.logspace(-9, 3, 13, base=2)
# 网格搜索交叉验证的参数范围,cv=3,3折交叉
param_grid = [{'kernel': ['rbf'], 'C': c_range, 'gamma': gamma_range}]
grid = GridSearchCV(svc, param_grid, cv=3, n_jobs=4)
# 训练模型
clf = grid.fit(train_vec, y_train)
# 计算测试集精度
score = grid.score(test_vec, y_test)
print('精度为%s' % score)
python

SVM的分来结果如下图所示,比朴素贝叶斯稍微好一点。

参考
-
贝叶斯定理. https://zh.wikipedia.org/wiki/贝叶斯定理 ↩︎
-
李航.统计学习方法(第2版)[M].北京:清华大学出版社,2019. ↩︎
