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

sklearn ColumnTransformer报错:str与bool无法比较,求调试帮助

sklearn ColumnTransformer 报错:'<' not supported between instances of 'str' and 'bool'

问题描述

使用sklearn的ColumnTransformer进行数据预处理时触发TypeError,提示'<' not supported between instances of 'str' and 'bool'。通过df.info()查看数据列类型仅为object或float64,无bool类型,参考同类问题后仍无法解决,相关代码及报错信息如下:

代码片段

X = df.drop("Transported", axis=1)
y = df.Transported
X.info()
"""
output:
>>> <class 'pandas.core.frame.DataFrame'>
RangeIndex: 8693 entries, 0 to 8692
Data columns (total 11 columns):
 #   Column        Non-Null Count  Dtype  
---  ------        --------------  -----  
 0   HomePlanet    8492 non-null   object 
 1   CryoSleep     8476 non-null   object 
 2   Cabin         8494 non-null   object 
 3   Destination   8511 non-null   object 
 4   Age           8514 non-null   float64
 5   VIP           8490 non-null   object 
 6   RoomService   8512 non-null   float64
 7   FoodCourt     8510 non-null   float64
 8   ShoppingMall  8485 non-null   float64
 9   Spa           8510 non-null   float64
 10  VRDeck        8505 non-null   float64
dtypes: float64(6), object(5)
memory usage: 747.2+ KB
"""
categorical_features = ["HomePlanet", "CryoSleep", "Cabin", "Destination", "VIP"]
categorical_transformer = Pipeline(steps=[
    ("imputer", SimpleImputer(strategy="constant", fill_value="missing")),
    ("encoder", OneHotEncoder(handle_unknown="ignore"))
])
numerical_features = ["Age", "RoomService", "FoodCourt", "ShoppingMall", "Spa", "VRDeck"]
numerical_transformer = Pipeline(steps=[
    ("imputer", SimpleImputer(strategy="median")),
    ("scaler", StandardScaler())
])
preprocessor = ColumnTransformer(transformers=[
    ("cat", categorical_transformer, categorical_features),
    ("num", numerical_transformer, numerical_features)
])
model = Pipeline(steps=[("preprocessor", preprocessor), ("model", RandomForestRegressor())])
X = df.drop("Transported", axis=1)
y = df["Transported"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model.fit(X_train, y_train)
model.score(X_test, y_test)

报错信息

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File D:\Programming\python\machine_learning\ml\lib\site-packages\sklearn\utils\_encode.py:173, in _unique_python(values, return_inverse, return_counts)
    171 uniques_set, missing_values = _extract_missing(uniques_set)
---> 173 uniques = sorted(uniques_set)
    174 uniques.extend(missing_values.to_list())

TypeError: '<' not supported between instances of 'str' and 'bool'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
Input In [68], in <cell line: 19>()
     17 y = df["Transported"]
     18 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
---> 19 model.fit(X_train, y_train)
...

问题分析

df.info()仅显示列的整体类型为object,但object列内部可能混合了字符串和布尔值(比如CryoSleep或VIP列中同时存在'True'/'False'字符串和True/False布尔值)。当OneHotEncoder尝试对这些混合类型的值排序时,就会触发字符串与布尔值无法比较的错误。

解决方法

1. 检查并统一object列内部的类型

先排查疑似问题列的取值类型:

# 查看CryoSleep列的取值类型集合
print(set(type(x) for x in df['CryoSleep'].dropna()))
# 查看VIP列的取值类型集合
print(set(type(x) for x in df['VIP'].dropna()))

如果输出同时包含<class 'bool'>和<class 'str'>,统一类型:

# 将布尔值转为字符串,确保列内类型一致
df['CryoSleep'] = df['CryoSleep'].astype(str)
df['VIP'] = df['VIP'].astype(str)

# 或者将字符串转为布尔值(需处理大小写等异常情况)
# df['CryoSleep'] = df['CryoSleep'].map({'True': True, 'False': False}).fillna(False)
# df['VIP'] = df['VIP'].map({'True': True, 'False': False}).fillna(False)

2. 在预处理管道中添加类型转换

在SimpleImputer之后显式转换类型,确保进入OneHotEncoder的都是字符串:

from sklearn.preprocessing import FunctionTransformer

categorical_transformer = Pipeline(steps=[
    ("imputer", SimpleImputer(strategy="constant", fill_value="missing")),
    ("type_cast", FunctionTransformer(lambda x: x.astype(str))),  # 新增类型转换步骤
    ("encoder", OneHotEncoder(handle_unknown="ignore"))
])

3. 替换回归器为分类器(可选优化)

目标变量Transported属于二分类任务,代码中使用的RandomForestRegressor是回归模型,建议替换为分类器:

from sklearn.ensemble import RandomForestClassifier

model = Pipeline(steps=[("preprocessor", preprocessor), ("model", RandomForestClassifier())])

内容的提问来源于stack exchange,提问作者user12585467

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:34:43