在多列数据上拟合 MultinomialNB

Posted

技术标签:

【中文标题】在多列数据上拟合 MultinomialNB【英文标题】:Fitting MultinomialNB on multiple columns of data 【发布时间】:2019-01-12 19:34:28 【问题描述】:

给定一个包含 100 行的数据表,例如:

Place    | Text             | Value | Text_Two
europe   | some random text | 3.2   | some more random text
america  | the usa          | 4.1   | the white house
...

我正在尝试使用以下内容进行分类:

df = pd.read_csv('data.csv')
mnb = MultinomialNB()
tf = TfidfVectorizer()

df.loc[df['Place'] == 'europe','Place'] = 0
df.loc[df['Place'] == 'america','Place'] = 1

X = df[['Text', 'Value', 'Text_Two']]
y = df['Place']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)
X_train_tf = tf.fit_transform(X_train)

mnb.fit(X_train_tf, y_train)

以上产生以下错误:

ValueError:发现输入变量的数量不一致 样本:[3, 100]

所以据我了解,它只看到使用X = df[['Text', 'Value', 'Text_Two']] 设置的类别,而不是这些类别中的数据。

如果我只为一个类别指定 X,则上面的代码有效,例如: X = df['文本']

是否可以将 MultinomialNB 拟合到多个类别的数据上?

【问题讨论】:

【参考方案1】:

我宁愿将列 Text 和 Text_Two 合并为一列,然后从那里构造分类器。 MultinomialNB 仅适用于一个分类器。下面是将列 Text 和 Text_Two 合二为一的代码。

您可能对多类或多标签分类感兴趣,但它指的是目标变量 (Y) 而不是因变量 (X)。 http://scikit-learn.org/stable/modules/multiclass.html。希望能帮助到你。

import pandas as pd
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split

df = pd.read_csv('data.csv', header=0, sep='|')
df.columns = [x.strip() for x in df.columns]

mnb = MultinomialNB()
tf = TfidfVectorizer()

#df.loc[df['Place'] == 'europe','Place'] = 0
#df.loc[df['Place'] == 'america','Place'] = 1
#X = df[['Text', 'Value', 'Text_Two']]
X = df.Text + df.Text_Two
y = df['Place']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)
pipe = make_pipeline(TfidfVectorizer(), MultinomialNB())
pipe.fit(X_train, y_train)
pipe.predict(X_test)

【讨论】:

那不是因为MultinomialNB,而是TfidfVectorizerTfidfVectorizer 仅适用于单列文本,将根据找到的术语将其转换为二维数组。【参考方案2】:

这与 MultinomialNB 无关。它可以很好地处理多列。问题是 TfidfVectorizer。

TfidfVectorizer 仅适用于单一维度的可迭代对象(数据框的单列),不会对输入数据的形状或类型进行任何类型的检查。

它将only do this:

for doc in raw_documents:
...
...

当您将数据框传递给它时(无论是单列还是多列),for doc in raw_documents: 在数据框上只会输出列名称而不是实际数据。你传入X 的数据有三列,所以只有这些列被用作文档,因此错误

ValueError: Found input variables with inconsistent numbers of samples: [3, 100]

因为您的 y 的长度为 100,而您的 X(即使它的长度为 100,但由于 tfidfvectorizer 现在只有 3 个长度)。

所以要解决这个问题,你有两个选择:

1) 您需要对每个文本列(TextText_Two)进行单独的 tf-idf 向量化,然后将得到的矩阵组合成要与 MultinomialNB 一起使用的特征矩阵。

2) 您可以按照@âńōŋŷxmoůŜ 的建议将两个文本列合并为一列,然后对该单列执行 tf-idf。

这两个选项都会导致不同的特征向量,所以你需要先了解每个选项的作用,然后选择你想要的。

【讨论】:

以上是关于在多列数据上拟合 MultinomialNB的主要内容,如果未能解决你的问题,请参考以下文章

EXCEL中如何把一列数据变为多列?

我们可以在 MS 访问数据库上创建多列唯一索引吗?

在多列上聚合时间序列数据

如何在熊猫数据透视表上添加列(多列)

matplotlib:在条形图上绘制多列熊猫数据框

在多列上应用 t 检验