如何移除sklearn PolynomialFeatures中仅含x₁或x₂单一变量的特征?
解决PolynomialFeatures移除特定单变量特征的问题
首先,你遇到的NotFittedError是因为powers_这类属性只有在PolynomialFeatures完成拟合(调用fit或fit_transform)之后才会生成,直接修改未拟合实例的内部属性肯定会触发错误。而且scikit-learn的Transformer设计不推荐手动修改内部状态,下面给你两种可靠的解决方案:
方法一:用自定义Transformer构建Pipeline(推荐)
这种方法能完美融入scikit-learn的Pipeline工作流,代码可复用性高:
from sklearn.base import TransformerMixin, BaseEstimator import numpy as np from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import make_pipeline from sklearn.linear_model import Ridge class FilterSingleVarFeatures(BaseEstimator, TransformerMixin): def __init__(self, target_vars=[0, 1]): # target_vars指定要排除的单变量索引(x₁是0,x₂是1) self.target_vars = target_vars def fit(self, X, y=None): # 从Pipeline的前一步获取PolynomialFeatures的powers_矩阵 poly_step = X.named_steps['polynomialfeatures'] self.powers_ = poly_step.powers_ # 生成保留特征的掩码 self.keep_mask_ = [] for power in self.powers_: non_zero_indices = np.where(power != 0)[0] # 只保留:不是仅包含target_vars中单个变量的特征 if not (len(non_zero_indices) == 1 and non_zero_indices[0] in self.target_vars): self.keep_mask_.append(True) else: self.keep_mask_.append(False) self.keep_mask_ = np.array(self.keep_mask_) return self def transform(self, X): # 对特征矩阵做过滤 return X[:, self.keep_mask_] # 构建新的Pipeline poly = PolynomialFeatures(3, interaction_only=False, include_bias=False) model = make_pipeline( poly, FilterSingleVarFeatures(target_vars=[0, 1]), Ridge(tol=0.001, alpha=1, fit_intercept=False) ) model.fit(initial_conditions, times_of_flight)
方法二:手动生成并过滤特征(快速验证用)
如果只是快速验证效果,不想写自定义Transformer,可以先生成所有多项式特征,再手动过滤:
from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import Ridge # 第一步:生成所有多项式特征 poly = PolynomialFeatures(3, interaction_only=False, include_bias=False) X_poly = poly.fit_transform(initial_conditions) powers = poly.powers_ # 第二步:生成过滤掩码 keep_mask = [] for power in powers: non_zero_indices = np.where(power != 0)[0] # 排除仅x₁或仅x₂的特征 if not (len(non_zero_indices) == 1 and non_zero_indices[0] in [0, 1]): keep_mask.append(True) else: keep_mask.append(False) # 第三步:过滤特征后拟合模型 X_filtered = X_poly[:, keep_mask] model = Ridge(tol=0.001, alpha=1, fit_intercept=False) model.fit(X_filtered, times_of_flight)
为什么直接修改属性会报错?
scikit-learn的PolynomialFeatures中,powers_、n_input_features_这些属性是拟合阶段才会计算赋值的,未拟合的实例根本没有这些属性,所以你强行修改自然会触发NotFittedError。另外,手动修改内部属性会破坏Transformer的状态一致性,后续的transform步骤很可能出问题,这也是官方不推荐这么做的原因。
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

