網站首頁 編程語言 正文
Apriori使用一種稱作逐層搜索的迭代方法,k項集用于探索(k+1)項集。?首先,通過掃描數據庫,累計每個項的計數,并收集滿足最小支持度的項,找出頻繁1項集的集合。該集合記作L1。然后,L1用于找頻繁2項集的集合L2,L2用于找L3,如此下去直到不能再找到頻繁k項集。找每個Lk需要一次數據庫全掃描。
Apriori定律1 :如果某商品組合小于最小支持度,則就將它舍去,它的超集必然不是頻繁項集。
Apriori定律2 :如果一個集合是頻繁項集,即這個商品組合支持度大于最小支持度,則它的所有子集都是頻繁
數據庫有5個事務。設min_sup=60%,min_conf=80%
TID |
購買的商品 |
T100 |
{M,O,N,K,E,Y} |
T200 |
{D,O,N,K,E,Y} |
T300 |
{M,A,K,E} |
T400 |
{M,U,C,K,Y} |
T500 |
{C,O,O,K,I,E} |
在程序中,使用Apriori算法,找出頻繁項集
步驟:
- 每個項都是候選1項集的集合C1的成員。算法掃描所有的事務,獲得每個項,生成C1(見下文代碼中的create_C1函數)。然后對每個項進行計數。然后根據最小支持度從C1中刪除不滿足的項,從而獲得頻繁1項集L1。
- 對L1的自身連接生成的集合執行剪枝策略產生候選2項集的集合C2,然后,掃描所有事務,對C2中每個項進行計數。同樣的,根據最小支持度從C2中刪除不滿足的項,從而獲得頻繁2項集L2。
- 對L2的自身連接生成的集合執行剪枝策略產生候選3項集的集合C3,然后,掃描所有事務,對C3每個項進行計數。同樣的,根據最小支持度從C3中刪除不滿足的項,從而獲得頻繁3項集L3。
- 以此類推,對Lk-1的自身連接生成的集合執行剪枝策略產生候選k項集Ck,然后,掃描所有事務,對Ck中的每個項進行計數。然后根據最小支持度從Ck中刪除不滿足的項,從而獲得頻繁k項集。
?
vc代碼:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#define D 5 /*D數事務的個數*/
#define MinSupCount 3 /*最小事務支持度數*/
void main()
{
char a[5][6] = {
{ 'M','O','N','K','E','Y' },
{ 'D','O','N','K','E','Y' },
{ 'M','A','K','E' },
{ 'M','U','C','K','Y'},
{ 'C','O','O','K','I','E' }
};
char b[20], d[100], t, b2[100][10], b21[100][10];//b用來保存數據庫中的元素
int i, j, k, x = 0, flag = 1, c[20] = { 0 }, x1 = 0, i1 = 0, j1, counter = 0, c1[100] = { 0 }, flag1 = 1, j2, u = 0, c2[100] = { 0 }, n[20], v = 1;
int count[100], temp;
for (i = 0; i<D; i++)
{
for (j = 0; a[i][j] != '\0'; j++)
{
/*這個循環是用來判斷之前保存的是否和a[i][j]一樣,不一樣就保存,一樣就不保存*/
for (k = 0; k<x; k++)
{
if (b[k] != a[i][j]);//b[k]是已存儲的項,已存儲的項不等于現在存儲的,意味著有新元素。
else
{
flag = 0; break;
}
}
/*這個if是用來判斷是否相等*/
if (flag == 1)
{
b[x] = a[i][j];
x++;
}
else flag = 1;/*這個不保存,那就跳到下一個數*/
}
}
//數組b用于存放元素,即x就是元素種類的個數
/*計算篩選出的元素的支持度計數*/
for (i = 0; i<D; i++)
{
for (j = 0; a[i][j] != '\0'; j++)
{
for (k = 0; k<x; k++)/*這個x是上面b數組中元素個數,用b數組和a[i][j]數組中的每一行和每一列進行比較,用來記錄b數組每一個元素的支持度計數*/
{
if (a[i][j] == b[k])
{
c[k]++; break;
}
}
}
}
//數組c用于存放每個元素的支持度計數
for (k = 0; k<x; k++)
{
if (c[k] >= MinSupCount)
{
d[x1] = b[k];
count[x1] = c[k];
x1++;//L1中元素的個數
}
}
//數組D即為L1
/*對選出的項集中的元素進行排序*/
for (i = 0; i<x1 - 1; i++)
{
for (j = 0; j<x1 - i - 1; j++)
{
if (d[j]>d[j + 1])
{
t = d[j]; d[j] = d[j + 1]; d[j + 1] = t;
temp = count[j]; count[j] = count[j + 1]; count[j + 1] = temp;
}
}
}
/*打印出L1*/
printf("L1 elements are:\n");
for (i = 0; i<x1; i++)
{
printf("{%c} = %d ", d[i], count[i]);
}
printf("\n");
/*計算事務的項的個數,并且保存到n[]數組中*/
for (i = 0; i<D; i++)
{
for (j = 0; a[i][j] != '\0'; j++);
n[i] = j;
}
//數組n表示各事務中的元素個數
/*對a[][]數組的每一行進行排序*///對本例沒影響,因為已經排好了序
for (i = 0; i<D; i++)
{
for (j = 0; j<n[i] - 1; j++)
{
for (k = 0; k<n[i] - j - 1; k++)
{
if (a[i][k]>a[i][k + 1])
{
t = a[i][k];
a[i][k] = a[i][k + 1];
a[i][k + 1] = t;
}
}
}
}
/*把L1中的每一個元素都放在b2[i][0]中*/
j1 = x1;//j1初始設置為L1中元素的個數。
for (i = 0; i<j1; i++)
{
b2[i][0] = d[i];
}
/*把L1中的元素進行組合,K=2開始,表示x1個元素選K個元素的組合(x1是頻繁一項集個數)*/
for (k = 2; b2[0][0] != '\0'; k++)
{ /*u是用來計數候選集中的組合總數的*/
u = 0; v = 1;/*v 是用來在進行輸出各種組合的標識數 v=1 說明正在進行輸出*/
for (i = 0; i<100; i++)
{
c2[i] = 0;//頻繁項集Lk中元素的支持度計數
}
for (i = 0; i<j1; i++)//j1是Lk-1中的集合個數,初始為L1中的集合個數x1
{
for (i1 = i + 1; i1<j1; i1++)
{
for (j = 0; j<k - 2; j++)
{
//k-2之前只要有不同的,說明不能鏈接,標記flag1為0
if (b2[i][j] != b2[i1][j])
{
flag1 = 0; break;
}
}
/*進行組合的部分*/
if (flag1 == 1 && b2[i][k - 2] != b2[i1][k - 2])//可以鏈接并且最后一個元素不相等
{
for (j2 = 0; j2<k - 1; j2++)
{
b21[u][j2] = b2[i][j2]; //k-1個元素保持不變
}
b21[u][k - 1] = b2[i1][k - 2]; //第k個元素加上不同的那個
u++;
}
flag1 = 1;
}
}
//b21為候選集
counter = 0;//候選k項集中的元素在某個事務中出現的次數
for (i = 0; i<D; i++)/*找候選項集Ck中滿足支持度計數的*///掃描D
{
for (i1 = 0; i1<u; i1++)/*U=Ck中所有組合總數*/
{
for (j1 = 0; j1<k; j1++)/*K 代表一個組合中的元素個數*/
{
for (j = 0; a[i][j] != '\0'; j++)/*逐個比較每一行的元素*/
{
if (b21[i1][j1] == a[i][j])
{
counter++;
break;
}
}
}
if (counter == k)
c2[i1]++;
/*把候選集是事務的子集的計數記錄在c2數組中(只要滿足有k個元素在某個事務中,則計數加1)*/
counter = 0;
}
}
j1 = 0; temp = 0;/*這里的temp 是用來分行*/
/*對u種情況進行選擇,選出支持度計數大于2的*/
//j1對Lk中的集合個數計數,每次在輸出前重置。
for (i = 0; i<u; i++)
{
if (c2[i] >= MinSupCount)
{
if (v == 1)
{
printf("L%d elements are:\n", k);
v = 0;
}
printf("{");
for (j = 0; j<k; j++)/*輸出每種組合k 個元素*/
{
b2[j1][j] = b21[i][j];
printf("%c,", b2[j1][j]);
}
j1++; //Lk計數加1
printf("\b}");
printf(" = %d ", c2[i]);
if (0 == (temp + 1) % 3) //printf("\n");
temp++;
}
}
b2[j1][0] = '\0';//j1是Lk中的集合個數
if (b2[0][0] != '\0')
printf("\b \n");
}
system("pause");
}
原文鏈接:https://blog.csdn.net/Joyce_Joe/article/details/126980496
相關推薦
- 2022-07-12 k8s 之 service ip
- 2022-10-24 python正則表達中的re庫常用方法總結_python
- 2022-06-10 AJAX原理以及axios、fetch區別實例詳解_AJAX相關
- 2023-04-24 FFmpeg實戰之分離出PCM數據_C 語言
- 2024-03-05 git的使用
- 2022-05-10 SpringBoot端口已占用解決:配置端口號
- 2022-11-07 React?全面解析excel文件_React
- 2022-03-21 C++存儲方案和動態分配_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支