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



我有一个看起来像 DF 的特征

text number
文本1 0
文本2 1

主要问题是返回数值的方式。x.number.values将返回一个形状(n_samples,)数组,FeatureUnion对象稍后将尝试将其与文本特征转换的结果相结合。在您的情况下,转换后的文本要素的维度(n_samples, 98)无法与您获得的数值要素矢量相结合。

一个简单的解决方法是将矢量重塑为尺寸(n_samples, 1)如下所示的 2D 数组:

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因为选择器将通过指定每个转换器要转换的列来处理这个问题。有关详细信息,请参阅文档。

最新更新