1. 项目概述
这个旅游推荐系统项目是我去年带队完成的一个企业级大数据应用案例。当时我们接到某OTA平台的需求,要解决用户在旅游产品选择时的"信息过载"问题——平台上百万级的酒店、景点、路线数据让普通用户根本无从下手。传统基于规则的推荐效果差强人意,我们决定构建一个基于用户行为数据的智能推荐系统。
系统架构上,我们采用"数据采集-存储计算-算法应用"的三层设计。爬虫模块负责实时抓取多源异构数据,Hadoop集群处理海量非结构化数据,Spark MLlib实现推荐算法。最终上线的系统使该平台转化率提升了37%,推荐准确度达到89.2%。
2. 核心技术栈解析
2.1 分布式爬虫架构
我们设计的爬虫系统需要应对三个特殊挑战:
- 反爬策略:旅游平台普遍采用动态渲染+行为验证
- 数据异构:包含结构化价格、半结构化评论、非结构化图片
- 实时性要求:节假日期间价格波动频繁
解决方案:
- 采用Scrapy-Redis分布式架构,部署20个节点
- 动态渲染使用Selenium集群(注意资源消耗)
- 验证码破解服务单独部署(成本约$0.1/千次)
- 数据标准化管道设计:
class TourismItem(scrapy.Item): price = Field(output_processor=PriceNormalizer()) comments = Field(input_processor=CommentExtractor()) images = Field(output_processor=ImageCompressor())2.2 Hadoop与Spark的协同计算
数据流程设计中的关键决策点:
| 处理阶段 | Hadoop适用场景 | Spark适用场景 |
|---|---|---|
| 原始数据存储 | HDFS分片存储 | 不适用 |
| 日志清洗 | MapReduce批处理 | Spark Streaming实时处理 |
| 特征工程 | 不适用 | MLlib特征转换 |
| 模型训练 | 不适用 | GraphX协同过滤 |
实际部署时我们遇到HDFS小文件问题(每天产生200万+图片文件),最终采用HAR归档方案将存储空间减少62%。
3. 推荐算法实现细节
3.1 混合推荐策略
系统采用三种算法混合:
- 基于内容的推荐(景点画像匹配)
- 协同过滤(用户行为相似度)
- 时空上下文推荐(节假日/地理位置)
核心算法代码片段:
val hybridModel = new WeightedHybridModel() .setContentWeight(0.3) .setCFWeight(0.5) .setContextWeight(0.2) val recs = hybridModel .setUserFeatures(userDF) .setItemFeatures(poiDF) .setContext(context) .recommendForUsers(10)3.2 冷启动解决方案
针对新用户/新景点的冷启动问题,我们设计了两阶段策略:
- 注册问卷收集基础偏好(3-5道选择题)
- 利用知识图谱补全特征:
- 景点层级:城市->商圈->品类
- 用户层级:人口统计->消费能力->旅行史
4. 性能优化实战
4.1 Spark调优关键参数
在生产环境遇到的典型性能问题及解决方案:
# executor内存溢出 spark.executor.memoryOverhead=2g # 数据倾斜处理 spark.sql.shuffle.partitions=200 spark.default.parallelism=100 # 广播join优化 spark.sql.autoBroadcastJoinThreshold=50mb4.2 缓存策略设计
根据数据访问特征采用三级缓存:
- Redis缓存实时推荐结果(TTL 15分钟)
- Alluxio缓存特征数据
- HDFS冷数据归档
缓存命中率从最初的68%提升至92%后,平均响应时间从1.4s降至320ms。
5. 踩坑实录与解决方案
5.1 数据质量陷阱
遇到的典型数据问题:
- 价格单位不统一(人民币/美元/泰铢)
- 景点同名不同地(全国32个"中山公园")
- 虚假评论检测(刷单水军识别)
我们的数据治理方案:
- 建立旅游领域本体库
- 设计多维度验证规则:
CREATE RULE price_sanity_check AS WHEN item_price > 3 * avg_category_price THEN severity = 'critical' - 搭建数据质量监控看板
5.2 算法效果波动
节假日期间出现的推荐异常:
- 春节期间的酒店推荐出现大量误判
- 国庆节前景点推荐集中度过高
解决方案:
- 引入节假日因子特征
- 设计时间衰减函数:
def time_decay(days): return 0.5 ** (days/7) # 半衰期1周 - 建立AB测试分流机制
这个项目给我的深刻体会是:旅游领域的实时推荐系统必须同时考虑算法精度和工程实效。我们后来将核心架构抽象成了可复用的推荐中台,目前已经支撑了公司3个业务线的推荐场景。对于想入门推荐系统的同学,建议先从MovieLens这样的小数据集开始,理解清楚协同过滤的本质后再接触工业级系统。