基本概念:
根据样本个体之间的相似度
支持度support 置信度confident
示例:如果一个人买了商品X,那么他很有可能购买商品Y (本例有两个特征值0和1,表示是否购买)
过程思路:
1、在numpy中加载数据集
- numpy是二维数组,看上去像一张表。
- 数组的每一项为个体的某项特征值。
- 数据集与文件放在同一目录下
- 输出前5行数据查看数据集
2、实现简单的排序
- 找出“如果一个人买了商品X,那么他很有可能购买商品Y”这个规则,就要找出数据集中所有同时购买的两件商品
- 规则:由前提条件和结论两部分组成
- 规则常用的衡量方法:支持度和置信度
- 支持度:在数据集中,规则中条件应验的次数(符合前提条件的数量) P(X)
- 置信度:规则中条件和结论同时应验的次数/支持度 P(Y|X)=P(XY)/P(X)
- 统计所有规则的相关数据:规则应验、规则无效、条件相同的规则数量
- 创建几个字典用于存放计算结果:用defaultdict(如果查找的键不存在,返回一个默认值)
- 循环结构:依次对样本的每个个体及个体的每个特征值进行检测,看是否满足条件。如果满足,该条件出现的次数加1;不满足,继续检测下一个。
- 在遍历过程中跳过条件和结论相同的规则(即如果买了X,那么会买X)
- 如果规则应验,规则应验的次数(即上面创建的字典中的元组)加1
- 计算每一条规则的支持度和置信度得到字典,支持度就是上面统计的规则应验的次数,置信度类似
- 声明函数接收参数:前提条件和结论的特征索引值、支持度字典、置信度字典、特征列表
- 格式化输出支持度与置信度,把索引替换成相应的特征。
3、排序找出最佳规则
- 根据支持度和置信度进行排序
- 如找出支持度最高的规则置信度排序同理
- 对支持度字典进行排序,字典的items()返回包含字典所有元素的列表;itemgetter()类作为键,对嵌套列表进行排序;itemgetter(1)表示以字典各元素的值作为排序依据,降序排列
1 import numpy as np
2
3 #在numpy中加载数据集
4 dataset_filename = "affinity_dataset.txt" #要用到的数据文件名为"affinity_dataset.txt" ,注意:数据集文件与笔记本文件放到同一个目录下
5
6 X=np.loadtxt(dataset_filename) #文件内容赋值给一个数组
7
8 print(X[:5]) #打印数组内容
9
10 #实现简单的排序规则
11 num_apple_purchases = 0 #初始购买apple的人数为0
12 for sample in X: #遍历数组X中的每一行(sample)
13 if sample[3] == 1: #如果第三列(apple)的值为1,即买了apple
14 num_apple_purchases += 1 #购买apple的人数加1
15 print("{0} people bought apples".format(num_apple_purchases)) #打印购买apple的总数
16 # format是格式化语法,{0}指定位置
17
18 #变量说明
19 n_samples,n_features = X.shape
20 #语法:shape函数是numpy.core.fromnumeric中的函数,它的功能是查看矩阵或者数组的维数。
21 features = ["bread","milk","cheese","apples","bananas"] #列表
22
23 from collections import defaultdict
24 #使用defaultdict创建相应的字典,好处是当查找的键不存在,返回一个默认值
25 valid_rules = defaultdict(int) #统计规则应验的数量(买了一个同时买了另一个)
26 invalid_rules = defaultdict(int) #统计规则无效的数量(买了一个却没有买另一个)
27 num_occurances = defaultdict(int) #统计条件相同的规则数量(购买的个体的数量)
28
29 #通过循环结构依次对个体及特征值进行处理,统计个体与个体之间的相关性 条件:如果顾客买了一种商品
30 for sample in X: #遍历每一行
31 for premise in range(5): #遍历每一列
32 #判断是否买了该商品
33 if sample[premise] == 0: #如果数组中的值为0(没有买该商品)
34 continue #跳过本次循环
35
36 num_occurances[premise] += 1 #条件相同的规则数量+1(买了该商品)
37
38 for conclusion in range(n_features): #遍历结论
39 if premise == conclusion: #如果条件和结论相同(如果买了苹果,那么买了苹果)
40 continue #跳过本次循环
41
42 if sample[premise] == 1: #条件满足,顾客买了一种商品
43 valid_rules[(premise,conclusion)] += 1 #规则应验的数量加1
44
45 else: #以上条件均不满足,无效规则
46 invalid_rules[(premise,conclusion)] += 1 #规则无效的数量加1
47
48 #计算支持度support和置信度confidence
49 support = valid_rules #p(x)所有买X的人数
50 confidence = defaultdict(float)
51 for premise,conclusion in valid_rules.keys(): #遍历有效规则中的条件和结论
52 rule = (premise,conclusion) #定义规则的形
53 confidence[rule] = valid_rules[rule]/num_occurances[premise] #p(Y|X)=所有买X和Y的人数/所有买X的人数
54
55 #声明一个函数用于接收参数
56 def print_rule(premise,conclution,support,confidence,features): #features是特征列表的索引
57 #把索引替换成相应的特征
58 premise_name = features[premise]
59 conclusion_name = features[conclusion]
60 #输出想要的结果
61 print("rule:if a person buys {0} they will also buy {1}".format(premise_name,conclusion_name))
62 print("-suppotr:{0}".format(support[(premise,conclusion)]))
63 print("-confidence:{0:.3f}".format(confidence[(premise,conclusion)])) #.3f保留3位小数点
64
65
66 #代码测试:尝试更换条件和结论,看看输出结果如何
67 premise=1
68 conclusion=3
69 print(premise,conclusion,support,confidence,features)
70
71 #排序找出最佳的规则
72 from operator import itemgetter #itemgetter可以对嵌套的列表进行排序
73 sorted_support = sorted(support.items(),key=itemgetter(1),reverse=True) #sorted排序
74 #items()函数返回包含字典所有元素的列表,item getter(1)表示以字典各元素的值(support)作为排序依据,reverse = True表示降序排列
75
76 #输出支持度最高的前五条规则
77 for index in range(5):
78 print("rule #{0}".format(index+1))
79 premise,conclusion = sorted_support[index][0] #索引
80 print_rule(premise,conclusion,support,confidence,features)
81
82 #同理输出置信度最高的规则
83 sorted_confidence = sorted(confidence.items(),key=itemgetter(1),reverse = True)
84
85 for index in range(5):
86 print("rule #{0}".format(index + 1))
87 premise, conclusion = sorted_confidence[index][0]
88 print_rule(premise, conclusion, support, confidence, features)