scikit-learn 0.21.2中OneHotEncoder属性缺失报错求助
解决scikit-learn 0.21.2中OneHotEncoder属性报错及关联编码列与原始变量的问题
你遇到的错误是因为在scikit-learn 0.21.2版本中,OneHotEncoder已经移除了active_features_和feature_indices_这两个旧API属性,取而代之的是更直观的属性和方法来获取编码后的列与原始变量的对应关系。下面我会一步步帮你修正代码,实现你想要的功能:
一、错误原因解析
在scikit-learn 0.19及更早版本中,OneHotEncoder确实提供active_features_和feature_indices_来追踪编码信息,但从0.20版本开始,这些属性被废弃,转而使用categories_属性和get_feature_names()方法来管理分类变量的编码映射。
二、修正后的完整代码
我们可以利用get_feature_names()直接生成包含原始变量和类别信息的列名,再和模型系数关联起来,代码更简洁易懂:
import pandas as pd from sklearn import preprocessing from sklearn.linear_model import LogisticRegression # 假设你用的是逻辑回归,可替换成你的实际模型clf # 1. 初始化并拟合OneHotEncoder(适配0.21.2版本) encoder = preprocessing.OneHotEncoder(categorical_features=[0,1,2], sparse=False) # 设置sparse=False直接得到数组,方便后续处理 X_train = encoder.fit_transform(data_train) # 2. 获取编码后的列名,格式为"x{原始列索引}_{类别}" encoded_feature_names = encoder.get_feature_names() # 3. 假设你已经训练好模型clf(这里以逻辑回归为例,替换成你的模型即可) clf = LogisticRegression() clf.fit(X_train, y_train) # y_train是你的目标变量,替换成实际变量名 # 4. 关联编码列、原始变量/类别和系数 results = [] for feature_name, coef in zip(encoded_feature_names, clf.coef_[0]): # 拆分列名,提取原始变量索引和对应类别 orig_col_idx, category = feature_name.split("_", 1) orig_col_idx = int(orig_col_idx.replace("x", "")) results.append({ 'original_column_index': orig_col_idx, 'category': category, 'coefficient': coef }) # 转成DataFrame查看最终结果 R = pd.DataFrame.from_records(results) print(R)
三、关键细节说明
- sparse=False:0.21版本的OneHotEncoder默认返回稀疏矩阵,设置该参数可以直接得到numpy数组,方便后续与pandas结合处理。
- get_feature_names():这个方法会自动生成类似
x0_类别A、x1_类别B的列名,直接帮你关联了原始变量(x后的数字对应你设置的categorical_features中的索引)和对应的类别,比手动计算索引更可靠。 - 系数关联:通过
zip将编码列名与模型系数一一配对,拆分列名就能轻松获取原始变量和类别信息,完美匹配你的需求。
四、更规范的进阶写法(推荐)
在scikit-learn 0.21版本中,官方已经推荐使用ColumnTransformer来处理不同类型的特征(分类、数值),代码更清晰,也为后续版本升级做好准备:
import pandas as pd from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder from sklearn.linear_model import LogisticRegression # 假设你的data_train是DataFrame,替换成实际的分类列名 categorical_cols = ['col0', 'col1', 'col2'] # 用ColumnTransformer指定对哪些列做独热编码,其他列保持原样 preprocessor = ColumnTransformer( transformers=[ ('cat_encoder', OneHotEncoder(sparse=False), categorical_cols) ], remainder='passthrough' # 保留非分类列(如数值列) ) X_train = preprocessor.fit_transform(data_train) # 获取编码后的列名:传入原始列名,生成更友好的名称(如col0_类别A) encoder = preprocessor.named_transformers_['cat_encoder'] encoded_feature_names = encoder.get_feature_names(categorical_cols) # 训练模型并关联系数 clf = LogisticRegression() clf.fit(X_train, y_train) results = [] for feature_name, coef in zip(encoded_feature_names, clf.coef_[0]): orig_col, category = feature_name.split("_", 1) results.append({ 'original_column': orig_col, 'category': category, 'coefficient': coef }) R = pd.DataFrame.from_records(results) print(R)
这种写法生成的列名直接使用原始列名,比索引更直观,也更便于维护。
内容的提问来源于stack exchange,提问作者Nafisa Afsana Taskia
相关产品推荐
相关产品推荐

