使用RandomForestRegressor构建餐厅推荐器时特征维度不匹配问题求助
问题原因及解决办法
核心问题
训练时模型接收的是2924维特征,但你手动构造的输入仅8维,维度不匹配导致报错。本质是训练时的独热编码覆盖了更多类别/特征,而预测时仅手动生成少量类别对应的特征,缺失了大量训练时存在的哑变量列。
解决步骤
1. 复用训练时的完整预处理管道
不要手动构造独热编码,应保存训练时使用的完整预处理工具(如ColumnTransformer),而非仅保存StandardScaler。
训练时的标准预处理示例(需匹配你的实际训练代码):
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.pipeline import Pipeline from sklearn.ensemble import RandomForestRegressor import joblib # 定义分类、数值特征列(需和训练数据列名一致) categorical_features = ['location', 'type'] numeric_features = ['cost', 'votes'] # 构建预处理管道:分类特征独热编码,数值特征标准化 preprocessor = ColumnTransformer( transformers=[ ('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features), ('num', StandardScaler(), numeric_features) ]) # 整合预处理和模型为完整管道 model_pipeline = Pipeline(steps=[ ('preprocessor', preprocessor), ('regressor', RandomForestRegressor()) ]) # 训练并保存整个管道 model_pipeline.fit(X_train, y_train) joblib.dump(model_pipeline, 'full_model_pipeline.pkl')
2. 预测时用保存的管道处理输入
直接通过完整管道处理输入,确保特征维度与训练时完全一致:
import joblib import pandas as pd # 加载完整模型管道 model_pipeline = joblib.load('full_model_pipeline.pkl') def preprocess_input(location, type_, cost, votes): # 用DataFrame构造输入,列名必须和训练时一致 return pd.DataFrame({ 'location': [location], 'type': [type_], 'cost': [cost], 'votes': [votes] }) input_data = preprocess_input('Whitefield', 'Casual Dining', 1000, 500) prediction = model_pipeline.predict(input_data) print(f"Predicted restaurant rating: {prediction[0]}")
3. 若已分开保存预处理组件
如果之前已单独保存训练时的OneHotEncoder,预测时需用它生成完整独热编码,而非手动编写:
import joblib import numpy as np import pandas as pd # 加载训练时的编码器、标准化器和模型 encoder = joblib.load('onehot_encoder.pkl') scaler = joblib.load('scaler.pkl') model = joblib.load('my_model.pkl') def preprocess_input(location, type_, cost, votes): # 处理分类特征 cat_df = pd.DataFrame({'location': [location], 'type': [type_]}) one_hot_features = encoder.transform(cat_df).toarray() # 处理数值特征 scaled_num_features = scaler.transform([[cost, votes]]) # 拼接所有特征 return np.hstack([one_hot_features, scaled_num_features]) input_data = preprocess_input('Whitefield', 'Casual Dining', 1000, 500) prediction = model.predict(input_data) print(f"Predicted restaurant rating: {prediction[0]}")
关键注意事项
- 训练时的所有预处理逻辑(独热编码的类别集合、特征顺序、标准化的均值/方差)必须与预测时完全一致,禁止手动修改。
- 若训练数据包含其他特征(如截图中的
cuisines、online_order等),预测时需补充这些特征的合理默认值(如online_order设为0或1),否则维度仍会不匹配。
内容的提问来源于stack exchange,提问作者Carl Jacob
相关产品推荐
相关产品推荐

