数据挖掘Aprior算法详解及c++源码
【算法大致描述】
Aprior算法主要有两个操作,扫描数据库+统计。计算每一阶频繁项集都要扫描一次数据库并且统计出满足支持度的n阶项集。
【算法主要步骤】
一、频繁一项集
算法开始第一步,通过扫描数据库,统计出每条记录中出现的每一个单独项并计数,数据库扫描完成,统计结束,根据支持度,选出满足条件的频繁一项集 L1。
二、连接
用 Lk-1自连接得到Ck。
方法,如果Lk-1中的两个元素的前K-2项都相同,只有最后一项不同,则自连接得到Ck中的一个元素。例如L3{(12,13,14),(12,13,15) }则可自连接得到C4{(12 13 14 15)}
三、修剪
对于自连接得到的Ck,其中有些元素是可以不用扫描数据库就可以确定它肯定不是频繁项集的。一个k-项集,如果它的一个k-1项集(它的子集 )不是频繁的,那它本身也不可能是频繁的。
例如L3{(12 ,13,14),(12,13,15)}自连接得到C4{(12,13,14,15)} 但是(13,14,15)不在L3中,所以可以肯定(12,13,14,15)不是频繁四项集,不用再去扫描数据库。
通过修剪,可以很快的减少Ck中的元素,减少数据库的扫描次数,大大加快效率。
四、扫描数据库得到频繁k项集Lk
将已经修剪过的Ck中的每一个元素拿到数据库中去找,统计出现次数,根据支持度得到结果。
C++源码
#include<bits/stdc++.h>
#include<string>
#include<vector>
#include<map>
using namespace std;
vector <string> result;
map<string,int>r1;
float suport;
vector<string> file;
void Getfile(){
ifstream ifile("D://retail.dat");
if(!ifile){
cout<<"open file error"<<endl;
}
else{
string temp;
while(getline(ifile,temp)){
file.push_back(temp);
}
}
ifile.close();
}
bool IsrealCk(vector<string>& Lk ,vector<string> &str){//判断str的子集是否在Lk-1中
string temp;
int i;
for( i=;i<str.size();i++){
temp.clear();
for(int j=;j<str.size();j++){//Cn 1
if(j!=i){
temp+=str[j];
temp.push_back(',');
}
}//生成一个子集
temp.erase(temp.size()-);
int k;
for( k=;k<Lk.size();k++){//
if(Lk[k]==temp)
break;
}
if(k>=Lk.size()){//不在Lk
break;
} }
if(i>=str.size())
return ;
else
return ;
}
vector<string> minCK(vector<string>& Lk,vector<string>& Ck){//剪枝 (12,45,32)
vector<string> minck;
vector<string> str;
for(int i=;i<Ck.size();i++){
string s;
str.clear();
for(int j=;j<Ck[i].size();j++){
while(Ck[i][j]!=','&&j<Ck[i].size()){
s.push_back(Ck[i][j]);
j++;
}
str.push_back(s);
s.clear();
}
if(IsrealCk(Lk,str)){
minck.push_back(Ck[i]);
}
}
return minck;
}
vector<string> GetL1_C2(){
vector <string> L1;
vector<int> count;
vector<string> l1;
vector<string> C2;
string temp;
int line=;
string lk;
for(int f=;f<file.size();f++){
temp=file[f];
line++;
int i;
for( i=;i<temp.size();i++){
while(temp[i]!=' '&&temp[i]!='\n'&&i!=temp.size()){
lk+=temp[i];
i++;
}
if(r1.find(lk)!=r1.end())
r1[lk]++;
else
r1[lk]=;
lk.clear();//
}
}
temp.clear();
map<string,int>::iterator it;
for(it=r1.begin();it!=r1.end();it++){//待删除
if(it->second>=ceil(suport*line)){
cout<<it->first<<" ("<<it->second<<")"<<endl;
result.push_back(it->first); }
}
for(int i=;i<result.size();i++){
for(int j=i+;j<result.size();j++){
string c2=result[i]+","+result[j];
C2.push_back(c2);
}
}
return C2;
}
vector<string> CK(vector<string>& L){
vector<string> Ck;//k+1候选像集
vector<string> minck;
for(int i=;i<L.size();i++){
for(int j=i+;j<L.size();j++){
if(i!=j){
string temp1,temp2;
int m1,m2;
for(m1=L[i].size()-;m1>;m1--){
if(L[i][m1]==',')
break;
}
temp1=L[i].substr(,m1+);
for(m2=L[j].size()-;m2>;m2--){
if(L[j][m2]==',')
break;
}
temp2=L[j].substr(,m2+);
if(temp1==temp2){//可以连接
string lk=temp1;
for(int x=m1+;x<L[i].size();x++) {
lk.push_back(L[i][x]);
}
lk.insert(lk.end(),',');
for(int x=m2+;x<L[j].size();x++) {
lk.push_back(L[j][x]);
}
Ck.push_back(lk);//加入候选项
}
}
}
}
// minck=minCK(L,Ck);
return minck=minCK(L,Ck);
} bool Isin(string& temp,string& str){
int j;
string s;
for( j=;j<temp.size();j++){//遍历temp
while(temp[j]!=' '&&j<temp.size()){
s.push_back(temp[j]);
j++;
}
if(s==str)
break;
s.clear();
}
if(j>=temp.size())
return ;
else
return ; }
vector<string> GetLk(vector<string>& Ck){
map<string,int> Lk;
string temp;
int flag=;
int line=;
for(int f=;f<file.size();f++){
temp=file[f];
line++;int t=;
vector<string> str;
for(int i=;i<Ck.size();i++){
string s;//记录单个元素 12,32 s=12
str.clear();
for( int j=;j<Ck[i].size();j++){//遍历 12,34
while(Ck[i][j]!=','&&j<Ck[i].size()){
s.push_back(Ck[i][j]);
j++;
}
str.push_back(s);
s.clear();
} int p;
for( p=;p<str.size();p++){
if(!Isin(temp,str[p]))
break;
}
if(p>=str.size()){//在temp中出现
if(Lk.find(Ck[i])!=Lk.end())
Lk[Ck[i]]++;
else
Lk[Ck[i]]=;
}
} }
/*********/
temp.clear();
vector<string> ck;
map<string,int>::iterator it;
for( it=Lk.begin();it!=Lk.end();it++){//待删除
if(it->second>=ceil(suport*line)){
ck.push_back(it->first);
}
}
return ck; }
void Apri(vector<string>& Ck){
if(Ck.size()<){
return ;
}
else{
vector<string> temp=GetLk(Ck);
if(temp.size()<)
return;
else{
for(int i=;i<temp.size();i++){
result.push_back(temp[i]);//记录Lk
}
vector<string>nextck= CK(temp);
Apri(nextck); }
}
}
int main(){
cout<<"请输入最小支持度"<<endl;
cin>>suport;
Getfile();
int c=;
vector<string> C2=GetL1_C2();
Apri(C2);
cout<<"频繁项集如下:"<<endl;
for(int i=;i<result.size();i++){
cout<<result[i]<<endl;
c++;
}
cout<<" count "<<c<<endl;
return ;
}
测试文件(有八万多条记录,测试代码建议跑0.1支持度)
https://pan.baidu.com/s/1Lp7LJOXksIRh3KBra2iVIw
数据挖掘Aprior算法详解及c++源码的更多相关文章
- 《Android NFC 开发实战详解 》简介+源码+样章+勘误ING
<Android NFC 开发实战详解>简介+源码+样章+勘误ING SkySeraph Mar. 14th 2014 Email:skyseraph00@163.com 更多精彩请直接 ...
- Android中Canvas绘图基础详解(附源码下载) (转)
Android中Canvas绘图基础详解(附源码下载) 原文链接 http://blog.csdn.net/iispring/article/details/49770651 AndroidCa ...
- Android事件传递机制详解及最新源码分析——ViewGroup篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...
- 【详解】ThreadPoolExecutor源码阅读(三)
系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) 线程数量的 ...
- 【详解】ThreadPoolExecutor源码阅读(二)
系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) AQS在W ...
- 【详解】ThreadPoolExecutor源码阅读(一)
系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) 工作原理简 ...
- SpringBoot Profile使用详解及配置源码解析
在实践的过程中我们经常会遇到不同的环境需要不同配置文件的情况,如果每换一个环境重新修改配置文件或重新打包一次会比较麻烦,Spring Boot为此提供了Profile配置来解决此问题. Profile ...
- Python开发技术详解(视频+源码+文档)
Python, 是一种面向对象.直译式计算机程序设计语言.Python语法简捷而清晰,具有丰富和强大的类库.它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结 ...
- Android 网络框架之Retrofit2使用详解及从源码中解析原理
就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题: 1 . 什么是Retrofit? Retrofit是针对于Android/Java的.基于okHttp的.一种轻量级且安全 ...
随机推荐
- Rsync 实现服务器文件的同步——服务端的安装配置
一.安装rsync 直接使用yum命令进行安装即可. yum -y install rsync 二.配置文件 网上大多教程都说安装是默认没有配置文件的,但是经过我的尝试,yum安装下默认是有配置文件的 ...
- 嵌入式C语言4.2 C语言内存空间的使用-指针与修饰符:const,volatile,typedef
const:变量,只读[不能变] 内存属性: 1. 内存操作的大小 2.内存的变化性,可写可读 char *p; const char *p; 描述字符串,p指向的内容是只读的,不可再次修改 ...
- python学习笔记:数据类型——列表/数组(list)
Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素.通过下标访问列表中的元素(又称索引.角标),下标从0开始计数.list定义,使用中括号[]. l ...
- 跨域篇--JSONP原理
一篇文章让你明白 jsonp原理详解 什么是JSONP? 先说说JSONP是怎么产生的: 其实网上关于JSONP的讲解有很多,但却千篇一律,而且云里雾里,对于很多刚接触的人来讲理解起来有些困难,着用自 ...
- python3中浮点数相减问题(大部分时候只需要关注整数的二进制形式就行了)
首先直接上判断方法:一切判断直接将整数部分装化成二进制,如果位数相等则相减后的值是等于的,如果不相等,相减大的结果一定不等于你要比较的结果. 如66.6-60.6==6.0的情况,66.6的二进制:1 ...
- iview 的table组件,自带过滤功能
html : <Table :columns="people" :data="scores"></Table> data: people ...
- 【总】.NET Core 2.0 详解
ASP.NET Core 认证与授权[7]:动态授权 雨夜朦胧 2017-11-24 11:21 阅读:7063 评论:19 ASP.NET Core 认证与授权[6]:授权策略是怎么执行的? 雨夜朦 ...
- Javascript高级程序设计--读书笔记之面向对象(一)
哈哈哈万物皆对象,终于到了js的面向对象篇. 一.属性类型 (1)数据属性 数据属性包含一个数据值的位置,在这个位置可以写入和读取数值,数据属性有四个描述器行为的特性 [[Configurable]] ...
- 数据结构:堆(Heap)
堆就是用数组实现的二叉树,所有它没有使用父指针或者子指针.堆根据"堆属性"来排序,"堆属性"决定了树中节点的位置. 堆的常用方法: 构建优先队列 支持堆排序 快 ...
- 关于 群晖 docker 百度云盘下载的使用心得
因为有了群晖,所以想折腾一下看看有什么更多的功能,今天就来折腾一下群晖百度云盘下载.毕竟现在云盘都限速了嘛... 在群晖里,要想用到百度云盘下载,就需要有个小东西,就是docker.docker很简单 ...