1. 程式人生 > 其它 >簡單易學的機器學習演算法——Apriori演算法

簡單易學的機器學習演算法——Apriori演算法

一、關聯分析

    最初接觸到資料探勘的朋友肯定都聽說過這樣的一個案例:啤酒和尿布。大意是將啤酒和尿布放在一起的銷售會提高。其實這背後隱含的原理就是關聯分析,簡單來講就是啤酒和尿布之間存在著某種關聯關係。關聯關係時指從大規模的資料集中尋找物品之間的隱含關係,有時關聯分析也可以稱為關聯規則學習。

二、關聯分析的重要概念

    關聯分析主要要做的工作是在大規模資料集上找到某些關係。主要有兩種形式:

  • 頻繁項集
  • 關聯關係

    對於一個具體的例子:

(摘自《機器學習實戰》)

三、Apriori演算法

1、Apriori演算法

        Apriori演算法是關聯分析的重要演算法,Apriori演算法主要是來尋找頻繁項集,採用的方法是查找出所有的可能,如下圖:

(摘自《機器學習實戰》)

2、Apriori原理

    如何避免指數級增長,我們應該儘量去減少一些不必要的結點,Apriori原理是說如果某個項集是頻繁的,那麼他的所有子集也是頻繁的。其逆否命題為:如果一個項集是非頻繁的,那麼他的所有超集也是非頻繁的。使用這個原理就可以避免指數級增長,原理如下圖所示:

(摘自《機器學習實戰》)

四、使用Apriori演算法發現頻繁項集

(實現過程)

五、從頻繁項集中挖掘關聯規則

六、Matlab實現

1、頻繁項集

主函式

%% 主函式
clear all;
clc;

%% 匯入資料
% 資料集中的0表示無
dataSet = load('data.txt');

% %構建第一個候選集C1
% C1 = createC1(dataSet);
% 
% %構建第一個頻繁項集L1
% [retList, supportData] = scanD(dataSet, C1, 0.7)

% 呼叫產生頻繁項集
[L, supportData] = apriori(dataSet, 0.5);

查詢候選集C1

%% 查詢候選集C1
function [ C1 ] = createC1( dataSet )
    C1 = unique(dataSet);%取得所有相異元素
end

生成頻繁項集

%% 計算頻繁項集L1
function [ retList, supportData ] = scanD( dataSet, Ck, minSupport )
    [m,n] = size(Ck);
    if m==0
        retList = [];
        supportData = 0;
    else
        if n==1
            Ck(Ck==0)=[];%將候選集中的0去掉
            [m,n] = size(Ck);%獲得候選集的大小,注意候選集的大小
            [m_1,n_1] = size(dataSet);%獲得整個資料集的大小
            %% 統計候選集中的元素在dataSet中出現的次數
            dataNum = zeros(m,1);
            for i = 1:m%行數為候選集中元素的個數
                for j = 1:m_1
                    if all(ismember(Ck(i,:), dataSet(j,:)))==1
                        dataNum(i,1) = dataNum(i,1)+1;
                    end
                end
%           if all(ismember(Ck(i,:), dataSet))==1
%               dataNum(i,1) = dataNum(i,1)+1;
%           end
            end
        else
            [m,n] = size(Ck);%獲得候選集的大小,注意候選集的大小
            [m_1,n_1] = size(dataSet);%獲得整個資料集的大小
            %% 統計候選集中的元素在dataSet中出現的次數
            dataNum = zeros(m,1);
            for i = 1:m%行數為候選集中元素的個數
                tmp = Ck(i,:);
                tmp(tmp==0)=[];%將候選集中的0去掉
                for j = 1:m_1
                    if all(ismember(tmp, dataSet(j,:)))==1
                        dataNum(i,1) = dataNum(i,1)+1;
                    end
                end
%           if all(ismember(Ck(i,:), dataSet))==1
%               dataNum(i,1) = dataNum(i,1)+1;
%           end
            end
        end
        %% 計算每個元素出現的比率
        numItems = length(dataSet);
        supportData = zeros(length(dataNum), 1);
        retListSize = 1;
        for i = 1:length(dataNum)
            supportData(i, 1) = dataNum(i, 1)/numItems;
            if supportData(i ,1) >= minSupport
                retList(retListSize, :) = Ck(i, :);
                retListSize = retListSize+1;
            end
        end
    end
end

生成後續的候選集

function [ retList ] = aprioriGen( Lk )
    [m,n] = size(Lk);%得到Lk矩陣的大小
    r = 1;
    for i = 1:m-1
        for j = i+1:m
            retListTmp_1(r,:) = [Lk(i,:),Lk(j,:)];
            tmp = unique(retListTmp_1(r,:));
            if length(tmp)<2*n
                tmp(1,2*n) = 0;%補0
            end
            retListTmp_2(r,:) = tmp;
            r = r+1;
        end
    end
    if m~=1
        retList=unique(retListTmp_2,'rows');
    else
        retList=[];
    end
end

總的生成頻繁項集的模組

%% 控制整個頻繁項集的生成
function [ L, supportData ] = apriori( dataSet, minSupport )
    C1 = createC1(dataSet)%生成最初的候選集
    [L1, supportData] = scanD(dataSet, C1, minSupport)%生成最初的頻繁項集
    L = L1;
    while ~isempty(L)
        Ck = aprioriGen(L)
        [Lk, supportData] = scanD(dataSet, Ck, minSupport)
        L = Lk;
    end
end

實現

第一步:

第二步:

第三步:

第四步: