多项式朴素贝叶斯 – 理论与实践

好的,我正在学习Andrew Ng的机器学习课程。目前我在阅读这一章,想尝试使用SKLearn和Python自己实现多项式朴素贝叶斯(见第12页底部)。Andrew提出了一种方法,其中每封邮件都被编码成这样

我们用x_i表示邮件中第i个词的身份。因此,x_i现在是一个整数,取值在{1, . . . , |V|}之间,其中|V|是我们词汇表(字典)的大小。一封包含n个词的邮件现在被表示为长度为n的向量(x1, x2, . . . , xn)注意不同文档的n可能会变化。例如,如果一封邮件以“A NIPS . . . , ”开头,那么x_1 = 1“a”是字典中的第一个词),而x2 = 35000(如果“nips”是字典中的第35000个词)。

请看重点内容。

所以我也在Python中做了同样的事情。我有一个vocabulary,它是一个包含502个词的列表,我对每封“邮件”进行了编码,使其与Andrew描述的方式相同,例如消息“this is sparta”被表示为[495, 296, 359],而“this is not sparta”被表示为[495, 296, 415, 359]

所以问题来了。

显然,SKLearn的MultinomialNB要求输入具有统一的形状(我对此不是很确定,但目前我得到的错误是ValueError: setting an array element with a sequence.,我认为这是因为输入向量的大小不一致)。

那么我的问题是,我如何使用MultinomialNB处理不同长度的消息?这是可能的吗?我错过了什么?

这是我正在做的部分代码:

X = posts['wordsencoded'].valuesy = posts['highview'].valuesclf = MultinomialNB()clf.fit(X, y)MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)print(clf.predict())

输入看起来像这样:enter image description hereenter image description hereenter image description here

堆栈跟踪:

---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-933-dea987cd8603> in <module>()      3 y = posts['highview'].values      4 clf = MultinomialNB()----> 5 clf.fit(X, y)      6 MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)      7 print(clf.predict())/usr/local/lib/python3.4/dist-packages/sklearn/naive_bayes.py in fit(self, X, y, sample_weight)    525             Returns self.    526         """--> 527         X, y = check_X_y(X, y, 'csr')    528         _, n_features = X.shape    529 /usr/local/lib/python3.4/dist-packages/sklearn/utils/validation.py in check_X_y(X, y, accept_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, multi_output, ensure_min_samples, ensure_min_features, y_numeric, warn_on_dtype, estimator)    508     X = check_array(X, accept_sparse, dtype, order, copy, force_all_finite,    509                     ensure_2d, allow_nd, ensure_min_samples,--> 510                     ensure_min_features, warn_on_dtype, estimator)    511     if multi_output:    512         y = check_array(y, 'csr', force_all_finite=True, ensure_2d=False,/usr/local/lib/python3.4/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator)    371                                       force_all_finite)    372     else:--> 373         array = np.array(array, dtype=dtype, order=order, copy=copy)    374     375         if ensure_2d:ValueError: setting an array element with a sequence.

回答:

是的,你的想法是对的。你需要用固定长度的向量对每封邮件进行编码。这个向量称为词频向量,在你的例子中,每封训练集邮件都有一个502维的词频向量。

每个词频向量包含训练文件中502个字典词的频率。当然,你可能已经猜到其中大部分都会是零。例如:“this is not sparta not is this sparta”将被编码如下:[0,0,0,0,0,…….0,0,2,0,0,0,……,0,0,2,0,0,…0,0,2,0,0,……2,0,0,0,0,0,0]

这里,所有四个2分别位于502长度词频向量的第296、359、415和495个索引位置。

因此,将生成一个特征向量矩阵,其行表示训练集文件的数量,列表示字典中的502个词。索引‘ij’处的值将是字典中第j个词在第i个文件中的出现次数。

这种生成的邮件编码(特征向量矩阵)可以提供给MultinomialNB进行训练。

在预测类别之前,你还需要为测试邮件生成类似的502长度编码。

你可以使用以下博客在ling-spam数据集上轻松构建一个使用MultinomialNB的垃圾邮件过滤器分类器。该博客文章使用了sklearn和Python进行实现。

https://appliedmachinelearning.wordpress.com/2017/01/23/nlp-blog-post/

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注