1. 程式人生 > >資料探勘十大演算法(九):樸素貝葉斯原理、例項與Python實現

資料探勘十大演算法(九):樸素貝葉斯原理、例項與Python實現

一、條件概率的定義與貝葉斯公式

二、樸素貝葉斯分類演算法

樸素貝葉斯是一種有監督的分類演算法,可以進行二分類,或者多分類。一個數據集例項如下圖所示:

現在有一個新的樣本, X = (年齡:<=30, 收入:中, 是否學生:是, 信譽:中),目標是利用樸素貝葉斯分類來進行分類。假設類別為C(c1=是 或 c2=否),那麼我們的目標是求出P(c1|X)和P(c2|X),比較誰更大,那麼就將X分為某個類。

下面,公式化樸素貝葉斯的分類過程。

三、例項

下面,將下面這個資料集作為訓練集,對新的樣本X = (年齡:<=30, 收入:中, 是否學生:是, 信譽:中)  作為測試樣本,進行分類。

我們可以將這個例項中的描述屬性和類別屬性,與公式對應起來,然後計算。

四、Python實現

現在,利用Python編寫上述例項對應的程式碼,程式碼如下。

# 針對 “買電腦”例項進行樸素貝葉斯分類


if __name__ == '__main__':

    # 描述屬性分別用數字替換
    # 年齡, <=30-->0, 31~40-->1, >40-->2
    # 收入, '低'-->0, '中'-->1, '高'-->2
    # 是否學生, '是'-->0, '否'-->1
    # 信譽: '中'-->0, '優'-->1
    # 類別屬性用數字替換
    # 購買電腦是-->0, 不購買電腦否-->1
    MAP = [{'<=30': 0, '31~40': 1, '>40': 2},
           {'低': 0, '中': 1, '高': 2},
           {'是': 0, '否': 1},
           {'中': 0, '優': 1},
           {'是': 0, '否': 1}]

    # 訓練樣本
    train_samples = ["<=30 高 否 中 否",
                     "<=30 高 否 優 否",
                     "31~40 高 否 中 是",
                     ">40 中 否 中 是",
                     ">40 低 是 中 是",
                     ">40 低 是 優 否",
                     "31~40 低 是 優 是",
                     "<=30 中 否 中 否",
                     "<=30 低 是 中 是",
                     ">40 中 是 中 是",
                     "<=30 中 是 優 是",
                     "31~40 中 否 優 是",
                     "31~40 高 是 中 是",
                     ">40 中 否 優 否"]

    # 下面步驟將文字,轉化為對應數字
    train_samples = [sample.split(' ') for sample in train_samples]
    # print(train_samples)
    # exit()
    train_samples = [[MAP[i][attr] for i, attr in enumerate(sample)]for sample in train_samples]
    # print(train_samples)

    # 待分類樣本
    X = '<=30 中 是 中'
    X = [MAP[i][attr] for i, attr in enumerate(X.split(' '))]

    # 訓練樣本數量
    n_sample = len(train_samples)

    # 單個樣本的維度: 描述屬性和類別屬性個數
    dim_sample = len(train_samples[0])

    # 計算每個屬性有哪些取值
    attr = []
    for i in range(0, dim_sample):
        attr.append([])

    for sample in train_samples:
        for i in range(0, dim_sample):
            if sample[i] not in attr[i]:
                attr[i].append(sample[i])

    # 每個屬性取值的個數
    n_attr = [len(attr) for attr in attr]

    # 記錄不同類別的樣本個數
    n_c = []
    for i in range(0, n_attr[dim_sample-1]):
        n_c.append(0)

    # 計算不同類別的樣本個數
    for sample in train_samples:
        n_c[sample[dim_sample-1]] += 1

    # 計算不同類別樣本所佔概率
    p_c = [n_cx / sum(n_c) for n_cx in n_c]
    # print(p_c)

    # 將使用者按照類別分類
    samples_at_c = {}
    for c in attr[dim_sample-1]:
        samples_at_c[c] = []
    for sample in train_samples:
        samples_at_c[sample[dim_sample-1]].append(sample)

    # 記錄 每個類別的訓練樣本中,取待分類樣本的某個屬性值的樣本個數
    n_attr_X = {}
    for c in attr[dim_sample-1]:
        n_attr_X[c] = []
        for j in range(0, dim_sample-1):
            n_attr_X[c].append(0)

    # 計算 每個類別的訓練樣本中,取待分類樣本的某個屬性值的樣本個數
    for c, samples_at_cx in zip(samples_at_c.keys(), samples_at_c.values()):
        for sample in samples_at_cx:
            for i in range(0, dim_sample-1):
                if X[i] == sample[i]:
                    n_attr_X[c][i] += 1

    # 字典轉化為list
    n_attr_X = list(n_attr_X.values())
    # print(n_attr_X)

    # 儲存最終的概率
    result_p = []
    for i in range(0, n_attr[dim_sample-1]):
        result_p.append(p_c[i])

    # 計算概率
    for i in range(0, n_attr[dim_sample-1]):
        n_attr_X[i] = [x/n_c[i] for x in n_attr_X[i]]
        for x in n_attr_X[i]:
            result_p[i] *= x

    print('概率分別為', result_p)

    # 找到概率最大對應的那個類別,就是預測樣本的分類情況
    predict_class = result_p.index(max(result_p))
    print(predict_class)

執行結果如圖所示:

表明,樣本被分為第一類,即會購買電腦。對應的概率與手動計算的結果相同。

參考:

1. 資料探勘十大演算法

2. 資料倉庫與資料探勘 李春葆