1. 程式人生 > >關聯規則挖掘算法

關聯規則挖掘算法

mit get 支持 msg 查看 關聯 submit selected 集中

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) { Init(); } //初始化程序主界面 private void Init() { this.Text = "關聯規則算法"; tData.Clear(); C0.Clear(); L0.Clear(); this.TDataView.Items.Clear(); this.CResultView.Items.Clear(); this.LResultView.Items.Clear(); this.ItemList.Items.Clear(); this.TDataView.Items.Add("TID\t商品ID的列表\n"); this.ItemList.Items.Add("I1"); this.ItemList.Items.Add("I2"); this.ItemList.Items.Add("I3"); this.ItemList.Items.Add("I4"); this.ItemList.Items.Add("I5"); this.confList.Items.Add("I1"); this.confList.Items.Add("I2"); this.confList.Items.Add("I3"); this.confList.Items.Add("I4"); this.confList.Items.Add("I5"); this.ListConf.Items.Add("I1"); this.ListConf.Items.Add("I2"); this.ListConf.Items.Add("I3"); this.ListConf.Items.Add("I4"); this.ListConf.Items.Add("I5"); this.txtbMinSup.Text = minSup.ToString(); step = 0; finish = false; } //刪除事務 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); } //示例事務 #region private void Example_Click(object sender, EventArgs e) { example(); } private void example() { 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); } #endregion //最小支持度閾值變化 private void txtbMinSup_TextChanged(object sender, EventArgs e) { try { //獲得最小支持度閾值,將其賦給minSup minSup = int.Parse(this.txtbMinSup.Text); } catch { MessageBox.Show("非法輸入!"); this.txtbMinSup.Text = minSup.ToString(); } } //添加事務 #region //獲得事務ID號 public string GetTID() { return this.TID.Text; } //獲得事務中的項 public ArrayList GetItemList() { ArrayList items = new ArrayList(); for (int i = 0; i < this.SelectItemList.Items.Count; i++) { string itemID = this.SelectItemList.Items[i].ToString(); items.Add(itemID); } items.Sort(); return items; } //添加項到備選欄 private void Add_Click(object sender, EventArgs e) { if (this.ItemList.SelectedIndex < 0) return; for (int i = 0; i < this.SelectItemList.Items.Count; i++) { if (this.SelectItemList.Items[i] == this.ItemList.SelectedItem) return; } this.SelectItemList.Items.Add(this.ItemList.SelectedItem); } //從備選欄中刪除項 private void Delete_Click(object sender, EventArgs e) { if (this.SelectItemList.SelectedIndex < 0) return; this.SelectItemList.Items.RemoveAt(this.SelectItemList.SelectedIndex); } //確定添加事務到挖掘準備框 private void Submit_Click(object sender, EventArgs e) { insertform(); } private void insertform() { trans t = new trans(); t.tID = GetTID(); t.items = GetItemList(); AddItemToDataView(t); tData.Add(t); } 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); } //取消添加事務到挖掘準備框 private void Cancel_Click(object sender, EventArgs e) { this.SelectItemList.Items.Clear(); } #endregion //計算下一項 private void Next_Click(object sender, EventArgs e) { if (finish == true) { this.Next.Text = "計算下一步"; Init(); return; } ArrayList OldL = new ArrayList(L0); //增加步驟計數,用來決定計算C或者是L。 step++; //計算L並顯示L視圖 #region //計算L if (step % 2 == 1) { //找出頻繁1項集L1 if (step == 1) { //當前事務總數tData.Count for (int i = 0; i < tData.Count; i++) { trans t = (trans)tData[i]; //當前一個事務中的項的總數t.items.Count for (int j = 0; j < t.items.Count; j++) { bool flag = true; //判斷一下當前項是不是已經被計算過支持度,L0用於存放頻繁K項集(items和sup) for (int k = 0; k < L0.Count; k++) { string mda=((itemAndSup)L0[k]).items[0].ToString(); 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); } } //更新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); } this.resultBox.Items.Clear(); this.resultBox.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 ResultLine = ""; for (int j = 0; j < items.Count; j++) { ResultLine = ResultLine + items[j].ToString() + ","; } ResultLine = ResultLine + "\t" + sup + "\n"; this.resultBox.Items.Add(ResultLine); } } else { this.resultBox.Items.Clear(); this.resultBox.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 ResultLine = ""; for (int j = 0; j < items.Count; j++) { ResultLine = ResultLine + items[j].ToString() + ","; } ResultLine = ResultLine + "\t" + sup + "\n"; this.resultBox.Items.Add(ResultLine); } OldL.Clear(); 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); } } //更新L說明 if (L0.Count != 0) this.Msg.Text = "比較候選支持度計數與最小支持度計數"; else { this.Msg.Text = "由於L為空,算法終止"; this.Next.Text = "完成(重新開始)"; finish = true; } } #endregion //計算C並顯示C視圖 #region //計算C else { //通過將Lk-1與Lk-1自身連接產生Ck,Lk-1中的items項的順序已經排好為由小到大 C0.Clear(); for (int i = 0; i < L0.Count; i++) { //items0(Lk)與Lk合並 ArrayList items0 = ((itemAndSup)L0[i]).items; //將可以合並到items0的值items[k]添加到addItem中,以防止後面重復添加 ArrayList addItem = new ArrayList(); for (int j = 0; j < L0.Count; j++) { //當自身與自身組合時,跳過這一步 if (j == i) continue; //Lk本身,將被合並到items0 ArrayList items1 = ((itemAndSup)L0[j]).items; for (int k = 0; k < items1.Count; k++) { //當前items1[k]是否比items0中最後一個數值小,如果小的話則進行下一次循環 if (((string)items1[k]).CompareTo((string)items0[items0.Count - 1]) <= 0) continue; //如果items[1]已經合並到items0的話,則進行下一次循環 if (addItem.Contains(items1[k])) continue; //對items0+items1[k]進行Ck與Lk-1測試,判斷Ck是否是Lk-1的超集, //如果不是超集 則合並後的項集的支持度肯定小於最小支持度閾值 bool mmm = ItemTest(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); } //更新C視圖說明 if (C0.Count != 0) this.Msg.Text = "由L產生C,並掃描D,對每個候選計數"; else { this.Msg.Text = "由於C為空,算法終止"; this.Next.Text = "完成(重新開始)"; finish = true; } } #endregion } //計算項集的支持度Sup private int FindItemSup(ArrayList item) { //初始化支持度為0 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++) { //只要有一個項不存在於事務中,flag=0,則此項集不存於事務中 if (!(t.items.Contains(item[j]))) { flag = false; break; } } //如果項集存在於事務中,則支持度加1 if (flag == true) count++; } //返回支持度計數 return count; } //對items0+items1[k]進行Ck與Lk-1測試,判斷Ck是否是Lk-1的超集,如果是超集,則返回true,如果不是則返回false 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(); for (int j = 0; j < L0.Count; j++) { bool flag2=true; ArrayList tempItems = ((itemAndSup)L0[j]).items; for (int k = 0; k < tempItems.Count;k++ ) { if (newItems[k]!=tempItems[k]) { flag2 = false; break; } } //只要有一個存在於Lk-1中即可返回true,結束本測試 if (flag2==true) { return true; } } } //如果所有對比均進行完畢,則返回false return false; } //推導項裏添加項集 private void btnAddConf_Click(object sender, EventArgs e) { if (this.confList.SelectedIndex < 0) return; for (int i = 0; i < this.confEnd.Items.Count; i++) { if (this.confEnd.Items[i] == this.confList.SelectedItem) return; } this.confEnd.Items.Add(this.confList.SelectedItem); } //推導項裏刪除項 private void btnCancelConf_Click(object sender, EventArgs e) { if (this.confEnd.SelectedIndex < 0) return; this.confEnd.Items.RemoveAt(this.confEnd.SelectedIndex); } //關聯項添加項集 private void btnConf_Click(object sender, EventArgs e) { if (this.ListConf.SelectedIndex < 0) return; for (int i = 0; i < this.EndConf.Items.Count; i++) { if (this.EndConf.Items[i] == this.ListConf.SelectedItem) return; } this.EndConf.Items.Add(this.ListConf.SelectedItem); } //關聯項刪除項 private void BtnConfCancel_Click(object sender, EventArgs e) { if (this.EndConf.SelectedIndex < 0) return; this.EndConf.Items.RemoveAt(this.EndConf.SelectedIndex); } //計算置信度 private void confBtn_Click(object sender, EventArgs e) { float sumconf = FindItemSup(insertSumConf()); float refconf = FindItemSup(insertConf()); float result = (sumconf / refconf) * tData.Count; txtConfidence.Text = (result).ToString(); } //獲取推導項集 private ArrayList insertConf() { ArrayList items = new ArrayList(); for (int i = 0; i < this.confEnd.Items.Count; i++) { string itemID = this.confEnd.Items[i].ToString(); items.Add(itemID); } items.Sort(); return items; } //獲取關聯項集 private ArrayList insertSumConf() { ArrayList items = new ArrayList(); for (int i = 0; i < this.EndConf.Items.Count; i++) { string itemID = this.EndConf.Items[i].ToString(); items.Add(itemID); } items.Sort(); return items; } } }

關聯規則挖掘算法