商品亲和性分析与关联规则挖掘

商品亲和性分析

亲和性分析根据样本个体之间的关系,确定它们关系的亲疏。它主要根据两个指标统计商品之间的亲和性:

  • 支持度:支持度指的是数据集中规则应验的次数。(商品交易中同时买A商品和B商品的交易数量【支持度也可以为次数/交易总量】)
  • 置信度:置信度代表的是规则的准确性如何。(既买A商品又买B商品的数量除以买A商品的数量)

首先,我们使用Pandas读取数据集:

import pandas as pd
from itertools import combinationsfeatures = ["bread", "milk", "cheese", "apple", "banana"]
df = pd.read_csv("affinity_dataset.txt", sep="\s+",header=None, names=features)
df.head()


数据集下载链接:https://pan.baidu.com/s/1rmgqvXeo8kCA-G89Cck7fw 密码:t3bu

也可以通过以下代码生成随机数据:

import numpy as npX = np.c_[np.random.random(100) < 0.3, np.random.random(100) < 0.5,np.random.random(100) < 0.2, np.random.random(100) < 0.25,np.random.random(100) < 0.5]
X[X.sum(axis=1) == 0, 4] = 1
print(X[:5])
np.savetxt("affinity_dataset.txt", X, fmt="%d")

每一行代表每一条交易包含的商品,0代表没有购买,1代表购买。

下面我们首先计算出所有商品A和商品B之间的支持度(同时买A商品和B商品的交易数量):

data = []for i, j in combinations(range(df.shape[1]), 2):support = df.iloc[:, [i, j]].all(axis=1).sum()data.append((i, j, support))data.append((j, i, support))
data = pd.DataFrame(data, columns=["A", "B", "support"])
data.A = pd.Categorical.from_codes(data.A, features)
data.B = pd.Categorical.from_codes(data.B, features)
data.head()

支持度也可以为次数/交易总量:

data['support2'] = data.support/df.shape[0]
data.head()

下面计算置信度(既买A商品又买B商品的数量除以买A商品的数量)。

首先我们计算出每个商品被购买的总次数:

num_occurances = df.sum()
num_occurances
bread     27
milk      46
cheese    41
apple     36
banana    59
dtype: int64

然后再来计算置信度:

data["confidence"] = data.support/num_occurances[data.A].values
data.head()
ABsupportsupport2confidence
0breadmilk140.140.518519
1milkbread140.140.304348
2breadcheese40.040.148148
3cheesebread40.040.097561
4breadapple50.050.185185

下面我们排序获取支持度前5的数据:

data.sort_values(["support", "confidence"], ascending=False, inplace=True)
data.head()
ABsupportsupport2confidence
16cheesebanana270.270.658537
17bananacheese270.270.457627
15applecheese250.250.694444
14cheeseapple250.250.609756
18applebanana210.210.583333

这就是商品的亲和性分析,对于分析商品两两之间的关系非常简单高效,但也很有局限性,例如不能挖掘出关联度很高的三个以上的商品,这时我们就可以使用相对复杂的关联规则模型来处理。

基于关联规则的Apriori算法

Agrawal等人在1993年提出关联规则的概念后,又在1994年提出了基于关联规则的 Apriori 算法,至今 Apriori 仍是关联规则挖掘的重要算法。

关联规则挖掘用于发现项与项(item 与 item)之间的关系,例如从消费者交易记录中发掘商品与商品之间的关联关系,进而通过商品捆绑销售或者相关推荐的方式带来更多的销售量。

Apriori算法的三个基本指标是:

  • 支持度:1个或多个商品组合出现的次数,或与总次数之间的比例。
  • 置信度: 购买A商品的订单中,同时购买B商品的订单比例。
  • 提升度:提升度 (A→B)= 置信度 (A→B)/ 支持度 (B)

注意:Apriori算法中支持度和置信度的概念与亲和性分析中支持度和置信度的概念含义几乎相同。

关联规则中的支持度、置信度和提升度

下面是5名客户购买的商品列表,我们以以下数据为例来说明这三个指标的具体概念:

data = [('牛奶', '面包', '尿布'),('可乐', '面包', '尿布', '啤酒'),('牛奶', '尿布', '啤酒', '鸡蛋'),('面包', '牛奶', '尿布', '啤酒'),('面包', '牛奶', '尿布', '可乐')]

将其转换为与前面商品亲和性分析时一致的数据形式:

import pandas as pd
import numpy as np
from itertools import chain,combinationscolumns = pd.Index(chain(*data)).unique()
zero_matrix = np.zeros((len(data), len(columns)), dtype='int8')
for i, rows in enumerate(data):t = columns.get_indexer(rows)zero_matrix[i, t] = 1
df = pd.DataFrame(zero_matrix, columns=columns)
df

支持度

支持度指的是某个商品组合出现的次数,或与总次数之间的比例。支持度越高,代表这个组合出现的频率越大。

在亲和性分析中,我们只计算K=2的情况,在关联规则挖掘中,k=N的情况都需要计算。

下面我们一次性计算K=N各种情况下的支持度:

rule = []
for k in range(1, len(columns)+1):for keys in combinations(columns, k):value = df.loc[:, keys].all(axis=1).sum()if value > 0:rule.append((k, keys, value))
rule = pd.DataFrame(rule, columns=["k", "rule", "support"])
rule['support2'] = rule.support/df.shape[0]
rule.sample(7)

获取支持度查询字典,方便后面计算:

support = rule.set_index("rule").support2

置信度

置信度是个条件概念,即在 A 发生的情况下,B 发生的概率是多少。

即购买了商品A的订单中,同时购买商品B的订单比例。

置信度(A→B)=支持度(A,B)/支持度(A)

例如,置信度(牛奶→啤酒)= 支持度(牛奶,啤酒)/支持度(牛奶):

support[('牛奶', '啤酒')]/support[('牛奶',)]
0.5

置信度(啤酒→牛奶)= 支持度(牛奶,啤酒)/支持度(啤酒):

support[('牛奶', '啤酒')]/support[('啤酒',)]
0.6666666666666667

提升度

提升度代表的是“商品 A 的出现,对商品 B 的出现概率提升的”程度。

提升度 (A→B)= 置信度 (A→B)/ 支持度 (B)=支持度(A,B)/支持度(A)/支持度(B)

提升度 (B→A)= 置信度 (B→A)/ 支持度 (A)=支持度(A,B)/支持度(B)/支持度(A)

因此,提升度 (A→B)=提升度 (B→A)=支持度(A,B)/支持度(A)/支持度(B)

这个公式是用来衡量 A 出现的情况下,是否会对 B 出现的概率有所提升:

  1. 提升度 (A→B)>1:代表有提升;
  2. 提升度 (A→B)=1:代表有没有提升,也没有下降;
  3. 提升度 (A→B)<1:代表有下降。

例如,提升度(牛奶→啤酒)=提升度(啤酒→牛奶)=支持度(牛奶,啤酒) / 支持度(牛奶)/ 支持度(啤酒):

support[('牛奶', '啤酒')]/support[('牛奶',)]/support[('啤酒',)]
0.8333333333333334

提升度(可乐→尿布)=支持度(可乐,尿布)/支持度(可乐)/支持度(尿布):

support[('尿布', '可乐')]/support[('可乐',)]/support[('尿布',)]
1.0

Apriori 算法的简介与工具使用

项集叫做itemset,它可以是单个的商品,也可以是商品的组合。

频繁项集是支持度大于等于最小支持度 (Min Support) 阈值的项集,非频繁项集就是支持度小于最小支持度阈值的项集。

Apriori 算法就是查找频繁项集 (frequent itemset) 的过程。

Apriori 算法的递归流程:

  1. K=1,计算 K 项集的支持度;
  2. 筛选掉小于最小支持度的项集;
  3. 如果项集为空,则对应 K-1 项集的结果为最终结果。
    如果项集不为空,K=K+1,回到第一步重复执行。

假设指定最小支持度是 50%,最终得到的全部频繁项集为:

itemset = rule.query("support2>=0.5")
itemset

efficient-apriori工具包可以很方便的使用Apriori 算法,使用如下命令安装:

pip install efficient-apriori

下面使用efficient-apriori计算最小支持度是50%的频繁集项:

from efficient_apriori.itemsets import itemsets_from_transactionsitemsets, num_trans = itemsets_from_transactions(data, min_support=0.5)
print("总条数:",num_trans)
itemsets
总条数: 5
{1: {('牛奶',): 4, ('面包',): 4, ('尿布',): 5, ('啤酒',): 3},2: {('尿布', '牛奶'): 4, ('尿布', '面包'): 4, ('牛奶', '面包'): 3, ('啤酒', '尿布'): 3},3: {('尿布', '牛奶', '面包'): 3}}

下面根据频繁集项和最低置信度要求生成频繁规则:

from efficient_apriori.rules import generate_rules_apriorirules = list(generate_rules_apriori(itemsets, min_confidence=0.5, num_transactions=num_trans))
rules
[{牛奶} -> {尿布},{尿布} -> {牛奶},{面包} -> {尿布},{尿布} -> {面包},{面包} -> {牛奶},{牛奶} -> {面包},{尿布} -> {啤酒},{啤酒} -> {尿布},{牛奶, 面包} -> {尿布},{尿布, 面包} -> {牛奶},{尿布, 牛奶} -> {面包},{面包} -> {尿布, 牛奶},{牛奶} -> {尿布, 面包},{尿布} -> {牛奶, 面包}]

当然也可以一次性将频繁项集和频繁规则都计算出来:

from efficient_apriori import aprioriitemsets, rules = apriori(data, min_support=0.5,  min_confidence=0.5)
print(itemsets)
print("-----")
print(rules)
{1: {('牛奶',): 4, ('面包',): 4, ('尿布',): 5, ('啤酒',): 3}, 2: {('尿布', '牛奶'): 4, ('尿布', '面包'): 4, ('牛奶', '面包'): 3, ('啤酒', '尿布'): 3}, 3: {('尿布', '牛奶', '面包'): 3}}
-----
[{牛奶} -> {尿布}, {尿布} -> {牛奶}, {面包} -> {尿布}, {尿布} -> {面包}, {面包} -> {牛奶}, {牛奶} -> {面包}, {尿布} -> {啤酒}, {啤酒} -> {尿布}, {牛奶, 面包} -> {尿布}, {尿布, 面包} -> {牛奶}, {尿布, 牛奶} -> {面包}, {面包} -> {尿布, 牛奶}, {牛奶} -> {尿布, 面包}, {尿布} -> {牛奶, 面包}]

不过efficient_apriori包对数据形式有特殊要求,假如我们需要将文章开头商品亲和性分析所用到的数据集进行关联规则挖掘,需要对数据进行一定的转化:

features = ["bread", "milk", "cheese", "apple", "banana"]
df = pd.read_csv("affinity_dataset.txt", sep="\s+",header=None, names=features)
df.head()

mask = df.columns
data = [tuple(mask[rows == 1]) for rows in df.values]
data[:5]
[('cheese', 'apple', 'banana'),('bread', 'milk', 'apple'),('bread', 'cheese', 'apple'),('cheese', 'apple', 'banana'),('milk', 'banana')]

然后就可以通过efficient-apriori包计算频繁项集和频繁规则:

itemsets, rules = apriori(data, min_support=0.2,  min_confidence=0.1)
print(itemsets)
print("-----")
print(rules)
{1: {('banana',): 59, ('apple',): 36, ('cheese',): 41, ('milk',): 46, ('bread',): 27}, 2: {('apple', 'banana'): 21, ('apple', 'cheese'): 25, ('banana', 'cheese'): 27}}
-----
[{banana} -> {apple}, {apple} -> {banana}, {cheese} -> {apple}, {apple} -> {cheese}, {cheese} -> {banana}, {banana} -> {cheese}]

FP-Growth算法

简介与工具包使用

FP-Growth算法是基于Apriori改进的关联挖掘的算法,Apriori 在计算的过程有哪些缺点呢?

  1. 采用排列组合的方式,可能产生大量的候选集。
  2. 每次计算每个项集的支持度都需要重新扫描数据集。

FP-Growth算法的特点是:

  1. 创建了一棵 FP 树来存储频繁项集,在创建前对不满足最小支持度的项进行删除。
  2. 整个生成过程只遍历数据集 2 次。

当然 Apriori 的改进算法除了 FP-Growth 算法以外,还有 CBA 算法、GSP 算法,本文只介绍FP-Growth算法。

FP-Growth算法的原理较为复杂,下面我们先直接使用现有的包pyfpgrowth,直接使用FP-GROWTH算法进行关联规则挖掘。

安装:pip install pyfpgrowth

pyfpgrowth计算最小支持度是20%的频繁集项(pyfpgrowth的支持度用的是数量):

import pyfpgrowth as fppatterns = fp.find_frequent_patterns(data, int(0.2*df.shape[0]))
patterns
{('bread',): 27,('apple', 'banana'): 21,('apple', 'cheese'): 25,('cheese',): 41,('banana', 'cheese'): 27,('milk',): 46,('banana',): 59}

pyfpgrowth计算最小支持度是10%的频繁规则:

fp.generate_association_rules(patterns, 0.1)
{('banana',): (('cheese',), 0.4576271186440678),('cheese',): (('banana',), 0.6585365853658537)}

再计算另一个基础示例:

data = [('牛奶', '面包', '尿布'),('可乐', '面包', '尿布', '啤酒'),('牛奶', '尿布', '啤酒', '鸡蛋'),('面包', '牛奶', '尿布', '啤酒'),('面包', '牛奶', '尿布', '可乐')]
patterns = fp.find_frequent_patterns(data, int(0.5*len(data)))
patterns
{('可乐',): 2,('可乐', '面包'): 2,('可乐', '尿布'): 2,('可乐', '尿布', '面包'): 2,('啤酒', '面包'): 2,('啤酒', '尿布', '面包'): 2,('啤酒', '牛奶'): 2,('啤酒', '尿布', '牛奶'): 2,('啤酒', '尿布'): 3,('牛奶',): 4,('尿布', '牛奶'): 4,('牛奶', '面包'): 2,('尿布', '牛奶', '面包'): 2,('面包',): 4,('尿布', '面包'): 4,('尿布',): 5}
fp.generate_association_rules(patterns, 0.5)
{('可乐',): (('尿布', '面包'), 1.0),('面包',): (('尿布',), 1.0),('可乐', '尿布'): (('面包',), 1.0),('可乐', '面包'): (('尿布',), 1.0),('尿布', '面包'): (('牛奶',), 0.5),('啤酒', '尿布'): (('牛奶',), 0.6666666666666666),('啤酒', '面包'): (('尿布',), 1.0),('牛奶',): (('尿布', '面包'), 0.5),('啤酒', '牛奶'): (('尿布',), 1.0),('尿布', '牛奶'): (('面包',), 0.5),('尿布',): (('面包',), 0.8),('牛奶', '面包'): (('尿布',), 1.0)}

FP-Growth算法的原理

整体过程如下:

  1. 创建项头表,对于满足最小支持度的单个项(K=1项集)按照支持度从高到低进行排序,同时删除不满足最小支持度的项。
  2. 构造 FP 树,根节点记为NULL节点,再次扫描数据集,对于每一条数据,按照支持度从高到低的顺序进行创建节点(项头表中的排序结果),并更新节点计数和项头表的链表。
  3. 通过 FP 树挖掘频繁项集,具体的操作运用“条件模式基”

FP Tree数据结构

FP-Growth 算法涉及的数据结构包括三部分:

  1. 项头表:

    里面记录了所有的1项频繁集出现的次数,按照次数降序排列。比如上图中B在所有10组数据中出现了8次,因此排在第一位。

  2. FP Tree:

    它将原始数据集映射到了内存中的一颗FP树

  3. 节点链表:

    所有项头表里的1项频繁集都是一个节点链表的头,它依次指向FP树中该1项频繁集出现的位置。这样做主要是方便项头表和FP Tree之间的联系查找和更新。

项头表的建立

假设有10条数据,设置支持度为20%,第一次扫描数据并对1项集计数,发现F,O,I,L,J,P,M, N都只出现一次,支持度低于20%的阈值,直接删除。剩下的A,C,E,G,B,D,F按照支持度的大小降序排列,组成了项头表。

接着第二次扫描数据,对于每条数据剔除非频繁1项集,并按照支持度降序排列。比如数据项ABCEFO,里面O是非频繁1项集,因此被剔除,只剩下了ABCEF。按照支持度的顺序排序,它变成了ACEBF。

整体步骤:第一次扫描数据,得到所有频繁一项集的的计数。然后删除支持度低于阈值的项,将1项频繁集放入项头表,并按照支持度降序排列。第二次扫描数据,将读到的原始数据剔除非频繁1项集,并按照支持度降序排列。

FP Tree的建立

首先将FP树的根节点设置为null,然后读入第一条数据ACEBF作为一条独立的路径插入到FP树中,所有节点计数为1, 项头表通过节点链表链接上对应的新增节点:

接着插入数据ACG,由于ACG和现有的FP树可以有共有的祖先节点序列AC,因此只需要增加一个新节点G,将新节点G的计数记为1。同时A和C的计数加1成为2。对应的G节点的节点链表也要更新:

用同样的办法更新后面8条数据:

至此,FP树的建立完成。

整体步骤:逐条读入排序后的数据集,按照排序后的顺序插入FP树中,排序靠前的节点是祖先节点,而靠后的是子孙节点。如果有共用的祖先,则对应的公用祖先节点计数加1。插入后,如果有新节点出现,则项头表对应的节点会通过节点链表链接上新节点。直到所有的数据都插入到FP树后,FP树的建立完成。

FP Tree的挖掘

整体步骤:得到了FP树和项头表以及节点链表,首先要从项头表的底部项依次向上挖掘。对于项头表对应于FP树的每一项,要找到它的条件模式基。所谓条件模式基是以要挖掘的节点作为叶子节点所对应的FP子树。得到这个FP子树,将子树中每个节点的的计数设置为叶子节点的计数,并删除计数低于支持度的节点。通过条件模式基就可以递归挖掘得到频繁项集。

先从最底下的F节点开始,寻找F节点的条件模式基,由于F在FP树中只有一个节点,因此候选就只有下图左所示的一条路径,对应{A:8,C:8,E:6,B:2, F:2}。接着将所有的祖先节点计数设置为叶子节点的计数,即FP子树变成{A:2,C:2,E:2,B:2, F:2}。一般条件模式基可以不写叶子节点,因此最终的F的条件模式基如下图右所示:

通过这个条件模式基很容易得到F的频繁2项集为{A:2,F:2}, {C:2,F:2}, {E:2,F:2}, {B:2,F:2}。递归合并二项集,得到频繁三项集为{A:2,C:2,F:2},{A:2,E:2,F:2},…还有一些频繁三项集。最大的频繁项集为频繁5项集,为{A:2,C:2,E:2,B:2,F:2}

D节点有两个叶子节点比F节点复杂一些。首先得到的FP子树如下图左,接着将所有的祖先节点计数设置为叶子节点的计数,即变成{A:2, C:2,E:1 G:1,D:1, D:1},此时E节点和G节点由于在条件模式基里面的支持度低于阈值被删除掉,最终在去除低支持度节点并不包括叶子节点后D的条件模式基为{A:2, C:2}。通过它,可得到F的频繁2项集为{A:2,D:2}, {C:2,D:2}。递归合并二项集,得到频繁三项集为{A:2,C:2,D:2}。D对应的最大的频繁项集为频繁3项集。

同样的方法可以得到B的条件模式基如下图右边,递归挖掘到B的最大频繁项集为频繁4项集{A:2, C:2, E:2,B:2}:

G的条件模式基如下图右边,递归挖掘到G的最大频繁项集为频繁4项集{A:5, C:5, E:4,G:4}:

E的条件模式基如下图右边,递归挖掘到E的最大频繁项集为频繁3项集{A:6, C:6, E:6}。

C的条件模式基如下图右边,递归挖掘到C的最大频繁项集为频繁2项集{A:8, C:8}。

A的条件模式基为空,因此不用去挖掘。

至此得到了所有的频繁项集,从上面的分析可以看到,最大的频繁项集为5项集。包括{A:2, C:2, E:2,B:2,F:2}。

案例:挖掘导演是如何选择演员的

接下来我们打算通过关联规则挖掘,分析导演选择演员的规律。

下面以张黎导演为例,首先在豆瓣爬取所需的数据:

豆瓣爬虫

打开https://search.douban.com/movie/subject_search?search_text=%E5%BC%A0%E9%BB%8E&cat=1002 ,爬取张黎导演的演员信息。

每条数据的最后一行是电影的演出人员的信息,第一个人员是导演,其余为演员姓名。姓名之间用“/”分割。显然不是演出人员的信息不是以张黎开头的,都不是张黎导演的电影,应该直接跳过。

由于 https://search.douban.com/movie/subject_search
页面使用了动态加载的方式,常规的Js分析很难一口气找到规律,这里直接用 selenium,比较方便。

selenium需要pip安装,我当前电脑未安装谷歌游览器,所以使用了PhantomJS。

Selenium和相应驱动的安装方法详见:https://blog.csdn.net/as604049322/article/details/114157526

from selenium import webdriver
from urllib.parse import quote
import time
from lxml import etree
import pandas as pd
from efficient_apriori import aprioridirector = '张黎'
start = 0
url_template = 'https://search.douban.com/movie/subject_search?search_text={}&cat=1002&start={}'
driver = webdriver.PhantomJS()
result = []
while start < 1000:url = url_template.format(quote(director), start)print(url)start += 15driver.get(url)time.sleep(1)html = driver.find_element_by_xpath("//*").get_attribute("outerHTML")html = etree.HTML(html)movie_list = html.xpath("//div[@class='item-root']//div[@class='detail']")for movie in movie_list:name = movie.xpath(".//a[@class='title-text']/text()")actors = movie.xpath("./div[@class='meta abstract_2']/text()")# 不是目标导演导演的电影则跳过if len(actors) == 0 or not actors[0].startswith(director):continueresult.append((name[0].replace("\u200e ", ""),actors[0].replace(" ", "")[len(director)+1:]))if len(movie_list) < 14:break
df = pd.DataFrame(result, columns=["name", "actors"])
# 清空演员为空的
df = df.query("actors!=''")
df
https://search.douban.com/movie/subject_search?search_text=%E5%BC%A0%E9%BB%8E&cat=1002&start=0
https://search.douban.com/movie/subject_search?search_text=%E5%BC%A0%E9%BB%8E&cat=1002&start=15
https://search.douban.com/movie/subject_search?search_text=%E5%BC%A0%E9%BB%8E&cat=1002&start=30

这样就爬到了张黎导演的电影,所选的演员有哪些,豆瓣的数据或许不全,但基本是够用了。

data = df.actors.str.split("/").to_list()
print(data)
[['陈宝国', '黄志忠', '王庆祥', '倪大红', '祝希娟', '徐光明', '张志坚', '郭广平'], ['王冰', '吕中', '马少骅', '孙淳', '李光洁', '孙宁', '徐敏', '郑天庸'], ['韩晓军', '沈严', '刘海波', '滕华涛', '林妍', '曹盾', '刘江', '姚晓峰', '李宁', '汪俊', '程源海', '彭三源', '杨文军', '杨阳', '张嘉益', '周一围', '谭卓', '张天爱', '何蓝逗', '梅婷', '雷佳音', '倪妮'], ['孙红雷', '黄志忠', '吕中', '孙淳', '张恒', '杨雪', '郑玉', '柯蓝'], ['成龙', '赵文瑄', '李冰冰', '胡歌', '孙淳', '姜武', '陈冲', '余少群'], ['杨洋', '张天爱', '吴尊', '王丽坤', '释小龙', '柳岩', '索笑坤', '董晴'], ['文章', '李雪健', '宋佳', '张歆怡', '刘韦伯', '矢野浩二', '汤晶媚', '柳岩'], ['张嘉益', '宋佳', '胡歌', '张歆怡', '黄志忠', '张可佳', '马浩博', '吕聿来'], ['姜文'], ['陈坤', '辛芷蕾', '王学圻', '吕中', '张宥浩', '芦芳生', '张子健', '包文婧'], ['杨洋', '张天爱', '吴尊', '王丽坤', '释小龙', '柳岩', '索笑坤', '董晴'], ['张国立', '宋佳', '张铮', '朱雨辰', '白庆琳', '周恒乐', '杨婷婷', '吴越'], ['黄伟', '罗晋', '焦俊艳', '李宗翰', '李光洁'], ['王学圻', '刘蓓', '王彤', '李光洁', '薛山', '李易祥', '张岩', '吴秀波'], ['刘淼淼', '朱刚日尧', '宋佳', '陈兵', '周一围', '孙淳', '王学圻', '衣珊', '党浩予'], ['刘淼淼', '段奕宏', '宋佳', '黄志忠', '袁文康', '柯蓝', '刘立伟', '练练', '程枫'], ['马伊琍', '王茂蕾', '文章', '谭凯', '刘文治', '黄志忠', '李强', '王劲松'], ['王雷'], ['刘淼淼', '宋佳', '谷智鑫', '郭涛', '耿乐', '张志坚'], ['牛犇', '纪玲', '魏伟', '封顺', '颜彼得'], ['王学圻', '刘仲元', '辛明', '王建成', '唐棣'], ['王丽萍', '黄志忠', '柏寒', '范伟', '王珞丹', '林雨申'], ['张博涵', '穆克代斯', '买政尧', '李东鹏']]

关联规则挖掘

爬到了演员列表信息后,我就可以通过FP-Growth算法挖掘张黎导演选择演员的规律。

# 挖掘频繁项集和关联规则
itemsets = fp.find_frequent_patterns(data, 3)
rules = fp.generate_association_rules(itemsets, 1)
print(itemsets)
print("--------")
print(rules)
{('吕中',): 3, ('李光洁',): 3, ('张天爱',): 3, ('柳岩',): 3, ('刘淼淼',): 3, ('刘淼淼', '宋佳'): 3, ('孙淳',): 4, ('王学圻',): 4, ('黄志忠',): 6, ('宋佳',): 6}
--------
{('刘淼淼',): (('宋佳',), 1.0)}

说明张黎导演在使用刘淼淼时,一般都会用宋佳。

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

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

相关文章

js 数组的 forEach,some,every,reduce,sort 方法

forEach() 方法的使用 forEach 遍历数组的每一项 const arr [小红,倪大红,苏大强,我滴宝]arr.forEach((item,index)>{if(item 苏大强){console.log(index); // 2}});some() 方法的使用 从开始便利找到符合条件的便停止便利&#xff0c;相比 forEach 在性能上有一定优势…

Python 利用百度文字识别 API 识别并提取图片中文字

Python 利用百度文字识别 API 识别并提取图片中文字 利用百度 AI 开发平台的 OCR 文字识别 API 识别并提取图片中的文字。首先需注册获取 API 调用的 ID 和 key&#xff0c;步骤如下&#xff1a; 打开百度AI开放平台&#xff0c;进入控制台中的文字识别应用(需要有百度账号&a…

调用阿里API实现图片中的文字识别

作者介绍 王雪玉&#xff0c;女&#xff0c;西安工程大学电子信息学院&#xff0c;2022级研究生 研究方向&#xff1a;机器视觉与人工智能 电子邮件&#xff1a;2239580540qq.com 王泽宇&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2022级研究生&#xf…

李飞飞高徒教你从0到1构建GPT,马斯克点赞

詹士 发自 凹非寺量子位 | 公众号 QbitAI “从0到1手搓GPT”教程来了&#xff01; 视频1个多小时&#xff0c;从原理到代码都一一呈现&#xff0c;训练微调也涵盖在内&#xff0c;手把手带着你搞定。 该内容刚发出来&#xff0c;在Twitter已吸引400万关注量&#xff0c;HackerN…

马斯克、米哈游轮番注资,AI医疗会是下一个风口吗?

图片来源&#xff1a;由无界AI生成 医疗健康一直都是老生常谈的话题&#xff0c;如今这个领域正面临着诸多挑战&#xff0c;如成本不断攀升或是全球性流行病等&#xff0c;而脑机接口等AI技术的出现有望为医疗领域提供新的解决方案。 如果你是科幻迷&#xff0c;你可能对脑机接…

《战略品牌管理》思维导图,教你如何对品牌进行管理

品牌一直在我们的生活中扮演了很重要的作用&#xff0c;它影响了我们的决策&#xff0c;甚至让我们痴迷。可是很少有人真正理解它的本质以及它是怎么建立并成长的&#xff0c;而战略品牌管理知识便是这样管理品牌的一本书&#xff0c;它能帮我们解释我们生活中的很多现象&#…

薅羊毛我愿称Python为最强,Python 自动化带你轻松赚钱

ps&#xff1a;本文仅限用于技术交流&#xff0c;请勿用于其他用途。 准 备 工 作 在编写代码之前&#xff0c;需要做如下准备工作&#xff1a; 1、配置好 Android ADB 开发环境 2、Python 虚拟环境内安装 pocoui 依赖库 3、操作剪切板的应用 APK 编 写 代 码 我们分 7 …

薅羊毛算副业吗?薅羊毛到底是怎么赚钱的?

薅羊毛算副业吗?薅羊毛到底是怎么赚钱的? 薅羊毛当然也算是一种副业! 薅羊毛拿佣金的起初,我的原因应该跟大部分人事一样的,“挣钱”。 我是先在知乎上,小红书大概了解的“薅羊毛”的运作方式,然后加入一个羊毛裙看了一下别人是怎么操作的,当时觉得也是很简单的,每…

羊毛大军杀入币圈,有人月入过万,有人惨遭反薅,沦为韭菜

文 | 棘轮 比萨 空投糖果、“月入过万”、“躺赚”……羊毛党大军&#xff0c;早已杀入币圈。 羊毛党圈流传的“史上最贵羊毛”——ONT空投&#xff0c;就出自币圈。甚至有职业羊毛党因此购入保时捷。 相较于互联网圈“羊毛”&#xff0c;币圈“羊毛”往往不需注册、实名验证。…

知乎带货月入过万的赚钱路子,前期操作后期可躺赚

如果说网络上有哪些值得投入并真正当做一个优质副业项目来操作的话&#xff0c;知乎好物推荐应该算一个&#xff0c;今天就跟大家聊聊知乎好物这个网络赚钱项目。 目前已经有很多小伙伴以此为副业&#xff0c;并且取得了很好的成绩&#xff0c;做到了睡后收入。 知乎好物&…

技术创造价值,手把手教你薅羊毛篇

距离上一篇年终总结的文章已经过了3个多月了&#xff0c;在年终总结中写到了利用脚本自动薅羊毛的话题&#xff0c;评论里有不少小伙伴比较感兴趣。so&#xff0c;今天就来给大家详细介绍一下如何让技术创造价值&#xff08;得给薅羊毛上升一个层次&#xff09;。本文没有什么技…

CSDN是如何让我副业月入过万的?

始 我跟 CSDN 的缘分要从 2011 年说起&#xff0c;当时我正上高二&#xff0c;当时好像是在搞鼓 MFC。当时家里有了第一台电脑&#xff0c;我也再也不用去黑网吧去敲代码了&#xff0c;在家搜索资料的时候出现在我眼帘之中&#xff0c;并且对我有帮助的基本上都是 CSDN 上的内…

薅羊毛 | Python 自动化带你轻松赚钱

作者&#xff1a;星安果 来源&#xff1a;AirPython 阅读文本大概需要 10 分钟。 1 目 标 场 景 最近&#xff0c;有一个朋友告诉我&#xff0c;她在某平台上购买了一部手机&#xff0c;收到货之后发现商品质量挺好的&#xff0c;价格也不贵。 临了随手给了个好评&#xff0c;商…

来来来,教你如何智慧薅羊毛!

提到边缘计算&#xff0c;熟悉ToB技术的朋友&#xff0c;首先可能想到的就是运营商的5G MEC&#xff08;移动边缘计算&#xff09;&#xff0c;以及云计算中的融合边缘系统理念。 的确&#xff0c;作为全球公认的创新技术趋势&#xff0c;边缘计算如今已经被广泛用于云计算、5G…

互联网薅羊毛指南

点击上方“程序猿杂货铺”&#xff0c;“星标或置顶公众号” 第一时间获取价值内容 阅读本文大概需要 9 分钟 本文经授权转载于公众号 | Python爱好者社区 作者 | 王大伟 微软最有价值专家&#xff08;MVP&#xff09; 薅羊毛&#xff0c;一种参与各种优惠活动的新型说法&#…

CSDN给你一个薅羊毛的机会!你真的不要吗?

抢红包、集福卡、转锦鲤等等&#xff0c;每年过年过节&#xff0c;各种价值几十亿的瓜分活动&#xff0c;对于网络冲浪选手来说&#xff0c;眼花缭乱但也乐趣满满。 可现实是&#xff1a;你抢了5毛8&#xff0c;人家抢了好几万&#xff01; 甚至前段时间&#xff0c;字节跳动安…

go-cqhttp QQ机器人入门

有关go-cqhttp QQ机器人的一些小问题 基础介绍介绍一些名词***2022-04-07更新***小问题汇总&#xff1a; 基础介绍 go-cqhttp机器人是基于onebot协议的一个应用,官网&#xff1a;https://docs.go-cqhttp.org/可以制作QQ机器人。娱乐性还是蛮强的。之前研究的时候发现网上的教程…

【Re:从零开始的QQ机器人搭建】——基于go-cqhttp和python

【Re&#xff1a;从零开始的QQ机器人搭建】—— 基于go-cqhttp 警告&#xff1a;小心智械危机&#xff08; 前言 之前酷Q用的好好的&#xff0c;谁知道刚打完工会战不到2天tx就封了大部分机器人。所幸小部分有生力量保留了下来&#xff0c;必可活用于下次机器人搭建。 一、…

使用NoneBot2可视化平台搭建QQ聊天机器人:本地和云部署教程

NoneBot是一个基于Python 3.8的异步、开源和可扩展的框架&#xff0c;用于构建和运行聊天机器人&#xff0c;支持各种聊天平台&#xff0c;如Telegram&#xff0c;Discord和WeChat。它是基于nonebot库构建的&#xff0c;提供了一个易于使用的界面&#xff0c;用于创建聊天机器人…

教你使用python搭建QQ机器人

注&#xff1a;本文中Linux系统指令均为Ubuntu使用&#xff0c;centos等请根据指令按系统情况改动。 目录 一、环境配置 二、配置go-cqhttp 三、安装nonebot 四、运行机器人 五、插件 六、最后 一、环境配置 1、python版本>3.8.0。如果版本不对请更新版本&#xff0c…