1. 项目概述
最近完成了一个基于机器学习的租房信息分析系统,采用Python+Django+MySQL技术栈实现。这个项目最初源于我在租房时遇到的实际痛点——面对海量房源信息时难以快速判断价格是否合理、区域是否适合自己。系统整合了房源管理、价格预测、区域分析等核心功能,能够帮助租客和房东更高效地完成租房交易。
系统主要包含8个功能模块:
- 用户认证(登陆/登出)
- 数据总览看板
- 房源CRUD管理
- 基于机器学习的租金预测
- 在线预约看房
- 租后评价系统
- 房源收藏夹
- 区域特征分析
提示:系统采用前后端分离架构,前端使用Vue.js+ElementUI,后端使用Django REST framework提供API服务,机器学习模块使用scikit-learn实现。
2. 技术栈选型与架构设计
2.1 核心技术组件
后端技术栈:
- Django 4.2:选择Django而非Flask的主要考虑是其自带完善的ORM、Admin和Auth系统,适合快速开发业务系统
- Django REST framework 3.14:提供规范的RESTful API支持
- MySQL 8.0:关系型数据库存储结构化数据
- Redis 7.0:缓存热点数据和会话管理
机器学习组件:
- scikit-learn 1.3:实现租金预测模型
- pandas 2.1:数据清洗和特征工程
- joblib 1.3:模型持久化存储
前端技术栈:
- Vue 3.2:前端框架
- Element Plus 2.3:UI组件库
- ECharts 5.4:数据可视化
2.2 系统架构设计
系统采用分层架构设计:
code复制客户端层 → API网关层 → 业务逻辑层 → 数据访问层 → 存储层
关键设计决策:
- 使用JWT进行无状态认证,避免Session存储开销
- 价格预测服务独立部署,通过gRPC与主服务通信
- 区域分析数据每小时通过Celery定时任务更新
- 前端使用CDN加速静态资源加载
3. 核心功能实现细节
3.1 用户认证模块
实现基于JWT的认证流程:
python复制# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(hours=2),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
'ROTATE_REFRESH_TOKENS': True
}
注意:生产环境必须配置HTTPS,避免Token被截获。我们使用了django-cors-headers处理跨域问题。
3.2 房源管理模块
房源数据模型设计:
python复制class House(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
area = models.FloatField() # 面积(㎡)
floor = models.CharField(max_length=50) # 楼层
orientation = models.CharField(max_length=20) # 朝向
district = models.ForeignKey(District, on_delete=models.CASCADE)
subway = models.ForeignKey(Subway, on_delete=models.SET_NULL, null=True)
facilities = models.ManyToManyField(Facility)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
indexes = [
models.Index(fields=['price']),
models.Index(fields=['district']),
models.Index(fields=['subway']),
]
3.3 价格预测模块
3.3.1 特征工程
我们从以下维度提取了26个特征:
| 特征类别 | 具体特征 |
|---|---|
| 房源属性 | 面积、楼层、朝向、装修程度 |
| 区位特征 | 行政区、地铁距离、商圈评分 |
| 周边设施 | 学校、医院、商场数量 |
| 市场因素 | 同区域均价、挂牌时长 |
3.3.2 模型训练
使用XGBoost回归模型:
python复制from xgboost import XGBRegressor
from sklearn.model_selection import train_test_split
# 数据准备
X = df[features]
y = df['price']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 模型训练
model = XGBRegressor(
n_estimators=500,
max_depth=6,
learning_rate=0.05,
subsample=0.8,
colsample_bytree=0.8
)
model.fit(X_train, y_train)
# 评估
score = model.score(X_test, y_test)
print(f'R2 Score: {score:.3f}')
实测在测试集上R²达到0.87,平均绝对误差约300元。
经验:特征工程中"地铁距离"采用对数变换后,模型效果提升显著。建议对距离类特征都进行类似处理。
4. 区域分析实现
4.1 数据聚合方案
sql复制-- 区域价格统计SQL
SELECT
d.name AS district,
COUNT(h.id) AS house_count,
AVG(h.price) AS avg_price,
AVG(h.price/h.area) AS avg_unit_price
FROM
houses_house h
JOIN
houses_district d ON h.district_id = d.id
GROUP BY
d.name
ORDER BY
avg_unit_price DESC;
4.2 可视化实现
前端使用ECharts绘制热力图:
javascript复制// 区域价格热力图
const option = {
tooltip: {
formatter: params => {
return `${params.name}<br/>
均价: ${params.data.value[2]}元/㎡<br/>
房源量: ${params.data.value[3]}套`
}
},
visualMap: {
min: minPrice,
max: maxPrice,
calculable: true,
inRange: {
color: ['#50a3ba', '#eac736', '#d94e5d']
}
},
series: [{
type: 'heatmap',
coordinateSystem: 'bmap',
data: heatData,
pointSize: 10,
blurSize: 5
}]
};
5. 部署方案
5.1 服务器配置
| 服务 | 规格 | 数量 |
|---|---|---|
| Web应用 | 2核4G | 2台(负载均衡) |
| MySQL | 4核8G(SSD) | 主从架构 |
| Redis | 1核2G | 1台 |
| 预测服务 | 4核8G(GPU) | 1台 |
5.2 CI/CD流程
yaml复制# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: |
python manage.py test
- name: Deploy to production
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.PROD_HOST }}
username: ${{ secrets.PROD_USER }}
key: ${{ secrets.PROD_SSH_KEY }}
script: |
cd /var/www/house-system
git pull origin main
pip install -r requirements.txt
python manage.py migrate
systemctl restart gunicorn
6. 踩坑实录与优化建议
6.1 性能优化经验
-
N+1查询问题:
- 错误做法:在房源列表接口中遍历查询每个房源的设施信息
- 解决方案:使用
select_related和prefetch_related
python复制queryset = House.objects.all().select_related( 'district', 'subway' ).prefetch_related( 'facilities' ) -
缓存策略:
- 区域分析数据每小时更新,使用Redis缓存
- 设置合理的缓存过期时间:
cache.set('district_stats', data, timeout=3600)
6.2 机器学习模型优化
-
特征重要性分析:
- 发现"地铁距离"是最重要特征
- 添加"最近3个地铁站的平均距离"作为新特征,模型效果提升2%
-
在线学习:
- 实现模型增量更新机制,每月用新数据fine-tune模型
- 使用joblib保存模型版本,支持快速回滚
6.3 安全防护
-
SQL注入防护:
- 坚持使用ORM或参数化查询
- 定期使用sqlmap进行安全扫描
-
XSS防护:
- 前端使用DOMPurify过滤富文本
- Django模板自动转义特殊字符
7. 扩展方向
-
移动端适配:
- 开发React Native跨平台应用
- 实现扫码看房功能
-
智能推荐:
- 基于用户收藏历史构建推荐系统
- 使用协同过滤算法推荐相似房源
-
租赁市场监测:
- 抓取竞品平台数据
- 构建价格波动预警系统
这个项目从技术选型到最终上线历时3个月,最大的收获是理解了如何将机器学习模型真正落地到业务系统中。特别要注意模型服务化的稳定性问题,我们最终采用了gRPC+健康检查的方案确保服务可用性。