0
点赞
收藏
分享

微信扫一扫

Android Room 记录一个Update语句不生效的问题解决记录

总结

本系列是机器学习课程的系列课程,主要介绍机器学习中关联规则和协同过滤。

参考

机器学习(三):Apriori算法(算法精讲)

Apriori 算法 理论 重点

MovieLens:一个常用的电影推荐系统领域的数据集

23张图,带你入门推荐系统

本门课程的目标

完成一个特定行业的算法应用全过程:

懂业务+会选择合适的算法+数据处理+算法训练+算法调优+算法融合
+算法评估+持续调优+工程化接口实现

机器学习定义

关联规则

啤酒与尿布

“啤酒与尿布” 的故事相信很多人都听过,年轻爸爸去超市购买尿布时,经常会买点啤酒犒劳自己。因此,沃尔玛将这两种商品进行了捆绑销售,最终获得了更好的销量。

这个故事背后的理论依据就是 “推荐算法”,因为尿布和啤酒经常出现在同一个购物车中,那么向购买尿布的年轻爸爸推荐啤酒确实有一定道理。

关联规则算法

获得啤酒与尿布的关系的一种算法就是关联规则算法

关联规则算法最开始是面向购物篮分析问题:

关联规则 (Association Rules,又称 Basket Analysis) 是形如X→Y的蕴涵式
其中, X和Y分别称为关联规则的先导(antecedent或left-hand-side, LHS)后继(consequent或right-hand-side, RHS)
在这当中,关联规则X→Y,利用其支持度和置信度从大量数据中挖掘出有价值的数据项之间的相关关系。
关联规则解决的常见问题如:“如果一个消费者购买了产品A,那么他有多大机会购买产品B?”以及“如果他购买了产品C和D,那么他还将购买什么产品?”

关联规则定义:

关联规则挖掘过程主要包含两个阶段:

举个栗子🌰说明下

TID牛奶面包尿布啤酒鸡蛋可乐
1110000
2011110
3101101
4111100
5111001

关联规则算法Apriori实现

Apriori算法实现原理

//  尺寸为k的候选项目集
C_k:Candidate itemsets of size k  
//大小为k的频繁项目集
L_k:frequent itemsets of size k  
L1={frequent 1-itemsets}; // 大小为1的频繁项目集
// k从1开始,频繁项目集不为0 
for (k=1;L_k≠0;k++)  
    // 从 L_k频繁项目集 中生成 C_k+1候选项目集
	C_k+1=GenerateCandidates(L_k)  
	// 对于每一个数据库D中的事务t 
	for each transaction t in database do 
	    // 包含在t中的C_k+1中的候选者的增量计数
	    increment count of candidates in C_k+1 that are contained in t 
	endfor 
	// 在 C_k+1中的候选集中找到大于最小支持度的作为L_K+1频繁候选项集 
	L_k+1=candidates in C_k+i with support >= min_sup 
endfor    
return U_kL_k;

协同过滤算法

基于用户的协同过滤

案例:基于用户的协同过滤。

基于物品协同过滤

由于物品整体变化不大,所以这个相似程度不用每天都算,节省计算资源;同时,可以只给某一样商品只备选5个相似商品,推荐时只做这5个相似物品的加权评分,避免对所有商品都进行加权评分,以避免大量计算。这么说有点抽象,还是看一个例子吧。

协同过滤算法案例

构建数据集

# A dictionary of movie critics and their ratings of a small#
critics = {
    'A': {'老炮儿':3.5,'唐人街探案': 1.0},
    'B': {'老炮儿':2.5,'唐人街探案': 3.5,'星球大战': 3.0, '寻龙诀': 3.5,
                  '神探夏洛克': 2.5, '小门神': 3.0},
    'C': {'老炮儿':3.0,'唐人街探案': 3.5,'星球大战': 1.5, '寻龙诀': 5.0,
                     '神探夏洛克': 3.0, '小门神': 3.5},
    'D': {'老炮儿':2.5,'唐人街探案': 3.5,'寻龙诀': 3.5, '神探夏洛克': 4.0},
    'E': {'老炮儿':3.5,'唐人街探案': 2.0,'星球大战': 4.5, '神探夏洛克': 3.5,
                     '小门神': 2.0},
    'F': {'老炮儿':3.0,'唐人街探案': 4.0,'星球大战': 2.0, '寻龙诀': 3.0,
                     '神探夏洛克': 3.0, '小门神': 2.0},
    'G': {'老炮儿':4.5,'唐人街探案': 1.5,'星球大战': 3.0, '寻龙诀': 5.0,
                      '神探夏洛克': 3.5}
    }

STEP1:编写函数计算欧式距离字典数据中两两用户的欧式距离。

from math import sqrt

# Returns a distance-based similarity score for person1 and person2
# 返回 person1 and person2基于距离的相似度
def sim_distance(prefs, person1, person2):
    # Get the list of shared_items
    si = {}
    for item in prefs[person1]:
        if item in prefs[person2]: si[item] = 1
    # if they have no ratings in common, return 0 如果没有共同评分返回0
    if len(si) == 0: return 0
    # Add up the squares of all the differences 所有差异平方相加
    sum_of_squares = sum([pow(prefs[person1][item] - prefs[person2][item], 2)
                          for item in prefs[person1] if item in prefs[person2]])
    return 1 / (1 + sqrt(sum_of_squares))

# 打印'B'对'星球大战'的评分
print(critics['B']['星球大战'])
# 打印相识分数
print(sim_distance(critics, 'A', 'B'))

输出为:
在这里插入图片描述
在STEP1基础上,编写函数依据欧式距离大小以及协同过滤算法(用户)实现电影的推荐。

# Gets recommendations for a person by using a weighted average of every other user's rankings
# 通过加权平均为一个人推荐
def getRecommendations(prefs, person, similarity=sim_distance):
    # 定义两个空字典
    totals = {}
    simSums = {}
    # 对传入的数据进行循环
    for other in prefs:
        # don't compare me to myself
        # 不与自己比较
        if other == person: continue
        # 计算这个人与其它人的评分
        sim = similarity(prefs, person, other)
        # ignore scores of zero or lower
        # 忽略<=0的分数
        if sim <= 0: continue
        # 对过滤后的数据再次遍历
        for item in prefs[other]:
            # only score movies I haven't seen yet
            # 只给没看过的电影打分
            if item not in prefs[person] or prefs[person][item] == 0:
                # Similarity * Score
                # 相似度 * 得分
                totals.setdefault(item, 0)
                totals[item] += prefs[other][item] * sim
                # Sum of similarities
                # 相似度总和
                simSums.setdefault(item, 0)
                simSums[item] += sim
    # Create the normalized list
    # 创建规范化列表
    rankings = [(total / simSums[item], item) for item, total in totals.items()]
    # Return the sorted list
    # 返回排序后的列表
    rankings.sort()
    rankings.reverse()
    return rankings

print(getRecommendations(critics, 'A'))

输出为:
在这里插入图片描述

基于surprise的协同过滤算法实现

电影数据集介绍
在这里插入图片描述数据获取:

MovieLens数据集可以从MovieLens网站上免费下载。不同版本的数据集具有不同的规模和数据量,可以根据研究或应用的需求选择适当的版本。
下载地址:https://grouplens.org/datasets/movielens/

按照依赖:

pip install scikit-surprise

STEP1:导入库
导入surprise库中的算法,数据集,网格搜索。

# 导入库
from surprise import SVD
from surprise import Dataset
from surprise import Reader
from surprise.model_selection import GridSearchCV
import os

STEP2:加载数据集
加载movielens-100K数据集,默认在线下载数据集,也可以加载本地数据
在这里插入图片描述

# 加载 movielens-100K
# 定义推荐数据集文件路径 绑定你的数据集地址
file_path = '/xxx/u.data'
# 指定分隔符
reader = Reader(line_format='user item rating timestamp', sep='\t')
# 导入文件
data = Dataset.load_from_file(file_path, reader=reader)

STEP3:网格搜索
设置网格搜索参数

# 网格搜索
param_grid = {'n_epochs': [5, 10], 'lr_all': [0.002, 0.005],
              'reg_all': [0.4, 0.6]}
gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mae'], cv=3)

STEP4:训练并获得最佳模型

# 训练模型
gs.fit(data)
# 输出最佳RMSE(均方根误差)得分
print('The best RMSE:',gs.best_score['rmse'])
# 输出最佳RMSE得分的参数组合
print('The best params:',gs.best_params['rmse']) 
# 获得最佳算法
algo = gs.best_estimator['rmse']
algo.fit(data.build_full_trainset())

STEP5:模型预测

# 模型预测
uid = str(196)  # 原始user id (在评分文件中的)
iid = str(302)  # 原始item id (在评分文件中的)
#对某一个具体的user和item给出预测
pred = algo.predict(uid, iid, r_ui=4, verbose=True)

STEP6:输出结果解释

The best RMSE 0.9629441271618542
The best params {'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}
user: 196        item: 302        r_ui = 4.00   est = 4.01   {'was_impossible': False}
# 说明:user为用户id,item为项目id,r_ui为真实评分,est为预测评分

推荐系统

推荐系统到底解决的是什么问题

推荐系统的应用场景

哪里有海量信息,哪里就有推荐系统,我们每天最常用的APP都涉及到推荐功能:

推荐系统的应用场景通常采用协同过滤算法

基于协同过滤的推荐算法:

除了关联规则和协同过滤,还有其他一些常见的推荐算法,如基于内容的推荐、基于矩阵分解的推荐、深度学习推荐等。这些算法都有各自的优缺点和适用场景,根据实际需求选择合适的算法进行推荐。

搜索、推荐、广告三者的异同

搜索和推荐是AI算法最常见的两个应用场景,在技术上有相通的地方。这里提到广告,主要考虑很多没做过广告业务的同学不清楚为什么广告和搜索、推荐会有关系,所以做下解释。

推荐系统的整体架构

上面是推荐系统的整体架构图,自下而上分成了多层,各层的主要作用如下:

从数据存储层到召回层、再到融合过滤层和排序层,候选集逐层减少,但是精准性要求越来越高,因此也带来了计算复杂度的逐层增加,这个便是推荐系统的最大挑战。

特征计算由于数据量大,通常采用大数据的离线和实时处理技术,像Spark、Flink等。然后将计算结果保存在Redis或者其他存储系统中(比如HBase、MongoDB或者ES),供召回和排序模块使用。

召回算法的作用是:从海量数据中快速获取一批候选数据,要求是快和尽可能的准。这一层通常有丰富的策略和算法,用来确保多样性,为了更好的推荐效果,某些算法也会做成近实时的。

排序算法的作用是:对多路召回的候选集进行精细化排序。它会利用物品、用户以及它们之间的交叉特征,然后通过复杂的机器学习或者深度学习模型进行打分排序,这一层的特点是计算复杂但是结果更精准。

图解经典的协同过滤算法

协同过滤(Collaborative Filtering,CF)是一个简单同时效果很好的算法,只要你有初中数学的基础就能看懂。协同过滤算法的核心就是「找相似」,它基于用户的历史行为(浏览、收藏、评论等),去发现用户对物品的喜好,并对喜好进行度量和打分,最终筛选出推荐集合,它又包括两个分支:

如何找相似?

Item-CF的算法流程

清楚了相似性的定义后,下面以Item-CF为例,详细说下这个算法到底是如何选出推荐物品的?

从0到1搭建一个推荐系统

有了上面的理论基础后,我们就可以用 Python 快速实现出一个推荐系统。

  1. 选择数据集

这里采用的是推荐领域非常经典的 MovieLens 数据集,它是一个关于电影评分的数据集,官网上提供了多个不同大小的版本,下面以 ml-1m 数据集(大约100万条用户评分记录)为例。

下载解压后,文件夹中包含:ratings.dat、movies.dat、users.dat 3个文件,共6040个用户,3900部电影,1000209条评分记录。各个文件的格式都是一样的,每行表示一条记录,字段之间采用 :: 进行分割。

以ratings.dat为例,每一行包括4个属性:UserID, MovieID, Rating, Timestamp。通过脚本可以统计出不同评分的人数分布:

在这里插入图片描述

  1. 读取原始数据

程序主要使用数据集中的 ratings.dat 这个文件,通过解析该文件,抽取出 user_id、movie_id、rating 3个字段,最终构造出算法依赖的数据,并保存在变量 dataset 中,它的格式为:dict[user_id][movie_id] = rate
在这里插入图片描述

  1. 构造物品的相似度矩阵
    基于第 2 步的 dataset,可以进一步统计出每部电影的评分次数以及电影的共生矩阵,然后再生成相似度矩阵。
    在这里插入图片描述

  2. 基于相似度矩阵推荐物品
    最后,可以基于相似度矩阵进行推荐了,输入一个用户id,先针对该用户评分过的电影,依次选出 top 10 最相似的电影,然后加权求和后计算出每个候选电影的最终评分,最后再选择得分前 5 的电影进行推荐。
    在这里插入图片描述

  3. 调用推荐系统
    下面选择UserId=1 这个用户,看下程序的执行结果。由于推荐程序输出的是 movieId 列表,为了更直观的了解推荐结果,这里转换成电影的标题进行输出。
    在这里插入图片描述

最终推荐的前5个电影为:
在这里插入图片描述

线上推荐系统的挑战

在这里插入图片描述

确定方向过程

针对完全没有基础的同学们
1.确定机器学习的应用领域有哪些
2.查找机器学习的算法应用有哪些
3.确定想要研究的领域极其对应的算法
4.通过招聘网站和论文等确定具体的技术
5.了解业务流程,查找数据
6.复现经典算法
7.持续优化,并尝试与对应企业人员沟通心得
8.企业给出反馈

举报

相关推荐

0 条评论