使用OneHotEncoder后调用make_column_transformer归一化报ValueError问题咨询
One-hot编码操作的正确性判定
你当前的one-hot编码操作不符合时序数据的特征处理逻辑,是错误的:
- 你对完整的时间字符串做编码,每个唯一时间戳对应一个独立特征,最终特征维度高达250万+,不仅造成维度灾难,还完全丢失了时间的先后顺序、间隔等核心时序信息,模型无法学习到时间和价格的关联规律。
- OneHotEncoder默认输出scipy稀疏矩阵,该数据结构不存在pandas DataFrame的
columns属性,是你后续归一化报错的直接原因。
正确处理方案
1. 时间特征提取
不要直接对完整时间字符串做编码,先将时间列转换为datetime类型,提取有业务意义的时间分量,保留时序属性:
# 读入数据后先处理时间列 btc_data["Time"] = pd.to_datetime(btc_data["Time"]) # 提取时间特征 btc_data["timestamp"] = btc_data["Time"].astype("int64") // 10**9 # 秒级Unix时间戳(数值型) btc_data["hour"] = btc_data["Time"].dt.hour # 小时(类别型,0-23) btc_data["dayofweek"] = btc_data["Time"].dt.dayofweek # 星期几(类别型,0-6) btc_data["month"] = btc_data["Time"].dt.month # 月份(类别型,1-12)
2. 预处理流程修正
你可以直接将编码和归一化整合到make_column_transformer流程中,避免手动处理带来的数据类型不匹配问题:
# 划分特征和标签 X = btc_data[["timestamp", "hour", "dayofweek", "month"]] y = btc_data["Open"] # 时间序列任务不要使用随机划分,按时间先后划分训练测试集 train_size = int(len(X) * 0.8) X_train, X_test = X.iloc[:train_size], X.iloc[train_size:] y_train, y_test = y.iloc[:train_size], y.iloc[train_size:] # 整合编码与归一化流程 ct = make_column_transformer( (MinMaxScaler(), ["timestamp"]), # 数值型时间戳做归一化 (OneHotEncoder(handle_unknown="ignore"), ["hour", "dayofweek", "month"]) # 类别型时间特征做one-hot编码 ) ct.fit(X_train) X_train_normal = ct.transform(X_train) X_test_normal = ct.transform(X_test)
上述处理后,后续的模型训练、评估代码可以正常运行。
额外注意事项
BTC价格预测属于时序预测任务,禁止使用train_test_split做随机划分,否则会打乱时间顺序造成数据泄露,得到的模型结果没有实际意义。
内容的提问来源于stack exchange,提问作者Khosraw Azizi
相关产品推荐
相关产品推荐

