机器学习(三):Apriori算法(实践篇)
在前面已经很详细的介绍了Apriori算法,接下来是对Apriori算法进行实践。如果是第一次接触到Apriori算法,可以前去机器学习(三):Apriori算法(算法精讲)理解Apriori算法后再进行实践。
实践基础内容:
- 理解 Apriori 算法的思想。
- 使用 Python 实现 Apriori 算法 。
- 使用 UCI 上面的 mushroom 数据集进行算法测试。
- 修改支持度和置信度,进行多次测试。
- 记录测试结果
所用数据集:
- 网址:http://archive.ics.uci.edu/ml/index.php
- 内容:mushroom 数据集
数据集分析
(1)数据集分析
Agaricus-lepiota.data 数据很庞大,例如:
跟上面一样的字母和逗号组成。一共 8123 行,23 列数据
(2) 数据介绍:
classes | 有毒为p,无毒为e |
---|---|
cap-shape | 钟型为b,conical锥为p等 |
cap-color | 纤维为b等 |
… | … |
(3)数据处理:
由于数据里面不同列之间的重复出现的字母会对Apriori算法产生不小的影响。所以需要将数据集中的字母转换成不同的字符。在这里我将数据转换成数字。比如:第一列的无毒为 1,有毒为 2,钟型为 3,依次类推,到最后一列。处理后的数据输出如下:
这样就生成了不同的特征变量,就不会造成两两特征之间的相互影响了。不过转换过程太过于麻烦和繁琐。不过这是我想到的比较暴力的方法。
算法的实现步骤
(1)算法(大方面)的实现步骤:
- 找出所有频繁项集
- 由频繁项集产生强关联规则
(2)挖掘频繁项集的步骤:
- 先搜索出候选 1 项集及对应的支持度,剪枝去掉低于最小支持度的项集,得到频繁 1 项集。
- 搜索出候选 2 项集及对应的支持度,再剪枝去掉低于最小支持度的项集,得到频繁 2 项集。
- 以此类推,一直迭代下取,直到频繁 k+1 项集位置。对应的 k 项集即为算法的输出结果。
(3)由频繁项集产生关联规则的步骤:
- 对于每个频繁项集,产生该项集的所有非空子集(这些非空子集一定是频繁项集)
- 对 于 每 一 个 非 空 子 集 , 如 果confidence(A=>B)>=confmin (最小置信度)则输出 A=>B。称为强关联规则。
算法的代码实现
(1)算法相关的函数
- loadDataSet():读入数据,并将数据转换成数字
- createC1(): 构建初始候选项集的列表,即所有候选集只包含一个元素
- scanD():计算 Ck 中项集在数据集的支持度,返回满足最小支持度的集合和所有支持度信息的字典
- aprioriGen():由初始候选集的集合生成新的候选集,k参数表示生成新项集中所含有的元素的个数
- apriori(): Apriori 算法重要函数,重要目的是返回所有满足条件的频繁项集的列表和所有选项集的支持度信息。
- generateRules():根据频繁项集和最小可信度生成规则
- calcConf():计算规则的可信度,返回满足最小可信度的规则
- rulesFromConseq():利用递归合并频繁项集和可以出现规则右部的元素
(2)代码如下:
# -*- coding:utf-8 -*-
import warnings
import numpy as np
import pandas as pd
from time import time
import matplotlib.pyplot as plt
warnings.filterwarnings('ignore') #忽略警告
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
def loadDataSet():
#读入文件
dataSet = pd.read_csv('agaricus-lepiota.data', ',', header=None)
#加上列名,便于操作
dataSet = pd.DataFrame(data=np.array(dataSet),columns=['classes', 'cap-shape', 'cap-surface', 'cap-color', 'bruises', 'odor', 'gill-attachment', 'gill-spacing', 'gill-size', 'gill-color', 'stalk-shape','stalk-root', 'stalk-surface-above-ring', 'stalk-surface-below-ring', 'stalk-color-above-ring', 'stalk-color-below-ring', 'veil-type', 'veil-color', 'ring-number', 'ring-type', 'spore-print-color', 'population', 'habitat'], index=range(8124))
model_label01 = dataSet["classes"].replace({
"e": '1', "p":'2' })
model_label02 = dataSet["cap-shape"].replace({
"b":'3', "c":'4', "x":'5', "f":'6', "k":'7', "s":'8'})
model_label03 = dataSet["cap-surface"].replace({
"f":'9', "g":'10', "y":'11', "s":'12'})
model_label04 = dataSet["cap-color"].replace({
"n":'13', "b":'14', "c":'15', "g":'16', "r":'17', "p":'18', "u":'19', "e":'20', "w":'21', "y":'22'})
model_label05 = dataSet["bruises"].