99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)大數(shù)據(jù)時(shí)代機(jī)器學(xué)習(xí)中Apriori是什么?如何實(shí)現(xiàn)?
機(jī)器學(xué)習(xí)中Apriori是什么?如何實(shí)現(xiàn)?
2020-07-23
收藏

前面小編在介紹FP-Growth算法時(shí),提到了Apriori算法,其實(shí)FP-Growth是基于Apriori的,今天小編就具體給大家介紹一下Apriori算法。

一、什么是Apriori算法

Apriori算法是一種最有影響的挖掘數(shù)據(jù)關(guān)聯(lián)規(guī)則頻繁項(xiàng)集的算法,能夠發(fā)現(xiàn)事物數(shù)據(jù)庫(kù)中頻繁出現(xiàn)的數(shù)據(jù)集,通過這些聯(lián)系構(gòu)成的規(guī)則,能夠幫助用戶找出某些行為特征,從而幫助企業(yè)進(jìn)行決策。

Apriori算法基于這樣的事實(shí):算法使用頻繁項(xiàng)集性質(zhì)的先驗(yàn)知識(shí)。Apriori使用一種稱作逐層搜索的迭代方法,k-項(xiàng)集用于探索(k+1)-項(xiàng)集。首先,找出頻繁1-項(xiàng)集的集合。該集合記作L1.L1用于找頻繁2-項(xiàng)集的集合L2.而L2用于找L3.如此下去,直到不能找到頻繁k-項(xiàng)集。找每個(gè)Lk需要一次數(shù)據(jù)庫(kù)掃描。

算法原始數(shù)據(jù)如下:

算法的基本過程如下圖:

二、Apriori算法原理

1.掃描數(shù)據(jù)集,得到所有出現(xiàn)過的數(shù)據(jù),作為候選1項(xiàng)集。

2.挖掘頻繁k項(xiàng)集。

3.掃描計(jì)算候選k項(xiàng)集的支持度。

4.剪枝去掉候選k項(xiàng)集中支持度低于最小支持度α的數(shù)據(jù)集,得到頻繁k項(xiàng)集。如果頻繁k項(xiàng)集為空,則返回頻繁k-1項(xiàng)集的集合作為算法結(jié)果,算法結(jié)束。如果得到的頻繁k項(xiàng)集只有一項(xiàng),則直接返回頻繁k項(xiàng)集的集合作為算法結(jié)果,算法結(jié)束。

5.基于頻繁k項(xiàng)集,連接生成候選k+1項(xiàng)集。

6.利用步驟2.迭代得到k=k+1項(xiàng)集結(jié)果。

三、Apriori算法利弊分析

1.利:

適合于稀疏數(shù)據(jù)集。

算法原理簡(jiǎn)單,很容易實(shí)現(xiàn)。

適合事務(wù)數(shù)據(jù)庫(kù)的關(guān)聯(lián)規(guī)則挖掘。

2.弊

有可能產(chǎn)生龐大的候選集。

算法需多次遍歷數(shù)據(jù)集,效率比較低,而且耗時(shí)。

三、算法實(shí)現(xiàn)

假如有項(xiàng)目集合I={1,2,3,4,5},有事務(wù)集T:


1,2,3
1,2,4
1,3,4
1,2,3,5
1,3,5
2,4,5
1,2,3,4
設(shè)定minsup=3/7,misconf=5/7。

*Apriori算法 2012.10.31*/ 
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;

vector<string> T;                   //保存初始輸入的事務(wù)集 
double minSup,minConf;              //用戶設(shè)定的最小支持度和置信度 
map<string,int> mp;                //保存項(xiàng)目集中每個(gè)元素在事務(wù)集中出現(xiàn)的次數(shù) 
vector< vector<string> > F;       //存放頻繁項(xiàng)目集 
vector<string> R;                 //存放關(guān)聯(lián)規(guī)則 


void initTransactionSet()       //獲取事務(wù)集 
{
    int n;
    cout<<"請(qǐng)輸入事務(wù)集的個(gè)數(shù):"<<endl;
    cin>>n;
    getchar();
    cout<<"請(qǐng)輸入事務(wù)集:"<<endl;
    while(n--)
    {
        string str;
        getline(cin,str);          //輸入的事務(wù)集中每個(gè)元素以空格隔開,并且只能輸入數(shù)字 
         T.push_back(str);
    }
    cout<<"請(qǐng)輸入最小支持度和置信度:"<<endl;      //支持度和置信度為小數(shù)表示形式 
    cin>>minSup>>minConf;
}


vector<string> split(string str,char ch) 
{
    vector<string> v;
    int i,j;
    i=0;
    while(i<str.size())
    {
        if(str[i]==ch)
            i++;
        else
        {
            j=i;
            while(j<str.size())
            {
                if(str[j]!=ch)
                    j++;
                else
                    break;
            }
            string temp=str.substr(i,j-i);
            v.push_back(temp);
            i=j+1;
        }
    }
    return v;
}

void genarateOneFrequenceSet()          //生成1-頻繁項(xiàng)目集 
{
    int i,j;
    vector<string> f;                 //存儲(chǔ)1-頻繁項(xiàng)目集 
     for(i=0;i<T.size();i++) 
    {
        string t = T[i];
        vector<string> v=split(t,' ');       //將輸入的事務(wù)集進(jìn)行切分,如輸入1 2 3,切分得到"1","2","3" 
        for(j=0;j<v.size();j++)             //統(tǒng)計(jì)每個(gè)元素出現(xiàn)的次數(shù),注意map默認(rèn)按照key的升序排序 
         {
            mp[v[j]]++;             
        }
    }

    for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++)    //剔除不滿足最小支持度要求的項(xiàng)集 
    {    
        if( (*it).second >= minSup*T.size())
        {
            f.push_back((*it).first);
        }
    }
    F.push_back(T);                 //方便用F[1]表示1-頻繁項(xiàng)目集 
    if(f.size()!=0)
    {
        F.push_back(f);                  
    }
}

bool judgeItem(vector<string> v1,vector<string> v2) //判斷v1和v2是否只有最后一項(xiàng)不同 
{
    int i,j;
    i=0;
    j=0;
    while(i<v1.size()-1&&j<v2.size()-1)
    {
        if(v1[i]!=v2[j])
            return false;
        i++;
        j++;
    }
    return true;
}

bool judgeSubset(vector<string> v,vector<string> f)        //判斷v的所有k-1子集是否在f中 
{
    int i,j;
    bool flag=true;
    for(i=0;i<v.size();i++)
    {
        string str;
        for(j=0;j<v.size();j++)
        {
            if(j!=i)
                str+=v[j]+" ";
        }
        str=str.substr(0,str.size()-1);
        vector<string>::iterator it=find(f.begin(),f.end(),str);
        if(it==f.end())
            flag=false;
    }
    return flag;
}

int calculateSupportCount(vector<string> v)      //計(jì)算支持度計(jì)數(shù) 
{
    int i,j;
    int count=0;
    for(i=0;i<T.size();i++) 
    {
        vector<string> t=split(T[i],' ');
        for(j=0;j<v.size();j++)
        {
            vector<string>::iterator it=find(t.begin(),t.end(),v[j]);
            if(it==t.end())
                break;
        }
        if(j==v.size())
            count++;
    }
    return count;    
}


bool judgeSupport(vector<string> v)                  //判斷一個(gè)項(xiàng)集的支持度是否滿足要求 
{
    int count=calculateSupportCount(v);
    if(count >= ceil(minSup*T.size()))
        return true;
    return false;
}


void generateKFrequenceSet()        //生成k-頻繁項(xiàng)目集 
{
    int k;
    for(k=2;k<=mp.size();k++)
    {
        if(F.size()< k)           //如果Fk-1為空,則退出 
            break;
        else                      //根據(jù)Fk-1生成Ck候選項(xiàng)集    
        {                
            int i,j;
            vector<string> c;
            vector<string> f=F[k-1];
            for(i=0;i<f.size()-1;i++)
            {
                vector<string> v1=split(f[i],' ');
                for(j=i+1;j<f.size();j++)
                {
                    vector<string> v2=split(f[j],' ');
                    if(judgeItem(v1,v2))       //如果v1和v2只有最后一項(xiàng)不同,則進(jìn)行連接 
                    {
                        vector<string> tempVector=v1;
                        tempVector.push_back(v2[v2.size()-1]);
                        sort(tempVector.begin(),tempVector.end());     //對(duì)元素排序,方便判斷是否進(jìn)行連接 

                            //剪枝的過程 
                            //判斷 v1的(k-1)的子集是否都在Fk-1中以及是否滿足最低支持度 
                            if(judgeSubset(tempVector,f)&&judgeSupport(tempVector))  
                        {
                            int p;
                            string tempStr;
                            for(p=0;p<tempVector.size()-1;p++)
                                tempStr+=tempVector[p]+" ";
                            tempStr+=tempVector[p];

                            c.push_back(tempStr);
                        }
                    }
                }
            }
            if(c.size()!=0)
                F.push_back(c);
        }
    }
}



vector<string> removeItemFromSet(vector<string> v1,vector<string> v2)    //從v1中剔除v2 
{
    int i;
    vector<string> result=v1;
    for(i=0;i<v2.size();i++)
    {
        vector<string>::iterator it= find(result.begin(),result.end(),v2[i]);
        if(it!=result.end())
            result.erase(it);
    }
    return result;
}

string getStr(vector<string> v1,vector<string> v2)        //根據(jù)前件和后件得到規(guī)則
{
    int i; 
    string rStr;
    for(i=0;i<v1.size();i++)
        rStr+=v1[i]+" ";
    rStr=rStr.substr(0,rStr.size()-1);
    rStr+="->";

    for(i=0;i<v2.size();i++)
        rStr+=v2[i]+" ";
    rStr=rStr.substr(0,rStr.size()-1);
    return rStr;    
} 

void ap_generateRules(string fs) 
{
    int i,j,k;
    vector<string> v=split(fs,' ');
    vector<string> h;                           
    vector< vector<string> > H;                   //存放所有的后件 
    int fCount=calculateSupportCount(v);         //f的支持度計(jì)數(shù) 

    for(i=0;i<v.size();i++)                    //先生成1-后件關(guān)聯(lián)規(guī)則 
    {
        vector<string> temp=v;
        temp.erase(temp.begin()+i);

        int aCount=calculateSupportCount(temp);

        if( fCount >= ceil(aCount*minConf))        //如果滿足置信度要求 
         {
            h.push_back(v[i]);
            string tempStr;
            for(j=0;j<v.size();j++)
            {
                if(j!=i)
                    tempStr+=v[j]+" ";
            }
            tempStr=tempStr.substr(0,tempStr.size()-1);
            tempStr+="->"+v[i];
            R.push_back((tempStr));
        }
    }

    H.push_back(v);
    if(h.size()!=0)
        H.push_back(h);

    for(k=2;k<v.size();k++)              //生成k-后件關(guān)聯(lián)規(guī)則 
     {
        h=H[k-1];
        vector<string> addH;
        for(i=0;i<h.size()-1;i++)
        {
            vector<string> v1=split(h[i],' ');
            for(j=i+1;j<h.size();j++)
            {
                vector<string> v2=split(h[j],' ');

                if(judgeItem(v1,v2)) 
                {
                    vector<string> tempVector=v1;                    
                    tempVector.push_back(v2[v2.size()-1]);                        //得到后件集合 
                       sort(tempVector.begin(),tempVector.end());

                    vector<string> filterV=removeItemFromSet(v,tempVector);      //得到前件集合 
                       int aCount=calculateSupportCount(filterV);                   //計(jì)算前件支持度計(jì)數(shù) 
                       if(fCount >= ceil(aCount*minConf))                           //如果滿足置信度要求 
                       {
                        string rStr=getStr(filterV,tempVector);                  //根據(jù)前件和后件得到規(guī)則 

                            string hStr;
                        for(int s=0;s<tempVector.size();s++)  
                            hStr+=tempVector[s]+" ";
                        hStr=hStr.substr(0,hStr.size()-1);
                        addH.push_back(hStr);                                    //得到一個(gè)新的后件集合 

                            R.push_back(rStr);
                    }
                }
            }
        }
        if(addH.size()!=0)                                                       //將所有的k-后件集合加入到H中 
            H.push_back(addH);
    }
}


void generateRules()               //生成關(guān)聯(lián)規(guī)則 
{
    int i,j,k;
    for(k=2;k<F.size();k++)
    {
        vector<string> f=F[k];
        for(i=0;i<f.size();i++)
        {
            string str=f[i];
            ap_generateRules(str);
        }
    }    
}


void outputFrequenceSet()          //輸出頻繁項(xiàng)目集 
{
    int i,k;
    if(F.size()==1)
    {
        cout<<"無頻繁項(xiàng)目集!"<<endl;
        return;
    }    
    for(k=1;k<F.size();k++)
    {
        cout<<k<<"-頻繁項(xiàng)目集:"<<endl;
        vector<string> f=F[k];
        for(i=0;i<f.size();i++)
            cout<<f[i]<<endl;
    }
}

void outputRules()              //輸出關(guān)聯(lián)規(guī)則 
{
    int i;
    cout<<"關(guān)聯(lián)規(guī)則:"<<endl;
    for(i=0;i<R.size();i++)
    {
        cout<<R[i]<<endl;
    }
}

void Apriori()
{
    initTransactionSet();
    genarateOneFrequenceSet();
    generateKFrequenceSet();
    outputFrequenceSet();
    generateRules();
    outputRules();
} 


int main(int argc, char *argv[])
{
    Apriori();
    return 0;
}


數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請(qǐng)參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }