Python ValueError:找到样本数不一致的输入变量:[6,80]

Python ValueError:找到样本数不一致的输入变量:[6,80],python,pandas,machine-learning,scikit-learn,nlp,Python,Pandas,Machine Learning,Scikit Learn,Nlp,我无法在管道中处理以下代码(它是imblearnpipepline) 形状的打印输出为:(80,6)(80,1) 功能和标签都是文本(我正在做文本分析) 正在从fit调用引发异常 我做错了什么?发生这种情况是因为您的管道中有一个文本转换器对象。这种方法的问题是管道将把整个数据帧传递给tfidfvectorier。但是,scikit学习的文本转换器需要1d输入 将2d数据帧传递给TfidfVectorizer会导致一些奇怪的处理,将列名误认为文档。您可以使用以下简单示例进行检查: X=pd.Dat

我无法在管道中处理以下代码(它是
imblearn
pipepline)

形状的打印输出为:
(80,6)(80,1)

功能和标签都是文本(我正在做文本分析)

正在从
fit
调用引发异常


我做错了什么?

发生这种情况是因为您的管道中有一个文本转换器对象。这种方法的问题是管道将把整个数据帧传递给
tfidfvectorier
。但是,
scikit学习的文本转换器需要1d输入

将2d数据帧传递给
TfidfVectorizer
会导致一些奇怪的处理,将列名误认为文档。您可以使用以下简单示例进行检查:

X=pd.DataFrame({
“f1”:[“这是doc1”,“这是doc2”,
“这是doc3”,“这是doc4”,“这是doc5'],
'f2':[0,1,1,0,0]
})
vec=TfidfVectorizer()
打印(vec.fit(X.get_feature_names())
>>>['f1','f2']
这解释了错误消息指出样本数不一致的原因:
tfidfvectorier
认为数据帧中的6列是样本,它们的名称是特征

如果要在管道中使用
TfidfVectorizer
,则必须确保仅向其传递包含文本文档的列。您可以通过将其包装在以下文件中来实现这一点:

#如果只需要转换一列
变压器=柱形变压器(
[('vec',TfidfVectorizer(),column)],#列应为字符串或int
余数=‘通过’
)
#如果需要转换多个列(不鼓励,请参见下面的注释)
变压器=柱形变压器(
[('vec',TfidfVectorizer(),col#u 1),#col#u 1应该是字符串或int
...
('vec',TfidfVectorizer(),col#n)],#col#n应该是字符串或int
余数=‘通过’
)
将上面的
column
替换为
TFIDFvectorier
必须转换的列的索引或名称,它将仅处理此特定列。
rements='passthrough'
将确保其他列保持原样,并与结果连接在一起。然后,您可以在管道中使用它,如下所示:

model=管道([
('vect',变压器),
('smote',SMOTETomek()),
(“chi”,选择kbest(chi2,k=1000)),
(“分类器”,算法)
])

注意


如果必须用文本转换多个列,则应考虑将列条目合并为单个组合文档,并仅对合并后的文档进行转换。否则,每一列都将使用一个新的词汇表来处理,尽管这些词汇表可能会在某种程度上重叠,并且您可能最终会得到一个非常高的维度/许多功能。

错误消息是什么?@jasonwong在主题中提到了为什么您的
X\U列
具有形状
(80,6)
?您可以在其上使用
TfidfVectorizer
?你不应该输入一个语料库(字符串列表)吗?@jasonwong My X_train是原始数据的所有列(最后1列除外)。每一行的内容如下:
{'A':'strA','B':'strB','C':'strC'}
您不能使用
tfidfvectorier
处理二维输入。请参阅下面的答案。我尝试了以下建议:
transformer=ColumnTransformer([('vec',TfidfVectorizer(),list(features.columns))],rements='passthrough')
但我仍然遇到类似的错误:
找到了样本数不一致的输入变量:[6,58]
当您将列名/索引列表传递给
ColumnTransfer
时,它将再次将2d数据帧传递给
TFIDFvectorier
。如果您真的想分别对每一列进行矢量化,则必须为transformer列表中的每一列添加一个元组。将编辑答案以显示这一点。但是,单独对每列进行矢量化不是一个好的选择,因为最终可能会得到非常大的维度,尽管每列的词汇表可能会在某种程度上重叠。最好是将所有记录(列值和文本)合并到一列中的一个记录中。我已经尝试了所有文本列的单列-分数很差使用不推荐的方法后,我得到了
ValueError:empty词汇表;可能文档只包含停止词
features = training_data.loc[:, training_data.columns[:-1]]
labels = training_data.loc[:, training_data.columns[-1:]]


X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2)
print(X_train.shape, y_train.shape)
algorithms = [   
    svm.LinearSVC(),
    ensemble.RandomForestClassifier(),

]

def train(algorithm, X_train, y_train):
    model = Pipeline([
        ('vect', TfidfVectorizer()),
        ('smote', SMOTETomek()),
        ('chi', SelectKBest(chi2, k=1000)),
        ('classifier', algorithm)
    ])
    model.fit(X_train, y_train)
    return model

score_dict = {}
algorithm_to_model_dict = {}
for algorithm in algorithms:
    model = train(algorithm, X_train, y_train)
    score = model.score(X_test, y_test)
    score_dict[algorithm] = int(score * 100)
    algorithm_to_model_dict[algorithm] = model