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 类核心数据,已做脱敏处理,可模拟真实场景:

  1. 用户行为日志(train_user.csv/test_user.csv):结构化数据,含用户 ID、浏览时长、加购次数、收藏次数、历史购买记录等 10 个特征,标签为 “是否购买(0 = 否,1 = 是)”;

  2. 商品图片数据(train_img/test_img/):非结构化数据,每个商品对应 1 张图片(尺寸 224×224),以 “商品 ID.jpg” 命名;

  3. 关联表(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 + 逻辑回归” 混合模型的搭建,核心经验总结如下,帮你避坑:

  1. 基模型选择要 “互补”:CNN 擅长处理图片,XGBoost 擅长处理结构化数据,二者互补才能体现混合价值;若选两个都处理结构化数据的模型(如 XGBoost+LR),融合增益会很低;

  2. 融合特征比融合概率更有效:本次用 “CNN 中间特征 + XGBoost 概率” 融合,而非直接融合两个模型的概率 —— 中间特征包含更丰富的信息,能让融合模型学到更多规律;

  3. 早停与正则化必加:混合模型参数多,易过拟合,XGBoost 的early_stopping_rounds、CNN 的Dropout、逻辑回归的默认正则化,都是防止过拟合的关键。

下一篇我们将进入 “文献算法改进” 环节,分析近 3 年混合集成领域的经典改进思路,比如如何用 “自适应权重” 替代固定逻辑回归融合,进一步提升模型性能,感兴趣的话继续跟进!

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐