2. 实战篇:手把手搭建电商购买意愿预测混合集成模型
2. 实战篇:手把手搭建电商购买意愿预测混合集成模型
上一篇我们理清了混合集成的理论框架,这一篇直接进入 “真刀真枪” 的实战环节。本次实战选择电商用户购买意愿预测场景 —— 这是电商平台的核心需求,数据包含 “用户行为日志(结构化)+ 商品图片(非结构化)”,正好适配混合集成 “多模态数据处理” 的优势。我们将搭建 “CNN(处理图片)+XGBoost(处理日志)+ 逻辑回归(融合结果)” 的混合模型,全程附代码 + 注释,新手也能跟着做。
2.1 实战准备:环境、数据、目标全明确
在写代码前,先把 “战场” 准备好,避免中途因环境或数据问题卡壳。
2.1.1 开发环境配置
本次实战基于 Python,核心库及版本建议如下(版本不强制一致,兼容即可):
| 库名称 | 作用 | 安装命令 |
|---|---|---|
| pandas/numpy | 数据处理与数值计算 | pip install pandas numpy |
| scikit-learn | 传统机器学习(逻辑回归、预处理) | pip install scikit-learn |
| xgboost | 处理结构化数据(用户行为日志) | pip install xgboost |
| tensorflow/pytorch | 搭建 CNN(处理商品图片) | pip install tensorflow |
| matplotlib/seaborn | 结果可视化 | pip install matplotlib seaborn |
安装完成后,可通过以下代码验证环境是否正常:
import pandas as pd
import xgboost as xgb
from sklearn.linear\_model import LogisticRegression
\# 若无报错,则环境正常
print("环境配置成功!")
2.1.2 数据集说明与预处理(附代码)
本次使用的 “电商用户购买数据集” 包含 3 类核心数据,已做脱敏处理,可模拟真实场景:
-
用户行为日志(train_user.csv/test_user.csv):结构化数据,含用户 ID、浏览时长、加购次数、收藏次数、历史购买记录等 10 个特征,标签为 “是否购买(0 = 否,1 = 是)”;
-
商品图片数据(train_img/test_img/):非结构化数据,每个商品对应 1 张图片(尺寸 224×224),以 “商品 ID.jpg” 命名;
-
关联表(user_item_map.csv):关联用户 ID 与商品 ID,确保 “用户行为” 与 “对应商品图片” 匹配。
预处理步骤(代码实现):
先完成数据加载与关联,再按上一篇讲的 “数据预处理 3 要求” 处理数据:
import pandas as pd
import os
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.preprocessing.image import load\_img, img\_to\_array
\# 1. 加载数据并关联
user\_df = pd.read\_csv("train\_user.csv") # 用户行为数据
img\_dir = "train\_img/" # 商品图片路径
map\_df = pd.read\_csv("user\_item\_map.csv")# 关联表
\# 关联用户与商品图片路径(通过商品ID)
user\_df = pd.merge(user\_df, map\_df, on="user\_id", how="left")
user\_df\["img\_path"] = user\_df\["item\_id"].apply(lambda x: os.path.join(img\_dir, f"{x}.jpg"))
\# 2. 结构化数据预处理(用户行为日志)
\# 2.1 缺失值填充(用中位数填充数值型特征)
num\_features = \["browse\_time", "add\_cart\_count", "collect\_count"]
for feat in num\_features:
  user\_df\[feat].fillna(user\_df\[feat].median(), inplace=True)
\# 2.2 标准化(Z-Score)
scaler = StandardScaler()
user\_df\[num\_features] = scaler.fit\_transform(user\_df\[num\_features])
\# 3. 图片数据预处理(商品图片)
def preprocess\_img(img\_path):
  \# 加载图片并 resize 到224×224(CNN输入要求)
  img = load\_img(img\_path, target\_size=(224, 224))
  \# 转为数组并归一化(像素值从0-255转为0-1)
  img\_array = img\_to\_array(img) / 255.0
  return img\_array
\# 生成图片特征数组(可分批处理,避免内存溢出)
user\_df\["img\_feature"] = user\_df\["img\_path"].apply(preprocess\_img)
\# 4. 拆分特征与标签
X\_user = user\_df\[num\_features].values # 结构化特征(用户行为)
X\_img = np.array(user\_df\["img\_feature"].tolist()) # 图片特征
y = user\_df\["is\_purchase"].values # 标签(是否购买)
2.1.3 实战目标与评估指标
明确目标:基于 “用户行为 + 商品图片” 预测用户是否购买,核心评估指标选择AUC(ROC 曲线下面积) 和F1 分数—— 这两个指标对 “类别不平衡” 场景(如购买用户占比低)更友好,符合电商真实情况。
2.2 分模块搭建基学习器(CNN+XGBoost)
混合集成的核心是 “先让每个基学习器足够好”,再做融合。我们先分别搭建处理图片的 CNN 和处理结构化数据的 XGBoost。
2.2.1 搭建 CNN:提取商品图片特征(附网络结构)
商品图片的 “视觉特征”(如颜色、款式、细节)会影响用户购买意愿,用 CNN 提取这些特征:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
\# 定义CNN模型(轻量级结构,适合新手训练)
def build\_cnn\_model(input\_shape=(224, 224, 3)):
  model = Sequential()
  \# 卷积层1:提取低级特征(如边缘、颜色)
  model.add(Conv2D(32, (3, 3), activation="relu", input\_shape=input\_shape))
  model.add(MaxPooling2D(pool\_size=(2, 2))) # 池化:降低维度,减少过拟合
   
  \# 卷积层2:提取中级特征(如纹理、形状)
  model.add(Conv2D(64, (3, 3), activation="relu"))
  model.add(MaxPooling2D(pool\_size=(2, 2)))
   
  \# 卷积层3:提取高级特征(如商品整体轮廓)
  model.add(Conv2D(128, (3, 3), activation="relu"))
  model.add(MaxPooling2D(pool\_size=(2, 2)))
   
  \# 全连接层:将卷积特征转为向量
  model.add(Flatten())
  model.add(Dense(256, activation="relu"))
  model.add(Dropout(0.5)) # Dropout:防止过拟合
   
  \# 输出层:输出图片特征的“购买概率倾向”(单输出,sigmoid激活)
  model.add(Dense(1, activation="sigmoid", name="img\_output"))
   
  \# 编译模型(二分类任务,用binary\_crossentropy损失)
  model.compile(optimizer="adam", loss="binary\_crossentropy", metrics=\["AUC"])
  return model
\# 初始化并训练CNN
cnn\_model = build\_cnn\_model()
print("CNN模型结构:")
cnn\_model.summary() # 打印模型结构(可查看各层参数)
\# 训练模型(用图片特征X\_img和标签y, epochs=10, batch\_size=32,新手可调整)
cnn\_history = cnn\_model.fit(
  X\_img, y,
  epochs=10,
  batch\_size=32,
  validation\_split=0.2 # 20%数据作为验证集,监控过拟合
)
\# 提取CNN的中间特征(后续融合用,而非直接用输出概率)
from tensorflow.keras.models import Model
\# 取“Dropout层”的输出作为图片特征向量(256维)
cnn\_feature\_model = Model(inputs=cnn\_model.input, outputs=cnn\_model.get\_layer(index=-2).output)
X\_img\_feature = cnn\_feature\_model.predict(X\_img) # 图片特征向量(shape: (样本数, 256))
2.2.2 搭建 XGBoost:挖掘用户行为规律(附参数说明)
用户的 “浏览时长、加购次数” 等行为直接反映购买意愿,用 XGBoost 处理这些结构化特征(擅长捕捉特征交互):
import xgboost as xgb
from sklearn.model\_selection import train\_test\_split
from sklearn.metrics import roc\_auc\_score
\# 拆分训练集与验证集(和CNN保持一致的验证集比例)
X\_user\_train, X\_user\_val, y\_train, y\_val = train\_test\_split(
  X\_user, y, test\_size=0.2, random\_state=42
)
\# 定义XGBoost模型(新手友好参数)
xgb\_model = xgb.XGBClassifier(
  objective="binary:logistic", # 二分类任务
  learning\_rate=0.1, # 学习率(小一点更稳定)
  max\_depth=5, # 树深度(防止过拟合)
  n\_estimators=100, # 树的数量
  subsample=0.8, # 样本采样率(防止过拟合)
  colsample\_bytree=0.8, # 特征采样率(防止过拟合)
  random\_state=42
)
\# 训练XGBoost
xgb\_model.fit(
  X\_user\_train, y\_train,
  eval\_set=\[(X\_user\_val, y\_val)],
  eval\_metric="auc", # 用AUC作为验证指标
  early\_stopping\_rounds=10, # 早停:验证集AUC10轮不提升则停止
  verbose=1 # 打印训练过程
)
\# 提取XGBoost的特征重要性(可选,分析哪些行为影响最大)
feature\_importance = pd.DataFrame({
  "feature": num\_features,
  "importance": xgb\_model.feature\_importances\_
}).sort\_values("importance", ascending=False)
print("XGBoost特征重要性:")
print(feature\_importance)
\# 生成XGBoost的预测概率(后续融合用)
X\_xgb\_prob = xgb\_model.predict\_proba(X\_user)\[:, 1].reshape(-1, 1) # 取正类概率(shape: (样本数, 1))
2.3 融合层:用逻辑回归整合双模型结果
现在我们有了 “CNN 的图片特征向量” 和 “XGBoost 的行为概率”,接下来用逻辑回归做融合 —— 它能自动学习两个基模型的权重,输出最终购买概率。
2.3.1 融合特征构造
先将两个基模型的输出拼接成 “融合特征”:
import numpy as np
\# 融合特征 = CNN图片特征(256维) + XGBoost概率(1维)
X\_fusion = np.hstack(\[X\_img\_feature, X\_xgb\_prob])
print(f"融合特征维度:{X\_fusion.shape}") # 输出:(样本数, 257),符合预期
2.3.2 逻辑回归融合与模型评估(附结果分析)
用融合特征训练逻辑回归,并评估最终模型性能:
from sklearn.linear\_model import LogisticRegression
from sklearn.metrics import roc\_auc\_score, f1\_score, confusion\_matrix
import seaborn as sns
import matplotlib.pyplot as plt
\# 拆分融合特征的训练集与验证集
X\_fusion\_train, X\_fusion\_val, y\_train, y\_val = train\_test\_split(
  X\_fusion, y, test\_size=0.2, random\_state=42
)
\# 训练逻辑回归融合模型
fusion\_model = LogisticRegression(max\_iter=1000) # 增加max\_iter避免不收敛
fusion\_model.fit(X\_fusion\_train, y\_train)
\# 验证集预测
y\_val\_pred\_prob = fusion\_model.predict\_proba(X\_fusion\_val)\[:, 1] # 预测概率
y\_val\_pred = fusion\_model.predict(X\_fusion\_val) # 预测类别(阈值0.5)
\# 计算评估指标
auc = roc\_auc\_score(y\_val, y\_val\_pred\_prob)
f1 = f1\_score(y\_val, y\_val\_pred)
conf\_matrix = confusion\_matrix(y\_val, y\_val\_pred)
\# 打印结果
print(f"融合模型验证集AUC:{auc:.4f}") # 预期AUC>0.85(优于单一模型)
print(f"融合模型验证集F1分数:{f1:.4f}") # 预期F1>0.7(符合电商需求)
\# 可视化混淆矩阵(更直观看预测效果)
plt.figure(figsize=(8, 6))
sns.heatmap(conf\_matrix, annot=True, fmt="d", cmap="Blues",
  xticklabels=\["不购买", "购买"], yticklabels=\["不购买", "购买"])
plt.xlabel("预测标签")
plt.ylabel("真实标签")
plt.title("融合模型混淆矩阵")
plt.show()
2.4 实战小结:3 个关键实战经验
本次实战完成了 “CNN+XGBoost + 逻辑回归” 混合模型的搭建,核心经验总结如下,帮你避坑:
-
基模型选择要 “互补”:CNN 擅长处理图片,XGBoost 擅长处理结构化数据,二者互补才能体现混合价值;若选两个都处理结构化数据的模型(如 XGBoost+LR),融合增益会很低;
-
融合特征比融合概率更有效:本次用 “CNN 中间特征 + XGBoost 概率” 融合,而非直接融合两个模型的概率 —— 中间特征包含更丰富的信息,能让融合模型学到更多规律;
-
早停与正则化必加:混合模型参数多,易过拟合,XGBoost 的
early_stopping_rounds、CNN 的Dropout、逻辑回归的默认正则化,都是防止过拟合的关键。
下一篇我们将进入 “文献算法改进” 环节,分析近 3 年混合集成领域的经典改进思路,比如如何用 “自适应权重” 替代固定逻辑回归融合,进一步提升模型性能,感兴趣的话继续跟进!
更多推荐



所有评论(0)