关联规则挖掘算法_简述数据挖掘之关联规则算法

5373bc60691edd4f2ec182d8b4fafd02.png

首先通过一个实际场景来给大家简单介绍一下关联规则算法:

客户在餐厅点菜时,面对菜单中大量的菜品信息,往往无法迅速找到满意的菜品,既增加了点菜的时间,也降低了客户的就餐体验。实际上,菜品的合理搭配是有规律可循的:顾客的饮食习惯、菜品的荤素和口味,有些菜品之间是相互关联的,而有些菜品之间是对立或竞争关系(负关联),而这些规律都隐藏在大量的历史菜单数据中,如果能够通过数据挖掘发现客户点餐的规则,就可以快速识别客户的口味,当用户下了某个菜品中的订单时推荐相关联的菜品,引导客户消费,提高顾客的就餐体验和餐饮企业的业绩水平。

关联规则分析也称为购物篮分析,最早是为了发现超市销售数据库中不同的商品之间的关联关系。例如,一个超市的经理想要更多地了解顾客的购物习惯,比如哪组商品可能会在一次购物中同时购买?或者某顾客购买了个人电脑,那该顾客三个月后购买数码相机的概率又多大?他可能会发现如果购买了面包的顾客同时非常有可能购买牛奶,这就导出了一条关联规则“面包》牛奶”,其中面包成为规则的前项,而牛奶称为后项。通过对面包降低售价进行促销,而适当提高牛奶的售价,关联销售出的牛奶就有可能增加超市整体的利润。

关联规则分析是数据挖掘中最活跃的研究方法之一,目的是在一个数据集中找出各项之间的关联关系,而这种关系并没有在数据中直接表现出来。常用的关联规则算法如下:

1,Apriori

关联规则最常用也是最经典的挖掘频繁项集的算法,其核心思想是通过连接产生候选项及其支持度然后通过剪枝生成频繁项集

2,FP-Tree

针对Apriori算法的固有的多次扫描事务数据集的缺陷,提出的不产生候选项频繁项集的方法。Apriori和FP_-Tree都是寻找频繁项集的算法

3,Eclat算法

Eclat算法是一种深度优先算法,采用垂直数据表示形式,在概念格理论的基础上利用基于前缀的等价关系将搜索空间划分为较小的空间

4,灰色关联法

分析和确定各因素之间的影响程度或是若干个因素(子序列)对主因素(母序列)的贡献度而进行的一种分析方法。

C语言实现的Apriori关联规则算法 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Collections; namespace Apriori { //事务 struct trans { public string tID; public ArrayList items; } //项集和支持度计数 struct itemAndSup { public ArrayList items; public int sup; } public partial class Form1 : Form { private ArrayList tData = new ArrayList(); //事务数据 private int minSup = 2; //最小支持度计数阀值 private ArrayList C0 = new ArrayList(); //L的超集 private ArrayList L0 = new ArrayList(); //频繁k项集 private int step; //已完成步骤数 private bool finish; //算法是否完成 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Reset(); //test1(); } private void Reset() { tData.Clear(); C0.Clear(); L0.Clear(); this.TDataView.Items.Clear(); this.CResultView.Items.Clear(); this.LResultView.Items.Clear(); this.TDataView.Items.Add("TID\t商品ID的列表\n"); this.MinSupTextBox.Text = minSup.ToString(); step = 0; finish = false; } private void AddItem_Click(object sender, EventArgs e) { Trans addTrans = new Trans(); if (addTrans.ShowDialog() == DialogResult.OK) { trans t = new trans(); t.tID = addTrans.GetTID(); t.items = addTrans.GetItemList(); AddItemToDataView(t); tData.Add(t); } } private void DeleteItem_Click(object sender, EventArgs e) { if (this.TDataView.SelectedIndex == 0) return; tData.RemoveAt(this.TDataView.SelectedIndex - 1); this.TDataView.Items.RemoveAt(this.TDataView.SelectedIndex); } private void Next_Click(object sender, EventArgs e) { if (finish == true) { this.Next.Text = "计算下一步"; Reset(); return; } ArrayList OldL = new ArrayList(L0); //增加步骤计数,用来决定计算C或者是L。 step++; //计算L if (step % 2 == 1) { //找出频繁1项集L1 if (step == 1) { for (int i = 0; i < tData.Count; i++) { trans t = (trans)tData[i]; for (int j = 0; j < t.items.Count; j++) { bool flag = true; for (int k = 0; k < L0.Count; k++) { if (((itemAndSup)L0[k]).items[0] == t.items[j]) { flag = false; break; } } if (flag == false) continue; ArrayList items = new ArrayList(); items.Add(t.items[j]); int sup = FindItemSup(items); if (sup >= minSup) { itemAndSup temp = new itemAndSup(); temp.sup = sup; temp.items = items; L0.Add(temp); } } } } //通过Ck来确定Lk else { L0.Clear(); for (int i = 0; i < C0.Count; i++) { itemAndSup temp = (itemAndSup)C0[i]; if (temp.sup >= minSup) L0.Add(temp); } } //对L0排序 { } //更新L的视图 { if (L0.Count != 0) { this.LResultView.Items.Clear(); this.LResultView.Items.Add("项集\t支持度计数\n"); for (int i = 0; i < L0.Count; i++) { ArrayList items = ((itemAndSup)L0[i]).items; int sup = ((itemAndSup)L0[i]).sup; string LResultLine = ""; for (int j = 0; j < items.Count; j++) { LResultLine = LResultLine + items[j].ToString() + ","; } LResultLine = LResultLine + "\t" + sup + "\n"; this.LResultView.Items.Add(LResultLine); } } else { this.LResultView.Items.Clear(); this.LResultView.Items.Add("项集\t支持度计数\n"); for (int i = 0; i < OldL.Count; i++) { ArrayList items = ((itemAndSup)OldL[i]).items; int sup = ((itemAndSup)OldL[i]).sup; string LResultLine = ""; for (int j = 0; j < items.Count; j++) { LResultLine = LResultLine + items[j].ToString() + ","; } LResultLine = LResultLine + "\t" + sup + "\n"; this.LResultView.Items.Add(LResultLine); } } } //更新说明 { if (L0.Count != 0) this.Msg.Text = "比较候选支持度计数与最小支持度计数"; else { this.Msg.Text = "由于L为空,算法终止"; this.Next.Text = "完成(重新开始)"; finish = true; } } } //计算C else { //通过将Lk-1与自身连接产生Ck C0.Clear(); for (int i = 0; i < L0.Count; i++) { ArrayList items0 = ((itemAndSup)L0[i]).items; ArrayList addItem = new ArrayList(); for (int j = 0; j < L0.Count; j++) { if (j == i) continue; ArrayList items1 = ((itemAndSup)L0[j]).items; for (int k = 0; k < items1.Count; k++) { /* if (items0.Contains(items1[k])) continue; */ //改进 if (((string)items1[k]).CompareTo((string)items0[items0.Count - 1]) <= 0) continue; if (addItem.Contains(items1[k])) continue; //对items0+items1[k]进行子集测试 if (ItemTest(items0, items1[k]))//测试通过 { ArrayList items = new ArrayList(items0); items.Add(items1[k]); items.Sort(); int sup = FindItemSup(items); itemAndSup temp = new itemAndSup(); temp.items = items; temp.sup = sup; C0.Add(temp); addItem.Add(items1[k]); } } } } //更新C的视图 { this.CResultView.Items.Clear(); this.CResultView.Items.Add("项集\t支持度计数\n"); for (int i = 0; i < C0.Count; i++) { ArrayList items = ((itemAndSup)C0[i]).items; int sup = ((itemAndSup)C0[i]).sup; string CResultLine = ""; for (int j = 0; j < items.Count; j++) { CResultLine = CResultLine + items[j].ToString() + ","; } CResultLine = CResultLine + "\t" + sup + "\n"; this.CResultView.Items.Add(CResultLine); } } //更新说明 { if (C0.Count != 0) this.Msg.Text = "由L产生C,并扫描D,对每个候选计数"; else { this.Msg.Text = "由于C为空,算法终止"; this.Next.Text = "完成(重新开始)"; finish = true; } } } } //把事务添加到视图 private void AddItemToDataView(trans t) { string transLine = ""; //添加TID transLine = transLine + t.tID + "\t"; //添加商品ID列表 for (int i = 0; i < t.items.Count; i++) { transLine = transLine + t.items[i].ToString() + ","; } transLine = transLine + "\n"; this.TDataView.Items.Add(transLine); } //计算项集的Sup private int FindItemSup(ArrayList item) { int count = 0; for (int i = 0; i < tData.Count; i++) { trans t = (trans)tData[i]; bool flag = true; for (int j = 0; j < item.Count; j++) { if (!(t.items.Contains(item[j]))) { flag = false; break; } } if (flag == true) count++; } return count; } //对items0+items1[k]进行子集测试 private bool ItemTest(ArrayList items, object addItem) { for (int i = 0; i < items.Count; i++) { ArrayList newItems = new ArrayList(items); newItems.RemoveAt(i); newItems.Add(addItem); newItems.Sort(); bool flag1 = false, flag2; for (int j = 0; j < L0.Count; j++) { ArrayList tempItems = ((itemAndSup)L0[j]).items; flag2 = true; for (int k = 0; k < tempItems.Count; k++) { if (tempItems[k] != newItems[k]) { flag2 = false; break; } } if (flag2 == true) { flag1 = true; break; } } if (flag1 == false) return false; } return true; } //test1 private void test1() { trans t1 = new trans(); t1.tID = "T100"; t1.items = new ArrayList(); t1.items.Add("I1"); t1.items.Add("I2"); t1.items.Add("I5"); AddItemToDataView(t1); tData.Add(t1); trans t2 = new trans(); t2.tID = "T200"; t2.items = new ArrayList(); t2.items.Add("I2"); t2.items.Add("I4"); AddItemToDataView(t2); tData.Add(t2); trans t3 = new trans(); t3.tID = "T300"; t3.items = new ArrayList(); t3.items.Add("I2"); t3.items.Add("I3"); AddItemToDataView(t3); tData.Add(t3); trans t4 = new trans(); t4.tID = "T400"; t4.items = new ArrayList(); t4.items.Add("I1"); t4.items.Add("I2"); t4.items.Add("I4"); AddItemToDataView(t4); tData.Add(t4); trans t5 = new trans(); t5.tID = "T500"; t5.items = new ArrayList(); t5.items.Add("I1"); t5.items.Add("I3"); AddItemToDataView(t5); tData.Add(t5); trans t6 = new trans(); t6.tID = "T600"; t6.items = new ArrayList(); t6.items.Add("I2"); t6.items.Add("I3"); AddItemToDataView(t6); tData.Add(t6); trans t7 = new trans(); t7.tID = "T700"; t7.items = new ArrayList(); t7.items.Add("I1"); t7.items.Add("I3"); AddItemToDataView(t7); tData.Add(t7); trans t8 = new trans(); t8.tID = "T800"; t8.items = new ArrayList(); t8.items.Add("I1"); t8.items.Add("I2"); t8.items.Add("I3"); t8.items.Add("I5"); AddItemToDataView(t8); tData.Add(t8); trans t9 = new trans(); t9.tID = "T900"; t9.items = new ArrayList(); t9.items.Add("I1"); t9.items.Add("I2"); t9.items.Add("I3"); AddItemToDataView(t9); tData.Add(t9); } private void Example_Click(object sender, EventArgs e) { test1(); } private void MinSupTextBox_TextChanged(object sender, EventArgs e) { try { minSup = int.Parse(this.MinSupTextBox.Text); } catch { MessageBox.Show("非法输入!"); this.MinSupTextBox.Text = minSup.ToString(); } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值