樸素貝葉斯法分類器的Python3 實現
阿新 • • 發佈:2019-01-11
本篇文章是我在讀了李航的<統計學習方法>後手寫的演算法實現之一
原理請參考統計學習方法第四章樸素貝葉斯法-李航
程式碼如下:
# - * - 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