@elibinary
2017-08-12T09:06:59.000000Z
字数 3108
阅读 1199
MachineLearning
贝叶斯定理是关于随机事件 A 和 B 的条件概率的一则定理,用公式来描述就是:
可以看出,通过贝叶斯公式我们可以在已知三个概率函数时推出第四个。重要应用之一就是根据
独立变量的联合分布:
假设:
A: features
求值:
假设各特征之间相互独立,也就是 之间都相互独立,那么就有
那么最终问题就转化为了对 和 求值,或者叫估值
就是 B 在训练集中的相对频率
在处理 时,有几种不同的处理方式
高斯模型
高斯模型假设特征在各类别下的观测值符合高斯分布
也就是说对于 有 ~
其中参数 可通过极大似然法来估计
多项式模型
多项式模型假设数据服从多项式分布
是对于特征 x 在一个样本中被类 B 拥有的概率
是在训练集中,特征 x 在属于类 B 的样本中出现的次数
是类 B 中的所有特征数量和
朴素贝叶斯尽管看起来其假设非常简单,但是在很多场景下朴素贝叶斯分类器却工作的相当优秀。
而广告识别说白了其实就是一个二分类,给定一个文本,它要么是广告,要么是正常文本,也就是说
下面我尝试使用多项式模型构建模型并估计参数
首先还是使用上一篇中讲的 文本特征提起 来对训练集进行特征提取,然后就是估计模型以及判别方法
import jiebafrom sklearn import feature_extractionfrom sklearn.feature_extraction.text import TfidfTransformerfrom sklearn.feature_extraction.text import CountVectorizerfrom collections import defaultdictimport math# global var for probabilityprobability_module = {}# { y_i: len_of_i_docs }t_n = {}# { feature_i: {num_of_y_1, num_of_y_2 ... ,num_of_y_n} }# features_num = defaultdict(dict)features_num = {}total_doc_num = 0samples = []def tf_idf(file_path):file = open(file_path, 'r')corpus = []temp_str = ''temp_samples = []for line in file:cut_res = jieba.lcut_for_search(line)temp_samples.append(cut_res)# corpus.append(' '.join(cut_res))temp_str += ' '.join(cut_res)temp_str += ' 'file.closesamples.append(temp_samples)corpus.append(temp_str)vectorizer = CountVectorizer()transformer = TfidfTransformer()word_freq = vectorizer.fit_transform(corpus)tf_idf = transformer.fit_transform(word_freq)words = vectorizer.get_feature_names()scores = tf_idf.toarray()[0]return zip(words, scores)# for i in range(len(scores)):# print(words[i], scores[i])# sort_res = sorted(list(arr), key=lambda item: item[1], reverse=True)def predict_module(samples, y, features):global total_doc_numfor i in range(len(y)):if y[i] not in t_n:t_n[y[i]] = {}t_n[y[i]]['docs'] = len(samples[i])t_n[y[i]]['features'] = len(features[i])t_n[y[i]]['total'] = 0for features_i in features:for item in features_i:features_num[item] = {}for i in range(len(samples)):for sample in samples[i]:total_doc_num += 1for word in sample:if word in features_num:t_n[y[i]]['total'] += 1if y[i] in features_num[word]:features_num[word][y[i]] += 1else:features_num[word][y[i]] = 1def bayes_multinomial(doc, y):v = len(features_num)cut_res = jieba.lcut_for_search(doc)scores = {}for y_i in y:p_y = t_n[y_i]['docs'] / total_doc_numscores[y_i] = math.log(p_y)for word in cut_res:if word in features_num:if y_i in features_num[word]:p_y_w = (features_num[word][y_i] + 1) / (t_n[y_i]['total'] + v)else:p_y_w = 1 / (t_n[y_i]['total'] + v)scores[y_i] += math.log(p_y_w)return scores
接下来就是测试其分类效果了
本来是要把训练数据分成两份,一份用于参数估计,另一份用于测试模型准确率的。但是因为我本身的训练数据量比较少,一共也就几百条。。。所以只在其中随机挑了几十条作为测试集,准确度在 80% 左右,在输入正常样本是产生误判的几率较大,另外由于训练集和测试集过小,我暂时并不能确定模型完善度。
接下来我打算先使用 NumPy 对实现中参数向量结构部分进行重写,然后去找一个现有的语料库找个大点的数据集跑测一下。顺便有时间再试一下高斯模型以及伯努利模型的效果。