大数据环境下电商食品偏好挖掘与购买行为预测算法优化实践
2026/9/9 22:19:50 网站建设 项目流程

每年到毕业设计选题季,都会有学弟学妹问我:大数据方向的毕设到底做什么题才不坑?今年被问到最多的,恰恰是“大数据环境下电商消费者食品偏好挖掘与购买行为预测算法优化”这个方向。说实话,第一次看到这个题我也觉得范围大得吓人,但完整做下来之后,发现它恰好把数据清洗、特征工程、偏好建模、行为预测、模型评估、论文撰写这一整条链路串起来了,非常适合数据科学与大数据技术、电子商务、应用统计方向的学生拿来当毕业设计项目。

这篇文章不聊虚的,直接把我做这个项目时的整体设计方案、偏好挖掘与预测算法的核心实现、代码结构、复现步骤,以及调试过程中踩过的坑全部整理出来。不管你是准备做同类毕设,还是想拿一个完整项目作为求职面试的项目经验,都可以直接参考。

1. 项目整体设计:先别急着写代码,把四个问题想清楚

1.1 这个题目要解决什么问题

标题里写了三件事:食品偏好挖掘、购买行为预测、算法优化。拆开看,它们是一个有先后关系的整体。

电商平台每天会产生海量用户行为日志,尤其是食品类目,用户购买频率高、复购周期短、决策链路复杂,今天买完零食,明天可能又买生鲜。这和海量的用户行为数据正好构成了一个典型的“大数据+挖掘+预测”任务。具体来说:

  • 偏好挖掘:从用户的历史行为(浏览、点击、加购、下单)中,提取用户对不同食品类目、品牌、价格带的偏好强度。
  • 行为预测:结合用户的偏好特征、商品特征和时间特征,预测用户在未来某个时间窗口(比如7天)内,是否会对某一类食品产生购买行为。
  • 算法优化:针对预测模型的准确率、召回率、训练效率等指标,做特征筛选、参数调优、样本处理等优化工作。

我选定的最终任务形式是二分类:预测用户在未来7天内是否会购买某个食品类目下的商品。既和电商业务贴合,又方便用准确率、AUC、F1等指标做量化评估,论文也好写。

1.2 技术栈选型和整体架构

做这类项目,最忌讳一上来就堆一堆高大上的技术名词。我的选型原则是:能用稳定成熟的,就不碰花哨的;能在一台机器上跑通的,就不强行搭三节点集群。

我的最终技术栈如下:

模块工具说明
数据处理Python 3.8 + Pandas + NumPy离线特征处理,数据量在百万级时足够用
大数据环境PySpark用Spark SQL做数据聚合,体现大数据处理能力,又不用真搭集群
特征存储MySQL + Parquet文件MySQL放维表,Parquet放行为明细和特征宽表
偏好挖掘Scikit-learn + 自定义策略加权行为评分 + FP-Growth辅助
行为预测LightGBM + XGBoost树模型梯度提升,处理表格型特征效果好
可视化Matplotlib + Seaborn画特征分布、模型ROC曲线、特征重要度图

这里要说清楚一个关键点:题目里带“大数据环境”四个字,不意味着你必须去运维一个Hadoop集群。我的做法是用PySpark在本地以local模式跑大数据量的聚合任务,同时在论文里说明这套代码可以无缝迁移到集群部署。这样做的好处是,评审老师看到的是你掌握了大数据工具链,而不是把时间浪费在集群搭建上。

1.3 为什么不选纯推荐算法或纯深度学习方法

我最初考虑过三条路线:

  • 纯协同过滤推荐,用户相似度算完直接做TopN推荐,代码量小,但问题在于它只能回答“推荐什么”,回答不了“用户会不会买”,和题目里的“购买行为预测”对不上。
  • 纯Deep Learning,比如DeepFM、Wide&Deep、阿里DIN这类CTR预估模型,效果可能上限更高,但对算力、调参经验要求高,且解释性弱,论文想讲清楚“为什么这么优化”难度很大。
  • 特征工程+集成学习预测,也就是我最终采用的路子。

第三条路线最稳。偏好挖掘可以用统计方法和关联规则讲清楚,行为预测用LightGBM这类模型保证效果,算法优化又有足够的篇幅去做特征筛选、参数调优、样本不平衡处理,整篇论文的逻辑链条特别完整。这也是我在答辩时能不用背稿就讲清楚整个项目的原因。

2. 核心细节解析:用户与行为特征

2.1 数据来源说明与格式

这里必须提醒后来人一句:毕设项目的数据,尽量别用自己写的模拟数据,不然很容易被一票否决。

我当时用的是阿里天池平台公开的电商用户行为数据集,数据量在百万到千万行级别,字段包含用户ID、商品ID、商品类目ID、行为类型(浏览/点击/加购/下单)、时间戳。虽然公开数据集最初不是专门做食品的,但通过类目筛选,我只保留了食品相关类目,并就把它定义为一个面向食品电商场景的子集。这个做法一定要写进论文的数据来源说明,既真实又严谨。

原始数据核心字段如下:

字段名类型说明
user_idstring用户ID,脱敏后的哈希值
item_idstring商品ID
category_idstring类目ID,需映射食品类目
behavior_typestringpv浏览 / fav收藏 / cart加购 / buy下单
timestampint行为发生的Unix时间戳

2.2 数据预处理的关键步骤

原始数据是没法直接建模的,我的预处理顺序是:

  1. 按user_id、item_id去重,剔除明显异常的重复记录。比如同一用户在同一秒内对同一商品的重复浏览,后台可能因为刷新产生了冗余日志。
  2. 剔除异常值,包括下单量为负的脏数据、用户ID或商品ID为空的记录、时间戳明显超出统计范围的记录。
  3. 行为时间统一转换成日期格式,并生成小时、星期、是否工作日等时间特征。
  4. 对行为按用户和时间排序,确保后续构造时间窗口特征时不会出现“未来数据混入过去特征”的标签泄漏问题。

这里第4点特别重要,我见过不少项目在构造特征时直接全量统计,导致模型训练集里混入了未来信息,离线评估分数虚高,上线后直接崩。正确做法是:每一个预测样本的特征,只能由该样本预测时刻之前的数据生成。

2.3 用户与食品类目偏好分如何计算

偏好挖掘不是简单统计用户买了多少商品,而是要区分不同行为的价值权重。我比较推荐的方案是“多行为加权偏好分”。具体计算公式是:

`pref(u, c) = Σ 行为行为行为行为

pref(u, c) = Σ (w_action * count_action(u, c)) * decay(t)

其中action是浏览、收藏、加购、下单四种行为,w_action是行为权重。我调出来的权重参考如下:浏览1、收藏2、加购4、下单8。这样设计的原因是,下单行为直接对应实际消费,权重最高;而浏览行为虽然量大,但噪声也大,所以权重低。收藏比浏览权重高,但低于加购,符合用户“想买但还没决定”的心理。

为了让偏好更贴近“现在”而非“过去”,我加入了时间衰减因子:

decay(t) = exp(-λ * (T_current - t))

其中λ是衰减系数,我取的是0.05左右,约等于20天前的行为权重衰减到当前权重的36%。这么做是因为食品消费有很强的时效性,半年前买过火锅底料,不代表这个月还喜欢买,时间衰减能让偏好特征更灵敏地反映近期兴趣变化。

2.4 基于类目关联的偏好延展

单纯的偏好分只刻画了用户和类目之间的直接关系,缺少“关联偏好”信息。我额外用FP-Growth关联规则挖掘,找出食品类目之间同时被大量购买的关系。比如发现“咖啡豆”和“燕麦奶”类目之间存在强关联,那么当用户频繁购买咖啡豆但从未买过燕麦奶时,可以基于关联规则给燕麦奶类目一个偏好加成。

这个方法在论文里是加分项,因为它不是自己拍脑袋想出来的规则,而是从数据里挖出来的。我设置的最小支持度为0.02,最小置信度为0.5,共得到上百条有效关联规则,然后取置信度Top50用于偏好延展计算。

3. 购买行为预测模型与算法优化实践

3.1 预测任务设计与样本构造

预测任务定为:预测用户u在未来7天内是否会对类目c下的商品产生购买行为。因此一个样本的粒度是三元组(user_id, category_id, 预测日)。正样本定义为预测日后7天内该用户确实在该类目产生下单行为,负样本则是没有下单的记录。

这里必须提一个常见问题:直接把全量未购买样本当负样本,会导致正负样本比例高达1:100甚至1:1000,模型会被负样本淹没。我做了两层处理:

  • 对负样本做下采样,将最终训练集的正负比例控制在1:5左右,既保留足够的负样本特征丰富度,又避免正样本信息被淹没。
  • 如果数据量不足,可以用SMOTE对正样本做少量过采样,但我实际跑下来LightGBM对样本比例并不特别敏感,下采样基本就够用了。

3.2 特征体系:如何把用户、商品、时间三类信息喂进模型

我把特征分成了四个维度:

特征组特征名称计算说明
用户基础特征用户总浏览数、总购买数、购买类目数、用户活跃天数直接按用户聚合
用户-类目交互特征该类目浏览次数、加购次数、购买次数、最近一次购买间隔、偏好分按用户+类目聚合生成
类目时序特征该类目近7天/30天的全局销量、热销排名变化捕捉流行趋势
时间特征预测日星期几、是否节假日、是否工作日食品消费的时间周期性明显

一些项目喜欢把特征堆到几百上千个,我建议控制在一百个以内。特征太多,LightGBM也扛不住噪声,而且论文里做特征重要度分析时会很难梳理。

3.3 模型选型:从LR到LightGBM的对比

我同时跑了好几个模型做对比,这是论文实验部分最核心的内容:

模型准确率AUCF1训练时间
逻辑回归0.5120.7190.3832分钟
随机森林0.6230.7820.44615分钟
XGBoost0.6510.8110.4728分钟
LightGBM0.6640.8270.4934分钟

逻辑回归的优势在于可解释性,但它无法自动处理特征之间的非线性关系,所以在AUC上明显落后。LightGBM用的是基于直方图的决策树算法,对类别特征和稀疏特征的处理效率都高,最终效果最好,训练时间也短,所以我把LightGBM作为最终模型。

3.4 算法优化的四个方向

这部分是项目能否拿高分的关键,标题里的“算法优化”落在四个具体动作上:

  • 特征筛选。训练完成后输出LightGBM的feature_importance,把重要度为0、且和业务逻辑对不上的特征删掉,比如某些原始行为ID的哈希特征,删掉后模型AUC不仅没降,还微涨了0.003,说明那些特征确实在引入噪声。
  • 正负样本阈值调整。默认分类阈值是0.5,但因为负样本更多,把阈值调低到0.35左右可以显著提升召回率。我通过交叉验证在“精准率-召回率”曲线下找最优点,最终F1从0.45提升到0.49。
  • 参数网格搜索。LightGBM最关键的四个参数是n_estimators、num_leaves、max_depth、learning_rate。我用的是Optuna自动搜索,跑了50组实验,最终确定的参数为主学习率0.05,叶子节点数48,层数,以及早期停止功能。网格搜索太慢,随机搜索又不够精细,Optuna的贝叶斯优化思路比较适合这种场景。
  • 时间窗口滑动验证。常见的K折交叉验证在时序数据里会引入未来信息,我用按时间划分的滑动验证:训练集用前70%时间的数据,验证集用后30%时间的数据,贴近真实业务。这个细节在答辩时很加分。

4. 实操过程与源码复现指南

4.1 项目目录结构与模块职责

很多学生拿到题目后第一件事是写模型,但我建议先从工程结构搭起。我的源码目录设计如下:

food_preference_project/ ├── config.py # 全局配置:路径、参数、类目映射 ├── requirements.txt # Python依赖列表 ├── data/ │ ├── raw/ # 原始数据(脱敏后) │ ├── processed/ # 预处理后的特征宽表 │ └── sample/ # 小样本测试数据 ├── src/ │ ├── 01_data_preprocessing.py # 数据清洗与类目筛选 │ ├── 02_feature_engineering.py # 特征构造与偏好分计算 │ ├── 03_preference_mining.py # 关联规则挖掘 │ ├── 04_model_train.py # 模型训练与参数搜索 │ ├── 05_model_evaluate.py # 模型评估与图表生成 │ └── model_inference.py # 模型预测入口 ├── models/ # 保存训练好的模型文件 ├── output/ # 评估图表与预测结果 └── paper/ # 论文素材图表

4.2 环境配置说明

依赖文件requirements.txt如下,这里贴出核心部分:

pandas==1.5.3 numpy==1.24.3 pyspark==3.4.1 scikit-learn==1.2.2 lightgbm==4.1.0 xgboost==2.0.1 optuna==3.3.0 matplotlib==3.7.1 seaborn==0.12.2

创建环境时我建议直接用conda:

conda create -n food_pref python=3.8 conda activate food_pref pip install -r requirements.txt

如果机器内存不够,可以把PySpark的local模式内存参数调低,在SparkConf里设置spark.driver.memory为2g,数据量大时再动态调大。

4.3 偏好分计算的源码解读

这里贴一段偏好分计算的简化代码,目的是让读者理解核心逻辑:

import numpy as np import pandas as pd def compute_preference_score(behavior_df, weight_map, decay_lambda=0.05, current_ts=None): """ 计算用户在类目维度上的偏好分 behavior_df: 用户行为明细,包含user_id, category_id, behavior_type, timestamp weight_map: {'pv':1, 'fav':2, 'cart':4, 'buy':8} """ if current_ts is None: current_ts = behavior_df['timestamp'].max() # 计算时间衰减权重 behavior_df['delta_days'] = (current_ts - behavior_df['timestamp']) / (24 * 3600) behavior_df['decay'] = np.exp(-decay_lambda * behavior_df['delta_days']) behavior_df['weight'] = behavior_df['behavior_type'].map(weight_map) * behavior_df['decay'] # 按照 用户+类目 聚合偏好分 pref_score = behavior_df.groupby(['user_id', 'category_id'])['weight'].sum().reset_index() pref_score.columns = ['user_id', 'category_id', 'pref_score'] return pref_score

这里有个细节:所有行为都算偏好分时,某用户如果浏览量极大,它的偏好分会被过分抬高。我实际测试后发现,每个类目内的偏好分更适合用rank或分位数归一化,而不是直接用原始累加值。归一化后模型AUC提升了1.5个百分点左右。

4.4 LightGBM训练与参数调优代码框架

模型训练部分,核心代码如下:

import lightgbm as lgb from sklearn.model_selection import StratifiedKFold from sklearn.metrics import roc_auc_score params = { 'objective': 'binary', 'metric': 'auc', 'learning_rate': 0.05, 'num_leaves': 48, 'max_depth': 7, 'feature_fraction': 0.8, 'bagging_fraction': 0.8, 'bagging_freq': 1, 'verbose': -1, 'seed': 42 } kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) cv_auc_list = [] for train_idx, valid_idx in kf.split(features, labels): X_train, X_valid = features.iloc[train_idx], features.iloc[valid_idx] y_train, y_valid = labels.iloc[train_idx], labels.iloc[valid_idx] train_set = lgb.Dataset(X_train, label=y_train) valid_set = lgb.Dataset(X_valid, label=y_valid) model = lgb.train( params, train_set, num_boost_round=1000, valid_sets=[valid_set], callbacks=[lgb.early_stopping(stopping_rounds=50)] ) y_pred = model.predict(X_valid, num_iteration=model.best_iteration) cv_auc_list.append(roc_auc_score(y_valid, y_pred)) print(f"五折AUC均值: {np.mean(cv_auc_list):.4f}")

Office环境里这样跑5折大概需要几分钟到十几分钟,取决于特征数和样本量。我把特征控制在80个左右,样本量大概几十万条,单折只需要一分钟左右。

4.5 从零跑通全流程的步骤清单

  • 第一步:把原始数据放入data/raw目录,运行01_data_preprocessing.py,生成清洗后的行为明细表。
  • 第二步:运行02_feature_engineering.py,生成用户-类目特征宽表。
  • 第三步:运行03_preference_mining.py,生成FP-Growth关联规则文件preference_rules.csv。
  • 第四步:运行04_model_train.py,先做轻量参数搜索,然后用最优参数训练最终模型。
  • 第五步:运行05_model_evaluate.py,输出ROC曲线、PR曲线、特征重要度Top30图表,保存在output目录。
  • 第六步:运行model_inference.py,输入一个用户-类目组合,输出未来7天的购买概率。

5. 常见问题与排查技巧实录

5.1 特征穿越问题,离线评估“虚高”

这是做预测类项目最容易犯的错误。我最初在构造用户总购买数时,用的是整个数据集的统计值,结果验证集AUC高达0.93,被导师一眼看穿,因为验证集里包含了“未来”行为,相当于开卷考试。

排查方法很直接:对每个样本,明确预测日,统计特征时严格限定在预测日之前。我后来用了一个通用的时间截止列,在构造特征时统一做groupby+where过滤,这个问题就解决掉了。论文里必须把这一条作为模型可信度的核心论证点来写。

5.2 数据稀疏导致偏好分不可靠

做过之后就会发现,很多用户的行为次数极少,有人甚至只有一两次浏览记录。这种用户的偏好分信噪比极低。我的处理方式是对用户行为次数分桶,行为数小于3的用户不参与关联规则挖掘,但在模型里额外增加一个稀疏用户标记特征,让模型自己去学习。

5.3 正负样本比例严重失衡

最开始正负比大约是1:128,模型预测出来的概率全部集中在0.05以下,等于都在猜负样本。下采样后我特意保留了原始验证集的真实分布来评估,保证论文里的指标不过度乐观。建议各位同学在做下采样时,把评估集和测试集保持原始分布,只有训练集做下采样。

5.4 PySpark本地运行时的内存报错

我在本地跑PySpark聚合时遇到Java heap space错误。解决方法是降低分区数,并显式设置driver和executor内存:

from pyspark import SparkConf, SparkContext conf = SparkConf().setAppName('pref_mining') \ .setMaster('local[4]') \ .set('spark.driver.memory', '2g') \ .set('spark.executor.memory', '2g') \ .set('spark.sql.shuffle.partitions', '50')

还包括在cluster部署时把local[4]换成yarn或standalone的master地址。做毕设不需要真集群,但代码要体现这种可迁移性。

5.5 模型训练时间过长

LightGBM训练时间增长主要来自特征太多或者num_leaves太大。我遇到过一次单折训练超过半小时的情况,后来用Optuna的TPESampler搜索时限制max_depth不超过9,num_leaves不超过64,训练时间缩短为原先的六分之一。

6. 论文写作与答辩的几点经验

6.1 论文结构怎么搭最稳妥

我最终的结构是七章:

  • 第一章绪论:研究背景与意义,国内外的研究现状,说清楚食物偏好挖掘和购买预测是电商领域的热点问题。
  • 第二章相关技术:写清楚大数据处理、偏好挖掘、机器学习模型相关基础,但不要抄书,每小节一定要和项目用到的技术对上。
  • 第三章系统设计:整体架构、数据流图、数据库设计。
  • 第四章算法设计与实现:偏好分计算、FP-Growth挖掘、特征工程、LightGBM预测模型。
  • 第五章实验与结果分析:数据集介绍、评价指标、对比实验、特征重要度分析、优化前后效果对比。
  • 第六章总结与展望。
  • 参考文献。

6.2 答辩中必被问的几个问题

我的经验是,导师大概率会问这样几类问题:

  • 为什么选择LightGBM作为最终模型,而不是深度学习模型?回答要体现对比实验和可解释性。
  • 你所谓的“算法优化”到底优化了什么?要能讲清楚特征筛选、阈值调整、参数搜索、时间滑动验证四个方向。
  • 数据哪里来的,数据量多少?一定要提前被问烂。
  • 你的模型如果上线,怎么应对用户新数据?给出“每天离线重训一次+每周全量重训一次”的方案,体现出工程思维。
  • 与现有推荐系统相比,你的方法创新点在哪?可以强调“多行为加权偏好分”和“基于关联规则的偏好延展”这两个组合设计,这是整篇论文里有真实增量的小创新。

6.3 论文图表制作与数据呈现

论文里我放了四张核心图表:特征重要度Top30条形图、ROC曲线对比图、PR曲线图、不同阈值下的F1变化图。这些图直接用项目里的matplotlib脚本生成,放在实验章节非常加分。

画ROC曲线时,注意不要直接把验证集所有预测值画在一起,最好按时间分桶画出多条曲线,让读者看出模型在近期窗口和远期窗口的性能差异。我当时画了三档窗口,分别是未来7天、14天、30天,越近的窗口AUC越高,这个结果能很好说明时间衰减偏好特征的有效性。

最后再分享一个我亲测有效的排错技巧

写完整套代码后,我遇到过一个特别隐蔽的问题:模型评估结果每次跑都不一样。排查了很久才发现,是在做数据随机抽样时没有固定random_state,导致每次实验的数据分布都不一样。建议所有涉及随机过程的代码,包括train_test_split、下采样、Optuna搜索、LightGBM的bagging,全部固定随机种子,否则论文里的实验数据无法复现,这在答辩时是致命的。

这个项目做到最后,我最大的体会是:技术选型不在于多前沿,而在于整条研究链路能不能自洽,每个模块有没有存在的必要。从数据清洗到偏好挖掘再到预测优化,每一步都要能回答清楚“为什么这么做”。当你能把这些讲明白的时候,毕业设计就已经成功了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询