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

我在处理下面的代码时遇到了问题(这是imblearn管道)

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)

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

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 modelscore_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

特征和标签都是文本(我在进行文本分析)。

异常是在fit调用时引发的

我做错了什么?


回答:

出现这种情况是因为你的管道中有一个文本转换器对象。这种方法的问题在于,管道会将整个数据框传递给TfidfVectorizer。然而,scikit-learn的文本转换器期望输入是一维的。

将二维数据框传递给TfidfVectorizer会导致一些奇怪的处理,它会将列名误认为是文档。你可以用这个简单的例子来检查:

X = pd.DataFrame({    'f1': ['This is doc1', 'This is doc2',           'This is doc3', 'This is doc4', 'This is doc5'],    'f2': [0, 1, 1, 0, 0]})vec = TfidfVectorizer()print(vec.fit(X).get_feature_names())>>> ['f1', 'f2']

这解释了为什么错误消息称样本数不一致:TfidfVectorizer认为数据框中的6列是样本,并将其名称视为特征。

如果你想在你的管道中使用TfidfVectorizer,你必须确保只将包含文本文档的列传递给它。你可以通过将其包装在ColumnTransformer中来实现这一点:

# 如果只需要转换一列transformer = ColumnTransformer(    [('vec', TfidfVectorizer(), column)],   # column 应为字符串或整数    remainder='passthrough')# 如果需要转换多列(不建议,参见下面的注意事项)transformer = ColumnTransformer(    [('vec', TfidfVectorizer(), col_1),  # col_1 应为字符串或整数     ...     ('vec', TfidfVectorizer(), col_n)],   # col_n 应为字符串或整数    remainder='passthrough')

将上面的column替换为TfidfVectorizer需要转换的列的索引或名称,它将只处理这一特定列。remainder='passthrough'将确保其他列保持原样,并与结果连接。你可以像这样在你的管道中使用它:

model = Pipeline([    ('vect', transformer),    ('smote', SMOTETomek()),    ('chi', SelectKBest(chi2, k=1000)),    ('classifier', algorithm)])

注意

如果你需要转换多个包含文本的列,你应该考虑将列条目合并成一个单一的、组合的文档,并且只转换这个组合文档。否则,每列将被视为新的词汇表,尽管这些词汇表可能在某种程度上重叠,你最终可能会得到非常高的维度/很多特征。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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