1. 程式人生 > >樸素貝葉斯法分類器的Python3 實現

樸素貝葉斯法分類器的Python3 實現

本篇文章是我在讀了李航的<統計學習方法>後手寫的演算法實現之一
原理請參考統計學習方法第四章樸素貝葉斯法-李航

程式碼如下:

# - * - coding: utf - 8 -*-
#
# 作者:田豐
# 郵箱:[email protected]
# 撰寫時間:2017年4月26日
# Python版本:3.6.1
# CSDN:http://blog.csdn.net/fontthrone
#
# 下一行為符號計算所匯入的包
# from fractions import Fraction

class NaiveBayesMethod:
    '''
    NaiveBayesMethod 的內部計算方式現在為數值計算,
    符號計算的程式碼已經註釋,如果需要請手動修改

    樸素貝葉斯法分類器 當lam=1 時,類分類方式為為貝葉斯估計
    實現了拉普拉斯平滑,以此避免出現要計算的概率為0的情況,以免計算錯誤的累積
    具體原理請參考李航的<統計學習方法>第四章
    lam = 0 時 類分類方式為為極大似然值估計
    '''
def __init__(self, inputArray, lam): self.input = inputArray self.lam = lam self.__lenInput = len(self.input) self.__y = self.input[self.__lenInput - 1] self.__onlyy = self.__only(self.__y) self.__county = self.__countList(self.__onlyy) # 計算列表總樣本數 return int
def __countList(self, list): count = {} for item in list: count[item] = count.get(item, 0) + 1 return len(count) # 檢查某列表中時候含有某個元素 def __findy(self, list, y): result = True for i in range(0, len(list)): if list[i] == y: result = False
return result # 返回列表種類 def __only(self, list): onlyy = [] for i in range(0, len(list)): if self.__findy(onlyy, list[i]): onlyy.append(list[i]) return onlyy # 統計列表中某元素的個數 def __countKind(self, list, element): return list.count(element) # 通過元素值返回位置索引 def __findOnlyElement(self, list, x): return self.__only(list).index(x) # 先驗概率 def __py(self, x): # return Fraction(self.__countKind(self.__y, x) + self.lam, len(self.__y) + self.__county * self.lam) return (self.__countKind(self.__y, x) + self.lam) / (len(self.__y) + self.__county * self.lam) # 返回p(x=?) def __probabilityX(self, list, x): # return Fraction(self.__countKind(list, x) + self.lam, len(list) + self.__countList(list) * self.lam) return (self.__countKind(list, x) + self.lam) / (len(list) + self.__countList(list) * self.lam) def __probabilityYX(self, list, x, yy): xx = self.__findOnlyElement(list, x) yindex = self.__findOnlyElement(self.__y, yy) fz = 0 onlyx = self.__only(list) onlyy = self.__only(self.__y) # 獲取 p(y=?|x1=?) 的分子 for i in range(0, len(list)): if list[i] == onlyx[xx] and self.__y[i] == onlyy[yindex]: fz += 1 # return Fraction(fz + self.lam, self.__countKind(list, onlyx[xx]) + self.__countList(list) * self.lam) return (fz + self.lam) / (self.__countKind(list, onlyx[xx]) + self.__countList(list) * self.lam) def fl(self, x, y): ps = [] for i in range(0, len(self.__onlyy)): p1 = self.__probabilityX(self.input[0], x) * self.__probabilityYX(self.input[0], x, 1) * self.__probabilityX( self.input[1], y) * self.__probabilityYX(self.input[1], y, self.__onlyy[i]) / self.__py(1) ps.append(p1) return self.__onlyy[ps.index(max(ps))] # 測試NaiveBayesMethod input = [[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3], [1, 2, 2, 1, 1, 1, 2, 2, 3, 3, 3, 2, 2, 3, 3], [-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1]] test = NaiveBayesMethod(input, 1) print(test.fl(2, 1)) test.lam = 0 print(test.fl(2, 1))
輸出結果如下:
-1
-1