08相关分析与关联分析


相关分析与关联分析

数据之间最常见的关系是函数关系,在数据函数关系下,一些数据发生变动,与之对应的另一些数据会严格按照函数关系发生相应的变动。但实际上,数据之间的变动清咖u给你还会收到其他没有考虑到或者根本无法考虑的因素的影响,使得数据变动状况很少真正能够用函数的形式来具体表述,数据之间的关系往往体现为相互依存的非函数关系。

还有些数据数值上可能不具有上述描述的关系,但是产生这些数据的行为可能发生关联。

相关分析

函数关系和相关关系

相关分析(correlation analysis)主要分析两个变量之间的相互依存关系,在学习相关分析之前,应当先区分变量或数据之间的两种主要关系

函数关系:当一个或几个变量取一定的值时,另一个变量有确定值与之具体严格相对应,则称这种关系为函数关系。

相关关系:变量之间的影响不能够用具体的函数来度量,但变量之间的关系确实存在数量上不是严格对应的相互依存关系,称之为相关关系。

函数关系时确定性的,往往把发生变动的变量称之为自变量,受自变量变动影响而发生变动的变量称之为因变量

相关关系是不确定的,主要考察变量之间的相互影响,这种影响不存在方向性,即变量A与变量B相关和变量B与变量A相关是一致的。相关关系主要体现为变量之间的相互依存关系。相关分析不具有传递性,即A和C相关,B和C相关,A和B不一定相关。

相关分析根据其分析方法和处理对象不同,可分为:简单相关分析、偏相关分析、非参数相关分析等。根据相关关系表现形式不同,可分为:线性相关分析、非线性相关分析。

简单相关分析

简单相关分析主要分析两个变量之间相互依存的关系,可以通过主管观测和客观测度指标来衡量。

主观观测变量之间的相关关系,主要是通过两个变量之间散点图的手段来进行分析的。客观测度主要是通过统计分析的方法,计算相关系数,利用相关系数数值的符号和大小来判定相关关系的方向和强弱。

  • 用图形描述相关关系

利用散点图可以描绘出两个变量的相互影响状况。根据散点图的不同表现情形,有如下类型:完全正线形相关、完全负线形相关、曲线相关、正线性相关、负线性相关、不相关。

  • 用相关系数测度相关关系

相关系数是描述线性相关程度和方向的统计量,根据样本收集的数据计算的相关系数,通常用字母 \(r\) 表示。\(r\) 的正负号表示相关关系的方向,\(r\) 的绝对值大小表示相关关系的强弱程度。

设两个变量分别是 \(x,y\),根据样本数据计算相关系数的方法主要采用Pearson提出的方法,即Pearson相关系数

\[r = \frac{\sum{(x-\bar{x})(y-\bar{y})}}{\sqrt{\sum{(x-\bar{x})^2}\cdot\sum{(y-\bar{y})^2}}}=\frac{x与y的协方差}{x标准差与y标准差的乘积} \]

相关系数 \(r\) 有如下情况

r=+1	表示完全正线性相关
r=-1	表示完全负线性相关
r<0		表示负线性相关
r>0		表示正线性相关
r=0		表示不存在线性关系

|r|<0.3		表示低度线性相关
0.3<=|r|<0.5表示中低度线性相关
0.5<=|r|<0.8表示中度线性相关
0.8<=|r|<1.0表示高度线性相关
  • 相关系数的显著性检验

相关系数的显著性检验主要是根据样本数据计算的样本相关系数 \(r\),利用 \(t\) 统计量,根据 \(r\) 服从自由度为 \(n-2\)\(t\) 分布的假定,对总体相关系数(\(\rho\))是否等于0进行假设检验。若在一定的显著性水平下,拒绝 \(\rho=0\) 的原假设,则表示样本相关系数 \(r\) 是显著的。其原假设和备择假设:

\[H_0:\rho=0;H_1:\rho \neq 0 \]

示例

import pandas as pd
import statsmodels.api as sm
import scipy.stats as stats
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 为了评价汽车最高时速和汽车自身相应指标的影响,收集了相关数据。

car_corr = pd.read_csv('./data/car_corr.csv')
print(car_corr.head(5))
#         Brand_Model  Weight  Circle  Max_Speed  Horsepower
# 0   Acura Legend V6    3265      42        163         160
# 1          Audi 100    2935      39        141         130
# 2          BMW 535i    3640      39        209         208
# 3     Buick Century    2880      41        151         110
# 4  Buick Riviera V6    3465      41        231         165

# 计算样本相关系数
# 方法一:numpy
res = np.corrcoef((car_corr['Weight'], car_corr['Circle'], car_corr['Max_Speed'], car_corr['Horsepower']))
print(res)
# [[ 1.          0.07548513  0.85458981  0.82559164]
#  [ 0.07548513  1.          0.26369327 -0.02829931]
#  [ 0.85458981  0.26369327  1.          0.75015192]
#  [ 0.82559164 -0.02829931  0.75015192  1.        ]]
# 主对角现的相关系数均为1,表示自己与自己完全相关。其他部分表示变量之间的相关系数。
# 方法二:pandas
res = car_corr.corr()  # 可自动识别DataFrame对象中的数值型数据
print(res)
#               Weight    Circle  Max_Speed  Horsepower
# Weight      1.000000  0.075485   0.854590    0.825592
# Circle      0.075485  1.000000   0.263693   -0.028299
# Max_Speed   0.854590  0.263693   1.000000    0.750152
# Horsepower  0.825592 -0.028299   0.750152    1.000000

# 显著性检验
# 1.计算两变量之间的相关系数
res = stats.pearsonr(car_corr['Max_Speed'], car_corr['Weight'])
print(res)  # (0.8545898074815489, 1.8591897095041332e-09)
# p_v \approx 0,拒绝原假设,线性相关显著。
# 2.计算多组数据两两之间的相关系数及显著性
correlation = []
for i in car_corr[['Weight', 'Circle', 'Horsepower']].columns:
    correlation.append(stats.pearsonr(car_corr['Max_Speed'], car_corr[i]))
print(correlation)
# [(0.8545898074815489, 1.8591897095041332e-09),
# (0.2636932690716119, 0.15913089371709174),
# (0.7501519209192845, 1.8164321769966608e-06)]

# 其他方法
# 1.仅有p值:sklearn
from sklearn.feature_selection import f_regression

F, P_value = f_regression(car_corr[['Weight', 'Circle', 'Horsepower']], car_corr['Max_Speed'])
print(F, P_value)
# [75.82819719  2.09245283 36.03335654] [1.85918971e-09 1.59130894e-01 1.81643218e-06]

# 结论:在不考虑其他因素作用下,最高时速与车身自重存在显著的高度正线性相关,与发动机马力存在显著的中度线性相关

偏相关分析

简单相关分析有时不能够真实反映现象之间的关系。如某个变量可能会影响其他的变量,而这种影由于相关关系的不可传递性,往往会得出错误的结论。

所以在进行相关分析时要控制这种变量,剔除其对其他变量的影响后,再研究变量之间的相关关系。这种方法称之为偏相关分析(partial correlation analysis)

一阶偏相关分析(控制住一个变量 \(p\),单纯分析 \(x,y\) 之间的相关关系)

\[r_{xy,p}=\frac{r_{xy}-r_{xp}r_{yp}}{\sqrt{1-r_{xp}^2}\sqrt{1-r_{yp}^2}} \]

其中 \(r_{xy},r_{xp},r_{yp}\) 分别表示 \(x\)\(y\)之间、\(x\) 和控制变量 \(p\)之间、\(y\) 和控制变量 \(p\)之间的简单相关系数。

示例

import pandas as pd
import statsmodels.api as sm
import scipy.stats as stats
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 为了评价汽车最高时速和汽车自身相应指标的影响,收集了相关数据。

car_corr = pd.read_csv('./data/car_corr.csv')
print(car_corr.head(5))
#         Brand_Model  Weight  Circle  Max_Speed  Horsepower
# 0   Acura Legend V6    3265      42        163         160
# 1          Audi 100    2935      39        141         130
# 2          BMW 535i    3640      39        209         208
# 3     Buick Century    2880      41        151         110
# 4  Buick Riviera V6    3465      41        231         165

# 马力可能对其他变量产生影响,控制主马力变量,进行偏相关分析
# 一阶偏相关系数
def partial_corr(x, y, partial=[]):
    # x,y为考察相关关系的变量,partical为控制变量
    xy, xyp = stats.pearsonr(x, y)
    xp, xpp = stats.pearsonr(x, partial)
    yp, ypp = stats.pearsonr(y, partial)
    n = len(x)
    df = n - 3
    r = (xy - xp * yp) / (np.sqrt(1 - xp * xp) * np.sqrt(1 - yp * yp))
    if abs(r) == 1:
        prob = 0.0
    else:
        t = (r * np.sqrt(df)) / np.sqrt(1 - r * r)
        prob = (1 - stats.t.cdf(abs(t), df)) * 2
    return r, prob


pcorrelation = []
for i in car_corr[['Weight', 'Circle']].columns:
    pcorrelation.append(partial_corr(car_corr[i], car_corr['Max_Speed'], partial=car_corr['Horsepower']))
print(pcorrelation) 
# [(0.6305309485292878, 0.00024594990184656496), (0.43104653010728905, 0.01957036695163783)]
# 剔除马力影响后,车身自重的相关系数有所下降,处于中度线性相关,非常显著;轮胎尺寸的相关系数有所提升,也较为显著。

点二列相关分析

点二列相关分析(point-biserial correlation)适用于两个变量中一个是来自正态总体的定距或定比数据,另一个变量是二分类数据。一般将后者编码为0,1,然后计算Pearson相关系数。计算公式

\[r = \frac{\bar{x}_p-\bar{x}_q}{s_x}\sqrt{pq} \]

其中 \(p\) 表示二分类数据某类的占比,\(q=1-p\) 表示另一类的占比。\(\bar{x}_p,\bar{x}_q\) 分别表示对应分类对应的另一个变量的平均数,\(s_x\) 为另一个变量的样本标准差。

示例

import pandas as pd
import statsmodels.api as sm
import scipy.stats as stats
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 分析性别和成绩之间的相关关系,0女1男

scorebygender = pd.read_csv('./data/scorebygender.csv')
print(scorebygender.head(5))
#    score  gender
# 0     68       1
# 1     81       1
# 2     78       0
# 3     91       0
# 4     91       1

# 相关系数及显著性水平
res = stats.pointbiserialr(scorebygender['gender'], scorebygender['score'])
print(res)  # PointbiserialrResult(correlation=0.013517390176463254, pvalue=0.8777414982748739)
# 相关系数比较低相关性非常弱,p_v比较大非常不显著,可以认为成绩和性别无关。

非参数相关分析

简单相关分析和偏相关分析广泛应用于定量数据或连续型数据的研究。

对于某些数据尤其是定性数据的相关分析而言,使用Pearson法计算相关系数,很难得到定性数据的协方差和标准差。对此类数据的相关分析往往从数据值的次序入手,并借助非参数统计分析的思想。

次序在数列中代表了某个具体变量值的位置、等级或秩,因此此类相关分析称之为非参数相关分析、等级相关分析或秩相关分析,其计算的相关系数变对应的称为非参数相关系数、等级相关系数或秩相关系数。

常用的方法有:Spearman、Kendall tau-b、Hoeffding's D相关系数等

  • Spearman系数

主要测度顺序变量间的线性相关关系,在计算过程中只考虑变量值的顺序不考虑变量值的大小。

其计算过程:首先把变量值转换为在样本所有变量值中的排列次序,再利用Pearson方法求解转换后的两个变量对应的排列次序的相关系数。其计算公式为

\[r = \frac{\sum{(R_{x_i}-\bar{R}_x)(R_{y_i}-\bar{R}_y)}}{\sqrt{\sum{(R_{x_i}-\bar{R}_x)^2}\cdot\sum{(R_{y_i}-\bar{R}_y)^2}}} \]

其中,\(R_{x_i},R_{y_i}\) 分别表示第 \(i\)\(x\) 变量和 \(y\) 变量经过排序后的次序,\(\bar{R}_x,\bar{R}_y\) 分别表示\(R_{x_i},R_{y_i}\) 的均值。

  • Kendall tau-b系数

主要测度顺序变量间的线性相关关系,在计算过程中只考虑变量值的顺序不考虑变量值的大小。

在Kendall tau-b系数计算过程中,除对数据进行排列顺序外,还应综合考虑该排序与变量值的具体情况,即

同序对:在两个变量上排列顺序相同的一对变量

异序对:在两个变量上排列顺序相反的一对变量

上述对子的数目简称为对子数,设 \(P\) 为同序对子数,\(Q\) 为异序对子数,\(T_x\) 为在 \(x\) 变量上是同序但在 \(y\) 变量上不是同序的对子数,\(T_y\)为在 \(y\) 变量上是同序但在 \(x\) 变量上不是同序的对子数,则Kendall tau-b系数

\[\tau_b = \frac{P-Q}{\sqrt{(P+Q+T_x)(P+Q+T_y)}} \]

\(\tau_b\) 的取值范围与简单相关系数相同,即 \(\tau_b \in [-1,+1]\)

  • Hoeffding's D系数

该系数主要测度顺序变量或具有等级水平变量间的线性相关关系,其计算公式为

\[D= 30\times\frac{(n-2)(n-3)D_1+D_2-2(n-2)D_3}{n(n-1)(n-2)(n-2)(n-4)} \]

其中:

\[D_1=\sum{(Q_i-1)(Q_i-1)} \\ D_2=\sum{(R_i-1)(R_i-2)(S_i-1)(S_i-2)} \\ D_3=\sum{(R_i-2)(S_i-2)(Q_i-1)} \]

\(R_i,S_i\)分别表示变量 \(x,y\) 的排列顺序,\(Q_i\)表示1加上变量 \(x,y\) 的值均小于这两个变量中的第 \(i\) 个值时的个数,也称之为双变量等级。

上述相关系数也可用于定量数据中,在相关分析中只要除去定量数据的数值意义即可。

示例

import pandas as pd
import statsmodels.api as sm
import scipy.stats as stats
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 考察研究生对自身所选专业的兴趣与其他因素之间的相关关系
# 各变量以1~5分的像是进行收集,对应值标签如下
# Interest: 更高、没变化、下降、失去兴趣、根本不感兴趣
# Major: 完全一致、基本一致、有点联系、不一致、完全不一致
# Teaching: 非常满意、比较满意、一般满意、不太满意、非常不满意
# Tutor: 非常大、比较大、一般、不大、没作用
# 由于需要用数字进行相关系数计算,故无需将值标签挂在数据集变量中

graduate = pd.read_csv('./data/graduate.csv')
print(graduate.head(5))
#    Interest  Major  Teaching  Tutor
# 0         2      2         2      2
# 1         2      2         1      2
# 2         4      3         4      4
# 3         1      1         2      1
# 4         3      3         3      3

# 由于变量都是顺序变量,可以用非参数相关系数考察各变量之间的相关系数
# 方法一:spearman
rho, p = stats.spearmanr(graduate)
print(rho, p)
# 相关系数
# [[1.         0.72134588 0.27430442 0.8062982 ]
#  [0.72134588 1.         0.28790361 0.73184305]
#  [0.27430442 0.28790361 1.         0.28440269]
#  [0.8062982  0.73184305 0.28440269 1.        ]]
# p值
#  [[0.00000000e+000 2.58589179e-163 6.31375185e-019 1.49316919e-232]
#  [2.58589179e-163 0.00000000e+000 9.09876371e-021 2.08047486e-170]
#  [6.31375185e-019 9.09876371e-021 0.00000000e+000 2.77199934e-020]
#  [1.49316919e-232 2.08047486e-170 2.77199934e-020 0.00000000e+000]]

# 方法二:kendall tau-b
kt = []
for i in graduate['Interest', 'Major', 'Teaching'].columns:
    kt.append(stats.kendalltau(graduate[i], graduate['Tutor']))
print(kt)
# 相关系数
# [[1.         0.72134588 0.27430442 0.8062982 ]
#  [0.72134588 1.         0.28790361 0.73184305]
#  [0.27430442 0.28790361 1.         0.28440269]
#  [0.8062982  0.73184305 0.28440269 1.        ]]
# p值
#  [[0.00000000e+000 2.58589179e-163 6.31375185e-019 1.49316919e-232]
#  [2.58589179e-163 0.00000000e+000 9.09876371e-021 2.08047486e-170]
#  [6.31375185e-019 9.09876371e-021 0.00000000e+000 2.77199934e-020]
#  [1.49316919e-232 2.08047486e-170 2.77199934e-020 0.00000000e+000]]

# 结论:学生专业兴趣与如下相关且显著:所学知识与专业方向相符性、导师对学业的帮助;与如下无关:教师上课的水平高低

关联分析

关联分析(association analysis)常用语发现大量数据中有意义的联系,这种联系前调的是产生数据的行为之间的联系。这些数据之间的关联即关联规则(association rule)。

这里讨论的关联指这些数据会同时出现,但不讨论之间的因果关系。

在关联分析时,需处理两个关键问题

1.从海量数据中发现规则或模式的计算成本非常高
2.所发现的规则或模式可能是偶然性的,实际应用价值不大

基本概念与预处理

  • 基本概念
import pandas as pd

# 购物篮数据

aa = pd.read_csv('./data/Association.csv', encoding='gbk')
print(aa.head(5))
#    TID             项集
# 0    1        {面包,牛奶}
# 1    2  {面包,尿布,啤酒,鸡蛋}
# 2    3  {牛奶,尿布,啤酒,可乐}
# 3    4  {面包,牛奶,尿布,啤酒}
# 4    5  {面包,牛奶,尿布,可乐}

每一行数据是一笔交易事务(transaction),记其总量为 \(N\);具体的某种产品叫做(item),是分析的基本对象。

项集(itemset):项的集合。若一个项集包含 \(k\) 各项,则称其为\(k-项集\)\(k\)为项集的长度。

关联规则(association rule):形如 $X \to Y $ 的蕴含表达式,其中 \(X\)\(Y\) 是不相交的项集。关联规则的强度可以用支持度和置信度来衡量,同时满足最小支持度和置信度的关联规则称之为强关联规则。
支持度计数(support count):指项集出现的频数,通常用 \(\sigma\) 表示。
支持度(support):所有交易中包含指定项集的比例,定义为

\[s(X \to Y)=\frac{\sigma(X\cup Y)}{N} \]

支持度可以用来衡量给定项集的频繁程度。

置信度(confidence):\(Y\) 在包含 \(X\) 的交易中出现的频繁程度。定义为

\[c(X\to Y) = \frac{\sigma(X\cup Y)}{\sigma(X)} \]

频繁项集(frequent itemset):支持度大于等于所设定阈值的项集,如果频繁项集中有 \(L\) 项,记为 \(L-频繁项集\)

如果有一个项集是频繁的,则它的所有子集也一定是频繁的,此即为先验原理1。如果一个项集是非频繁的,那么包含该项集的超集也一定是非频繁的,此即为先验原理2

依据频繁项集的原理可以节约算法搜索相关项集的时间,提高计算效率,这种过程称为剪枝。基于支持度度量修剪搜索空间的策略称为基于支持度的剪枝,这种剪枝策略依赖于支持度的一个关键性质,即一个项集的支持度绝对不会超过它的子集的支持度,该性质被称为支持度度量的反单调性(anti-monotone)

关联规则的主要任务就是要从给定的交易或事物数据集合中,找出支持度和置信度大于等于其各自阈值的所有规则。但是当数据规模较大时(如数目为 \(d\) 项的数据,理论上有 \(2^d\) 各候选项集和 \(3^d-2^{d+1}+1\) 个规则),如果再去计算每个项集的支持度和置信度,将会对系统的计算能力提出极高的要求。

围绕如何发现频繁项集降低计算频次等具体问题产生了较多的关联分析算法。大体可分为三类:

1. 搜索法:只适用于项集数量相对较小数据集的关联规则挖掘
2. 分层算法:宽度优先算法,以Apriori算法为典型代表,需扫描数据集的次数等于最大频繁项目集的项目数
3. 深度优先算法:以FP-growth算法为典型代表
  • 预处理

在实际分析过程中,往往通过正则表达式、分词等文本分析技术将数据中的项识别处理啊,然后处理为如下的机构数据进行分析

#    TID  面包 牛奶 尿布 啤酒 鸡蛋 可乐 
# 0    1    1   1   0   0   0   0
# 1    2    1   0   1   1   1   0  
# 2    3    0   1   1   1   0   1
# 3    4    1   1   1   1   0   0
# 4    5    1   1   1   0   0   1

一般采用“0-1”型二元变量:如果项在事务中出现赋值为1,反之则为0。

Apriori算法

是一种频繁项集算法,其两个输入参数是最小支持度和数据集。该算法首先生成所有单项(项集长度为1)列表,得到满足最小支持度的 \(1-项集\),将其进行组合生成包含2个元素的 \(2-项集\),继续提出不满足最小支持度的项集,重复上述过程直到所有非频繁项集都被剔除。

示例

from random import randint

import pandas as pd
import statsmodels.api as sm
import scipy.stats as stats
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 分析业务订购之间的关联规则

mpb = pd.read_csv('./data/mpb.csv')
print(mpb.head(5))
#    news  email  callreminder
# 0     0      1             0
# 1     0      1             0
# 2     0      1             0
# 3     0      1             0
# 4     0      1             0

# 挖掘关联规则
# python中虽有apriori/orange等包实现,但是多年未更新,可靠性未知
sign = '-->'  # 定义蕴含符,用于描述关联规则


class Apriori(object):
    def __init__(self, minsupport=0.1, minconfidence=0.4):
        self.minsupport = minsupport
        self.minconfidence = minconfidence

    def link(self, x, sign):
        '''
        该函数用于连接前项和后项
        '''

        x = list(map(lambda i: sorted(i.split(sign)), x))
        l = len(x[0])
        r = []
        for i in range(len(x)):
            for j in range(i, len(x)):
                if x[i][:l - 1] == x[j][:l - 1] and x[i][l - 1] != x[j][l - 1]:
                    r.append(x[i][:l - 1] + sorted([x[j][l - 1], x[i][l - 1]]))
        return r

    def apriori(self, data):
        '''
        该函数用于频繁项集的挖掘
        '''
        final = pd.DataFrame(index=['support', 'confidence'])
        support_series = 1.0 * data.sum() / len(data)  # 生成支持度序列
        column = list(support_series[support_series > self.minsupport].index)
        # 初步支持度筛选
        k = 0
        while len(column) > 1:
            k = k + 1
            column = self.link(column, sign)
            sf = lambda i: data[i].prod(axis=1, numeric_only=True)
            # 支持度的计算函数
            data_2 = pd.DataFrame(list(map(sf, column)),
                                  index=[sign.join(i) for i in column]).T
            support_series_2 = 1.0 * data_2[[sign.join(i) for i in column]].sum() / len(data)
            # 更新支持度
            column = list(support_series_2[support_series_2 > self.minsupport].index)
            # 更新后支持度筛选
            support_series = support_series.append(support_series_2)
            column2 = []
            for i in column:
                i = i.split(sign)
                for j in range(len(i)):
                    column2.append(i[:j] + i[j + 1:] + i[j:j + 1])
            # 计算置信度
            confidence_series = pd.Series(index=[sign.join(i) for i in column2], dtype='float64')
            for i in column2:
                confidence_series[sign.join(i)] = support_series[sign.join(sorted(i))] \
                                                  / support_series[sign.join(i[:len(i) - 1])]
            for i in confidence_series[confidence_series > self.minconfidence].index:
                # 置信度筛选
                final[i] = 0.0
                final[i]['confidence'] = confidence_series[i]
                final[i]['support'] = support_series[sign.join(sorted(i.split(sign)))]

        # 计算结果
        final = final.T.sort_values(['confidence', 'support'], ascending=False)
        return final


# 创建用于分析的实例对象
rule = Apriori()
# 调用实例对象的apriori方法对mpb数据对象进行规则挖掘
res = rule.apriori(mpb)
print(res)
#                        support  confidence
# news-->email          0.184727    0.540640
# callreminder-->email  0.100120    0.477597
# 将置信度放宽
rule = Apriori(minconfidence=0.2)
res = rule.apriori(mpb)
print(res)
#                        support  confidence
# news-->email          0.184727    0.540640
# callreminder-->email  0.100120    0.477597
# email-->news          0.184727    0.242870

FP-growth算法

FP-growth算法只需扫描原始数据2遍,将原始数据中的事务压缩到一个FP-tree中,从而达到压缩数据的目的。在FP-tree中找出每个项集的条件模式基、条件FP-tree,递归的挖掘条件FP-tree得到所有的频繁项集。

构造FP-tree主要有两个步骤:从事务数据集中构建FP-tree和从FP-tree中挖掘出规则。具体步骤如下:首先扫描数据集1次,生成 \(1-频繁项集\),然后将 \(1-频繁项集\)降序排列后放入 \(L\) 频繁项集表中;再次扫描数据集,将每个事务相应项集的关联及频数等信息记入FP-tree中。

示例

from random import randint

import pandas as pd
import statsmodels.api as sm
import scipy.stats as stats
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 分析业务订购之间的关联规则

mpb_fpg = pd.read_csv('./data/mpb_fpgrowth.csv')
res = mpb_fpg.iloc[[randint(0, 98371) for _ in range(10)]]
print(res)
#        new  email  callreminder
# 58375  new  email           NaN
# 42039  NaN  email  callreminder
# 28960  NaN  email  callreminder
# 20923  NaN  email           NaN
# 71076  new    NaN           NaN
# 89245  NaN  email           NaN
# 31867  NaN  email           NaN
# 90654  NaN  email           NaN
# 17114  NaN  email           NaN
# 37505  NaN  email  callreminder

# fp_growth支持python2,不支持python3
from fp_growth import find_frequent_itemsets as ffi
# find_frequent_itemsets可用于频繁项集的挖掘
# 参数1:事务数据,参数2:最小支持度计数=支持度阈值*样本量

for itemset in ffi(np.array(mpb_fpg), minimum_support=int(len(np.array(mpb_fpg)) * 0.1)):
    if nan in itemset:
        # 舍去含有NaN的项集
        pass
    elif len(itemset) == 1:
        # 舍去1-项集
        pass
    else:
        # 该算法是逆向输出结果,将列表反序即可得到结果
        print(itemset[::-1])
        
# ['news', 'email']
# ['callreminder', 'email]
# 结果输出满足最小支持度0.1的结果与Apriori算法一致,且效率更高


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM