【发布时间】:2018-06-27 11:20:27
【问题描述】:
这个问题不是有人建议的duplicate。为什么?因为在那个例子中,所有可能的值都是已知的。在这个例子中,它们不是。此外,除了对未知值使用自定义转换器之外,这个问题还专门询问如何以与初始转换相同的方式执行转换。我可以再一次告诉我我最终必须回答我自己的问题。
在创建自定义 scikit-learn 转换器时,如何保证或“强制”转换方法仅输出它最初匹配的列?
下图说明。这是我的示例转换器。
import numpy as np
import pandas as pd
from sklearn.base import TransformerMixin
from sklearn.linear_model import LogisticRegression
class DFTransformer(TransformerMixin):
def fit(self, df, y=None, **fit_params):
return self
def transform(self, df, **trans_params):
self.df = df
self.STACKER = pd.DataFrame()
for col in self.df:
dtype = self.df[col].dtype.name
if dtype == 'object':
self.STACKER = pd.concat([self.STACKER, self.get_dummies(col)], axis=1)
elif dtype == 'int64':
self.STACKER = pd.concat([self.STACKER, self.cut_it(col)], axis=1)
return self.STACKER
def get_dummies(self, name):
return pd.get_dummies(self.df[name], prefix=name)
def cut_it(self, name, bins=5):
s = self.df[name].copy()
return pd.get_dummies(pd.cut(s, bins), prefix=name)
这里有一些虚拟数据。我的一种方法使用pd.cut in-efforts 来合并大范围的整数或浮点数。另一种方法使用pd.get_dummies,它将唯一值转换为列。
df = pd.DataFrame({'integers': np.random.randint(2000, 20000, 30, dtype='int64'),
'categorical': np.random.choice(list('ABCDEFGHIJKLMNOP'), 30)},
columns=['integers', 'categorical'])
trans = DFTransformer()
X = trans.fit_transform(df)
y = np.random.binomial(1, 0.5, 30)
lr = LogisticRegression()
lr.fit(X, y)
X_test = pd.DataFrame({'integers': np.random.randint(2000, 60000, 30, dtype='int64'),
'categorical': np.random.choice(list('ABGIOPXYZ'), 30)},
columns=['integers', 'categorical'])
lr.predict(trans.transform(X_test))
我遇到的问题是,当我去转换“测试”数据(我想对其进行预测的数据)时,转换很可能不会输出完全相同的列,因为不同的分类值(例如:可能出现一次然后再也看不到或听到的模糊值)。
例如,上面的代码会产生这个错误:
Traceback (most recent call last):
File "C:/Users/myname/Downloads/SO009949884.py", line 44, in <module>
lr.predict(trans.transform(X_test))
File "C:\python36\lib\site-packages\sklearn\linear_model\base.py", line 324, in predict
scores = self.decision_function(X)
File "C:\python36\lib\site-packages\sklearn\linear_model\base.py", line 305, in decision_function
% (X.shape[1], n_features))
ValueError: X has 14 features per sample; expecting 20
问题:如何确保我的转换方法以相同的方式转换我的测试数据?
我能想到的一个糟糕的解决方案是:转换训练数据、转换测试数据、查看列相交的位置、修改我的转换函数以将输出限制为这些列。或者,为缺少的那些填写空白列。这是不可扩展的。肯定有更好的方法吗?我不想事先知道输出列必须是什么。
我的总体目标是在训练和测试数据集中以一致的方式转换分类变量。我有 150 多列要转换!
【问题讨论】:
-
如果可以,请使用当前开发分支中的CategoricalEncoder instead。其他见我的other answer
-
pd.get_dummies() 仅在对整个数据使用然后拆分时才推荐使用。反之亦然。
-
@VivekKumar 如果使用 get_dummies 与 CategoricalEncoder 有什么区别?当应用于测试数据时,是否存在一些有助于转换过程的有利差异?我看不出您的建议如何解决这里的问题,即测试数据中的某些值不存在和/或测试数据具有训练数据转换没有的值。
-
pd.get_dummies 在不同的数据上使用时会返回不同的列,因此在拆分后使用它显然会返回不同的列数和您现在面临的相同问题。
-
我写了一篇博文来解决这个问题:blog.pursuitofzen.com/…
标签: python scikit-learn