使用 TfidfVectorizer 进行二进制文本分类给出 ValueError: setting an array element with a sequence

数据挖掘 机器学习 Python scikit-学习 熊猫
2021-09-29 19:54:44

我正在使用 pandas 和 scikti-learn 使用在 DataFrame 上使用 TfidfVectorizer 编码的文本特征进行二进制文本分类。这是一些虚拟代码,说明了我在做什么:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.svm import LinearSVC
from sklearn.feature_extraction.text import TfidfVectorizer
data_dict = {'tid': [0,1,2,3,4,5,6,7,8,9],
         'text':['This is the first.', 'This is the second.', 'This is the third.', 'This is the fourth.', 'This is the fourth.', 'This is the fourth.', 'This is the nintieth.', 'This is the fourth.', 'This is the fourth.', 'This is the first.'],
         'cat':[0,0,1,1,1,1,1,0,0,0]}
df = pd.DataFrame(data_dict)
tfidf = TfidfVectorizer(analyzer='word')
df['text'] = tfidf.fit_transform(df['text'])
X_train, X_test, y_train, y_test = train_test_split(df[['tid', 'text']], df[['cat']])
clf = LinearSVC()
clf.fit(X_train, y_train)

这给出了以下错误:

Traceback (most recent call last):

  File "<ipython-input-151-b0953fbb1d6e>", line 1, in <module>
    clf.fit(X, y)

  File "C:\Users\Me\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\svm\classes.py", line 227, in fit
    dtype=np.float64, order="C")

  File "C:\Users\Me\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\utils\validation.py", line 573, in check_X_y
    ensure_min_features, warn_on_dtype, estimator)

  File "C:\Users\Me\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\utils\validation.py", line 433, in check_array
    array = np.array(array, dtype=dtype, order=order, copy=copy)

ValueError: setting an array element with a sequence.

我发现很多帖子(例如这里这里)提到这个错误可能表明数据的不均匀性。这篇关于相同错误的帖子表明它也可能是由于数据输入问题。但是,我看不出我的非常简单的例子是如何归因于这些中的任何一个。我肯定缺少一些简单的东西。帮助!

2个回答

TfidfVectorizer返回一个(稀疏)二维数组或矩阵。您不能在df['text']不弄乱尺寸的情况下将列设置为矩阵。相反,您需要将结果TfidfVectorizer与数据框中的其余特征连接起来。

df_text = pd.DataFrame(tfidf.fit_transform(df['text']).toarray()) 
X_train, X_test, y_train, y_test = train_test_split(pd.concat([df[['tid']],df_text],axis=1), df[['cat']])

一个可能的问题:train_test_split期望返回四个值:X_train, X_test, y_train, y_test. 如果您在下一行使用clf.fit(X_train, y_train). 我认为您的玩具数据需要包含更多内容才能train_test_split智能地工作:如果我进行上述更改,我会得到一个ValueError: not enough values to unpack (expected 4, got 2).

因此,请尝试仅使用 fit 例程中的训练数据,并尝试扩展玩具数据集以获得更多值。