如何使用FeatureUnion和Pipeline正确构建包含文本和数值数据的SGDClassifier?

我有一个特征数据框(DF),看起来像这样:

文本 数字
文本1 0
文本2 1

其中数字列是二进制的,而文本列每行包含约2000个字符。目标数据框包含三个类别。

def get_numeric_data(x):    return [x.number.values]def get_text_data(x):    return [record for record in x.text.values]transfomer_numeric = FunctionTransformer(get_numeric_data)transformer_text = FunctionTransformer(get_text_data)

当尝试拟合时,使用下面的代码,我得到了错误File "C:\fakepath\scipy\sparse\construct.py", line 588, in bmat raise ValueError(msg) ValueError: blocks[0,:] has incompatible row dimensions. Got blocks[0,1].shape[0] == 98, expected 1.。我尝试以不同的方式构建get_text_dataget_numerical_data函数,但都没有帮助。

combined_clf = Pipeline([    ('features', FeatureUnion([        ('numeric_features', Pipeline([            ('selector', transfomer_numeric)        ])),        ('text_features', Pipeline([            ('selector', transformer_text),            ('vect', vect),            ('tfidf', tfidf),            ('scaler', scl),        ]))    ])),    ('clf', SGDClassifier(random_state=42,                          max_iter=int(10 ** 6 / len(X_train)), shuffle=True))])gs_clf = GridSearchCV(combined_clf, parameters, cv=5,n_jobs=-1)gs_clf.fit(X_train, y_train)

回答:

主要问题在于你返回数值的方式。x.number.values会返回形状为(n_samples,)的数组,而FeatureUnion对象会尝试将其与文本特征的转换结果结合。在你的案例中,转换后的文本特征的维度是(n_samples, 98),这无法与数值特征的向量结合。

一个简单的解决方法是将向量重塑为维度为(n_samples, 1)的二维数组,如下所示:

def get_numeric_data(x):    return x.number.values.reshape(-1, 1)

请注意,我删除了表达式周围的括号,因为它们不必要地将结果包装在一个列表中。


虽然上述方法可以让你的代码运行,但你的代码中仍有一些不甚高效的地方,可以进行改进。

首先是表达式[record for record in x.text.values]是多余的,因为x.text.values已经足够。两者的唯一区别在于前者是一个list对象,而后者是一个通常更受欢迎的numpyndarray对象。

其次,正如Ben Reiniger在他的评论中已经指出的,FeatureUnion旨在对相同的数据进行多种转换,并将结果合并成一个对象。然而,看起来你只是想单独转换文本特征和数值特征。在这种情况下,ColumnTransformer提供了一种更简单且更规范的方式:

combined_clf = Pipeline([    ('transformer', ColumnTransformer([        ('vectorizer', Pipeline([            ('vect', vect),            ('tfidf', tfidf),            ('scaler', scl)        ]), 'text')    ], remainder='passthrough')),    ('clf', SGDClassifier(random_state=42, max_iter=int(10 ** 6 / len(X_train)), shuffle=True))])

如上所述,ColumnTransformer只选择文本列并将其传递给转换管道,最终会将其与直接通过的数值列合并。请注意,定义你自己的选择器变得多余,因为ColumnTransformer通过指定每个转换器要转换的列来处理这一点。请参阅文档以获取更多信息。

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中创建了一个多类分类项目。该项目可以对…

发表回复

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