前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于关联规则的每日音乐分享

基于关联规则的每日音乐分享

作者头像
庄闪闪
发布2021-04-09 11:01:14
8870
发布2021-04-09 11:01:14
举报
文章被收录于专栏:庄闪闪的R语言手册

不知道大家用音乐播放器的时候会不会有听“每日推荐”这个歌单的习惯,当你戴着耳机突然切换到一首从未听过但是非常对味的歌,这种感觉是不是超惊喜呀!

这个看起来很复杂的功能,其实由一个简单易懂的算法就可以实现哟,它就是我们今天的C位——基于关联规则的Apriori算法

1 关联规则 简介

关联规则(association rule),顾名思义就是找到事物之间的关联性,可用来寻找大量变量之间有趣的联系。关联规则学习是无监督的,不需要训练算法,也不需要提前标记数据。基于数据集,就可以简单地运行程序。一个典型的规则可以表述为如下形式:

{轻音乐,古典}

{\rightarrow}

{民谣}

这个规则表达的意思就是:如果爱听轻音乐和古典乐,那么很有可能会爱听民谣。大括号内的事物组合表示它们构成一个集合,被称为项集。关联规则是根据项集的子集研究得到的。

2 Apriori算法 简介

Apriori算法采用一个简单的先验准则来减少关联规则的搜索空间:一个频繁项集的所有子集一定是频繁的,一个不频繁的项集的所有父集一定是不频繁的。基于这条规则,可以有效限制搜索规则的次数。例如,如果集合{轻音乐,古典}是频繁的,当且仅当{轻音乐}和{古典}同时频繁地发生。因此,如果轻音乐或者古典中只要有一个是非频繁的,那么任意一个含有这两项的集合都可以从搜索中删除。

3 度量统计量

支持度(

support

):项集在数据中出现的频率,定义公式为:

support(X)=\frac{count(X)}{N}\

置信度(

confidence

):该规则的预测能力或者准确度的度量,定义公式为:

confidence(X{\rightarrow}Y)=\frac{support(X,Y)}{support(X)}\

提升度(

lift

):度量一类事物相对于它的一般选择率,此时被选择的可能性有多大,定义公式为:

lift(X{\rightarrow}Y)=\frac{confidence(X,Y)}{support(Y)}

通过对这些统计量设置阈值并结合Apriori原则,能够大幅度地限制报告的规则数。

4 用Apriori原则创建规则

step 1

:识别所有满足最小支持度阈值的项集。

step 2

:根据满足最小置信度阈值的项集来创建规则。

5 R语言实战

5.1 收集数据

通过对31位同学的调查,获取了他们"我喜爱“歌单里的部分歌手信息,数据集比较小,仅用于算法练习。若需要进行专业的数据分析,可利用工具爬取大量数据。原始的singer.csv文件部分数据如下所示:

5.2 数据准备

事务性数据是无法直接被利用的,为解决此问题采用了一个称为稀疏矩阵的数据结构,稀疏矩阵的每一行表示一个项集,每一列表示项集中的一个事物。

代码语言:javascript
复制
#安装和加载arules程序包
install.packages("arules")
library(arules)
singer<-read.transactions("singer.csv",sep = ",")

如果想查看singer数据集的一些基本信息,可以使用summary()函数,从运行结果中可以看出包含3个或4个事物的项集个数居多,出现频率最高的是“五月天”和“周杰伦”。

代码语言:javascript
复制
> summary(singer)
transactions as itemMatrix in sparse format with
 35 rows (elements/itemsets/transactions) and
 31 columns (items) and a density of 0.1225806 

most frequent items:
   五月天    周杰伦    王力宏 blackpink    林俊杰   (Other) 
       15        15         8         7         7        81 

element (itemset/transaction) length distribution:
sizes
 2  3  4  5  6 
 2 12 14  5  2 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    2.0     3.0     4.0     3.8     4.0     6.0 

使用inspect()函数可以查看稀疏矩阵的内容:

代码语言:javascript
复制
> inspect(singer[1:6])
    items                                    
[1] {方大同,林俊杰,王力宏,五月天,周杰伦}     
[2] {蔡健雅,陈粒,孙燕姿,五月天}              
[3] {blackpink,exo,刘瑞琦,温岚,五月天,周杰伦}
[4] {blackpink,BTS,EXO,ITZY,mino,twice}      
[5] {陈奕迅,林俊杰,田馥甄,五月天}            
[6] {林宥嘉,刘瑞琦,王力宏,五月天,周杰伦}   

要想计算每个歌手的支持度(默认按字母顺序排序):

代码语言:javascript
复制
> itemFrequency(singer)
       Beyond     blackpink           BTS           exo           EXO 
   0.02857143    0.20000000    0.11428571    0.02857143    0.08571429 
         ITZY Justin bieber          mino         twice        八三幺 
   0.05714286    0.02857143    0.02857143    0.05714286    0.08571429 
       蔡健雅          曹格          陈粒        陈奕迅        方大同 
   0.08571429    0.05714286    0.05714286    0.17142857    0.08571429 
       李宇春        林俊杰        林宥嘉        刘瑞琦        刘若英 
   0.11428571    0.20000000    0.08571429    0.11428571    0.14285714 
       刘思鉴        孙燕姿          陶喆        田馥甄        王力宏 
   0.14285714    0.20000000    0.08571429    0.05714286    0.22857143 
         温岚        五月天          伍佰          张杰        张艺兴 
   0.14285714    0.42857143    0.11428571    0.05714286    0.08571429 
       周杰伦 
   0.42857143 
5.3 数据可视化
  • 显示singer数据集中支持度至少为10%的歌手。
代码语言:javascript
复制
itemFrequencyPlot(singer,support=0.1)
  • 根据频率绘制词云图:
代码语言:javascript
复制
Freq<-itemFrequency(singer)
Fre<-as.data.frame(Freq)
Fre$word<-row.names(Fre)
Fre$freq<-Freq
Fre<-Fre[,-1]
wordcloud2(Fre,size=0.4)
  • 通过添加topN参数,限制歌手的具体数量,下图显示了支持度前五的歌手:
代码语言:javascript
复制
itemFrequencyPlot(singer,topN=5)
  • 除了可视化歌手信息,还可以可视化整个稀疏矩阵,矩阵中填充有黑色单元表示在这行中,该列被选择了。例如,第一行有5个黑色单元,表示这个项集中有5个事物。
代码语言:javascript
复制
image(singer)
5.4 寻找规则集

R语言为我们提供了功能强大的apriori()函数,不需要复杂的代码就可实现探寻功能。虽然运行apriori()函数很简单,但是需要我们去寻找合适的支持度和置信度参数,参数设置过高可能会发现没有规则或者找到无用的规则。阈值设置过低可能会导致规则的数量过多,使得算法运行时间变长。

代码语言:javascript
复制
#使用apriori的默认参数值:support=0.1,confidence=0.8
>apriori(singer)
set of 2 rules 

使用默认参数值只找到两条规则,显然是不够的,需要修改参数值。

代码语言:javascript
复制
>singerrules<-apriori(singer,parameter = list(support=0.06,confidence=0.4,minlen=2))
> singerrules
set of 15 rules 
> inspect(singerrules[1:5])
    lhs            rhs         support    confidence coverage  lift count
[1] {刘瑞琦}    => {周杰伦}    0.08571429 0.7500000  0.1142857 1.75 3    
[2] {BTS}       => {blackpink} 0.08571429 0.7500000  0.1142857 3.75 3    
[3] {blackpink} => {BTS}       0.08571429 0.4285714  0.2000000 3.75 3    
[4] {温岚}      => {周杰伦}    0.08571429 0.6000000  0.1428571 1.40 3    
[5] {孙燕姿}    => {五月天}    0.08571429 0.4285714  0.2000000 1.00 3 
5.5 深入分析模型
代码语言:javascript
复制
> summary(singerrules)
set of 15 rules

rule length distribution (lhs + rhs):sizes
 2  3 
12  3 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    2.0     2.0     2.0     2.2     2.0     3.0 

summary of quality measures:
    support          confidence        coverage           lift      
 Min.   :0.08571   Min.   :0.4286   Min.   :0.1143   Min.   :1.000  
 1st Qu.:0.08571   1st Qu.:0.4833   1st Qu.:0.1571   1st Qu.:1.167  
 Median :0.11429   Median :0.5714   Median :0.2000   Median :1.556  
 Mean   :0.13143   Mean   :0.6156   Mean   :0.2286   Mean   :1.903  
 3rd Qu.:0.15714   3rd Qu.:0.7083   3rd Qu.:0.2286   3rd Qu.:2.333  
 Max.   :0.22857   Max.   :1.0000   Max.   :0.4286   Max.   :3.750  

mining info:
   data ntransactions support confidence
 singer            35    0.06        0.4

在我们找到的规则集中,有12个规则包含2位歌手,3个规则包含3位歌手。

代码语言:javascript
复制
> inspect(singerrules[1:3])
    lhs            rhs         support    confidence coverage  lift count
[1] {刘瑞琦}    => {周杰伦}    0.08571429 0.7500000  0.1142857 1.75 3    
[2] {BTS}       => {blackpink} 0.08571429 0.7500000  0.1142857 3.75 3    
[3] {blackpink} => {BTS}       0.08571429 0.4285714  0.2000000 3.75 3   

第一条规则简单意思就是“如果一个用户喜欢听刘瑞琦的歌,那么她还会听周杰伦的歌。”其支持度大约为0.0857,置信度为0.75,我们可以确定该条规则涵盖了大约8.57%的用户,而且涉及“刘瑞琦”收听的正确率为75%。这条规则也是存在一定合理逻辑的,刘瑞琦就是因为翻唱周杰伦的歌出名,听完翻唱觉得歌不错再去听原唱也是很有可能的。

常受关注的是高支持度、高置信度的规则,但如果大多数或者所有规则都非常接近最小阈值,那我们还需要关注规则的提升度,

lift(A{\rightarrow}B)>1

,这意味着这两类歌手同时出现在用户喜爱歌单里比只出现一位歌手更常见。因此,一个大的提升度值是一个重要的指标,它表明一个规则是很重要的,反映了事物之间的真实联系。

代码语言:javascript
复制
> inspect(sort(singerrules,by="lift")[1:4])
    lhs                rhs         support    confidence coverage 
[1] {BTS}           => {blackpink} 0.08571429 0.7500000  0.1142857
[2] {blackpink}     => {BTS}       0.08571429 0.4285714  0.2000000
[3] {五月天,周杰伦} => {王力宏}    0.11428571 0.5714286  0.2000000
[4] {王力宏}        => {周杰伦}    0.22857143 1.0000000  0.2285714
    lift     count
[1] 3.750000 3    
[2] 3.750000 3    
[3] 2.500000 4    
[4] 2.333333 8  

当你需要找到包含“周杰伦”的所有规则时,可以利用subset()函数:

代码语言:javascript
复制
> sub<-subset(singerrules,items %in% "周杰伦")
> inspect(sub)
    lhs                rhs      support    confidence coverage  lift    
[1] {刘瑞琦}        => {周杰伦} 0.08571429 0.7500000  0.1142857 1.750000
[2] {温岚}          => {周杰伦} 0.08571429 0.6000000  0.1428571 1.400000
[3] {王力宏}        => {周杰伦} 0.22857143 1.0000000  0.2285714 2.333333
[4] {周杰伦}        => {王力宏} 0.22857143 0.5333333  0.4285714 2.333333
[5] {周杰伦}        => {五月天} 0.20000000 0.4666667  0.4285714 1.088889
[6] {五月天}        => {周杰伦} 0.20000000 0.4666667  0.4285714 1.088889
[7] {王力宏,周杰伦} => {五月天} 0.11428571 0.5000000  0.2285714 1.166667
[8] {王力宏,五月天} => {周杰伦} 0.11428571 1.0000000  0.1142857 2.333333
[9] {五月天,周杰伦} => {王力宏} 0.11428571 0.5714286  0.2000000 2.500000
5.6 保存数据
代码语言:javascript
复制
#将关联规则保存到文件
write(singerrules,file = "singerrules.csv",sep=",",quote=T,row.names=F)

生成的表格如下所示:

代码语言:javascript
复制
#将关联规则保存到数据框
> singerframe<-as(singerrules,"data.frame")
> singerframe
                         rules    support confidence  coverage     lift
1         {刘瑞琦} => {周杰伦} 0.08571429  0.7500000 0.1142857 1.750000
2         {BTS} => {blackpink} 0.08571429  0.7500000 0.1142857 3.750000
3         {blackpink} => {BTS} 0.08571429  0.4285714 0.2000000 3.750000
4           {温岚} => {周杰伦} 0.08571429  0.6000000 0.1428571 1.400000
5         {孙燕姿} => {五月天} 0.08571429  0.4285714 0.2000000 1.000000
6         {陈奕迅} => {五月天} 0.11428571  0.6666667 0.1714286 1.555556
7         {林俊杰} => {五月天} 0.11428571  0.5714286 0.2000000 1.333333
8         {王力宏} => {周杰伦} 0.22857143  1.0000000 0.2285714 2.333333
9         {周杰伦} => {王力宏} 0.22857143  0.5333333 0.4285714 2.333333
10        {王力宏} => {五月天} 0.11428571  0.5000000 0.2285714 1.166667
11        {周杰伦} => {五月天} 0.20000000  0.4666667 0.4285714 1.088889
12        {五月天} => {周杰伦} 0.20000000  0.4666667 0.4285714 1.088889
13 {王力宏,周杰伦} => {五月天} 0.11428571  0.5000000 0.2285714 1.166667
14 {王力宏,五月天} => {周杰伦} 0.11428571  1.0000000 0.1142857 2.333333
15 {五月天,周杰伦} => {王力宏} 0.11428571  0.5714286 0.2000000 2.500000

总结

看完文章是不是发现Apriori算法很好理解呢,通过设置兴趣度的最小阈值就可以去搜寻事物之间的关联模式,一个典型的应用实例就是“购物篮分析”,赶紧动动小手去实践一下吧~需要数据可在公众号后台回复命令关联规则数据即可。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 庄闪闪的R语言手册 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 关联规则 简介
  • 2 Apriori算法 简介
  • 3 度量统计量
  • 4 用Apriori原则创建规则
  • 5 R语言实战
    • 5.1 收集数据
      • 5.2 数据准备
        • 5.3 数据可视化
          • 5.4 寻找规则集
            • 5.5 深入分析模型
              • 5.6 保存数据
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档