首页 > 解决方案 > 使用 BaseEstimator、TransformerMixin 自定义 Transformer

问题描述

我试图了解X_train以下代码中的转换是否已到位:

# Custom transformer for creating new attributes by combining existing attributes
from sklearn.base import BaseEstimator, TransformerMixin

total_rooms_idx, households_idx, population_idx, total_bedrooms_idx = 3, 6, 5, 4

class AttributesAdder(BaseEstimator, TransformerMixin):
    def __init__(self, add_bedrooms_per_room = True):
        self.add_bedrooms_per_room = add_bedrooms_per_room
        
    def fit(self, X, y=None):
        return self    # Nothing to do in fit in this scenario
    
    def transform(self, X):           
        X['rooms_per_household'] = X.iloc[:, total_rooms_idx] / X.iloc[:, households_idx]
        X['population_per_household'] = X.iloc[:, population_idx] / X.iloc[:, households_idx]
        
        if self.add_bedrooms_per_room:
            X['bedrooms_per_room'] = X.iloc[:, total_bedrooms_idx] / X.iloc[:, total_rooms_idx]
        
        return X


obj = AttributesAdder()
obj.transform(X_train)

print(X_train)

我没有存储变换函数的返回值,但 X_train 仍然被修改。这种转变是否到位?这个功能是从基类中采用的吗?

标签: pythonpandasscikit-learn

解决方案


您在其中编辑的对象transform是您通过变量 X 访问的数据框。除非您复制此数据框,否则操作是就地的。此外,无需从函数返回任何内容。

我创建了一个简短的示例来回答您的问题。

class AttributesAdder():
    def transform(self, X):
        X['A'] = 2
        X['B'] = 3

df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

obj = AttributesAdder()
obj.transform(df)

输出将是:

    A   B
0   2   3
1   2   3
2   2   3

这是另一个使用数据框视图的示例:

df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df_view = df
obj.transform(df_view)

df
    A   B
0   2   3
1   2   3
2   2   3

如您所见,传递数据框的视图transform也会转换您的原始数据框。您可以看到存储数据帧(如地址)的变量。

如果您不想要这种行为,则需要使用复制原始数据框new_df = df.copy()


推荐阅读