简介:基于数据挖掘的个人服装推荐系统毕业设计资源包,面向计算机科学相关专业毕业论文与课程设计场景。系统采用B/S架构,后端以Django框架与Python语言实现,使用MySQL存储数据,通过Scrapy爬取淘宝女装等服装信息,借助Echarts进行可视化,并运用协同过滤算法根据用户历史行为生成推荐。管理员可统一管理用户、服装商城、社交互动、订单及优惠券等模块,功能覆盖整站常用业务。整套资源共640个文件,压缩包约31.46MB,包含Vue前端页面、JavaScript交互、Python后端代码、SQL数据库脚本、PNG/JPG图片素材、SVG图标、多类型辅助文件及bat快捷启动脚本,还可看到LW论文文档与初始化数据库脚本,目录结构清晰,便于运行调试和二次开发。已有118人学习下载,适合需要完整参考实现、理解推荐流程或快速搭建毕设演示环境的高校学生。
1. 系统整体思路与推荐方案选型
1.1 需求拆解:毕设题目背后到底要做什么
“基于数据挖掘的个人服装推荐系统设计与实现”这个题目,拿到手第一眼感觉挺常规,但拆开看其实是有几个层次的要求在里面的。数据挖掘是手段,服装推荐是业务场景,个人化是核心目标,代码加数据库加LW(论文文档)是交付物,四者缺一不可。很多同学栽在“只做了推荐却没体现数据挖掘过程”这个误区上。
实际做的时候,我把它拆成了三条主线:一是数据层的处理,包括服装数据的采集、清洗、特征工程,这是数据挖掘的“前戏”;二是算法层的设计,包括用户相似度计算、物品相似度计算、评分预测与Top-N推荐,这是推荐系统的“心脏”;三是展示层的落地,包括用户登录注册、商品浏览、评分记录、推荐列表展示,这是让评委老师能直观看到效果的“门面”。三条线串起来,整个系统的完整度就出来了。
再聊聊选型。我当时技术栈定的是Python + Flask + MySQL + Bootstrap,前端用简单的Layui或者原生HTML模板都可以。Python负责数据挖掘和推荐算法,Flask负责把算法结果暴露成接口,MySQL存用户、商品、评分数据,Bootstrap兜底页面展示。这套组合最大的优势是每个部分都有大量现成资料,遇到问题搜一下就有答案,对毕设党非常友好。别一上来就上SpringCloud那种重型框架,时间和精力都耗不起。
1.2 推荐算法怎么选:协同过滤还是混合推荐
推荐算法这块,教科书上写了一大堆,但毕设里真正实用、能讲清楚原理的,无非就是两大类:基于用户的协同过滤(User-CF)和基于物品的协同过滤(Item-CF)。前者找“和我口味相似的人”,后者找“和我买过的东西相似的东西”。服装推荐场景里,我最终做的是两者融合的混合推荐,简单说就是:User-CF算出来的结果和Item-CF算出来的结果各占一定权重,加权合并后去重输出,同时用基于内容的推荐兜底解决冷启动问题。
为什么这么选?因为只做单一算法,答辩时很容易被追问“如果新用户没有任何行为数据,你怎么推荐”。基于内容的方案恰好能补上这个缺口——新用户注册时先选风格偏好、价位区间,系统根据商品属性和用户画像做初筛推荐,等用户产生评分或点击行为后再切换成协同过滤主导。这个逻辑讲出来,整个系统在技术深度和业务完整性上就都站得住了。
2. 数据库设计与数据预处理
2.1 数据库表结构规划:五张表撑起整套业务
数据库是整套系统的地基,表结构设计出了问题,后面写代码会处处难受。我当时设计了五张核心表,不多不少,刚好覆盖业务闭环。
第一张是用户表(user),字段包含用户ID、用户名、密码(MD5加密存储)、性别、年龄段、偏好风格、注册时间。这里有个容易被忽略的细节:偏好风格字段要设计成支持多选的字符串拼接,比如“休闲,运动,通勤”,而不是单个字段存一个值,这样后面做基于内容的推荐时会省很多事。
第二张是商品表(product),字段包含商品ID、商品名称、所属分类(上装、下装、外套、鞋靴等)、风格标签、价格区间、颜色、适用季节、图片路径、销量、评分均值。商品数据我爬的是公开电商演示数据,大概800条左右,覆盖五六个分类,足够做演示了。每条商品尽量保证风格标签不少于两个,方便后续计算相似度。
第三张是评分表(rating),字段包含评分ID、用户ID、商品ID、评分值(1到5分)、评分时间。这张表是整个推荐算法的数据基础,一定要做主键唯一约束(user_id + product_id联合唯一),避免同一个用户对同一件商品重复评分导致数据异常。
第四张是行为日志表(rating_log),记录用户浏览、收藏、加入购物车等隐式反馈行为。虽然评分表已经能支撑协同过滤,但有了一张行为日志表,论文里可以多写一段“基于隐式反馈的推荐增强”,技术点会更有层次。
第五张是推荐结果表(recommend_result),跑完推荐算法后把结果写进去,前端页面直接查这张表展示。这样做的好处是推荐过程可控、可追溯,还能避免每次请求都实时跑一遍算法导致页面卡顿。
2.2 数据预处理:推荐效果的分水岭
很多同学做完系统才发现推荐结果一塌糊涂,问题往往不是出在算法上,而是出在数据没洗干净。服装数据里最常见的脏数据有这几类:商品价格为0或负数、风格标签为空、图片链接失效、同一商品重复录入、评分数据稀疏到大部分用户只有一两条评分。
我在预处理阶段写了几个核心函数,简单但非常有效。第一步是去重,用商品名称加分类的组合键做去重,保留首次记录。第二步是填充,风格标签为空时根据商品名称里的关键词自动映射,比如名称里含“衬衫”默认补“通勤”,含“T恤”默认补“休闲”。第三步是过滤,评分数据不足5条的用户对应的评分直接剔除,因为数据量太少,算出来的相似度没有统计意义,反而会干扰推荐结果。第四步是归一化,在计算相似度前,对评分矩阵做均值中心化,消除不同用户打分习惯的偏差——有的用户手松全打4分5分,有的用户手紧全是3分,不中心化的话相似度会被带偏。
为了能直观展示数据预处理前后的变化,我写了个统计脚本,每次跑完输出当前表的行数、缺失值数量、用户数、商品数、评分数。这个细节在写论文的时候很好用,直接截两张图对比,数据挖掘的“过程感”就出来了。
3. 推荐核心模块的实现
3.1 基于用户的协同过滤:找同类人,推他们喜欢的东西
User-CF的核心就三步:构建用户-物品评分矩阵、计算用户间相似度、选取Top-N相似用户生成推荐。我用Python的pandas直接操作DataFrame实现,代码结构清晰,答辩也好讲。
相似度计算我采用的是皮尔逊相关系数,公式网上都有,这里说下实现时的关键细节。皮尔逊相关系数比余弦相似度多了均值中心化这一步,能剔除用户打分尺度不同带来的偏差。代码实现时要注意分母的处理——如果两个用户的共同评分项只有一两个,算出来的相关系数可能虚高,我用了一个折中方案:共同评分项少于3个时,相似度乘以0.8的惩罚系数,防止冷门商品对结果的过度影响。
生成推荐时,我取当前用户最相似的K个用户(K一般取10),把这K个用户评分过但当前用户没评分的商品找出来,按相似度加权评分排序,去掉已经买过或者明确不喜欢的商品,取前N个输出。推荐结果存到recommend_result表,前端直接读表渲染。
3.2 基于物品的协同过滤:用“买过A的人也买过B”兜底
Item-CF的逻辑正好反过来,先算商品之间的相似度,再根据用户历史评分的商品去推荐相似商品。两种算法的适用场景不太一样:User-CF适合用户多、物品少的场景,Item-CF适合物品多、用户少的场景。服装商品的品类数量一般远大于用户数,理论上Item-CF效果会更好,但实际测试下来,两者结合往往才是最优解。
商品相似度计算我用了修正余弦相似度。为什么用修正版?因为原始余弦相似度没有考虑用户评分尺度的差异,两个用户一个全打4分以上、一个全打3分以下,对同一件商品的评分虽然绝对数值不同,但相对偏好是一致的,修正余弦会先减去用户均值再计算,精度会好很多。
Item-CF的实际测试效果很有意思:在数据量不大时,User-CF推荐结果比较“泛”,什么类型都有;Item-CF推荐结果则更“聚焦”,推的基本都是同风格或同分类的商品。对服装场景来说,用户的风格偏好往往很明显,Item-CF的聚焦效果观感上更舒服,这也是我最终给Item-CF更高权重的原因。
3.3 冷启动问题与新用户的个性化初筛
冷启动是推荐系统里绕不开的经典问题,新用户没有任何行为数据,协同过滤完全算不了。我的处理方案是在注册页面增加一个“风格偏好选择”的引导页,用户勾选喜欢风格、价位区间、常见穿着场景,系统把这些信息存进user表的偏好字段,然后基于内容推荐来生成初始推荐列表。
基于内容的推荐实现起来比协同过滤简单:把商品的风格标签和用户偏好风格做集合交集计算,再叠加价格区间匹配度,最后按销量排序输出。举个例子,用户偏好“休闲 + 运动 + 100-300元”,系统就会优先推荐同时命中“休闲”和“运动”标签、价格在100到300之间的商品,然后是只命中一个标签的商品,没有命中的商品直接不出现。这样新用户登录后第一眼看到的推荐内容就是有理由可讲的,不是纯随机推荐。
代码实现的时候,我封装了一个recommend_user函数和recommend_item函数,再写了一个total_recommend函数做加权融合。加权系数放配置文件里,方便后面调参。实际调参经验是:Item-CF权重0.5、User-CF权重0.3、基于内容权重0.2,这个组合在演示数据上效果最均衡,推荐列表不会太单一也不会太散。
4. Web端与数据库联动实现
4.1 系统架构与Flask后端搭建
整体架构我采用了经典的B/S三层结构:浏览器发起请求,Flask处理路由和业务逻辑,MySQL存数据。前端页面不算复杂,主要包含登录注册页、首页推荐列表、商品详情页、个人评分页、后台管理页五个核心页面。
Flask的代码组织用的是蓝图(Blueprint)模式,把用户模块、商品模块、推荐模块、管理模块分开写。每个模块独立成一个Python文件,init里统一注册蓝图。这种组织方式的优势很明显:写代码时各模块互不干扰,论文里也方便画架构图分层描述。
数据库连接用的是SQLAlchemy ORM框架,定义好ORM模型后,增删改查不用手写原生SQL,既安全又省事。有一点要提醒:SQLAlchemy默认在访问MySQL时会有连接池和session的管理问题,多线程并发访问时容易报错。我的处理方式是用scoped_session确保每个请求线程拿到独立的session实例,用完及时关闭,这套处理跑完整轮测试没再出问题。
4.2 推荐结果展示与性能优化
推荐结果展示页是整个系统里我最花心思的部分。用户登录后进入首页,顶部是欢迎语和“为我推荐”按钮,下面就是推荐商品卡片列表,每个卡片包含商品图片、名称、风格标签、价格、综合评分,右下角是“喜欢”和“不喜欢”两个按钮,用户点按后直接写入评分表,同时触发一次后台推荐结果的增量更新。
性能优化方面踩过一个小坑:最开始我把推荐算法放在请求里实时运算,结果每次打开首页都要等两三秒,体验很差。后来改成“定时跑批 + 结果缓存”的方案——用户登录后首次请求推荐时,如果recommend_result表里没有该用户的数据,就现场计算并写入;如果已经有了,就直接读表返回。用户对某个商品点击“喜欢”后,触发该用户推荐结果的增量刷新(只重新计算该用户,不重算全局)。这套机制跑下来,页面响应时间从3秒降到了200毫秒以内。
要显示推荐理由的话,可以在recommend_result表里加一个reason字段,记录这条推荐来自“与你有相似喜好的用户偏好”还是“与你喜欢的商品相似”。这个细节答辩时加分很多,实际效果也特别好,用户会感觉系统“懂事”,不是瞎推荐。
4.3 数据库操作与CURD封装
数据库操作这块,我写了一个通用的BaseRepository类,封装了增删改查的基本方法,包括分页查询、条件筛选、排序、批量插入。所有业务模块都继承这个类,避免重复代码。批量插入这个接口特别有用——第一版协同过滤跑完要写几百条推荐结果进recommend_result表,用insert_many比循环逐条insert快了一个数量级。
事务处理也要留心。用户评分这个操作涉及两张表:rating表插入一条评分记录,product表的评分均值字段同步更新。这两个操作必须放在同一个事务里,要么都成功,要么都失败,否则就会出现商品评分均值跟实际评分记录对不上的情况。SQLAlchemy的session.begin()和session.commit()可以实现这种原子性,推荐代码里固定加上。
5. 常见问题与调试实录
5.1 推荐结果不准的排查思路
这是整个系统开发过程中调试时间最长的问题。一开始跑出来的推荐结果怎么都不对——明明喜欢休闲风,推荐列表里却出现了一大堆正装衬衫,查了三天代码,最后定位到三个原因。
第一个原因是数据清洗没过关,商品标签和实际风格存在人工标注错误,比如某件“休闲T恤”被错误标成了“正装”。我的处理方式是手工核对了一批数据,同时加了一层清洗逻辑:名称关键词与标签冲突时以名称关键词为准强制覆盖。第二个原因是相似度计算时没有做均值中心化,导致评分偏好差异被误判为品味差异。这个在前面已经提过,修正后效果立竿见影。第三个原因是Top-N的选择问题,K值取太小会导致推荐列表全是某一个分类的商品,用户觉得系统“不会变通”。我把K值调整到10到15之间,同时强制推荐列表里同一分类的商品不超过40%,效果就正常多了。
5.2 MySQL编码、连接与多线程踩坑
MySQL的编码问题几乎每个新手都会遇到。建表时如果默认字符集是latin1,插入中文商品名称就会直接报错或者乱码。我的解决方案是:建库时明确指定utf8mb4字符集和utf8mb4_unicode_ci排序规则,连接串里也加上charset=utf8mb4参数,双保险,之后再没出过乱码。
另一个常见坑是数据库连接超时。系统跑一段时间后,MySQL默认的wait_timeout会自动断开空闲连接,Flask这边还拿着旧连接去请求就会报“MySQL server has gone away”。处理方式是在SQLAlchemy的engine配置里加上pool_pre_ping=True,每次从连接池取连接前先做一次ping检查,失效连接自动丢弃重建。这个配置几行代码就搞定,却帮我省掉了大量半夜被报警吵醒的烦恼。
5.3 LW(论文文档)写作中容易忽视的技术点
代码写得再漂亮,LW写不好照样影响最终评价。我总结了几条容易踩坑但特别加分的经验。
第一,论文里一定要有数据挖掘全流程的图,包括数据采集、数据清洗、数据集成、数据变换、数据挖掘、模式评估、知识表示七个环节,每步对应到系统里具体做了什么,这条线走下来,整个论文的学术骨架就立住了。第二,算法章节不要光写公式,要配上自己系统里的实际数据演算过程,比如拿三个用户的数据手算一遍相似度,从输入到输出每一步都摆出来,导师看了会觉得你是真懂而不是抄的。第三,测试章节要写清楚评价指标,推荐系统常用的准确率、召回率、覆盖率、F1值,至少算两个指标出来,并解释数值高低代表什么含义。第四,数据库设计里ER图要画规范,表的字段说明、主外键关系、索引设计都得写到,这部分技术含量不高但工作量足,能显著拉高论文的页数。
另外建议代码仓库里的每个函数都写清楚docstring,包括输入参数、输出结果、作用描述,答辩时被追问某个函数做了什么,翻一下文档就能答上来,不会现场手忙脚乱。
6. 实操心得与扩展方向
整套系统从搭建到调试完整体验下来,最大的感受是:推荐系统的效果好不好,七分在数据,三分在算法。数据清洗和特征工程做到位了,即便用最基础的协同过滤也能跑出说得过去的推荐结果;反过来,再花哨的算法喂给一堆脏数据,推荐效果照样不行。这也是为什么我在上面花了大量篇幅讲数据预处理和冷启动处理,这两个点真的是最容易拉开差距的地方。
再分享一个小技巧:调试推荐算法时,一定要建一个“离线评估”脚本。固定一份测试数据集,每次调整算法参数后先跑离线评估,对比准确率和召回率的数值变化,而不是直接上Web页面凭感觉看推荐列表。只有量化对比才能知道你改的每个参数到底是变好了还是变差了,纯靠肉眼判断很容易被主观感受误导。
如果后续想继续扩展这个项目,几个方向可以参考:引入用户的实时点击流数据做在线学习,让推荐结果随着用户行为动态调整;加入深度学习的向量召回,用双塔模型把用户和商品映射到同一个向量空间,再做近邻检索;或者把推荐结果加上“推荐理由”的文案生成模块,让系统解释“为什么推荐这件衣服给你”,这个在业界叫推荐可解释性,也是当前研究热点。毕设阶段把这些方向中的任何一个点到为止,都能让整个课题的技术层次提升不少。
本文还有配套的精品资源,点击获取