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

如何使用sklearn.preprocessing对river流对象做分位数变换与归一化

修复方案

报错根源

  • 类型不兼容:river 的 iter_pandas 迭代返回的单条样本是字典格式,而 Sklearn 的 QuantileTransformer 要求输入为二维数值类数组结构,直接传入字典会触发类型转换失败。
  • 特征类型错误:样本中的 course_no 是字符串类型的分类特征,分位数变换仅支持数值特征输入,未预处理直接传入会报错。
  • 逻辑错误:
    • 循环内每次调用 fit_transform 相当于用单样本重新拟合变换器,会完全丢失历史流数据的统计信息,不符合流式处理逻辑。
    • 变换后的新特征没有传入模型,原代码仍使用原始未变换特征训练预测。

修复步骤

  1. 先对分类特征做数值编码,转换为模型和预处理工具支持的数值格式。
  2. 固定特征顺序,保证字典转数组的过程中特征顺序一致,避免特征错位。
  3. 使用 Sklearn 预处理接口的 partial_fit 方法做增量拟合,适配流式数据的处理需求。
  4. 将变换后的数组转回字典格式,适配 river 模型的输入要求。
  5. 把变换后的新特征传入模型做预测和训练。

完整可运行代码

import pandas as pd
import numpy as np
from river.stream import iter_pandas
from river import metrics
from river import ensemble
from sklearn.preprocessing import QuantileTransformer 

# 构造数据集
students=pd.DataFrame()
students['r_no']=[1,2,3,4,5]
students['course_no']=['CS_123','CS_456','CS_890','CS_678','CS_123']
students['pass']=[1,1,0,0,1]

x_students=students.drop(['pass'],axis=1)
# 对分类特征做独热编码,转成数值特征
x_students = pd.get_dummies(x_students, columns=['course_no'])
y_students=students['pass']
# 固定特征顺序,保证后续字典转数组的一致性
feature_order = x_students.columns.tolist()

c1 = ensemble.AdaptiveRandomForestClassifier(split_confidence=0.01,tie_threshold=0.07, seed=123)
c2 = ensemble.AdaptiveRandomForestClassifier(split_confidence=0.01,tie_threshold=0.07, seed=123)

trans_st1 = QuantileTransformer(n_quantiles=3, random_state=123)
trans_st2 = QuantileTransformer(n_quantiles=3, output_distribution='normal', random_state=456)

strm_st1=iter_pandas(X=x_students,y=y_students)
strm_st2=iter_pandas(X=x_students,y=y_students)

metric1 = metrics.Accuracy()
metric2 = metrics.Accuracy()

y_preds_st1 = []
y_preds_st2 = []

for ((xi1, yi1),(xi2, yi2)) in zip(strm_st1,strm_st2):
    # 字典转二维数组,适配sklearn预处理接口
    arr_xi1 = np.array([[xi1[feat] for feat in feature_order]])
    arr_xi2 = np.array([[xi2[feat] for feat in feature_order]])
    
    # 增量拟合+变换,保留历史统计信息
    trans_st1.partial_fit(arr_xi1)
    new_arr_xi1 = trans_st1.transform(arr_xi1)
    trans_st2.partial_fit(arr_xi2)
    new_arr_xi2 = trans_st2.transform(arr_xi2)
    
    # 数组转回字典,适配river模型输入
    new_xi1 = dict(zip(feature_order, new_arr_xi1[0]))
    new_xi2 = dict(zip(feature_order, new_arr_xi2[0]))

    # 使用变换后的特征做预测和训练
    y_pred1 = c1.predict_one(new_xi1)
    y_pred2 = c2.predict_one(new_xi2)
    c1.learn_one(new_xi1, yi1)
    c2.learn_one(new_xi2, yi2)

    metric1.update(y_pred=y_pred1, y_true=yi1)
    metric2.update(y_pred=y_pred2, y_true=yi2)

    y_preds_st1.append(y_pred1)
    y_preds_st2.append(y_pred2)

    print(f"Accuracy for c1: {metric1.get():.4f}")
    print(f"Accuracy for c2: {metric2.get():.4f}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:12:03