A-Priori算法
来源:互联网 发布:华语乐坛唱功最好知乎 编辑:程序博客网 时间:2024/05/15 00:36
一、实验内容
给定某超市购物篮数据库文件basketdata.xls,里面有18项商品的747条购买记录。取支持度阈值s =185,请利用A-Priori算法提取其中的最大频繁项集Lk。
附件:某超市数据集basketdata.xls
二、实验设计(原理分析及流程)
首先,当然是将超市购物篮的数据文件读取到一个数据结构中保存起来。这里,因为开始的购物车数量以及商品数量已知,使用分割函数将信息文件信息存放到静态数组。我选择使用一个747行,18列的静态数组来存储信息。建立几个静态数组来存放频繁项集以及候选项集,之后根据伪代码进行操作。
三、这里使用set会比较简单,但当时还没学,所以就没用上,代码比较丑陋。。。
四、代码:
#include <fstream>#include <string>#include <iostream>#include <streambuf>#include <vector>#define ListLen 747 // 购物车数量#define GoodsNum 18 // 商品数量#define S 185 // 阈值using namespace std;// 存放商品名称的string数组const string ItemName[GoodsNum] ={ "饮料", "冲饮食品", "乳制冲饮", "罐头食品", "即食主食", "中式挂面/通心粉", "酱油", "醋", "调味品", "饼干", "中式糕点", "膨化食品", "休闲小食品", "炒货食品", "糖果巧克力", "进口食品", "香烟", "啤酒"};// 分割函数,将从文件读取的一行string分割成多个列// 参数为 源字符串,分界符,存放单词的容器int Split(const string &str, const string &splitchar, std::vector <string> &vec){ string stmp = ""; string::size_type pos = 0, prev_pos = 0; vec.clear(); // 删除存在的元素 while ((pos = str.find_first_of(splitchar, pos)) != string::npos) { stmp = str.substr(prev_pos, pos - prev_pos); vec.push_back(stmp); prev_pos = ++pos; } stmp = str.substr(prev_pos, pos - prev_pos); if (stmp.length() > 0) { vec.push_back(stmp); } return 0;}// 生成数据矩阵的函数 从文本中读取数据// 参数:矩阵,存放单词的容器,矩阵列的数目,文本行数目int MatrEst(int DataList[][GoodsNum], vector <string> &LineWord, int GN, int LineCount){ for (int i = 1; i < GN + 1; i++) // 跳过原行号,将新的数组行号作为行号 { // 将数据文件的信息转化为数组信息 if (!(LineWord[i]).compare("T")) DataList[LineCount][i-1] = 1; else if (!(LineWord[i]).compare("F")) DataList[LineCount][i-1] = 0; else cout << "Error!" << endl; } return 0;}// 构造频繁一项集,容器存放频繁项的列号 列号:0-17 返回频繁一项个数// 参数:容器,信息矩阵int OneItem(vector<int> &OneFrc,int DataList[][GoodsNum]){ vector<int> OneCanVec(18, 0); for (int i = 0; i < ListLen; i++) { for (int j = 0; j < GoodsNum; j++) { if (DataList[i][j]) OneCanVec[j]++; } } for (int i = 0; i < GoodsNum; i++) { if (OneCanVec[i] < S) ; else // 一项集,若支持度大于阈值,加入一项频繁项集 OneFrc.push_back(i); } unsigned ItemNum = OneFrc.size(); // 频繁项集数目 if (ItemNum == 0) return 0; else return ItemNum;}// 构造频繁二项集,容器存放频繁项的列号 列号:0-17 返回频繁二项个数// 参数:存放频繁二项集的数组,信息矩阵,频繁一项个数,频繁一项集容器int TwoItem(int TwoFrc[][2], int DataList[][GoodsNum], int OneNum, vector<int> &OneFrc){ // 从频繁一项集中组成二项集并判断 int TwoCount = 0, TwoFrcFi = 0, TwoFrcNum = 0;// 支持度计数 int i, j; for (i = 0; i < OneNum - 1; i++) // 0-8 { for (j = i + 1; j < OneNum; j++) // 1-9 { for (int k = 0; k < ListLen; k++) // 遍历每一行并统计该二项集支持度 { int first = OneFrc[i], second = OneFrc[j]; //cout << "First: " << first << " Second " << second << endl; if (DataList[k][first] && DataList[k][second]) // 两项同时出现在一个购物篮 TwoCount++; } if (TwoCount >= S) { // 记录频繁二项集 TwoFrc[TwoFrcFi][0] = OneFrc[i], TwoFrc[TwoFrcFi][1] = OneFrc[j]; TwoFrcFi++; TwoFrcNum++; } TwoCount = 0; } } return TwoFrcNum;}// 判断两个项是否存在于频繁二项集中 返回 1表示存在 0 不存在// 参数:第一个列序号,第二个列序号,频繁二项集,频繁二项集数目int ExistTwo(int i, int j, int TwoFrc[][2], int TwoNum){ int IN = 0; for (int k = 0; k < TwoNum; k++) if ((TwoFrc[k][0] == i) && (TwoFrc[k][1] == j)) { IN = 1; break; } if (IN) return 1; else return 0;}// 构造频繁三项集,容器存放频繁项的列号 列号:0-17 返回频繁三项个数// 参数:存放频繁二项集的数组,存放候选三项集数组,存放频繁三项集数组,信息矩阵,频繁二项个数int ThreeItem(int TwoFrc[][2], int ThrCan[][3], int ThrFrc[][3],int DataList[][GoodsNum], int TwoNum){ int ThCount = 0, ThFrCount = 0, ThFrNum = 0; for (int i = 0; i < TwoNum - 1; i++) // 每一行 { for (int j = i + 1; j < TwoNum; j++) { int first = TwoFrc[i][1], second = TwoFrc[j][1]; if ((TwoFrc[i][0] == TwoFrc[j][0]) && ExistTwo(first, second, TwoFrc, TwoNum)) { ThrCan[ThCount][0] = TwoFrc[i][0]; ThrCan[ThCount][1] = first; ThrCan[ThCount][2] = second; ThCount++; } } } cout << "ThCount: " << ThCount << endl; for (int i = 0; i < ThCount; i++) { int first = ThrCan[i][0], second = ThrCan[i][1], third = ThrCan[i][2]; for (int k = 0; k < ListLen; k++) // 遍历每一行并统计该二项集支持度 { if (DataList[k][first] && DataList[k][second] && DataList[k][third])// 项同时出现在一个购物篮 ThFrCount++; } if (ThFrCount >= S) { // 记录频繁二项集 ThrFrc[ThFrNum][0] = first; ThrFrc[ThFrNum][1] = second; ThrFrc[ThFrNum][2] = third; ThFrNum++; } ThFrCount = 0; } return ThFrNum;}int main (void){ vector<string> LineWord; // 存放一行单词集合来处理 vector<int> OneFrc; // 存放频繁一项集 int TwoFrc[45][2]; // 存放频繁二项集 int ThreeCan[20][3]; // 存放候选三项集 int ThreeFrc[10][3]; // 存放频繁二项集 int DataList[ListLen][GoodsNum]; // 创建静态数组来保存购物车信息看做一个矩阵 const string SplitStr = ","; // CSV文件分隔符 ifstream DataStream; // 读取文件流 string FileLine; // 读取文件行存放的string int LineCount = 0; // 行计数 int KItem[GoodsNum]; // 保存频繁项集的个数数组 DataStream.open("basketdata.csv", ios::in); if(!DataStream) // 读取不成功则是NULL { cout << "Can't not open data file!\n"; return 0; } getline(DataStream, FileLine); // 读取掉前面两行 getline(DataStream, FileLine); while(LineCount < ListLen && getline(DataStream, FileLine) )// 每次读取数据文件的一行进行处理 { // 因为转化为csv文件,根据,来对每个数据存储到静态数组 // 将一行数据中的每一列分开 Split(FileLine, SplitStr, LineWord); MatrEst(DataList, LineWord, GoodsNum, LineCount); LineCount++; } KItem[1] = OneItem(OneFrc, DataList); // 获得频繁一项集 KItem[2] = TwoItem(TwoFrc, DataList, KItem[1], OneFrc); KItem[3] = ThreeItem(TwoFrc, ThreeCan, ThreeFrc, DataList, KItem[2]); if ( KItem[3] < 4) { cout << "找到最大频繁项集,项数为3,个数: " << KItem[3] << endl; cout << ItemName[ThreeFrc[0][0]] << ", " << ItemName[ThreeFrc[0][1]] << ", " << ItemName[ThreeFrc[0][2]] << endl; cout << ItemName[ThreeFrc[1][0]] << ", " << ItemName[ThreeFrc[1][1]] << ", " << ItemName[ThreeFrc[1][2]] << endl; } cout << "Done!" << endl; return 0;}
阅读全文
0 0
- A-Priori算法
- A-priori算法的简单实现
- A-priori算法的优化实现
- 数据挖掘经典算法--priori算法
- 数据挖掘(一)A-Priori
- 数据挖掘(一)A-Priori
- On Visible Surface Generation BY A PRIORI TREE STRUCTURES
- weka,FP,priori
- prior 和 priori的区别
- A*算法
- A*算法
- A*算法
- A*算法
- A*算法
- A*算法
- A* 算法
- A*算法
- A * 算法
- 基于asp.net的登录页面开发
- 怎么给网页写一个侧栏(横向两列布局-使用绝对定位和相对定位的方法)
- Xshell 上下左右键乱码问题
- Avplayer 添加播放网络视频
- 面向对象
- A-Priori算法
- lintcode--最长连续序列
- 如何利用MySQL语句将自增重置为1
- C语言中数组与指针区别精解
- Java内存分配
- Oracle11g RAC集群启动关闭
- Linux 驱动开发前奏---驱动开发概述、硬件访问技术
- 2018国家公务员考试行测备考:比例思想巧解工程问题
- datagrid的列如何取得相关联表的值