系列文章目录
文章目录
前言
本文主要介绍关联分析算法简介以及相关的案例举例说明与代码解释
一、关联分析介绍
关联分析算法是一种用于挖掘大规模数据集中有趣关系的方法。其目标是找出数据集中频繁出现的item集合,以及item之间的关联规则。
关联分析算法通常包括以下步骤:
- 1. 数据预处理:读取数据集,计算每个item的出现次数,并按照出现次数从高到低排序。
- 2. 生成候选项集:从单个item开始,逐步生成包含多个item的项集。
- 3. 计算项集的支持度:对于每个项集,计算其在数据集中出现的支持度,即项集中所有item在数据集中同时出现的次数。
- 4. 筛选频繁项集:根据设定的最小支持度筛选出频繁项集,即支持度大于等于最小支持度的项集。
- 5. 生成关联规则:对于每个频繁项集,生成所有可能的关联规则,计算其置信度,即关联规则中右部item在左部item出现的条件下出现的概率。
- 6. 筛选强关联规则:根据设定的最小置信度筛选出强关联规则,即置信度大于等于最小置信度的关联规则。
关联分析算法在许多领域中都有广泛的应用,例如市场营销、医疗诊断、推荐系统等。
二、关联分析算法实现以及相关的语句解释
2.1、 关联分析算法的C语言代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ITEMS 1000
#define MAX_TRANSACTIONS 1000
typedef struct {
int item;
int count;
} item_t;
typedef struct {
int n_items;
int items[MAX_ITEMS];
} transaction_t;
typedef struct {
int n_transactions;
transaction_t transactions[MAX_TRANSACTIONS];
item_t items[MAX_ITEMS];
int n_items;
int min_support;
int min_confidence;
} dataset_t;
void read_dataset(dataset_t *dataset, FILE *fp) {
char line[1000];
char *ptr;
while (fgets(line, 1000, fp)) {
transaction_t transaction;
transaction.n_items = 0;
ptr = strtok(line, " ");
while (ptr != NULL) {
transaction.items[transaction.n_items] = atoi(ptr);
transaction.n_items++;
ptr = strtok(NULL, " ");
}
dataset->transactions[dataset->n_transactions] = transaction;
dataset->n_transactions++;
}
}
void compute_item_counts(dataset_t *dataset) {
int i, j, k;
for (i = 0; i < dataset->n_transactions; i++) {
for (j = 0; j < dataset->transactions[i].n_items; j++) {
int item = dataset->transactions[i].items[j];
for (k = 0; k < dataset->n_items; k++) {
if (dataset->items[k].item == item) {
dataset->items[k].count++;
break;
}
}
if (k == dataset->n_items) {
item_t item_count;
item_count.item = item;
item_count.count = 1;
dataset->items[dataset->n_items] = item_count;
dataset->n_items++;
}
}
}
}
int compare_items(const void *a, const void *b) {
item_t *item1 = (item_t *) a;
item_t *item2 = (item_t *) b;
if (item1->count < item2->count) {
return 1;
} else if (item1->count > item2->count) {
return -1;
} else {
return 0;
}
}
void sort_items(dataset_t *dataset) {
qsort(dataset->items, dataset->n_items, sizeof(item_t), compare_items);
}
void print_dataset(dataset_t *dataset) {
int i, j;
printf("Transactions:\n");
for (i = 0; i < dataset->n_transactions; i++) {
printf("{ ");
for (j = 0; j < dataset->transactions[i].n_items; j++) {
printf("%d ", dataset->transactions[i].items[j]);
}
printf("}\n");
}
printf("Items:\n");
for (i = 0; i < dataset->n_items; i++) {
printf("%d: %d\n", dataset->items[i].item, dataset->items[i].count);
}
}
int main(int argc, char *argv[]) {
FILE *fp;
dataset_t dataset;
if (argc != 4) {
printf("Usage: %s <datafile> <min support> <min confidence>\n", argv[0]);
exit(1);
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("Error: could not open file %s\n", argv[1]);
exit(1);
}
dataset.n_transactions = 0;
dataset.n_items = 0;
dataset.min_support = atoi(argv[2]);
dataset.min_confidence = atoi(argv[3]);
read_dataset(&dataset, fp);
compute_item_counts(&dataset);
sort_items(&dataset);
print_dataset(&dataset);
fclose(fp);
return 0;
}
上述代码演示了关联分析算法中的数据预处理部分,包括读取数据集,计算每个item的出现次数,并对item按照出现次数从高到低排序。
2.2、相关解释
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
这几行代码是C语言中的头文件引入,其中`stdio.h`包含了输入输出函数,`stdlib.h`包含了一些常用的函数,如`malloc()`、`free()`等,`string.h`包含了字符串操作函数。
#define N 1000
#define M 1000
这两行代码定义了常量N和M,分别表示数据集中的事务数和物品的种类数,这里分别设置为1000。
int data[N][M];
int count[M];
这两行代码定义了整型数组`data`和`count`。其中`data`是一个二维数组,表示数据集中的事务,每行表示一个事务,每列表示一个物品,如果一个事务中包含某个物品,则对应的值为1,否则为0。`count`是一个一维数组,表示每个物品出现的次数。
void init()
{
FILE *fp = fopen("data.txt","r");
memset(count,0,sizeof(count));
char buf[1024];
int i = 0;
while(fgets(buf,sizeof(buf),fp))
{
char *p = strtok(buf," ");
while(p)
{
int k = atoi(p);
data[i][k] = 1;
count[k]++;
p = strtok(NULL," ");
}
i++;
}
fclose(fp);
}
这一部分代码是数据读取和预处理部分,包含了如下几个步骤:
1. 打开文件`data.txt`并读取其中的数据。
2. 将`count`数组所有元素初始化为0,以便于统计每个物品出现的次数。
3. 逐行读取`data.txt`文件中的数据,将每行数据转化为一个事务。
4. 对于每个事务,将其中出现的物品在`data`数组中标记为1,并将`count`数组对应的元素加1。
void output()
{
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
printf("%d ",data[i][j]);
}
printf("\n");
}
}
这一部分代码是输出`data`数组的内容,可以用于检查数据读取和预处理是否正确。
void generate_itemset(int *a,int n,int k,int cur)
{
if(cur==k)
{
for(int i=0;i<k;i++)
{
printf("%d ",a[i]);
}
printf("\n");
return;
}
for(int i=n;i<M;i++)
{
a[cur] = i;
generate_itemset(a,i+1,k,cur+1);
}
}
这一部分代码是生成项集的函数,其中参数`a`表示当前正在生成的项集,`n`表示当前项集中最后一个物品的编号,`k`表示当前项集中包含的物品个数,`cur`表示当前已经生成了几个物品。函数通过递归方式生成所有k个物品的组合,将其输出。
int get_support(int *a,int n,int k)
{
int sum = 0;
for(int i=0;i<N;i++)
{
int flag = 1;
for(int j=0;j<k;j++)
{
if(data[i][a[j]]==0)
{
flag = 0;
break;
}
}
if(flag==1)
{
sum++;
}
}
return sum;
}
这一部分代码是计算项集的支持度,其中参数`a`表示当前项集,`n`表示项集中物品的种类数,`k`表示项集中包含的物品个数。函数遍历`data`数组,对于每个事务,如果其中包含当前项集中的所有物品,则将计数器加1。最后返回计数器的值,即项集的支持度。
void filter_itemset(int *a,int n,int k,int min_sup)
{
int sup = get_support(a,n,k);
if(sup>=min_sup)
{
for(int i=0;i<k;i++)
{
printf("%d ",a[i]);
}
printf("(%d)\n",sup);
}
}
这一部分代码是筛选频繁项集,其中参数`a`表示当前项集,`n`表示项集中物品的种类数,`k`表示项集中包含的物品个数,`min_sup`表示最小支持度。函数调用`get_support()`函数计算项集的支持度,如果支持度不小于`min_sup`,则将其输出。
void generate_itemset_k(int *a,int n,int k,int *b,int cur)
{
if(cur==k-1)
{
for(int i=n+1;i<M;i++)
{
int flag = 1;
for(int j=0;j<k-1;j++)
{
if(a[j]!=b[j])
{
flag = 0;
break;
}
}
if(flag==1)
{
a[k-1] = i;
filter_itemset(a,n,k,min_sup);
}
}
return;
}
for(int i=n+1;i<M;i++)
{
a[cur] = i;
generate_itemset_k(a,i,k,b,cur+1);
}
}
这一部分代码是生成k+1项集的函数,其中参数`a`表示当前正在生成的k+1项集,`n`表示当前项集中最后一个物品的编号,`k`表示当前项集中包含的物品个数,`b`表示当前已知的频繁k项集,`cur`表示当前已经生成了几个物品。函数通过递归方式生成所有k+1个物品的组合,并调用`filter_itemset()`函数筛选频繁项集。
void generate_frequent_itemset(int min_sup)
{
int a[100];
for(int k=1;k<=M;k++)
{
generate_itemset(a,-1,k,0);
}
}
这一部分代码是生成所有频繁项集的函数,其中参数`min_sup`表示最小支持度。函数从1项集开始,依次生成2项集、3项集、4项集,直到最大项集。对于每个项集,调用`filter_itemset()`函数筛选频繁项集。
int main()
{
init();
output();
generate_frequent_itemset(2);
return 0;
}
这一部分代码是主函数,其中调用了`init()`函数读取数据和预处理,调用了`output()`函数输出数据,最后调用了`generate_frequent_itemset()`函数生成所有频繁项集。
总结
以上就是今天的内容~
最后欢迎大家点赞👍,收藏⭐,转发🚀,
如有问题、建议,请您在评论区留言💬哦。