Pandas线性回归场景下如何仅对指定列执行StandardScaler标准化
报错原因
你当前报错的核心原因有两个:
- 你将包含
number_orders、number_items、number_segments、year、month、day共6列的训练集直接传入StandardScaler,转换后输出的是6列结果,但你构造DataFrame时只传入了3个列名,列数不匹配触发报错。 - 你前期代码存在逻辑问题:将特征集X直接转为了numpy数组,numpy数组没有列名标识无法直接筛选指定列;调用
train_test_split时拆分的是未定义的df变量,且直接用全量特征拟合模型存在数据泄露问题。
解决方案
步骤1:修正前期数据处理逻辑
首先把数据读取、拆分的逻辑修正,保留特征的DataFrame格式方便筛选列:
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LinearRegression # 读取数据 new_data=pd.read_csv('https://raw.githubusercontent.com/michalis0/DataMining_and_MachineLearning/master/data/regression_sales.csv') # 定义特征和标签,X保留DataFrame格式不要提前转numpy y = new_data['sales_per_day'] X = new_data[['number_orders', 'number_items', 'number_segments', 'year', 'month', 'day']] # 拆分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = 77)
步骤2:仅对指定列执行标准化
有两种常用实现方式,按需选择即可:
方式1:手动拆分列处理后合并
逻辑直观,不需要额外引入依赖:
# 定义要标准化的列、不需要标准化的列 scale_cols = ['number_orders', 'number_items', 'number_segments'] no_scale_cols = ['year', 'month', 'day'] scaler = StandardScaler() # 仅对指定列拟合、转换训练集 X_train_scale = scaler.fit_transform(X_train[scale_cols]) # 转换测试集的指定列 X_test_scale = scaler.transform(X_test[scale_cols]) # 合并标准化列和未标准化列,两种拼接方式选一种即可 # 方式1:拼接为numpy数组直接喂给模型 X_train_final = np.concatenate([X_train_scale, X_train[no_scale_cols].values], axis=1) X_test_final = np.concatenate([X_test_scale, X_test[no_scale_cols].values], axis=1) # 方式2:拼接为DataFrame方便后续查看 X_train_final = pd.DataFrame(X_train_scale, columns=scale_cols, index=X_train.index).join(X_train[no_scale_cols]) X_test_final = pd.DataFrame(X_test_scale, columns=scale_cols, index=X_test.index).join(X_test[no_scale_cols])
方式2:用ColumnTransformer自动处理
更优雅的工业界常用写法,不需要手动拼接:
from sklearn.compose import ColumnTransformer # 定义要标准化的列 scale_cols = ['number_orders', 'number_items', 'number_segments'] # 构造列转换器:指定列用StandardScaler,剩余列原样保留输出 preprocessor = ColumnTransformer( transformers=[ ('scaler', StandardScaler(), scale_cols) ], remainder='passthrough' ) # 直接完成训练集拟合转换、测试集转换 X_train_final = preprocessor.fit_transform(X_train) X_test_final = preprocessor.transform(X_test)
步骤3:训练模型
用处理好的训练集数据拟合模型即可:
regression_model = LinearRegression(fit_intercept=True) regression_model.fit(X_train_final, y_train)
内容的提问来源于stack exchange,提问作者cped
相关产品推荐
相关产品推荐

