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

2024-10-03 13:26:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个

^{tb1}$

其中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.。我试图以不同的方式构建函数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)

Tags: textinnumberdatagetreturnpipelinedef
1条回答
网友
1楼 · 发布于 2024-10-03 13:26:58

主要问题是返回数值的方式x.number.values将返回一个shape (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

其次是本·雷尼格尔在评论中已经说过的话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将通过指定每个转换器要转换的列来解决这一问题,这一点已经过时。有关更多信息,请参见documentation

相关问题 更多 >