基于Sklearn StandardScaler构建自定义缩放器时的TypeError问题排查
错误原因与解决方案
问题根源
报错是因为sklearn的StandardScaler构造函数从0.24版本开始,copy、with_mean、with_std参数必须以关键字参数形式传递,不能直接按位置传参。原代码中StandardScaler(copy,with_mean, with_std)是把三个变量作为位置参数传入,而StandardScaler的__init__只接受self作为位置参数,其余参数必须用关键字指定。
修正后的代码
from sklearn.base import BaseEstimator, TransformerMixin from sklearn.preprocessing import StandardScaler import numpy as np import pandas as pd class CustomScaler(BaseEstimator, TransformerMixin): def __init__(self, columns, copy=True, with_mean=True, with_std=True): # 用关键字参数传递StandardScaler的参数 self.scaler = StandardScaler(copy=copy, with_mean=with_mean, with_std=with_std) self.columns = columns self.mean_ = None self.var_ = None def fit(self, X, y=None): self.scaler.fit(X[self.columns], y) # 直接使用StandardScaler计算好的均值和方差,避免重复计算 self.mean_ = self.scaler.mean_ self.var_ = self.scaler.var_ return self def transform(self, X, y=None): init_col_order = X.columns X_scaled = pd.DataFrame(self.scaler.transform(X[self.columns]), columns=self.columns, index=X.index) X_not_scaled = X.loc[:, ~X.columns.isin(self.columns)] # 保持原始列顺序返回 return pd.concat([X_not_scaled, X_scaled], axis=1)[init_col_order]
额外优化说明
- 修正参数传递方式:将
StandardScaler(copy,with_mean, with_std)改为StandardScaler(copy=copy, with_mean=with_mean, with_std=with_std),符合sklearn的API要求。 - 复用scaler计算结果:fit方法中直接引用
self.scaler.mean_和self.scaler.var_,而不是自己用np.mean/np.var计算,保证和缩放时使用的统计量完全一致。 - 保留索引:构造
X_scaled时添加index=X.index,避免拼接时因索引不一致出现问题。
实例化方式
现在可以正常使用CustomScaler(columns_to_scale)实例化,若需要修改默认缩放参数,可通过关键字指定:
# 示例:禁用均值中心化 scaler = CustomScaler(columns_to_scale, with_mean=False)
内容的提问来源于stack exchange,提问作者sowfi
相关产品推荐
相关产品推荐

