You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:17:37