失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【关联规则挖掘】基于Aprioir的蔬菜价格关联性分析

【关联规则挖掘】基于Aprioir的蔬菜价格关联性分析

时间:2024-07-15 02:03:34

相关推荐

【关联规则挖掘】基于Aprioir的蔬菜价格关联性分析

1. 什么是关联规则挖掘?

关联规则挖掘:用于发现数据库中属性之间的有趣联系。

如:用户在购买牛奶的时候,是否会同时购买面包? 购买面包的时候,是否会同时购买牛奶?

如图,可以看出4位顾客有3位同时购买了牛奶和面包,购买牛奶的顾客都购买了面包,购买面包的顾客都购买了牛奶,关联规则就是寻求此类关系。

2. 相关概念

事务:一次交易记录;

项:事务中的一个元素(商品);

项集:多件商品的组合;

k-项集:项集中包含个项(k件商品构成的项集);

频繁项集:对于一个项集,它出现在若干事务中;

支持度:表示同时包含项X和项Y的事务占所有事务的比例;

对{X,Y},support{X,Y}=P(X&Y)=同时含X,Y的事务数/总事务数;

最小支持度:人为设定的一个阈值,用来评判一个项集是否是频繁项集。若一个项集大于最小支持度即为频繁项集;

置信度:设X,Y位两个项集,则:

confidence(XY)=P(Y|X)=support(X,Y)/support(X)=同时含X,Y的事务数/含X的事务数;

eg:beerDiaper的置信度=3/3=100%;

最小置信度:人为设定的一个阈值;

强关联规则: support{X,Y} > 最小支持度

confidence(XY) > 最小置信度

3. Apriori算法实现过程

直接图解,文字表达可以看这:/llhthinker/p/6719779.html

4. 实例

蔬菜价格相关性分析

蔬菜价格会受季节、天气等多方面因素的影响,但许多会出现同涨或同跌等现象,根据给出的蔬菜价格数据,采用关联规则发现算法,发现那些蔬菜之间具有同涨、同跌或者涨跌不同步的现象。

4.1 数据预处理

数据初始情况如下图,我们选择剔除空值,将数据重新组织,

import numpy as npimport pandas as pddef DataArrage():data = pd.read_excel('蔬菜价格_原版.xls',sheet_name = '蔬菜价格3');data = data.drop_duplicates(['日期','蔬菜名'],'last'); #去除可能出现的一种蔬菜一天重复统计的可能data = data.drop_duplicates(['日期','肉食禽蛋'],'last'); # 去除可能出现的一种肉食禽蛋一天重复统计的可能data = data.dropna(); #去除含有缺失值的行#提取蔬菜类k1 = data['蔬菜名'] != '蔬菜类';vegetable = data[k1];#提取肉蛋类k2 = data['肉食禽蛋'] != '肉食禽蛋类';meat = data[k2];# 新数据dataveg = vegetable.pivot(index='日期', columns='蔬菜名', values='价格');datam = meat.pivot(index='日期', columns='肉食禽蛋', values='批发价格');data = pd.merge(dataveg, datam, on="日期");#用Nan代替空格以便下面的dropna操作for i in data.columns:data[i] = data[i].apply(lambda x: np.NaN if str(x).isspace() else x)df_null = data[data[i].isnull()]df_not_null = data[data[i].notnull()]data = data.dropna(axis = 1) # 去除没有价格的蔬菜/肉蛋(有空值的列)# 不选择填充是因为如果填充的数据不合适会影响涨跌关联分析# 存入excel表writer = pd.ExcelWriter('新蔬菜价格.xlsx') #需要手动将excel日期列的数字分类设置为日期才能正常显示日期data.to_excel(writer)writer.save()if __name__ == '__main__':DataArrage();

重新组织后的数据如下:

4.2 生成蔬菜价格涨跌情况

"""pandas读出数据类型为DataFrame,为了方便操作数据,使用xlwd和xlrd模块,读出的数据保存为元组,易于操作1表示价格同比上一日增长0 表示不变-1表示跌"""import xlrd;import xlwt;def rise_fall():'''1表示价格同比上一日增长0 表示不变-1表示跌'''workbook = xlrd.open_workbook(r'新蔬菜价格.xlsx')workspace = xlwt.Workbook(encoding='ascii')booksheet = workbook.sheet_by_index(0)createsheet = workspace.add_sheet('蔬菜价格', cell_overwrite_ok=True)r_num = booksheet.nrowsc_num = booksheet.ncols#生成横纵表头for r in range(0,r_num):createsheet.write(r, 0, booksheet.cell_value(r, 0))r = r + 1for c in range(0,c_num):createsheet.write(0, c, booksheet.cell_value(0, c))c = c + 1for c in range(1,c_num): #日期最早的一天,没有对比createsheet.write(1,c,0)for r in range(2,r_num):for c in range(1,c_num):dis = booksheet.cell_value(r,c) - booksheet.cell_value(r-1,c)if dis > 0:createsheet.write(r,c,1)elif dis < 0:createsheet.write(r,c,-1)else:createsheet.write(r,c,0)workspace.save('蔬菜价格趋势.xls')if __name__ == '__main__':rise_fall()

4.3 利用上面得到的数据进行Apriori分析

import xlrdworkbook = xlrd.open_workbook(r'蔬菜价格趋势.xls')booksheet = workbook.sheet_by_index(0)r_num = booksheet.nrows - 1; # 第一行为标题c_num = booksheet.ncols - 1; # 第一列为时间MAXI = 0 # 统计单日最多有多少个蔬菜存在涨跌for i in range(1,r_num):tmp = 0for j in range(1,c_num):if booksheet.cell_value(i,j) != 0:tmp += 1if tmp > MAXI:MAXI = tmp"""将单日中出现的价格涨跌全部列入data用up后缀表示涨的蔬菜名称,用down表示跌"""data = []for i in range(1,r_num):t = set()for j in range(1,c_num):if booksheet.cell_value(i,j) == 1:t.add(booksheet.cell_value(0,j) + "_up")elif booksheet.cell_value(i,j) == -1:t.add(booksheet.cell_value(0,j) + "_down")data.append(t)all_thing = [] # 所有事件frequent_thing = [] # 用于储存所有的频繁项集for j in range(1,c_num):l = []t = set()t.add(booksheet.cell_value(0,j) + "_up")all_thing.append(t)l.append(t)frequent_thing.append(l)for j in range(1,c_num):l = []t = set()t.add(booksheet.cell_value(0,j) + "_down")all_thing.append(t)l.append(t)frequent_thing.append(l)k = 0;support = 30; # 最小支持度level = 2;def frequent_1(): #生成频繁1项集for i in range(0,len(frequent_thing)):count = 0for j in range(0,len(data)):if frequent_thing[i][0].issubset(data[j]): #ft[i][0]时否包含在data[j]中count += 1frequent_thing[i] += [count]i= 0while i < len(frequent_thing):if frequent_thing[i][1] < support:del frequent_thing[i];else:i = i + 1;def isfrequentThing(fre_thing): # 判断集合的子集是否都是频繁deset = set()relen = len(fre_thing)for i in range(0,len(all_thing)):tmp = 0deset = fre_thing.difference(all_thing[i]) #可以得到所有真子集if len(deset) == relen - 1:for j in range(0,len(frequent_thing)):if frequent_thing[j][0] == deset:tmp = 1breakif tmp == 0:return 0return 1;def fuction(listq, k): # 循环主函数initlist = [];initset = set();g = 0for i in listq:if len(i[0]) == k - 1: # 循环k-1项集for j in listq:if len(j[0]) == k - 1:if i[0] != j[0]:initset = i[0].union(j[0]);if len(initset) == k:if isfrequentThing(initset) == 1:count = 0 # 统计出现次数g = 0for g in range(0,len(data)):if initset.issubset(data[g]) == 1:count = count + 1tmp = 0for kt in range(0,len(initlist)):if initlist[kt][0] == initset:tmp = 1if tmp == 0:if count >= support:initlist = initlist + [[initset, count]]listq = listq + initlist #不单独列出频繁 1 2 3...,直接组合时判断是否为k项集,跑得慢但是省空间且好写return listqdef showResult():for i in range(0, len(frequent_thing)):if len(frequent_thing[i][0]) >= 2:print(frequent_thing[i][0])if __name__ == '__main__':frequent_1()frequent_thing = fuction(frequent_thing, level)frequent_thing = fuction(frequent_thing, level + 1)frequent_thing = fuction(frequent_thing, level + 2)showResult()

处理结果:

即得到的满足最低要求的频繁项集,可以认为同一项集内的蔬菜价格具有列出的相性。

如果觉得《【关联规则挖掘】基于Aprioir的蔬菜价格关联性分析》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。