强关联规则挖掘

挖掘强关联规则的过程:

1.得到最大频繁项目集(这里使用apriori算法)

2.在最大频繁项目集中找强关联规则

工程结构:

(把下面的文件放到自己建的工程中就可以运行了,如果嫌麻烦的话把这些都放到main.cpp中也可以,建议分开放。但是要注意代码中有一个地方用到了自动数据类型auto,要开c++11,否则编译会报错,如果没开的话按照代码注释改一下就可以了。)

codeblock中开c++11:

settings->compiler:

运行结果:

含的文件:

(代码中都有注释,很容易看懂的)

mian.cpp

#include "mining.h"
int main()
{
    //freopen("in.txt","r",stdin);
    PSet D;  //
    int min_support,num;
    cout<<"输入最小支持度和事务个数:"<<endl;
    cin>>min_support>>num;
    cout<<"输入所有事务"<<endl;
    for(int i=0;i<num;i++)
    {
        ItemSet tem;
        cin>>tem.items;
        tem.cnt=1;
        D.push_back(tem);
    }

    //得到频繁项目集
    PSet result=apriori(D,min_support);
    cout<<endl<<"所有的频繁项目集:"<<endl<<'{';
    for(int i=0;i<result.size();i++)
        i==result.size()-1?cout<<result[i].items<<'}'<<endl:cout<<result[i].items<<',';

    //得到最大频繁项目集
    result=get_max(result);
    cout<<endl<<"最大频繁项目集:"<<endl<<'{';
    for(int i=0;i<result.size();i++)
        i==result.size()-1?cout<<result[i].items<<'}'<<endl:cout<<result[i].items<<',';

    cout<<endl;

    double min_conf;
    cout<<"输入最小置信度:";
    cin>>min_conf;

    //找强关联规则
    RuleSet rules=find_rules(D,result,min_conf);

    cout<<endl<<"满足条件的所有强关联规则(后面两个分别是置信度和支持度):"<<endl;
    for(int i=0;i<rules.size();i++)
        cout<<rules[i].f<<"->"<<rules[i].t<<"   "<<rules[i].conf<<"  "<<rules[i].support<<endl;

    return 0;
}


 

 

mining.h

#include "base.h"
#include "apriori.h"
#include "gen.h"

 

 

base.h

#include <bits/stdc++.h>
using namespace std;

//项集的数据结构
struct ItemSet
{
    string items;
    int cnt;
     bool operator <(ItemSet t)const
    {
        if(items==t.items)return cnt<t.cnt;
        return items<t.items;
    }
    bool operator ==(ItemSet t)const
    {
        return items==t.items&&cnt==t.cnt;
    }
};

//规则的数据结构
struct Rule
{
    string f,t;
    double support,conf;
    bool operator ==(Rule x)const
    {
        return f==x.f&&t==x.t&&support;
    }
    bool operator <(Rule x)const
    {
        if(f==x.f)
        return t<x.t;
        else return f<x.f;
    }
};

//项目集的数据类型
typedef vector<ItemSet> PSet;

//规则集合
typedef vector<Rule> RuleSet;


//判断a中有多少个项目不属于b,显然当返回值是0的时候a是b的自子集
//gen.h和apriori.h中都会用到
int belong(string a,string b)
{
    int ct=0;
    for(int i=0;i<a.length();i++)
        if(b.find_first_of(a[i])==string::npos)ct++;
    return ct;
}



 

 

apriori.h

//apriori算法初始时用到,获得L1
PSet get(PSet &D)
{
    set<char> se;
    PSet ans;
    for(int i=0;i<D.size();i++)
    {
        for(int j=0;j<D[i].items.length();j++)
            se.insert(D[i].items[j]);
    }
    auto it=se.begin();//如果没有开c++11标准的话,把auto改为set<char>::iterator
    while(it!=se.end())
    {
        ItemSet tem;
        tem.cnt=0;
        tem.items.push_back(*it);
        ans.push_back(tem);
        it++;
    }
    return ans;
}


//将b加到a中,用于将apriori中产生的Li加入到最后的结果中
void con(PSet &a,PSet &b)
{
    for(int i=0;i<b.size();i++)a.push_back(b[i]);
}


//生成候选集时用到,根据a和b生成一个候选项集
string gen(string a,string b)
{
    sort(a.begin(),a.end());
    sort(b.begin(),b.end());
    for(int i=0;i<a.length();i++)
    {
        if(b.find_first_of(a[i])==string::npos)
        {
            b.push_back(a[i]);
            sort(b.begin(),b.end());
            return b;
        }
    }
}


//get_candidates中会用到的函数,判断items是否包含非频繁项目集
bool contain_inf(PSet &Li,string items)
{
    for(int i=0;i<items.length();i++)
    {
        string tem=items;
        tem.erase(tem.begin()+i);
        bool flag=false;
        for(int j=0;j<Li.size();j++)
        {
            if(!belong(tem,Li[j].items))
            {
                flag=true;break;
            }
        }
        if(!flag)return 1;
    }
    return 0;
}

//在频繁项目集中求最大频繁项目集
PSet get_max(PSet &L)
{
    PSet ans;
    for(int i=0;i<L.size();i++)
    {
        bool flag=false;
        for(int j=0;j<L.size();j++)
            if(i!=j&&!belong(L[i].items,L[j].items))
            {
                flag=true;
                break;
            }
        if(!flag)ans.push_back(L[i]);
    }
    return ans;
}


//apriori算法要用到的函数,根据Li(每个项集都是k项)生成候选项目集Ci(每个项集都是k+1项)
PSet get_candidates(PSet &Li)
{
    PSet Ci;
    for(int i=0;i<Li.size();i++)
    {
        for(int j=i+1;j<Li.size();j++)
        {
            if(i!=j&&belong(Li[i].items,Li[j].items)==1)
            {
                ItemSet tem;
                tem.cnt=0;
                tem.items=gen(Li[i].items,Li[j].items);
                if(!contain_inf(Li,tem.items))
                Ci.push_back(tem);
            }
        }
    }
    sort(Ci.begin(),Ci.end());
    Ci.erase(unique(Ci.begin(),Ci.end()),Ci.end());
    return Ci;
}


//apriori算法主体,求频繁项目集
PSet apriori(PSet &D,int min_support)
{
    PSet Ci,Li,L;
    Li=get(D);
    while(true)
    {
        con(L,Li);
        Ci=get_candidates(Li);
        for(int i=0;i<Ci.size();i++)
        {
            for(int j=0;j<D.size();j++)
                if(!belong(Ci[i].items,D[j].items))
                Ci[i].cnt++;
        }
        Li.clear();
        for(int i=0;i<Ci.size();i++)
            if(Ci[i].cnt>=min_support)
            Li.push_back(Ci[i]);
        if(Li.size()==0)break;
    }
    return L;
}


 

 

gen.h

//求差集b-a
string inter(string a,string b)
{
    int pos;
    for(int i=0;i<a.length();i++)
    {
        pos=b.find_first_of(a[i]);
        if(pos!=string::npos)
        b.erase(b.begin()+pos);
    }
    return b;
}

//将b中的规则加到a中
void con_rule(RuleSet &a,RuleSet &b)
{
    for(int i=0;i<b.size();i++)a.push_back(b[i]);
}

//求a的支持数(这里只能说是支持度,因为并没有除总事务的个数)
double support(PSet &D,ItemSet a)
{
    double conf=0;
    for(int i=0;i<D.size();i++)
        if(!belong(a.items,D[i].items))conf++;
    return conf;
}


RuleSet gen_rules(PSet &D,ItemSet Li,ItemSet Lm,double min_conf)
{
    double conf;
    RuleSet rules;
    for(int i=0;i<Lm.items.length();i++)
    {
        ItemSet tem=Lm;
        tem.items.erase(tem.items.begin()+i);
        conf=(double)Li.cnt/support(D,tem);
        if(conf>min_conf)
        {
            Rule rule;
            rule.f=tem.items;
            rule.t=inter(tem.items,Li.items);
            rule.conf=conf;
            rules.push_back(rule);
        }
        if(tem.items.length()>1)
        {
            RuleSet rules2=gen_rules(D,Li,tem,min_conf);
            con_rule(rules,rules2);
        }
    }
    sort(rules.begin(),rules.end());
    rules.erase(unique(rules.begin(),rules.end()),rules.end());
    return rules;
}


RuleSet find_rules(PSet &D,PSet &L,double min_conf)
{
    RuleSet rules;
    for(int i=0;i<L.size();i++)
    {
        RuleSet tem=gen_rules(D,L[i],L[i],min_conf);
        con_rule(rules,tem);
    }
    sort(rules.begin(),rules.end());
    rules.erase(unique(rules.begin(),rules.end()),rules.end());
    return rules;
}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值