繁体   English   中英

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

[英]How to properly build a SGDClassifier with both text and numerical data using FeatureUnion and Pipeline?

我有一个看起来像的功能 DF

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

其中number列是二进制的, text列包含每行约 2k 个字符的文本。 目标 DF 包含三个类。

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. 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 object 稍后将尝试将其与文本特征转换的结果相结合。 在您的情况下,转换后的文本特征的维度是(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 object,而后者是通常首选的 numpy ndarray

其次是 Ben Reiniger 在他的评论中已经说过的。 FeatureUnion旨在对相同的数据执行多个转换并将结果组合到单个 object 中。 但是,您似乎只是想将文本特征与数字特征分开转换。 在这种情况下, 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将通过指定每个转换器要转换的列来处理这一点。 有关更多信息,请参阅文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM