相同数据和步骤的 Scikit-learn 管道无法分类

Posted

技术标签:

【中文标题】相同数据和步骤的 Scikit-learn 管道无法分类【英文标题】:Scikit-learn pipeline for same data and steps fails to classifiy 【发布时间】:2018-01-18 22:00:06 【问题描述】:

我有从 doc2vec 算法创建的浮点向量及其标签。当我将它们与简单的分类器一起使用时,它可以正常工作并提供预期的准确性。工作代码如下:

from sklearn.svm import LinearSVC
import pandas as pd
import numpy as np

train_vecs #ndarray (20418,100)
#train_vecs = [[0.3244, 0.3232, -0.5454, 1.4543, ...],...]
y_train #labels
test_vecs #ndarray (6885,100)
y_test #labels

classifier = LinearSVC()
classifier.fit(train_vecs, y_train )
print('Test Accuracy: %.2f'%classifier.score(test_vecs, y_test))

但是现在我想将它移动到管道中,因为将来我计划使用不同的功能进行功能联合。我所做的是将向量移动到数据框中,然后使用 2 个自定义转换器来 i) 选择列,ii) 更改数组类型。奇怪的是,完全相同的数据,具有完全相同的形状、dtype 和类型.. 给出了 0.0005 的精度。这对我来说根本没有意义,它应该提供几乎相同的准确性。在 ArrayCaster 转换器之后,输入的形状和类型与之前完全相同。整个事情真的很令人沮丧。

from sklearn.svm import LinearSVC
import pandas as pd
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.base import BaseEstimator, TransformerMixin

# transformer that picks a column from the dataframe
class ItemSelector(BaseEstimator, TransformerMixin):

    def __init__(self, column):
        self.column = column

    def fit(self, X, y=None, **fit_params):
        return self

    def transform(self, X):
        print('item selector type',type(X[self.column]))
        print('item selector shape',len(X[self.column]))
        print('item selector dtype',X[self.column].dtype)
        return (X[self.column])

# transformer that converts the series into an ndarray
class ArrayCaster(BaseEstimator, TransformerMixin):
    def fit(self, x, y=None):
        return self

    def transform(self, data):
        print('array caster type',type(np.array(data.tolist())))
        print('array caster shape',np.array(data.tolist()).shape)
        print('array caster dtype',np.array(data.tolist()).dtype)
        return np.array(data.tolist())


train_vecs #ndarray (20418,100)
y_train #labels
test_vecs #ndarray (6885,100)
y_test #labels

train['vecs'] = pd.Series(train_vecs.tolist())
val['vecs'] = pd.Series(test_vecs.tolist())


classifier = Pipeline([
            ('selector', ItemSelector(column='vecs')),
            ('array', ArrayCaster()),
            ('clf',LinearSVC())])

classifier.fit(train, y_train)
print('Test Accuracy: %.2f'%classifier.score(test, y_test))

【问题讨论】:

【参考方案1】:

好吧,对不起..我想通了。这个错误很烦人。我所要做的就是将它们转换为列表并将它们放入数据框中,而不是将它们转换为系列。 改变这个

train['vecs'] = pd.Series(train_vecs.tolist())
val['vecs'] = pd.Series(test_vecs.tolist())

进入:

train['vecs'] = list(train_vecs)
val['vecs'] = list(test_vecs)

【讨论】:

以上是关于相同数据和步骤的 Scikit-learn 管道无法分类的主要内容,如果未能解决你的问题,请参考以下文章

在 scikit-learn 管道中插入或删除步骤

scikit-learn:应用任意函数作为管道的一部分

如何创建一个应用 z-score 和交叉验证的 scikit-learn 管道?

当最后一个估计器不是转换器时,如何使用 scikit-learn 管道进行转换?

在管道中使用时带有 scikit-learn PLSRegression 的 ValueError

scikit-learn 在管道中使用多个类预处理 SVM