虽然Scikit-Learn提供了许多有用的转换器,但是您可能需要写你自定义的转换器,来实现定制的清理工作以及组合特定属性。您将希望您的转换器与Scikit-Learn的功能(如管道)无缝地协作工作,并且由于Scikit-Learn依赖于动态类型(而不是继承),您所需要的只是创建一个类并实现三个方法:fit()(返回self即可)、transform()和fit_transform()。您可以通过简单地添加TransformerMixin作为基类,来免费获得最后一个方法的实现。另外,如果您添加 BaseEstimator作为基类(并且避免在构造函数中使用*args和**kargs),您将得到两个额外的方法(get_params()和set_params()),这对自动超参数调优有用。例如,这里有一个小的转换器类,它添加了我们前面讨论过的组合属性:
from sklearn.base import BaseEstimator, TransformerMixin
rooms_ix, bedrooms_ix, population_ix, household_ix = 3, 4, 5, 6
class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
def __init__(self, add_bedrooms_per_room = True): # no *args or **kargs
self.add_bedrooms_per_room = add_bedrooms_per_room
def fit(self, X, y=None):
return self # nothing else to do
def transform(self, X, y=None):
rooms_per_household = X[:, rooms_ix] / X[:, household_ix]
population_per_household = X[:, population_ix] / X[:, household_ix]
if self.add_bedrooms_per_room:
bedrooms_per_room = X[:, bedrooms_ix] / X[:, rooms_ix]
return np.c_[X, rooms_per_household, population_per_household,
bedrooms_per_room]
else:
return np.c_[X, rooms_per_household, population_per_household]
attr_adder = CombinedAttributesAdder(add_bedrooms_per_room=False)
housing_extra_attribs = attr_adder.transform(housing.values)
在本例中,转换器有一个超参数add_bedrooms_per_room,默认设置为True(提供合理的默认值通常是有帮助的)。这个超参数可以让你很容易地发现添加这个属性是否有助于机器学习算法。更一般的情况是,您可以添加一个超参数来设置任何你不能100%确定的数据准备步骤。数据准备步骤越自动化,你就可以自动尝试更多的组合,使你更有可能找到一个完美的组合(并节省你大量的时间)。