完整教程:【Hive】基于物品协同过滤 [ ItemCF ] 推荐课程-余弦相似度计算

news/2025/10/20 10:16:33/文章来源:https://www.cnblogs.com/wzzkaifa/p/19151913

一、项目背景

随着线上教育平台的发展,如何为每位用户智能推荐感兴趣的课程,成为平台提升用户活跃度和学习转化率的关键手段。本文使用某教育平台用户行为数据,基于协同过滤算法构建推荐系统,结合 Hive 思想分层处理数据,最终输出推荐结果。

二、数据介绍

本文基础数据是课程学习信息表:
study_information.csv【课程学习信息表】

字段名含义
user_id用户唯一标识,外键关联 users.csv
course_id课程 ID
course_join_time加入课程的时间
learn_process课程学习进度
price课程价格

三、数据分层存储

第一层 ODS层原始数据存储

创建数据库-上传数据到HDFS上-创建数据表-向数据表中装载数据。

-- 创建ods_prject数据库
CREATE DATABASE IF NOT EXISTS ods_project;
USE ods_project;
-- 创建【课程学习信息表】
CREATE TABLE IF NOT EXISTS ods_study_information (
user_id STRING,
course_id STRING,
course_join_time TIMESTAMP,
learn_process STRING,
price INT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE
TBLPROPERTIES ('skip.header.line.count'='1');
-- 向【用户信息表】中装载数据
LOAD DATA INPATH '/data/ods/study_information.csv' INTO TABLE ods_study_information;
-- 检查数据是否存在
SELECT * FROM ods_study_information limit 10;

第二层 DWD层对ODS层做一定清洗工作

清洗study_information表:

  1. 将learn_process的进度提取,作为课程评分标准。
CREATE TABLE IF NOT EXISTS dwd_study_information (
user_id STRING,
course_id STRING,
course_join_time TIMESTAMP,
learn_process DOUBLE,
price INT
);
INSERT OVERWRITE TABLE dwd_study_information
SELECT
user_id,
course_id,
course_join_time,
CAST(
REGEXP_EXTRACT(learn_process, '([0-9]+)', 1) AS DOUBLE
)/100 AS learn_process,  -- 提取百分数字符并转为数字
price
FROM ods_study_information
WHERE user_id IS NOT NULL;

第三层 DWS汇总所需数据

CREATE TABLE IF NOT EXISTS dws_user_course_progress AS
SELECT
user_id,
course_id,
learn_process
FROM dwd_study_information
WHERE user_id IS NOT NULL AND course_id IS NOT NULL;

四、协同过滤推荐

三种协同过滤类型
本例中使用基于物品的协同过滤,采用余弦相似度计算。具体解释:如果很多用户同时学习了课程A和课程B,且他们在A和B的学习行为(如学习进度)相似,那么A和B就被认为是相似课程,此后对未学习B,但学习A的用户,会优先推荐A。
相较于用户协同过滤,物品协同过滤不会因为用户快速增长导致计算代价巨大,而且物品的相似关系更加稳定,本例更加适用。

相似度计算

方法说明
欧氏/曼哈顿距离主要用于“数值型特征”
余弦相似度适用于高维稀疏向量(如课程学习进度、评分矩阵),忽略绝对值差异
皮尔逊相关系数衡量两个变量的线性相关程度,考虑值的均值中心化,对偏移不敏感。适合评分数据为连续值时使用,比如 1~5 的用户评分。
Jaccard 相似度比较两个集合的交集与并集比,适用于二值型数据(如是否点过赞、是否收藏、是否注册过课程)

本例将推荐系统可用的三个计算方式都进行说明。

余弦相似度

在这里插入图片描述
手算示意原理
构造一个用户-课程矩阵

user_idcourse_Acourse_Bcourse_C
10.90.10.0
21.00.30.4
30.00.20.5

课程AB的相似度
向量:
course_A = [0.9, 1.0, 0.0]
course_B = [0.1, 0.3, 0.2]

高中知识,弄这一块复习了很久。。。

各课程相似度

course_Acourse_Bcourse_C
course_A1.0000.7750.464
course_B0.7751.0000.921
course_C0.4640.9211.000

结论

PYTHON代码

import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
# 读取已经清洗好的CSV(从 Hive 导出)
df = pd.read_csv('cleaned_study_information.csv')
# 1. 创建 用户-课程 学习进度矩阵
pivot = df.pivot_table(index='user_id', columns='course_id', values='learn_process_num').fillna(0)
# 2. 转置为 课程-用户 矩阵,计算课程间相似度(物品协同过滤)
course_user_matrix = pivot.T
similarity_matrix = pd.DataFrame(
cosine_similarity(course_user_matrix), # cosine_similarity:将每行当作一个向量计算余弦相似度
index=course_user_matrix.index,
columns=course_user_matrix.index
)
# 3. 模拟给用户 1 推荐新课程:先拿到用户 1 学过的课程
user_id = '1'
user_vector = pivot.loc[user_id]
# 用户未学习的课程
unlearned_courses = user_vector[user_vector == 0].index
# 推荐分 = 用户已学课程的进度 × 与未学课程的相似度
recommend_scores = {}
for course in unlearned_courses:
# 所有已学习课程与目标课程的相似度
sim_courses = similarity_matrix[course]
learned = user_vector[user_vector > 0]
# 推荐分 = ∑(进度 × 相似度) / ∑(相似度)
score = (learned * sim_courses[learned.index]).sum()
sim_sum = sim_courses[learned.index].sum()
recommend_scores[course] = score / sim_sum if sim_sum != 0 else 0
# 4. 输出推荐结果
recommend_df = pd.DataFrame.from_dict(recommend_scores, orient='index', columns=['recommend_score'])
recommend_df = recommend_df.sort_values(by='recommend_score', ascending=False)
print(recommend_df)

Jaccard相似度概述

在这里插入图片描述

user_idcourse_Acourse_Bcourse_Ccourse_Dcourse_E
111001
210101
301010
410101
501001

用户二推荐B还是D,相似度计算如下:
B\A:1/5=0.2
B\C:0/5=0
B\E:2/5=0.4
B的推荐分:(0.21+01+0.4*1)/(0.2+0.4)=1
D\A:0/4=0
D\C:0/3=0
D\E:0/5=0
D的推荐分:0
此处数据太少,所以才会出现0和1的极端值。

皮尔逊相似度概述

在这里插入图片描述

user_idcourse_Acourse_Bcourse_C
10.90.10.0
21.00.30.4
30.00.20.5

因为皮尔逊是衡量线性相关,所以只有课程AB在同一用户下都有有效观测值才有意义,这就意味着用户3不参与皮尔逊相似度计算。
course_A: [0.9, 1.0]
course_B: [0.1, 0.3]
Ā = (0.9 + 1.0) / 2 = 0.95
B̄ = (0.1 + 0.3) / 2 = 0.2
Pearson(A, B)=[(0.9−0.95)(0.1−0.2)+(1.0−0.95)(0.3−0.2)]/0.0707*0.1414=1.0

五、写在最后

目前推荐系统常用的是矩阵分解而非协同过滤,之所以完成这个项目是因为刚接触数据分析就是这个,因为想有输出所以查找资料发现了矩阵分解,但协同过滤写了过半,不能放弃,就有了这篇文章。
协同过滤的主要缺点:协同过滤无法将两个物品相似这一信息推广到其他物品的相似性计算上。这就导致了一个比较严重的问题:推荐结果的头部效应较明显,可扩展性很差;即热门的物品具有很强的头部效应,容易跟大批物品产生相似性;而尾部的物品由于特征向量稀疏, 很少与其他物品产生相似性,导致很少被推荐。
协同过滤优点是可解释性很高而且适合入门,我将在进入数分行业后深入矩阵分解算法,这里只做简单提及。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/940951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本周精选 - jobleap4u.com - 2025.10.20

本周精选 - jobleap4u.com - 2025.10.20jobleap4u.com给你带来最受欢迎的精选文章。今日热门信息 - jobleap4u.com 内容概览:共 79 篇内容(按发布时间倒序排列,数据源自提供的ArticleCollection) 官方链接:今日热…

Impulse Noise(图像脉冲噪音)的抑制和处理方法(提取自《现代图像处理算法教程》一书并做解释)。

脉冲噪声是影响单个的、随机选择的像素或相邻像素的组合,而不是影响图像的所有像素(这个是高斯噪声的特征),我们传统概念中提到的椒盐噪音其实只是脉冲噪音的一种特例,如何去除这种噪音,本文分享了一些资料。相关…

基于STM32与RS485总线的串口通信

一、硬件架构设计 1. 硬件连接示意图 STM32(F103C8T6) MAX485芯片 LabVIEW PC - - USART1_TX → DI → RO (MAX485) USART1_RX ← RO → DI (MAX485) DE/RE → GPIOA.8 → …

2025 年最新推荐净化工程公司排行榜:聚焦车间 / 实验室 / 无尘车间 / 手术室 / 医院 / 厂房 / 空气 / 医药场景,精选实力企业助力精准选择

引言当前净化工程行业对医疗、电子、食品等众多领域的发展至关重要,其质量直接影响产品品质、生产安全与人员健康。但市场上企业良莠不齐,部分企业技术薄弱、用材劣质,难以满足客户需求,且售后运维服务缺失,给客户…

2025年10月超声波清洗机厂家推荐:十强对比评测榜助您高效选型

一、引言 在精密制造、半导体、光学、汽车、航空等行业,零部件表面洁净度直接决定后续工艺良率与产品寿命。对于采购负责人、设备工程师及创业者而言,如何在预算可控的前提下,选到性能匹配、售后及时、能耗合规的超…

CF2123G Modular Sorting

首先看 \(2\) 操作,不难发现其有最小元,也就是肯定有一个数 \(d\),使得变为对 \(a\) 加 \(d\) 或减 \(d\),能否使其单调不降,比较容易猜出 \(d = \gcd (m, k)\)。 然后考虑一下固定 \(k\) 时怎么做,因为要修改,…

结构体

> 结构体:从声明、初始化、指针数组到零长数组、地址对齐、位段、可移植性、占位符,附堆结构体数组抽卡 Demo + 对齐示意图 。一、结构体基础:声明定义初始化 基本概念C语言提供了众多的基本类型,但现实生活中的…

专栏导航:《数据中心网络与异构计算:从瓶颈突破到架构革命》 - 实践

专栏导航:《数据中心网络与异构计算:从瓶颈突破到架构革命》 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &q…

2025年10月长白山旅游度假酒店推荐:五家热选对比排行与实用评测

一、引言 十月初秋,长白山进入全年色彩最饱和的时段,枫叶与初雪同框,摄影爱好者、亲子家庭、自驾车队、企业团建四方客流叠加,度假酒店成为行程成败的关键节点。对计划2025年10月赴长白山的消费者而言,核心需求集…

CTFHub 信息泄露通关笔记9:Git泄露 Index - 指南

CTFHub 信息泄露通关笔记9:Git泄露 Index - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

2025年10月抗老面霜推荐:小鸟传领衔五强对比评测榜

一、引言 抗老面霜已从“可选”变为25岁以上消费者的“刚需”。熬夜、蓝光、压力叠加,皮肤胶原流失速度提前,细纹、松弛、暗沉同步出现。对精致妈妈、新锐白领、Z世代而言,选对面霜意味着在有限预算内同时解决“紧致…

基于STM32芯片通过CAN总线控制电机运动

一、硬件架构设计 1. 系统组成 STM32主控模块 CAN总线网络 电机驱动模块 ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ STM32F407…

2025 酒店家具厂家最新推荐榜:北木斋领衔五大新锐品牌,品质与创新双优之选全解析

随着酒店行业向高端化、特色化加速升级,家具作为塑造空间格调与入住体验的核心载体,其选型直接影响酒店口碑与运营效益。当前市场中,既有深耕多年的龙头企业,也涌现出大批聚焦细分领域的新锐品牌,然而信息不对称导…

文献阅读笔记格式

Abstract gap: goal: 解决方案的关键: Introduction background:用于支撑的背景知识创新点: Method Experiment result: limitation: Conclusion Inspiration:(你认为可改进的点) 其他: 有用的论点、句子、…

企业AI应用的数据策略 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

深入解析:c++的STL:string类与string类的手动基础实现

深入解析:c++的STL:string类与string类的手动基础实现pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

JS中的值传递和引用传递

JS中的值传递和引用传递 JS没有引用传递 (arguments除外)值传递:内存独立,互不影响引用传递:共享一块内存空间,指向同一个地址var a = {} var b = a b.n = 3 a // {n:3}var a = {} var b = a b = {n:3} a // {…

乐理和蜂鸣器的实现

在学习计算机无源蜂鸣器的发声过程中,想到可以借此机会掌握乐理知识。 B站有一个从零基础讲解的非常好的视频: 20分钟乐理通俗讲解 这里想写一篇博客记录一下学习历程1.首先用Aduino+无源蜂鸣器实现《小星星》的旋律…

CF1288C Two Arrays 分析

题目概述 题目链接:https://www.luogu.com.cn/problem/CF1288C。 长度为 \(m\) 的序列 \(a,b\),值域为 \([1,n]\),求 \((a,b)\) 的数量满足:\(a\) 单调不降。 \(b\) 单调不升。 对于每个 \(i\),满足 \(a_i\leq b_…

基于Java+Springboot+Vue开发的母婴商城管理系统源码+运行步骤

项目简介该项目是基于Java+Springboot+Vue开发的母婴商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过…