数据挖掘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的.一种轻量级且安全 ...
随机推荐
- Python基础-main
Python基础-_main_ 写在前面 如非特别说明,下文均基于Python3 一.__main__的官方解释 参考 _main_ -- Top-level script environment ' ...
- IDEA 报错记录
IDEA 报错记录 Process finished with exit code 0 这种主要是配了默认的 Tomcat ,然后又配置了外部的 Tomcat.解决办法,注释掉默认的: <dep ...
- Java关于Math类的三个取整方法
0x01 在java的Math类中有三个关于浮点数取整数的方法,分别是ceil (向上取整) floor(向下取整) round(四舍五入) 三个方法 0x02 ceil 向上取整,取整后总是比原来的 ...
- shell awk匹配字符串(从配置文件)
配置文件 config.properties xxx_yyy_lib_path="路径" xxx_yyy_bin_path="路径" 想通过shell来读入路径 ...
- Rust <10>:宏导出、导入
源 crate 中使用 #[macro_export] 属性标记的宏,调用者可在导入此 crate 时添加 #[macro_use] 属性使用. 没有 #[macro_export] 的宏,外部不可见 ...
- 自动化监控Zabbix之主机自动发现
创建思路 首先说下自动发现强大的功能,它到底可以帮助我们完成什么工作: 快速发现并添加主机 简单的管理 随着环境的改变而快速搭建监控系统 自动发现基于网络发现功能,而网络发现又基于以下信息: IP地址 ...
- 知识点整理01- 引用对象被子方法赋值后不改变;CheckBox 取消选择不可用问题
1. Class 实体是引用类型,但传入方法时是null的情况在子方法中不论怎么赋值当 FirstService.SetPerson(person,ref tempMsg); 执行后Person都是n ...
- PAT 乙级练习题1002. 写出这个数 (20)
1002. 写出这个数 (20) 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式 ...
- 2019-9-2-win10-uwp-Markdown
title author date CreateTime categories win10 uwp Markdown lindexi 2019-09-02 12:57:38 +0800 2018-2- ...
- 嵌入式 emmc 中 安装 烧录 内核 kernel,设备树 devicetree ,根文件系统 rootfs
一般调试嵌入式开发板喜欢选择 利用 TFTP 传送 内核与 设备树, 利用 nfs 加载根文件系统. uboot 环境变量 设置如下: bootargs=root=/dev/nfs rw nfs ...