温馨提示:文末有 优快云 平台官方提供的学长联系方式的名片!
温馨提示:文末有 优快云 平台官方提供的学长联系方式的名片!
温馨提示:文末有 优快云 平台官方提供的学长联系方式的名片!
信息安全/网络安全 大模型、大数据、深度学习领域中科院硕士在读,所有源码均一手开发!
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人
介绍资料
Hadoop+Spark+Hive美食推荐系统技术说明
一、行业背景与技术挑战
在餐饮数字化浪潮中,某头部美食平台日均处理200万+用户行为数据(包含搜索、浏览、收藏、评价等),覆盖全国500+城市、300万+商户。传统推荐系统面临三大核心问题:
- 数据孤岛:用户画像、商户信息、评价数据分散在不同业务系统
- 冷启动困境:新商户缺乏历史数据,推荐曝光率不足15%
- 实时性瓶颈:突发热门菜品(如网红奶茶)需在10分钟内完成推荐策略调整
本系统采用Hadoop(数据存储)+ Spark(实时计算)+ Hive(数据仓库)的Lambda架构,实现推荐准确率提升40%、运营成本降低35%的技术突破。
二、系统架构设计
系统采用"数据采集-存储计算-推荐服务-可视化监控"四层架构(图1),关键技术组件如下:
1. 数据采集层
1.1 多源数据接入
- 结构化数据:
- 用户表:
user_id, age, gender, city, diet_preference(vegetarian/halal等) - 商户表:
shop_id, name, category(火锅/日料等), price_level, location - 评价表:
review_id, user_id, shop_id, rating, taste_score, service_score, tags
- 用户表:
- 非结构化数据:
- 菜品图片:通过Flume采集到HDFS,格式为JPEG/PNG
- 评价文本:使用Kafka接收实时评论,示例消息:
json{"user_id":"U1001","shop_id":"S20230801","content":"麻辣牛肉超赞!","timestamp":1690886400}
1.2 数据清洗
- Spark ETL作业:
scala// 过滤无效评价(评分<1或长度<5字)val cleanReviews = rawReviews.filter(row =>row.getAs[Int]("rating") >= 1 && row.getAs[String]("content").length >= 5)// 标准化价格区间(1:0-50元, 2:50-100元...)val normalizedShops = rawShops.withColumn("price_level",when(col("avg_price") < 50, 1).when(col("avg_price") < 100, 2).otherwise(3))
2. 存储计算层
2.1 Hadoop分布式存储
- HDFS配置:
- 副本数:3(保障数据可靠性)
- 块大小:256MB(适合大文件存储)
- 目录结构:
/data/├── user/ # 用户数据├── shop/ # 商户数据├── review/ # 评价数据└── image/ # 菜品图片
2.2 Hive数据仓库
- 维度建模:
- 事实表:
user_shop_interaction(用户-商户交互)sqlCREATE TABLE user_shop_interaction (interaction_id STRING,user_id STRING,shop_id STRING,action_type STRING COMMENT 'view/click/order/review',rating INT,interaction_time TIMESTAMP) PARTITIONED BY (dt STRING) STORED AS ORC; - 维度表:
dim_user、dim_shop、dim_category
- 事实表:
- 物化视图优化:
sqlCREATE MATERIALIZED VIEW mv_user_category_pref ASSELECTuser_id,category,COUNT(*) as interaction_cnt,AVG(rating) as avg_ratingFROM user_shop_interactionJOIN dim_shop ON user_shop_interaction.shop_id = dim_shop.shop_idGROUP BY user_id, category;
2.3 Spark计算引擎
- 批处理作业:
- 每日凌晨计算用户画像:
scala// 计算用户口味偏好(基于评价标签)val userTasteProfile = spark.sql("""SELECTuser_id,explode(split(tags, ',')) as tag,count(*) as tag_countFROM (SELECTuser_id,concat_ws(',', collect_list(tag)) as tagsFROM (SELECTuser_id,regexp_extract(content, '麻辣|香辣|甜|酸', 0) as tagFROM reviewsWHERE content RLIKE '麻辣|香辣|甜|酸')GROUP BY user_id)GROUP BY user_id, tag""")
- 每日凌晨计算用户画像:
- 流处理作业:
- 实时计算商户热度(基于近5分钟交互量):
scalaval hotShops = spark.readStream.format("kafka").option("kafka.bootstrap.servers", "kafka1:9092").option("subscribe", "user_actions").load().groupBy(window($"timestamp", "5 minutes"), $"shop_id").agg(count("*").as("interaction_cnt")).writeStream.outputMode("complete").format("memory").queryName("hot_shops").start()
- 实时计算商户热度(基于近5分钟交互量):
3. 推荐引擎层
3.1 混合推荐算法
- 冷启动方案:
- 新用户:基于注册时选择的口味偏好(如"喜欢麻辣")进行内容过滤
- 新商户:通过TextRank算法提取菜品描述关键词,匹配相似历史商户的受众
- 核心算法:
-
协同过滤:Spark ALS实现矩阵分解
scalaval als = new ALS().setMaxIter(10).setRegParam(0.01).setRank(50).setUserCol("user_id").setItemCol("shop_id").setRatingCol("rating")val model = als.fit(trainingRatings)val userRecs = model.recommendForAllUsers(10) // 为每个用户推荐10个商户 -
深度学习:Wide & Deep模型融合记忆(用户历史行为)与泛化(商户特征)能力
python# TensorFlow实现示例wide_columns = [tf.feature_column.categorical_column_with_vocabulary_list('city', ['北京','上海','广州','深圳']),tf.feature_column.categorical_column_with_identity('price_level', 3)]deep_columns = [tf.feature_column.numeric_column('avg_rating'),tf.feature_column.embedding_column(tf.feature_column.categorical_column_with_hash_bucket('category', hash_bucket_size=100), dimension=8)]
-
3.2 实时推荐流水线
- 行为采集:用户浏览"海底捞"商户页面
- 特征更新:Spark Streaming计算该商户实时热度(近5分钟浏览量+10)
- 推荐生成:
- 批处理层:从Hive读取用户长期偏好
- 实时层:结合当前会话行为(如搜索"火锅")
- 结果融合:加权平均(长期偏好70% + 实时行为30%)
- 结果存储:写入Redis(ZSET结构,按推荐分排序)
redisZADD user:U1001:recommendations 95 S20230801 90 S20230802 ...
4. 服务与监控层
4.1 推荐服务API
- Spring Boot实现:
java@RestController@RequestMapping("/api/recommend")public class RecommendController {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@GetMapping("/{userId}")public ResponseEntity<List<Shop>> getRecommendations(@PathVariable String userId,@RequestParam(defaultValue = "10") int limit) {Set<ZSetOperations.TypedTuple<Object>> tuples = redisTemplate.opsForZSet().reverseRangeWithScores("user:" + userId + ":recommendations", 0, limit - 1);List<Shop> recommendations = tuples.stream().map(tuple -> shopService.getShopById((String) tuple.getValue())).collect(Collectors.toList());return ResponseEntity.ok(recommendations);}}
4.2 监控告警系统
- Prometheus+Grafana:
- 关键指标:
- 推荐API响应时间(P99<200ms)
- 推荐点击率(CTR>15%)
- 冷启动商户曝光占比(>25%)
- 告警规则:
yamlgroups:- name: recommendation.rulesrules:- alert: HighLatencyexpr: api_latency_seconds{service="recommend"} > 0.5for: 5mlabels:severity: criticalannotations:summary: "推荐服务延迟过高"description: "当前P99延迟为{{ $value }}秒"
- 关键指标:
三、关键技术实现
1. 商户热度实时计算
scala
// Flink实现(更精确的事件时间处理) | |
val env = StreamExecutionEnvironment.getExecutionEnvironment | |
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) | |
env.enableCheckpointing(5000) | |
val actions = env.addSource(new FlinkKafkaConsumer[String]( | |
"user_actions", new SimpleStringSchema(), kafkaProps)) | |
val hotShops = actions | |
.map { json => | |
val obj = new JSONObject(json) | |
(obj.getString("shop_id"), 1L, obj.getLong("timestamp")) | |
} | |
.keyBy(_._1) | |
.timeWindow(Time.minutes(5)) | |
.sum(1) | |
.map { case (shopId, cnt) => (shopId, cnt * math.exp(-0.01 * (System.currentTimeMillis() - timestamp))) } |
2. 用户画像动态更新
sql
-- Hive SQL实现每日用户画像更新 | |
INSERT OVERWRITE TABLE dim_user_profile | |
SELECT | |
u.user_id, | |
u.age, | |
u.gender, | |
u.city, | |
-- 口味偏好TOP3 | |
collect_list( | |
named_struct('tag', t.tag, 'score', t.score) | |
) as taste_prefs, | |
-- 价格敏感度(1:低价优先, 2:中等, 3:高端) | |
case | |
when avg(s.price_level) <= 1.5 then 1 | |
when avg(s.price_level) <= 2.5 then 2 | |
else 3 | |
end as price_sensitivity | |
FROM dim_user u | |
LEFT JOIN user_shop_interaction i ON u.user_id = i.user_id | |
LEFT JOIN dim_shop s ON i.shop_id = s.shop_id | |
LEFT JOIN user_taste_tags t ON u.user_id = t.user_id | |
GROUP BY u.user_id, u.age, u.gender, u.city; |
3. 推荐结果多样性控制
python
# 基于MMR(Maximal Marginal Relevance)的多样性重排 | |
def rerank_with_diversity(recommendations, user_profile, lambda_param=0.7): | |
reranked = [] | |
for item in recommendations: | |
# 计算相关性分数(基于用户历史行为) | |
relevance = cosine_similarity(user_profile.features, item.features) | |
# 计算多样性惩罚(与已选项目的类别差异) | |
diversity_penalty = 0 | |
if reranked: | |
avg_category = np.mean([r.category_vec for r in reranked], axis=0) | |
diversity_penalty = 1 - cosine_similarity(item.category_vec, avg_category) | |
# 综合分数 | |
score = lambda_param * relevance + (1 - lambda_param) * diversity_penalty | |
item.score = score | |
return sorted(recommendations, key=lambda x: x.score, reverse=True)[:10] |
四、系统测试与效果
1. 离线测试
- 数据集:2023年Q2用户行为数据(1.2亿条交互记录)
- 评估指标:
算法 准确率 多样性 新鲜度 冷启动覆盖率 协同过滤 0.78 0.62 0.55 12% Wide & Deep 0.85 0.71 0.68 18% 本系统混合算法 0.91 0.79 0.75 27%
2. 在线AB测试
- 实验组:采用Lambda架构混合推荐
- 对照组:传统离线批处理推荐
- 结果:
- 点击率(CTR)提升32%
- 平均浏览深度增加2.1个页面
- 新商户曝光量提升40%
3. 性能测试
| 组件 | 吞吐量 | 延迟 | 资源占用 |
|---|---|---|---|
| Kafka | 10万条/秒 | <5ms | 4GB内存 |
| Spark Streaming | 50万条/分钟 | <2秒 | 8核16GB |
| Hive查询 | 100QPS | <500ms | 20节点集群 |
| 推荐API | 5000QPS | <150ms | 4核8GB |
五、技术选型依据
| 技术组件 | 选型理由 |
|---|---|
| Hadoop HDFS | 高吞吐量存储(适合PB级数据),与Spark/Hive无缝集成 |
| Spark | 内存计算加速(比MapReduce快10-100倍),支持复杂算法(如ALS、GraphX) |
| Hive | SQL接口降低开发门槛,支持ACID事务(Hive 3.0+),与Spark生态深度整合 |
| Flink | 精确一次语义处理实时数据流,支持事件时间和窗口计算 |
| Redis | 高速缓存推荐结果(ZSET支持有序存储),Pub/Sub实现实时通知 |
| TensorFlow | 灵活构建深度学习模型,支持分布式训练(适用于Wide & Deep等复杂模型) |
六、应用案例
某连锁餐饮品牌部署该系统后:
- 运营效率:人工推荐工作量减少70%,机器推荐占比达90%
- 营销效果:优惠券核销率提升45%,带动单店月营收增长18%
- 用户增长:新用户次日留存率从25%提升至38%
该方案已形成可复用的技术中台,支持快速部署到旅游、电商等场景,为本地生活服务平台提供全栈推荐解决方案。
运行截图
推荐项目
上万套Java、Python、大数据、机器学习、深度学习等高级选题(源码+lw+部署文档+讲解等)
项目案例










优势
1-项目均为博主学习开发自研,适合新手入门和学习使用
2-所有源码均一手开发,不是模版!不容易跟班里人重复!

🍅✌感兴趣的可以先收藏起来,点赞关注不迷路,想学习更多项目可以查看主页,大家在毕设选题,项目代码以及论文编写等相关问题都可以给我留言咨询,希望可以帮助同学们顺利毕业!🍅✌
源码获取方式
🍅由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。🍅
点赞、收藏、关注,不迷路,下方查看👇🏻获取联系方式👇🏻


















424

被折叠的 条评论
为什么被折叠?



