MultinomialNB - 理论与实践

时间:2017-02-09 16:48:48

标签: python machine-learning scikit-learn text-classification multinomial

好的,所以我只是在研究Andrew Ng的机器学习课程。我目前正在阅读this chapter并希望使用SKLearn和Python为自己尝试Multinomial Naive Bayes(第12页底部)。所以安德鲁提出了一种方法,在这种情况下,每种电子邮件都被编码为

  

我们让x_i表示电子邮件中i个字的标识。因此,x_i现在是{1, . . . , |V|}中取整数值的整数,其中|V|(x1, x2, . . . , xn)   我们词汇量的大小(字典)。现在是一封n字的电子邮件   由长度为n 的向量“A NIPS . . . ,”表示,请注意n   可能因文件不同而不同。例如,如果电子邮件启动   使用x_1 = 1然后“a”x2 = 35000是第一个单词   字典)和“nips”(如果vocabulary是第35000个字   字典)。

见精彩集锦。

所以这也是我在Python中所做的。我有一个[495, 296, 359],这是一个包含502个单词的列表,我对每个“电子邮件”进行编码,使其表示方式与Andrew描述的方式相同,例如消息“this is sparta”由{{1 {},[495, 296, 415, 359]和“这不是sparta”。

所以这就出现了问题。

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

所以我的问题是,如何将MultinomialNB用于多个长度的消息?可能吗?我错过了什么?

以下是我正在使用的代码:

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

输入内容如下:enter image description here enter image description here enter 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.

1 个答案:

答案 0 :(得分:2)

是的,你的想法是正确的。您必须使用固定长度向量对每封邮件进行编码。对于每个训练集的电子邮件,此向量称为502维度的字数向量(在您的情况下)。

每个字数统计向量包含训练文件中502个字典单词的频率。当然,你现在可能已经猜到了大多数都是零。例如:&#34;这不是sparta不是这个sparta&#34;将编码如下。 [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'的值将是第i个文件中第j个单词出现次数。

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

在预测课程之前,您还必须为测试电子邮件生成类似的502长度编码。

您可以使用以下博客轻松地在ling-spam数据集上使用multinomialNB构建垃圾邮件过滤器分类器。博客帖子使用sklearn和python来实现。

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