初步理解一下:對於一組輸入,根據這個輸入,輸出有多種可能性,需要計算每一種輸出的可能性,以可能性最大的那個輸出作為這個輸入對應的輸出。
那么,如何來解決這個問題呢?
貝葉斯給出了另一個思路。根據歷史記錄來進行判斷。
思路是這樣的:
1、根據貝葉斯公式:P(輸出|輸入)=P(輸入|輸出)*P(輸出)/P(輸入)
2、P(輸入)=歷史數據中,某個輸入占所有樣本的比例;
3、P(輸出)=歷史數據中,某個輸出占所有樣本的比例;
4、P(輸入|輸出)=歷史數據中,某個輸入,在某個輸出的數量占所有樣本的比例,例如:30歲,男性,中午吃面條,其中【30歲,男性就是輸入】,【中午吃面條】就是輸出。
一、條件概率的定義與貝葉斯公式
二、朴素貝葉斯分類算法
朴素貝葉斯是一種有監督的分類算法,可以進行二分類,或者多分類。一個數據集實例如下圖所示:
現在有一個新的樣本, X = (年齡:<=30, 收入:中, 是否學生:是, 信譽:中),目標是利用朴素貝葉斯分類來進行分類。假設類別為C(c1=是 或 c2=否),那么我們的目標是求出P(c1|X)和P(c2|X),比較誰更大,那么就將X分為某個類。
下面,公式化朴素貝葉斯的分類過程。
三、實例
下面,將下面這個數據集作為訓練集,對新的樣本X = (年齡:<=30, 收入:中, 是否學生:是, 信譽:中) 作為測試樣本,進行分類。
我們可以將這個實例中的描述屬性和類別屬性,與公式對應起來,然后計算。
參考python實現代碼
#coding:utf-8 # 極大似然估計 朴素貝葉斯算法 import pandas as pd import numpy as np class NaiveBayes(object): def getTrainSet(self): dataSet = pd.read_csv('F://aaa.csv') dataSetNP = np.array(dataSet) #將數據由dataframe類型轉換為數組類型 trainData = dataSetNP[:,0:dataSetNP.shape[1]-1] #訓練數據x1,x2 labels = dataSetNP[:,dataSetNP.shape[1]-1] #訓練數據所對應的所屬類型Y return trainData, labels def classify(self, trainData, labels, features): #求labels中每個label的先驗概率 labels = list(labels) #轉換為list類型 labelset = set(labels) P_y = {} #存入label的概率 for label in labelset: P_y[label] = labels.count(label)/float(len(labels)) # p = count(y) / count(Y) print(label,P_y[label]) #求label與feature同時發生的概率 P_xy = {} for y in P_y.keys(): y_index = [i for i, label in enumerate(labels) if label == y] # labels中出現y值的所有數值的下標索引 for j in range(len(features)): # features[0] 在trainData[:,0]中出現的值的所有下標索引 x_index = [i for i, feature in enumerate(trainData[:,j]) if feature == features[j]] xy_count = len(set(x_index) & set(y_index)) # set(x_index)&set(y_index)列出兩個表相同的元素 pkey = str(features[j]) + '*' + str(y) P_xy[pkey] = xy_count / float(len(labels)) print(pkey,P_xy[pkey]) #求條件概率 P = {} for y in P_y.keys(): for x in features: pkey = str(x) + '|' + str(y) P[pkey] = P_xy[str(x)+'*'+str(y)] / float(P_y[y]) #P[X1/Y] = P[X1Y]/P[Y] print(pkey,P[pkey]) #求[2,'S']所屬類別 F = {} #[2,'S']屬於各個類別的概率 for y in P_y: F[y] = P_y[y] for x in features: F[y] = F[y]*P[str(x)+'|'+str(y)] #P[y/X] = P[X/y]*P[y]/P[X],分母相等,比較分子即可,所以有F=P[X/y]*P[y]=P[x1/Y]*P[x2/Y]*P[y] print(str(x),str(y),F[y]) features_label = max(F, key=F.get) #概率最大值對應的類別 return features_label if __name__ == '__main__': nb = NaiveBayes() # 訓練數據 trainData, labels = nb.getTrainSet() # x1,x2 features = [8] # 該特征應屬於哪一類 result = nb.classify(trainData, labels, features) print(features,'屬於',result)
#coding:utf-8 #朴素貝葉斯算法 貝葉斯估計, λ=1 K=2, S=3; λ=1 拉普拉斯平滑 import pandas as pd import numpy as np class NavieBayesB(object): def __init__(self): self.A = 1 # 即λ=1 self.K = 2 self.S = 3 def getTrainSet(self): trainSet = pd.read_csv('F://aaa.csv') trainSetNP = np.array(trainSet) #由dataframe類型轉換為數組類型 trainData = trainSetNP[:,0:trainSetNP.shape[1]-1] #訓練數據x1,x2 labels = trainSetNP[:,trainSetNP.shape[1]-1] #訓練數據所對應的所屬類型Y return trainData, labels def classify(self, trainData, labels, features): labels = list(labels) #轉換為list類型 #求先驗概率 P_y = {} for label in labels: P_y[label] = (labels.count(label) + self.A) / float(len(labels) + self.K*self.A) #求條件概率 P = {} for y in P_y.keys(): y_index = [i for i, label in enumerate(labels) if label == y] # y在labels中的所有下標 y_count = labels.count(y) # y在labels中出現的次數 for j in range(len(features)): pkey = str(features[j]) + '|' + str(y) x_index = [i for i, x in enumerate(trainData[:,j]) if x == features[j]] # x在trainData[:,j]中的所有下標 xy_count = len(set(x_index) & set(y_index)) #x y同時出現的次數 P[pkey] = (xy_count + self.A) / float(y_count + self.S*self.A) #條件概率 #features所屬類 F = {} for y in P_y.keys(): F[y] = P_y[y] for x in features: F[y] = F[y] * P[str(x)+'|'+str(y)] features_y = max(F, key=F.get) #概率最大值對應的類別 return features_y if __name__ == '__main__': nb = NavieBayesB() # 訓練數據 trainData, labels = nb.getTrainSet() # x1,x2 features = [10] # 該特征應屬於哪一類 result = nb.classify(trainData, labels, features) print(features,'屬於',result)
參考鏈接:
https://blog.csdn.net/ten_sory/article/details/81237169