基于老客RFM分群的KNN新客触达建模流程校验及报错解决咨询
建模流程合理性评估
- 编码逻辑错误:对训练集和测试集分别执行
fit_transform,会导致同一个类别值在两个数据集的编码结果不一致,特征含义完全混乱;同时LabelEncoder会为无序类别特征强加数值顺序,KNN是基于距离计算的算法,会直接导致距离计算结果失真,建议替换为独热编码或目标编码。 - 特征对齐错误:训练集使用8个特征(包含
Title字段),测试集仅使用7个特征,特征数量不匹配,模型无法正常推理。 - 维度逻辑错误:
sklearn中所有模型的输入特征矩阵都要求为(样本数, 特征数)的二维格式,你对Xtrain执行转置操作后,相当于把12个特征当成了12个样本,把3492个样本当成了3492个特征,完全搞反了样本和特征的维度定义。 - 标签逻辑错误:RFM分群得到的11个类别是模型要学习的预测标签,标签维度应该和训练样本数一致(即3492个标签值),你代码中的Ytrain维度
(12,983)完全不符合标签要求。
报错原因及修复方案
直接报错原因
模型训练时接收的输入特征维度为(12, 3492),要求预测的输入Xtest为一维数组,既不符合二维输入要求,特征数量也和训练时的3492个特征不匹配,因此抛出维度错误。
完整修复步骤
- 对齐特征列:保证训练集和测试集使用完全相同的特征字段,若新客数据集无
Title字段,需同步删除训练集的Title字段。 - 修正编码逻辑:
import pandas as pd from sklearn.preprocessing import LabelEncoder # 统一使用的特征列 use_cols = ['address', 'state', 'gender', 'job_title', 'job_industry_category', 'wealth_segment', 'owns_car'] enc_dict = {} for col in use_cols: enc = LabelEncoder() # 合并两数据集的该列值做拟合,避免测试集出现训练集未覆盖的类别报错 all_values = pd.concat([Training[col].astype(str), Test[col].astype(str)], axis=0) enc.fit(all_values) # 分别转换训练集和测试集 Training[col] = enc.transform(Training[col].astype(str)) Test[col] = enc.transform(Test[col].astype(str)) enc_dict[col] = enc
- 修正数据集维度与训练逻辑:
from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier # 拆分老客特征与标签,y为RFM分群得到的11个类别标签 X = Training[use_cols] y = Training['rfm_cluster'] # 替换为你实际的RFM分群标签字段名 # 拆分训练验证集,不需要转置操作 X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42) # 训练模型 classifier = KNeighborsClassifier(n_neighbors=5) classifier.fit(X_train, y_train) # 先验证老客测试集效果 y_val_pred = classifier.predict(X_val) # 预测新客的分群结果,Test为新客数据集 y_new_pred = classifier.predict(Test[use_cols])
注意:如果特征为无序类别,建议替换LabelEncoder为OneHotEncoder,避免KNN距离计算失真
内容的提问来源于stack exchange,提问作者Nikhil Kumar Macharla
相关产品推荐
相关产品推荐

