Sklearn ColumnTransformer处理混合数据类型报错,求正确转换方案
问题分析与解决方案
核心错误原因
- 错误地将列转为numpy数组:你把列名列表转换成了numpy数组,导致后续尝试拼接数组时出现
float与str相加的类型错误。 - 重复添加转换器步骤:多个转换器(如
StandardScaler、OneHotEncoder)被重复添加,这完全没必要且会导致冗余计算。 - 目标列处理不当:将目标列转为numpy数组后无法直接用于
data[]索引。
修正后的完整代码
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import StandardScaler, OneHotEncoder, OrdinalEncoder from sklearn.pipeline import Pipeline from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report, confusion_matrix import pandas as pd import numpy as np # 处理TotalCharges的空值问题(Telco Churn数据集常见问题) data['TotalCharges'] = pd.to_numeric(data['TotalCharges'], errors='coerce').fillna(0) # 定义列名列表(不要转numpy数组!) numerical_cols = ['MonthlyCharges', 'TotalCharges', 'tenure'] ordinal_cols = ['Contract'] categorical_cols = ['PaperlessBilling', 'PaymentMethod'] target_col = 'Churn' # 定义有序列的顺序 contract_order = ['Month-to-month', 'One year', 'Two year'] # 创建转换器(移除重复步骤) numeric_transformer = Pipeline(steps=[ ('scaler', StandardScaler()) ]) ordinal_transformer = Pipeline(steps=[ ('ordinal', OrdinalEncoder(categories=[contract_order])) ]) categorical_transformer = Pipeline(steps=[ ('onehot', OneHotEncoder(handle_unknown='ignore')) ]) # 列转换器:传入列名列表而非数组 preprocessor = ColumnTransformer([ ('num', numeric_transformer, numerical_cols), ('ord', ordinal_transformer, ordinal_cols), ('cat', categorical_transformer, categorical_cols) ]) # 构建完整 pipeline model = Pipeline(steps=[ ('preprocessor', preprocessor), ('classifier', LogisticRegression(max_iter=1000)) # 增加迭代次数避免收敛警告 ]) # 分离特征与目标变量 X = data[numerical_cols + ordinal_cols + categorical_cols] y = data[target_col].map({'Yes': 1, 'No': 0}) # 更简洁的编码方式 # 划分训练测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 训练模型 model.fit(X_train, y_train) # 评估模型 y_pred = model.predict(X_test) print(confusion_matrix(y_test, y_pred)) print(classification_report(y_test, y_pred))
关键修正点说明
- 列名定义:直接使用字符串列表指定列名,而非将列数据转为numpy数组,这是
ColumnTransformer要求的正确用法。 - 移除重复转换器:每个转换器只保留一个步骤,避免冗余操作。
- 目标变量编码:使用
map方法替代apply,更高效简洁。 - TotalCharges处理:针对Telco Churn数据集常见的空值问题,先转为数值型并填充空值,避免后续标准化出错。
- LogisticRegression迭代次数:增加
max_iter=1000,防止因数据未完全收敛导致的警告。
内容的提问来源于stack exchange,提问作者s213439
相关产品推荐
相关产品推荐

