Apriori算法基本流程:
0.设定最小支持度(数)和最小置信度(数)
1.遍历事件集,形成1项集,删去不满足的最小支持度(数)和最小置信度(数)的事件,得到频繁1项集。
2.由频繁k项集生成(k+1)项集,对于新项集中每个事件根据剪枝方法进行剪枝,在根据最小支持度和最小置信度进行删除和保留,得到频繁(k+1)项集。
3.循环2,直至产生的频繁(k'+1)项集为空为止。
其中剪枝条件为:频繁项集的所有子集都频繁,不频繁项集的所有项集都不频繁。
源文件:蔬菜价格3.xls (链接:https://pan.baidu.com/s/1b1df0KT482SBQSJdyNmpCw 密码:wdms)
该文件中,第一列为日期(2008.9.29-2010.1.30),第二列和第三列分别为蔬菜的名称和价格,第四列和第五列分别为肉类的名称和价格。
第一步:对数据进行预处理(1):把数据整理成比较有规律(reform.py)
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 24 23:14:19 2018
@author: Type真是太帅了
"""
'''
part 1
整理表格
'''
import xlrd;
import xlwt;
workbook=xlrd.open_workbook(r'C:\Users\71405\Desktop\大数据分析\03-04\蔬菜价格3.xls')
workspace=xlwt.Workbook(encoding='ascii')
booksheet=workbook.sheet_by_index(0)
createsheet=workspace.add_sheet('蔬菜价格',cell_overwrite_ok=True)
createsheet.write(0,0,'日期')
ri=2 #遍历原始第i行
rj=0#遍历原始第i列
wi=0#写入表格的第k行
wj=1
#创建表头
while ri<45:
rj=0
while rj<5:
if rj%2==1:
if booksheet.cell_value(ri,rj)!='':
createsheet.write(0,wj,booksheet.cell_value(ri,rj))
wj=wj+1
rj=rj+1
ri=ri+1
ri=48 #遍历原始第i行
rj=0#遍历原始第i列
wi=0#写入表格的第k行
wj=1
while ri<22326:
if ri%47==1:#新的一天
wi=wi+1
createsheet.write(wi,0,booksheet.cell_value(ri,0))
else:
rj=1
while rj<5:
if rj%2==1:
if booksheet.cell_value(ri,rj)!='':
#print(booksheet.cell_value(ri,rj+1))
if booksheet.cell_value(ri,rj+1)!='':
createsheet.write(wi,wj,booksheet.cell_value(ri,rj+1))
wj=wj%63+1
rj=rj+1
ri=ri+1
workspace.save('蔬菜价格2.xls')#生成表格1 每个行表示日期 列表示货品 单元格表示价格
'''
part 2
生成涨跌分布图
单元格类似同上
-1表示价格同比上一日增长
0 表示不变
1表示跌
其中 数据丢失的取前几日的值(如果前几日均丢失则取后几日的值)
'''
得到蔬菜价格2.xls:
对数据进行预处理(2):填充表格中空缺部分(fillform.py):
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 25 14:05:45 2018
@author: Type真是太帅了
"""
'''填充表格中的空缺部分
取前几日的值
如果前几日均丢失则取后几日的值
如果均丢失则恒为0
'''
import xlrd;
import xlwt;
workbook=xlrd.open_workbook(r'C:\Users\71405\Desktop\大数据分析\03-04\蔬菜价格2.xls')
workspace=xlwt.Workbook(encoding='ascii')
booksheet=workbook.sheet_by_index(0)
createsheet=workspace.add_sheet('蔬菜价格',cell_overwrite_ok=True)
ri=1
rj=1
while ri<475:
rj=0
while rj<64:
if booksheet.cell_value(ri,rj)!='':
createsheet.write(ri,rj,booksheet.cell_value(ri,rj))
else:
# print(ri,rj)
i=ri
tmp=0 #判断是否找到
while i>0:
if booksheet.cell_value(i,rj)!='':
tmp=1
createsheet.write(ri,rj,booksheet.cell_value(i,rj))
break
i=i-1
if tmp==0:
i=ri
while i<475:
if booksheet.cell_value(i,rj)!='':
tmp=1
createsheet.write(ri,rj,booksheet.cell_value(i,rj))
break
i=i+1
if tmp==0:
createsheet.write(ri,rj,0)
rj=rj+1
ri=ri+1
rj=0;
while rj<64:
createsheet.write(0,rj,booksheet.cell_value(0,rj))
rj=rj+1
workspace.save('蔬菜价格1.xls')
得到蔬菜价格1.xls:
数据预处理(3):得到涨跌数据(rise&fall.py):
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 25 13:46:15 2018
@author: Type真是太帅了
"""
'''
part 2
生成涨跌分布图
单元格类似同上
1表示价格同比上一日增长
0 表示不变
-1表示跌
其中 数据丢失的取前几日的值(如果前几日均丢失则取后几日的值)
'''
import xlrd;
import xlwt;
workbook=xlrd.open_workbook(r'C:\Users\71405\Desktop\大数据分析\03-04\蔬菜价格1.xls')
workspace=xlwt.Workbook(encoding='ascii')
booksheet=workbook.sheet_by_index(0)
createsheet=workspace.add_sheet('蔬菜价格',cell_overwrite_ok=True)
ri=0
rj=0
wi=0
wj=0
while ri<475:
createsheet.write(ri,0,booksheet.cell_value(ri,0))
ri=ri+1
while rj<64:
createsheet.write(0,rj,booksheet.cell_value(0,rj))
rj=rj+1
#生成横纵表头
ri=2;
rj=1;
while ri<475:
rj=1
while rj<64:
d=booksheet.cell_value(ri,rj)-booksheet.cell_value(ri-1,rj)
if d>0:
createsheet.write(ri,rj,1)
if d<0:
createsheet.write(ri,rj,-1)
if d==0:
createsheet.write(ri,rj,0)
rj=rj+1
ri=ri+1
workspace.save('蔬菜价格.xls')
最后得到最终预处理的结果 蔬菜价格.xls:
关联分析:
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 29 16:53:47 2018
@author: Type真是太帅了
"""
import xlrd
workbook=xlrd.open_workbook(r'C:\Users\71405\Desktop\大数据分析\03-04\蔬菜价格.xls')
booksheet=workbook.sheet_by_index(0)
N=booksheet.nrows-2;#减去第一行的标题栏以及第二行的空行 得出事件的个数
maxi=0#统计单日最多有多少个蔬菜存在涨跌
i=2
while i<=474:
j=1
tmp=0
while j<=63:
if booksheet.cell_value(i,j)!=0:
tmp=tmp+1
j=j+1
if tmp>maxi:
maxi=tmp
i=i+1
data=[]
temp=set()
i=2
'''
将单日中出现的价格涨跌全部列入data
其中为了区分涨跌,用up后缀表示涨的蔬菜名称,用down表示跌
'''
while i<=474:
j=1
temp=set()
while j<=63:
if booksheet.cell_value(i,j)==1:
temp.add(booksheet.cell_value(0,j)+"_down")
elif booksheet.cell_value(i,j)==-1:
temp.add(booksheet.cell_value(0,j)+"_up")
j=j+1
data.append(temp)
i=i+1
i=1
ele=[]#所有事件
seti=[]#用于储存所有的频繁项集
while i<=63:
le=[]
tmp=set()
tmp.add(booksheet.cell_value(0,i)+"_up")
ele.append(tmp)
le.append(tmp)
seti.append(le)
i=i+1
i=1
while i<=63:
le=[]
tmp=set()
tmp.add(booksheet.cell_value(0,i)+"_down")
ele.append(tmp)
le.append(tmp)
seti.append(le)
i=i+1
i=0;
k=0;
support=30; #最小支持度
level=2;
'''
生成频繁1项集
'''
while i<len(seti):
count=0;
j=0;
while j<len(data):
if seti[i][0].issubset(data[j]):
count=count+1;
j=j+1;
seti[i]=seti[i]+[count];
i=i+1;
i=0;
while i<len(seti):
if seti[i][1]<support:
del seti[i];
else:
i=i+1;
def isfreset(freset):#判断集合的子集是否都是频繁
deset=set()
relen=len(freset)
i=0
while i<len(ele):
j=0
tmp=0
deset=freset.difference(ele[i])
if len(deset)==relen-1:
while j<len(seti):
if seti[j][0]==deset:
tmp=1
break
j=j+1
if tmp==0:
return 0
i=i+1
return 1;
def fuction (listq,k):#循环主函数
initlist=[];
initset=set();
g=0
for 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 isfreset(initset)==1:
count=0#统计出现次数
g=0
while g<len(data):
if initset.issubset(data[g])==1:
count=count+1
g=g+1
tmp=0
kt=0
while kt<len(initlist):
if initlist[kt][0]==initset:
tmp=1
kt=kt+1
if tmp==0:
if count>=support:
initlist=initlist+[[initset,count]]
listq=listq+initlist
return listq
seti=fuction(seti,level)
seti=fuction(seti,level+1)
seti=fuction(seti,level+2)
i=0
while i<len(seti):
if len(seti[i][0])>=2:
print(seti[i][0])
i=i+1
最后得出结果:
{'大白菜_up', '菠菜_up'}
{'大白菜_up', '韭菜_up'}
{'大白菜_up', '油菜_up'}
{'大头菜_up', '大白菜_up'}
{'大白菜_up', '芸豆_up'}
{'大白菜_up', '西红柿_up'}
{'大白菜_up', '鲜蘑菇_up'}
{'大白菜_up', '菜花_up'}
{'大白菜_up', '尖椒_up'}
{'菠菜_up', '韭菜_up'}
{'油菜_up', '菠菜_up'}
{'大头菜_up', '菠菜_up'}
{'菠菜_up', '芸豆_up'}
{'茄子_up', '菠菜_up'}
{'黄瓜_up', '菠菜_up'}
{'菠菜_up', '茭瓜_up'}
{'茼蒿_up', '菠菜_up'}
{'菠菜_up', '尖椒_up'}
{'大头菜_up', '韭菜_up'}
{'芸豆_up', '韭菜_up'}
{'黄瓜_up', '韭菜_up'}
{'菜花_up', '韭菜_up'}
{'芸豆_up', '芹菜_up'}
{'油菜_up', '芸豆_up'}
{'茄子_up', '油菜_up'}
{'鲜蘑菇_up', '油菜_up'}
{'油菜_up', '尖椒_up'}
{'大头菜_up', '芸豆_up'}
{'大头菜_up', '茄子_up'}
{'大头菜_up', '茭瓜_up'}
{'大头菜_up', '菜花_up'}
{'大头菜_up', '尖椒_up'}
{'茄子_up', '芸豆_up'}
{'黄瓜_up', '芸豆_up'}
{'芸豆_up', '茭瓜_up'}
{'芸豆_up', '菜花_up'}
{'茼蒿_up', '芸豆_up'}
{'尖椒_up', '芸豆_up'}
{'大白菜_down', '芸豆_up'}
{'茄子_up', '青椒_up'}
{'茄子_up', '尖椒_up'}
{'青椒_up', '茭瓜_up'}
{'尖椒_up', '青椒_up'}
{'黄瓜_up', '茭瓜_up'}
{'鲜蘑菇_up', '茭瓜_up'}
{'茭瓜_up', '菜花_up'}
{'尖椒_up', '菜花_up'}
{'菠菜_down', '大白菜_down'}
{'大头菜_down', '大白菜_down'}
{'芸豆_down', '大白菜_down'}
{'西红柿_down', '大白菜_down'}
{'黄瓜_down', '大白菜_down'}
{'鲜蘑菇_down', '大白菜_down'}
{'大白菜_down', '菜花_down'}
{'大白菜_down', '尖椒_down'}
{'菠菜_down', '韭菜_down'}
{'菠菜_down', '油菜_down'}
{'菠菜_down', '大头菜_down'}
{'菠菜_down', '芸豆_down'}
{'菠菜_down', '茄子_down'}
{'菠菜_down', '黄瓜_down'}
{'菠菜_down', '茭瓜_down'}
{'菠菜_down', '鲜蘑菇_down'}
{'菠菜_down', '菜花_down'}
{'菠菜_down', '茼蒿_down'}
{'菠菜_down', '尖椒_down'}
{'黄瓜_down', '韭菜_down'}
{'油菜_down', '芸豆_down'}
{'油菜_down', '茄子_down'}
{'油菜_down', '茼蒿_down'}
{'大头菜_down', '菜花_down'}
{'芸豆_down', '茄子_down'}
{'芸豆_down', '青椒_down'}
{'西红柿_down', '芸豆_down'}
{'黄瓜_down', '芸豆_down'}
{'芸豆_down', '菜花_down'}
{'芸豆_down', '茼蒿_down'}
{'芸豆_down', '尖椒_down'}
{'青椒_down', '茄子_down'}
{'西红柿_down', '茄子_down'}
{'黄瓜_down', '茄子_down'}
{'茄子_down', '菜花_down'}
{'青椒_down', '尖椒_down'}
{'西红柿_down', '黄瓜_down'}
{'黄瓜_down', '菜花_down'}
以上每组表明强烈的涨跌影响关系,再进行分析涨跌关系即可。
--------------------这里是分割线
2019/11/8修改:
由于大批人反映问题,现在此说明,由于给定的表格中存在‘\u3000’的长空格,与其他单空格' '等不同,而且不太好在之前的函数内修改,最简单的办法是又新加一个函数replace来把'\u3000'替换为空'':(当时偷懒直接在excel把长空格替换为空了)
import xlrd;
import xlwt;
workbook=xlrd.open_workbook(r'D:\大数据分析\03-04\蔬菜价格2.xls')
workspace=xlwt.Workbook(encoding='ascii')
booksheet=workbook.sheet_by_index(0)
createsheet=workspace.add_sheet('蔬菜价格',cell_overwrite_ok=True)
ri=1
rj=1
while ri<475:
rj=0
while rj<64:
if booksheet.cell_value(ri,rj)=='\u3000' or ' ':
createsheet.write(ri,rj,'')
else:
createsheet.write(ri,rj,booksheet.cell_value(ri,rj))
rj=rj+1
ri=ri+1
rj=0;
while rj<64:
createsheet.write(0,rj,booksheet.cell_value(0,rj))
rj=rj+1
workspace.save('蔬菜价格1.xls')
然后之后再用'蔬菜价格1.xls'做fillform、rise&fall和分析即可。