基于协同过滤的租房推荐系统设计与实现——Python+Django实战解析

发布时间:2026/10/21 23:16:33
基于协同过滤的租房推荐系统设计与实现——Python+Django实战解析 每年到了毕业设计选题季节最常被问到的就是“做什么题目既好过又能学到东西”。如果你正琢磨着把Python、推荐算法、Web框架凑到一个项目里那“基于协同过滤的租房推荐系统”这个方向确实值得认真考虑一下。它既有算法含量的体现又有Web工程的可视化呈现数据层面还能撑起“大数据分析”的描述一套组合拳打下来无论用于课程设计还是毕业设计从开题到答辩都拿得出手。这篇文章我就从零开始拆解这个系统的完整实现思路。说句实在话这类项目网上同名源码不少但真正把协同过滤算法讲清楚、把Django工程细节写到位的并不多。为了让你少踩几个坑我会把需求拆分、算法核心、模型设计、可视化接入以及常见的报错和排查经验一并整理出来你可以把它当成一份可以直接动手跟做的实操笔记。1. 项目定位与整体设计思路1.1 为什么选“租房推荐”作为毕设方向租房的本质是“在特定价格区间和地理范围内找一套合适的房子”这个场景非常适合套用推荐系统。大多数同学选电商推荐或电影推荐这些题目太常见答辩老师看一眼目录就知道是抄的框架。租房推荐有几个天然优势房源数据好解释字段直观包括价格、户型、区域、面积、朝向、楼层、标签。用户行为数据丰富一个租客在平台上的搜索、浏览、收藏、预约看房、最终下单每个动作都能映射成评分数据。推荐结果容易验证系统推荐出来的楼盘如果落在用户关注的价格段和区域附近合理性一眼就能看出来。另外一个重要原因是租房市场天然带有强地域属性与价格敏感特征这为协同过滤算法提供了天然的稀疏但高密度局部数据结构。你可以在答辩时说“房源数据具有长尾分布和地域聚集特征”这句话本身就是一个加分项。1.2 功能模块与技术选型拆解一个完整的租房推荐系统核心模块可以划分为四层数据层用户表、房源表、行为记录表评分/收藏/浏览、相似度结果缓存表。算法层构建用户-房源评分矩阵通过协同过滤算法计算相似度生成TopN推荐列表。应用层Django Web框架包含用户注册登录、房源展示、搜索筛选、详情页、收藏、在线评分、推荐结果展示。可视化层后台统计面板通过图表展示房源分布、价格区间、推荐热门、用户活跃度等数据指标。技术选型上Python语言、Django框架、MySQL或SQLite数据库、Pandas做数据处理、Scikit-learn或手写协同过滤算法再加上ECharts做前端图表展示这套组合在易用性和答辩可讲性之间达到了很好的平衡妥妥是一个五脏俱全的小型数据应用项目。之所以不用FastAPI或Flask是因为Django自带Admin后台、ORM和用户认证体系这些功能在毕业设计中几乎是刚性的需求。与其自己搭轮子实现登录和后台管理不如直接依赖框架自带能力把精力集中在算法层和业务层上。1.3 推荐链路与数据流转整个系统推荐链路的业务流程是这样走的用户注册并登录系统完善自己的偏好信息比如预算区间、意向区域、期望户型。用户的每一次浏览、收藏、评分行为都会落到行为记录表。算法模块定时或在用户请求推荐时构建评分矩阵计算用户与用户之间的相似度。根据相似用户的评分历史预测当前用户对未看过的房源的评分。过滤掉用户已经评分或已经排除的房源生成TopN推荐结果。可视化模块读取统计聚合数据生成图表展示在后台面板。这条链路保证了系统的完整性从数据采集、算法推导到结果展示全部打通而且每一个环节都有对应的代码文件和表结构支撑答辩时讲解起来很清晰。2. 协同过滤算法核心实现2.1 用户评分矩阵的构建协同过滤的基础是评分矩阵行是用户列是房源值代表用户对房源的评分。如果用户没有对某套房源产生过行为对应位置默认为0或空值。实际开发中用户不可能对大量房源评分直接让用户打分体验很差所以一般用行为映射评分。我的做法是定义这样一套映射规则浏览房源一次得1分浏览重复只计一次。收藏房源得3分。预约看房得5分。完成租房模拟动作得10分也可以归一化为5分制。这样做的好处是把原始的稀疏行为日志转化成了有语义的评分数据。如果你觉得这套规则说服力不够还可以加一个时间衰减因子用户昨天的行为比一个月前行为权重高更贴近实际场景。构建评分矩阵时需要注意数据量的问题。假设系统里有10个用户和200套房源评分矩阵就是10×200数据量很小。如果你自己伪造了1000个用户和500套房子矩阵规模也就50万级别内存完全可以承受。需要注意的是真实生产环境下推荐系统面临的是千万级甚至亿级矩阵但毕业设计不需要处理那类规模你可以在答辩时提一句“本系统针对小规模数据做了优化大规模数据场景可采用矩阵分解或引入Spark、Flink等分布式计算框架”点到即止反而显得你有架构视野。2.2 余弦相似度与UserCF计算流程协同过滤分为基于用户和基于物品两大类这里我先把基于用户的UserCF讲透。UserCF的思路归纳起来是“人以群分”。两个用户如果对同一批房子的评分很接近那么他们就是相似用户我们可以把A用户喜欢的房源推荐给B用户。相似度计算最常用的是余弦相似度公式是用户u和用户v在评分向量上的余弦夹角值。实现起来并不复杂import numpy as np def cosine_similarity(user_vector, other_vector): # 只取双方都有评分的维度 mask (user_vector 0) (other_vector 0) if not mask.any(): return 0.0 u user_vector[mask] v other_vector[mask] dot np.dot(u, v) norm_u np.linalg.norm(u) norm_v np.linalg.norm(v) if norm_u 0 or norm_v 0: return 0.0 return dot / (norm_u * norm_v)拿到用户相似度之后预测用户u对房源p的评分做法是找到与u最相似的K个用户这些用户对p有过评分然后计算加权平均分。def predict_score(user_id, house_id, sim_matrix, score_matrix, top_k5): sim_scores sim_matrix[user_id] similar_users np.argsort(sim_scores)[-top_k:] total_sim 0 weighted_sum 0 for v in similar_users: if score_matrix[v, house_id] 0 and sim_scores[v] 0: weighted_sum sim_scores[v] * score_matrix[v, house_id] total_sim sim_scores[v] if total_sim 0: return 0 return weighted_sum / total_sim经过这步计算每一个用户对所有未看过的房源都会得到一个预测评分。选出最高分的N套房子再进行过滤比如去掉用户明确排除的户型、超过预算价格的房子剩下的就是推荐列表。2.3 ItemCF与UserCF的取舍既然有了UserCF那什么时候用ItemCF这里我说一下两者的实际差异。UserCF比较适合用户量偏少、房源较多的小型系统它的推荐结果偏“个性化”能看到相似用户的新偏好。ItemCF更适合用户量大、物品相对稳定的场景它计算的是“物品与物品之间的相似度”推荐时可以结合用户已有行为快速给出“看了A房的人也看了B房”这类结果。在租房场景里用户是频繁变化的群体而房源数据相对稳定从理论上看ItemCF确实有优势。但我在实际开发中综合考量后还是选用了UserCF原因是毕业设计的数据规模下UserCF实现更直观算法流程也更容易在答辩时用图表讲清楚。如果你想让项目更丰富可以同时实现两种算法在接口里设置一个算法切换开关对比推荐效果这属于加分项时间充裕的同学建议做一下。2.4 冷启动问题的实际解法协同过滤有个天然缺陷就是冷启动问题。新用户没有任何行为记录评分矩阵该用户行全是0相似用户根本找不到推荐结果自然为空。房源同理新上架的房源因为没有用户评分永远不会被推荐出去。我在项目中用了几条比较实用的对策针对新用户注册阶段强制选择偏好标签包括预算范围、意向区域、期望户型推荐阶段先用这些标签做规则匹配生成“猜你喜欢”的初始列表。针对新房源设置一个“新盘专区”或者给刚上架30天的房源加固定热度加成。兜底策略如果协同过滤计算出的推荐列表为空自动返回全站热门房源Top10按浏览量加收藏量排序。这些策略不复杂但能保证任何用户打开推荐页面都有内容可看测评时不会出现空白页面这在验收时的体验分提升上是决定性的。3. Django工程落地与关键编码细节3.1 数据模型设计与表结构Django的ORM让数据建模变得非常直观。我的models.py中自定义了用户表、房源表、用户行为表外加一个用于存储相似度矩阵的缓存表。from django.db import models from django.contrib.auth.models import User class House(models.Model): title models.CharField(max_length128) price models.IntegerField() # 月租金单位元 area models.FloatField() # 面积单位平方米 region models.CharField(max_length32) # 所属区域 layout models.CharField(max_length32) # 户型如 2室1厅 orientation models.CharField(max_length16) # 朝向 tags models.CharField(max_length200, blankTrue) # 标签逗号分隔 image models.ImageField(upload_tohouses/, blankTrue) is_active models.BooleanField(defaultTrue) created_at models.DateTimeField(auto_now_addTrue) class UserBehavior(models.Model): user models.ForeignKey(User, on_deletemodels.CASCADE) house models.ForeignKey(House, on_deletemodels.CASCADE) action_type models.CharField(max_length16) # view/favorite/appoint/rent score models.FloatField(default0) created_at models.DateTimeField(auto_now_addTrue)把用户行为做成一张独立的表既是日志又参与评分计算设计上比较干净。第一次初始化系统时你可以写一个数据迁移脚本把房源Excel表批量导入数据库用户行为数据可以用脚本模拟添加几千条保证算法有数据可跑。3.2 推荐逻辑与用户行为采集落地推荐模块我单独放在一个名为recommend的App中向外暴露一个get_recommendations(user_id)的接口函数。内部流程是从UserBehavior表取全量行为数据构造评分矩阵。计算用户相似度矩阵如果缓存表存在且版本未变直接读取缓存避免重复计算。对当前用户执行预测评分。排除用户已经互动过的房源按预测评分排序取TopN。用户点击房源详情时要在views.py里记录浏览行为这一步骤很关键但经常被忽略。我的做法是在详情页视图函数里针对登录用户写入一条action_type为view的记录并在同一视图里取一次推荐结果追加到模板上下文。这样用户看完详情页直接在页面下方看到“为您推荐的其他房源”链路完整且用户体验顺滑。注意用户行为写入时同一个用户对同一套房源多次浏览应该做去重否则评分矩阵会被刷爆推荐结果也会偏向浏览频次高的房源失去真实参考价值。3.3 管理后台与数据初始化Django自带的Admin后台是个隐藏的效率神器。我自定义了Admin配置把房源表、用户行为表、算法参数表都注册进去表头列表页可以直接进行搜索和筛选还可以用导入导出插件导入初始房源数据。在Admin里调整算法参数非常方便比如你想要修改TopN的N值或者修改最小相似用户数阈值只需要在系统设置页面改配置项不需要改代码重启服务。这个功能实现起来也不难class SystemConfig(models.Model): key models.CharField(max_length64, uniqueTrue) value models.CharField(max_length256)管理员在后台修改参数后推荐模块读取配置再执行计算整个算法流程就变成了可以动态调节的配置化引擎。答辩现场演示时你可以现场把N值从5改成8然后刷新推荐页面观察结果变化这种互动效果非常有说服力。3.4 数据处理与Pandas的高效操作在构建评分矩阵时纯Python写循环虽然能跑通但代码冗长又容易出错。我的建议是引入Pandas辅助处理。从UserBehavior表取出全部数据后转成DataFrame做pivot操作就能直接得到用户-房源评分矩阵import pandas as pd from .models import UserBehavior def build_score_matrix(): queryset UserBehavior.objects.values(user_id, house_id, score) df pd.DataFrame(list(queryset)) # 如果有重复记录取最大值 df df.groupby([user_id, house_id]).agg({score: max}).reset_index() matrix df.pivot(indexuser_id, columnshouse_id, valuesscore).fillna(0) return matrix运行效率上这种方法处理几百个用户和几千套房源游刃有余代码量也少读起来逻辑非常清楚。答辩时如果老师问到“数据预处理怎么做的”这个答案比手写双层循环更能说明问题。4. 可视化面板与数据指标呈现4.1 可视化要展示哪些核心指标可视化部分是项目门面也是很多人忽略的地方。我的观点是推荐系统核心不能只看算法准确率还要通过可视化手段把数据特征和推荐效果呈现给用户和管理员。前端首页交给用户看的主要是推荐列表而后台数据看板我建议包含以下四类图表房源区域分布图柱状图展示各区房源数量与平均租金。户型比例图饼图展示一居、两居、三居占比。租金区间统计直方图展示500-1500、1500-2500、2500-4000等区间房源数。热度排行榜展示收藏量最高和推荐命中率最高的Top10房源。4.2 ECharts接入与数据聚合实现ECharts是目前最稳妥的前端图表库选择不需要额外引包路径简单配置就能生成漂亮图表。在Django中接入方式也很顺手在页面模板中引入ECharts的CDN资源。后端写一个返回JSON数据的视图接口数据用Pandas聚合后转成列表。前端用Ajax请求接口数据动态渲染图表。[views.py中核心聚合逻辑]def chart_data(request): data House.objects.filter(is_activeTrue).values(region, price, layout) df pd.DataFrame(list(data)) region_count df.groupby(region).size().to_dict() price_bins pd.cut(df[price], bins[0, 1500, 2500, 4000, 8000]) price_stat price_bins.value_counts().to_dict() payload { region: [{name: k, value: v} for k, v in region_count.items()], price: [{range: str(k), count: v} for k, v in price_stat.items()], } return JsonResponse(payload)一个接口返回多组聚合数据前端只请求一次就能完成所有图表渲染比逐个接口请求更高效。4.3 热词标签与词云点缀除了常规统计图表一个小的亮点是加入标签词云。房源表中有一个tags字段记录“近地铁”“朝南”“精装”“独立卫浴”“可短租”“业主直租”等标签。后端对全部房源标签做分词统计计算每个词频并输出给前端生成词云图。词云图放在首页底部或者数据分析页面视觉冲击力很强而且让“大数据”的感觉直观地呈现出来。配合房源标题里的热门关键词还可以延伸出一个“当前城市找房热词”的模块。整个可视化部分做出来之后系统的完整度和完成度会提升一个档次答辩时的印象分自然就上去了。5. 常见问题与排查经验实录5.1 评分矩阵稀疏导致相似度全为零这是最常遇到的问题。模拟数据时如果用户量有50个房源有300套每个用户的行为记录只有三到五条那么用户之间共同评过分的房源几乎没有余弦相似度为0推荐结果自然为空。排查思路很简单先打印评分矩阵的非零值分布统计一下稀疏度。上线前尽量保证每个用户至少有5到10条行为记录。如果真实数据不足可以写一个仿真脚本模拟用户按偏好集中浏览某些区域的房源人为构造一些相似群体。5.2 推荐结果跑偏的调试技巧如果推荐出来的房型和用户关注的区域完全不相关先说结论大概率是评分映射规则有问题。比如浏览行为的分数权重太低收藏和预约的分数权重太高导致少数几次收藏行为完全主导了推荐结果将用户偏好带偏了。换个角度说用户收藏可能是顺手收藏并不代表真正想租。调试时我习惯把各类行为的分数权重做成可调参数在后台设置页面就能改然后不断测试对比推荐列表的变化调到合理范围为止。常见的一组能用的初始值是浏览1分、收藏4分、预约8分、成交10分。5.3 推荐响应速度的优化用户点击推荐页面时如果实时计算全量相似度矩阵响应时间可能会达到2到3秒甚至更久体验不太好。我给出的优化方案是双轨制落地页第一次访问用户时推荐结果用缓存表保存之后定时刷新。比如每日凌晨2点更新一次推荐结果缓存。对于活跃用户的实时请求只计算该用户与全量用户的相似度其余用户间相似度矩阵从内存中读取。这种方法实测下来能把推荐接口的响应压缩到300毫秒以内完全满足毕设演示要求。关于缓存一个关键点当用户产生新的收藏行为后缓存可能已过期但还没到更新时机推荐列表不会立刻反映最新偏好。我加了一个中间方案在用户行为被写入的同时如果该行为是分数较高的收藏或者看房则自动清除该用户对应的推荐缓存并在当前请求结束后异步更新该用户的推荐结果。5.4 答辩演示时容易忽略的细节讲几个演示时特别容易翻车的点提前准备好能省掉很多尴尬。第一演示数据库里要有足够的模拟用户数据至少不要只有你自己测试的两个账号否则推荐结果很单调展示不出算法效果。我建议预置30个模拟用户、200套房源、2000条行为记录数据规模刚刚好。第二项目启动前先跑一次推荐结果生成脚本检查一下有没有房源图片路径失效或者模板中字段引用错误。很多时候演示现场出错不是算法问题而是模板变量名写错这种低级问题。第三如果评委让你现场演示推荐系统效果提前准备一个专门用来演示的账号这个账号的行为记录已经造好登录后推荐列表直接刷新可见不需要现场临时找房源“养数据”。第四图片文件不要用超大原图建议统一转换成WEBP格式或者压缩为800像素宽既加快加载速度又能让界面整齐美观。室内实拍图配上统一的尺寸在演示时视觉效果最稳定。最后再说一个防坑提示整个项目在做数据迁移时注意处理一下中文字段和数据库编码的问题。Django默认设置的编码正常但如果你从Excel导入房源数据时读取的中文出现乱码多半是文件编码和数据库连接配置不一致统一设置UTF-8后重新导入即可。整体来说这个项目无论从技术完整度还是演示效果上看都是毕业设计里性价比很高的方向。只要算法核心是自己写的不是为了跑通而照搬答辩时把UserCF的每一步推导讲明白老师很难问倒你。在实际操作中我最深的体会是真正把推荐结果调到合理、能看出个性化差异的阶段才算完成了一个闭环单纯把代码跑通只是起点。如果你手头也正在搭这套系统建议把重点放在评分规则的合理性和推荐结果的直观解释性上这两点做到了项目就立住了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询