Apriori算法基本流程:

0.设定最小支持度(数)和最小置信度(数)

1.遍历事件集,形成1项集,删去不满足的最小支持度(数)和最小置信度(数)的事件,得到频繁1项集。

2.由频繁k项集生成(k+1)项集,对于新项集中每个事件根据剪枝方法进行剪枝,在根据最小支持度和最小置信度进行删除和保留,得到频繁(k+1)项集。

3.循环2,直至产生的频繁(k'+1)项集为空为止。

其中剪枝条件为:频繁项集的所有子集都频繁,不频繁项集的所有项集都不频繁。

源文件:蔬菜价格3.xls  (链接:https://pan.baidu.com/s/1b1df0KT482SBQSJdyNmpCw 密码:wdms)

使用Apriori实现蔬菜价格涨跌关联分析_desktop

该文件中,第一列为日期(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:

使用Apriori实现蔬菜价格涨跌关联分析_大数据分析_02

对数据进行预处理(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:

使用Apriori实现蔬菜价格涨跌关联分析_频繁项集_03

数据预处理(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:

使用Apriori实现蔬菜价格涨跌关联分析_数据_04

关联分析:

# -*- 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和分析即可。