一、工欲善其事必先利其器
首先确保最新的版本吧,python最让人头痛和无解的就是版本兼容性问题,不过既然选择了就不要怕麻烦,不断的纠错不断的尝试,在频繁的错误中提高自己。
Python3.6
Pycharm2017.3.2
scipy 1.2.1
numpy 1.16.0
pandas 0.24.1
scikit-learn 0.19.1
二、亲和性分析
数据挖掘有个常见的应用场景,即顾客在购买一件商品时,商家可以趁机了解他们还想买什么,以便把多数顾客愿意同时购买的商品放到一起销售以提升销售额。当商家收集到足够多的数据时,就可以对其进行亲和性分析,以确定哪些商品适合放在一起出售。就是传说中的啤酒和尿布问题,不管是不是真的,姑且认为是真的吧。
亲和性问题属于关联分析,关联分析采用的是Apriori算法和FP-growth算法,不过很奇怪的是,scikit-learn没有内置这些算法,需要靠代码来实现。
三、数据集合
亲和性分析用的数据集是affinity_dataset.txt,主要包括以下内容:
Bread、milk、cheese、apples、bananas(是面包、牛奶、奶酪、苹果和香蕉)
代码语言:javascript复制1 0 0 1 0
1 1 0 1 0
0 0 1 1 1
1 1 0 1 0
简而言之就是一行记录对应一次事务交易,1和0分别对应是否购买,我们的任务是找到这五种商品中同时购买两种可能性最大的。
四、支持度和置信度
支持度指数据集中规则应验的次数,统计起来很简单。有时候,还需要对支持度进行规范化,即再除以规则有效前提下的总数量。我们这里只是简单统计规则应验的次数。
支持度衡量的是给定规则应验的比例,而置信度衡量的则是规则准确率如何,即符合给定条件(即规则的“如果”语句所表示的前提条件)的所有规则里,跟当前规则结论一致的比例有多大。计算方法为首先统计当前规则的出现次数,再用它来除以条件(“如果”语句)相同的规则数量。
TID | Items |
---|---|
001 | Cola, Egg, Ham |
002 | Cola, Diaper, Beer |
003 | Cola, Diaper, Beer, Ham |
004 | Diaper, Beer |
支持度:支持度计数除于总的事务数。在上面图表中总的事务数为4,{Diaper, Beer}的支持度计数为3,所以它的支持度是3÷4=75%,说明有75%的人同时买了Diaper和Beer
置信度:对于规则{Diaper}→{Beer},{Diaper, Beer}的支持度计数除于{Diaper}的支持度计数,为这个规则的置信度。例如规则{Diaper}→{Beer}的置信度为3÷3=100%。说明买了Diaper的人100%也买了Beer。
强关联规则:大于或等于最小支持度阈值和最小置信度阈值的规则叫做强关联规则。
五、亲和性分析代码的关注点
主要有两个包需要注意,一个是defaultdict,一个是itemgetter。
defaultdict 就是一个字典,只不过python自动的为它的键赋了一个初始值。这也就是说,你不显示的为字典的键赋初值python不会报错。
operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号,主要用来做多级排序。
代码语言:javascript复制#原文的代码比较零散,网上的代码大多数互抄,先基于个人的理解对代码进行了归纳整理,并添加了注释
import numpy as np
from collections import defaultdict
from operator import itemgetter
#生成关联规则
def make_relation_rule(X,n_features):
valid_rules=defaultdict(int) #定义规则有效的集合
invalid_rules=defaultdict(int) #定义规则无效的集合
num_occurances=defaultdict(int) #定义某商品支持度集合
#复杂度分析(Complexity Analysis) n_samples*n_features*n_features
for sample in X: #循环对样本的每个个体进行处理
for premise in range(n_features): #循环对样本的每个个体的每个特征值进行处理
if sample[premise]==0:continue #检测个体是否满足条件,如果不满足,继续检测下一个条件。
num_occurances[premise] =1 #如果条件满足(即值为1),该条件的出现次数加1
for conclusion in range(n_features): #再次循环样本的每个个体的每个特征值进行处理
if premise==conclusion:continue #在遍历过程中跳过条件和结论相同的情况
if sample[conclusion]==1: #如果个体的目标特征值为1
valid_rules[(premise,conclusion)] = 1 #存入规则有效的集合
else:
invalid_rules[(premise,conclusion)] = 1 #规则无效的集合
support=valid_rules #规则有效的集合,即支持度集合
confidence=defaultdict(float) #定义置信度集合
#print(valid_rules) #打印规则有效的结果集
#print(invalid_rules) #打印规则无效的结果集
for premise,conclusion in valid_rules.keys(): #valid_rules是个元祖集合
rule=(premise,conclusion) #获取每个规则
confidence[rule]=float(valid_rules[rule])/num_occurances[premise] #这里需要将valid_rules的规则条目数从int转成float,生成规则的置信度
return support,confidence
#输出某两件商品的支持度和置信度
def print_especial_rule(premise,conclusion,support,confidence,features):
premise_name=features[premise] #转换为商品名称
conclusion_name=features[conclusion] #转换为商品名称
print("Rule:If a person buys {0} they will also buy {1}".format(premise_name,conclusion_name)) #输出商品名称
print("-Support:{0}".format(support[(premise,conclusion)])) #输出支持度
print("-Confidence:{0:.3f}".format(confidence[(premise,conclusion)])) #输出支持度
#输出该结果集支持度topN最高的商品
def print_topN_suppor_rule(support,confidence,features,topN):
sorted_support = sorted(support.items(), key=itemgetter(1), reverse=True)
print('支持度最高的前{0}条规则:'.format(topN))
for index in range(topN):
print("规则 #{0}".format(index 1))
premise,conclusion = sorted_support[index][0]
print_especial_rule(premise, conclusion, support, confidence, features)
#输出该结果集置信度topN最高的商品
def print_topN_confidence_rule(support,confidence,features,topN):
sorted_confidence = sorted(confidence.items(), key=itemgetter(1), reverse=True)
print('置信度最高的前{0}条规则:'.format(topN))
for index in range(topN):
print("规则 #{0}".format(index 1))
premise,conclusion = sorted_confidence[index][0]
print_especial_rule(premise, conclusion, support, confidence, features)
if __name__ == '__main__':
#使用numpy加载数据集
X=np.loadtxt("affinity_dataset.txt")
#定义物品的映射关系
features = ["bread", "milk", "cheese", "apples", "bananas"]
'''
#Version1 购买苹果的支持度
num_app_purchases=0
for sameple in X:
if sameple[3]==1:
num_app_purchases =1
print('{0}people bought Apples'.format(num_app_purchases))
'''
#获取数据集的大小形状,np_sameple为样本数量,n_features为样本列数
n_samples,n_features=X.shape
print(n_samples,n_features)
#生成支持度和置信度集合
support,confidence=make_relation_rule(X,n_features)
#定义待求关联结果的物品和物品
premise=1
conclusion=3
#输出两件商品的置信度和支持度
print_especial_rule(premise,conclusion,support,confidence,features)
#输出支持度高的前5条规则
print_topN_suppor_rule(support,confidence,features,5)
#输出置信度高的前5条规则
print_topN_confidence_rule(support, confidence, features, 5)