概率图模型简单的说,就是用图来表示概率模型。它是一种通用化的不确定性知识表示和处理方法。在概率图模型的表达中,结点表示随机变量,结点之间直接相连的边表示随机变量之间的概率关系。
贝叶斯网络是一种基于概率推理的数学模型,其理论基础是贝叶斯公式。
一个贝叶斯网络就是一个有向无环图,结点表示随机变量,可以是可观测量、隐含变量、未知参量或假设等;结点之间的有向边表示条件依存关系,箭头指向的结点依存于箭头发出的结点(父结点)。
下面以经济状况、房地产销售额、空调销售额三个随机变量为例,构建一个简单的贝叶斯网络。
图-1
上图展示了经济状况、房地产销售额、空调销售额三个随机变量的依赖关系。其中,房地产销售额依赖于经济状况,空调销售额依赖于经济状况和房地产销售额。如果用随机变量E、R、A分别表示经济状况、房地产销售额和空调销售额,图-1可简化为下图。
图-2
构造贝叶斯网络是一项复杂的任务,主要涉及三个方面的问题:表示、推断和学习。
(1)表示:在某一随机变量的集合上给出其联合概率分布
.例如,图-2中三个事件的联合概率函数可表示为:
公式(1)
(2)推断:当观察到某些变量时,推断另一些变量子集的变化。如上例中,当观察到经济状况E和房地产销售额R时,推断空调销售额随机变量A的取值的概率。
(3)学习:参数学习的目的是决定变量之间相互关联的量化关系,即依存强度估计。如上例中,房地产销售额对经济状况的依存强度、空调销售额对经济状况、房地产销售额的依存强度都是学习参数。
贝叶斯网络反映的是随机变量间的相互依存关系。如果把文本的类别与文本的特征都看作是随机变量,那么它们之间也存在依存关系。文本所具有的特征词往往决定文本所属的类别,而当文本类别确定后,所属该类文本的特征词大概率会出现在文本中。
这里用随机变量表示新闻类别,
的样本空间
,
表示某类新闻,
,共有
类新闻。随机变量
表示新闻文本的特征,
。
表示特征词,
. 假设某篇新闻中出现了
,共
个特征词,那么新闻分类问题可形式化表示为:
公式(2)
显然,公式(2)不好直接求解,我们可以换一种思路,用贝叶斯公式将公式(2)稍作变换,
公式(3)
上式中,可以从语料中统计得到,而
和
还是不好求解。
但是,如果假设特征词间相互独立,则有
公式(4)
公式(5)
上式中,,
都可以从训练语料中通过统计获取。
这种加上条件独立的贝叶斯有个专门的名称,叫作朴素贝叶斯。
根据Section 2所述,贝叶斯网络涉及三个问题:表示、推断和学习。至此,新闻文本分类问题的贝叶斯网络,关于表示和推断问题已经解决了。那么,新闻分类的参数学习指的是什么呢。这里的参数学习实际上就是用词频统计法求出,
,
,
,
。然后,在推断类别的时候就可以直接用它们。
下面用代码来实现这个基于朴素贝叶斯方法的新闻分类模型。
现已有新闻数据集,其中包括健康、体育、旅游、教育、财经等9个类别。
首先,需要从训练语料中构建一个特征词集,。可以用TF/IDF算法,从训练语料中选取特征词。也可以用词频法,从训练语料中选取词频较高的前
个词。词频最高的前几个词通常是一些没什么区分度的词,可以考虑将其舍弃。下面是提取特征词的代码
def words_dict(all_words_list, deleteN, stopwords_set=set()):
"""
:param all_words_list: 语料库单词列表
:param deleteN: 删除前deleteN个高频词
:param stopwords_set: 停用词集
:return: 特征词列表
"""
feature_words = []
n = 1
for t in range(deleteN, len(all_words_list), 1):
# 循环时从第deleteN个开始,也就是舍弃前deleteN个词语
if n > 1000: # feature_words的维度1000
break
if not all_words_list[t].isdigit() and \
all_words_list[t] not in stopwords_set and \
1 < len(all_words_list[t]) < 5:
# 满足三个条件:不是数字;不在停用词表;长度2~4
feature_words.append(all_words_list[t])
n += 1
return feature_words
接下来需要用词频法计算公式(4)和公式(5)中的概率值,以及的值。这些繁琐的统计计算在sklearn中有一个函数可以帮我们实现,它就是MultinomialNB( )函数。
# sklearn分类器
classifier = MultinomialNB().fit(train_feature_list, train_class_list)
上述代码中,train_class_list是文章类别标签列表。train_feature_list是特征词标记列表,如果该索引位置对应的词是特征词,则值等于1,否则等于0。train_feature_list的构建过程如下方代码所示。
def text_features(train_data_list, test_data_list, feature_words):
def text_features(text, feature_words):
text_words = set(text) # 样本去重
# sklearn特征 list
features = [1 if word in text_words else 0 for word in feature_words]
# 遍历每个样本词语,若样本词语出现在1000个特征词里,值为1,否则为0
return features
train_feature_list = [text_features(text, feature_words) for text in train_data_list]
# text为每一个训练的样本,返回值是二维列表
test_feature_list = [text_features(text, feature_words) for text in test_data_list]
return train_feature_list, test_feature_list