bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

樸素貝葉斯和半樸素貝葉斯(AODE)分類器Python實現-創新互聯

  一、概述

為敦化等地區用戶提供了全套網頁設計制作服務,及敦化網站建設行業解決方案。主營業務為成都網站設計、成都網站建設、敦化網站設計,以傳統方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業、用心的態度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

  機器學習最后一次實驗,要求實現樸素貝葉斯和AODE的半樸素貝葉斯分類器。由于老師說可以調用現成的相關機器學習的庫,所以我一開始在做樸素貝葉斯分類器的時候,直接調用了sklearn庫,很方便,可是問題來了,在做AODE半樸素貝葉斯分類器的時候,并沒有找到集成好的方法。所以就想著自己把半樸素貝葉斯分類器實現了,樸素貝葉斯分類就直接調用庫算了。可是讓人頭大的是,上來就直接實現AODE分類器還是不太科學,還得從基本的貝葉斯原理到樸素貝葉斯開始,所以我又從頭看,主要看的這篇博客 西瓜書讀書筆記——第七章:貝葉斯分類器,寫的非常好,看完之后就基本弄懂了。我感覺實現起來,樸素貝葉斯和半樸素貝葉斯有很多相似之處,索性就先把樸素貝葉斯實現了,正好也能加深一下理解,然后再實現AODE半樸素貝葉斯分類器就會容易些了。

  二、貝葉斯分類器

  2.1 樸素貝葉斯分類器

  (1)貝葉斯分類基本思想簡單解釋

  首先,貝葉斯分類的思想很簡單,假設數據一共有nnn種類別,即Label={L1,L2,??,Ln}Label=\{L_1,L_2,\cdots,L_n\}Label={L1,L2,?,Ln},給定一個樣本數據x={x1,x2,??,xm}x=\{x_1,x_2,\cdots,x_m\}x={x1,x2,?,xm},注意,這里的xxx是一個樣本數據,x1,x2,??,xmx_1,x_2,\cdots,x_mx1,x2,?,xm表示這個數據有mmm維特征,當知道了樣本數據xxx,根據xxx計算出來這個數據屬于每一種類別的概率P={PL1,PL2,??,PLn}P=\{P_{L_1},P_{L_2},\cdots,P_{L_n}\}P={PL1,PL2,?,PLn},最后將這個數據xxx劃分為大概率對應的類別。比如,如果argmax{PL1,PL2,??,PLn}=L2argmax\{P_{L_1},P_{L_2},\cdots,P_{L_n}\}=L_2argmax{PL1,PL2,?,PLn}=L2,那么xxx就被劃分為L2L_2L2。

  (2)貝葉斯分類基本原理

  其次,貝葉斯分類的實現也很簡單。現在已經知道了基本原理,設xxx所屬的類別為ccc,xix_ixi代表樣本xxx的第iii個屬性值(第iii個維度的值),那么上面所說的要求樣本xxx屬于每種類別的概率就記為P(c∣x)P(c|x)P(c∣x),根據貝葉斯模型和極大似然估計原理,那么就有:

  P(c∣x)=P(x∣c)P(c)P(x)=P(c)P(x)∏i=1mP(xi∣c)

  P(c|x)=\frac{P(x|c)P(c)}{P(x)}=\frac{P(c)}{P(x)}\prod_{i=1}^mP(x_i|c)

  P(c∣x)=P(x)P(x∣c)P(c)=P(x)P(c)i=1∏mP(xi∣c)

  其中P(x)=∏i=1mP(xi)P(x)=\prod_{i=1}^mP(x_i)P(x)=∏i=1mP(xi),對于數據xxx來說,計算對應的每一種類別的概率時,P(x)P(x)P(x)是相同的,所以為了計算方便,可以省略掉,記為:

  P(c∣x)∝P(c)∏i=1mP(xi∣c)

  P(c|x)\propto P(c)\prod_{i=1}^mP(x_i|c)

  P(c∣x)∝P(c)i=1∏mP(xi∣c)(注:在實現時,為了防止概率連乘導致趨近于0,將∏i=1mP(xi∣c)\prod_{i=1}^mP(x_i|c)∏i=1mP(xi∣c)取對數變成連加)所以最終計算xxx所對應的類別就有:

  L(x)=argmaxP(c)∏i=1mP(xi∣c)

  L(x)=argmax P(c)\prod_{i=1}^mP(x_i|c)

  L(x)=argmaxP(c)i=1∏mP(xi∣c)這里c是所要求的值。根據這個公式就知道,要求xxx所屬的類別,只要求出P(c)P(c)P(c)和P(xi∣c)P(x_i|c)P(xi∣c)就行了。

  設整個樣本數據集為DDD,當∣D∣|D|∣D∣足夠大時(即樣本數量足夠多),就可以利用頻率估計概率(大數定律)來計算出先驗概率P(c)P(c)P(c),

  P(c)=∣Dc∣∣D∣

  P(c)=\frac{|D_c|}{|D|}

  P(c)=∣D∣∣Dc∣∣D∣|D|∣D∣代表所有數據的數量,∣Dc∣|D_c|∣Dc∣表示類別為ccc的樣本的數量。現在P(c)P(c)P(c)很容易的求出來了,然后就是P(xi∣c)P(x_i|c)P(xi∣c)了。

  然而,對于樣本屬性xix_ixi來說,其可分為連續性樣本屬性和離散型樣本屬性。先理解一下什么是“離散型樣本屬性”,那么“連續型”就比較容易理解了。

  “離散型樣本屬性”:比如,對于西瓜AAA來說,AAA就是整個西瓜家族里面的一個樣本,那么AAA的屬性就會有{外皮顏色,敲擊聲音,觸摸手感,??}\{外皮顏色,敲擊聲音,觸摸手感,\cdots\}{外皮顏色,敲擊聲音,觸摸手感,?},而對于“外皮顏色”這個屬性來說,它的取值可能有{黃色,綠色,青綠色,??}\{黃色,綠色,青綠色,\cdots\}{黃色,綠色,青綠色,?},這個屬性的取值是離散的,有限的,那么這個屬性就是“離散型”屬性了,另外兩個屬性也是一樣。對于離散型樣本屬性的條件概率計算公式也是根據頻率估計概率得到:

  P(xi∣c)=∣Dc,xi∣∣Dc∣

  P(x_i|c)=\frac{|D_{c,x_i}|}{|D_c|}

  P(xi∣c)=∣Dc∣∣Dc,xi∣∣Dc,xi∣|D_{c,x_i}|∣Dc,xi∣為類別ccc中的所有數據的第iii個屬性值為xix_ixi的樣本的數量。

  “連續型樣本屬性”:還是對西瓜AAA來說,AAA除了上面提到的那些屬性之外,還有{含糖量,水分}\{含糖量,水分\}{含糖量,水分}這些屬性,這兩個屬性如果以定量方法(精確地測量數值)來表示,比如含糖量為45.678%45.678\%45.678%,這樣就叫做“連續型”屬性了,但是如果以定性方法來表示,比如將含糖量劃分為{低,中,高}\{低,中,高\}{低,中,高}三個等級,那么就是“離散型”屬性了。對于連續型樣本屬性的條件概率計算公式使用高斯核密度估計(應該是這么叫吧,希望數理統計沒白學)得到:

  P(xi∣c)=12πσc,iexp(?(xi?μc,i)22σc,i2)

  P(x_i|c)=\frac{1}{\sqrt{2\pi}\sigma_{c,i}}exp\left(-\frac{(x_i-\mu_{c,i})^2}{2\sigma^2_{c,i}}\right)

  P(xi∣c)=2πσc,i1exp(?2σc,i2(xi?μc,i)2)其中μc,i\mu_{c,i}μc,i和σc,i\sigma_{c,i}σc,i分別為第ccc類樣本在第iii個屬性取值的均值和標準差。

  為了避免數據集不充分而導致估計概率為0的情況,需要在實現過程中引入拉普拉斯修正(具體拉普拉斯修正方法也很簡單),但我為了圖方便,直接在先驗概率和條件概率(針對離散型屬性)的分子和分母都 +1 了(實際測試中,并沒有發現有太大的差別)。

  2.2 AODE半樸素貝葉斯分類器

  首先,要知道什么是AODE(Averaged One-Dependent Estimator),就要先了解什么是SPODE(Super-Parent One-Dependent Estimator)。在上面所講的樸素貝葉斯分類都是基于樣本的所有屬性是相互獨立的,那么如果某些屬性存在依賴關系怎么辦呢。SPODE就是假設樣本的每個屬性都依賴于某一個屬性,這個屬性就叫做“超父”。比如,將x1x_1x1屬性設置為“超父”,那么計算xxx屬于第ccc類數據的概率公式為:

  P(c∣x)∝P(c)∏i=1mP(xi∣c,x1)

  P(c|x)\propto P(c)\prod_{i=1}^mP(x_i|c,x_1)

  P(c∣x)∝P(c)i=1∏mP(xi∣c,x1)而AODE就是在此基礎上,將樣本的屬性依次作為超父來計算概率,最后求和,同時,假設類別ccc也依賴于樣本的屬性,那么計算xxx屬于類別ccc的概率公式為:

  P(c∣x)∝∑i=1mP(c,xi)∏j=1mP(xj∣c,xi)

  P(c|x)\propto \sum_{i=1}^m P(c,x_i)\prod_{j=1}^mP(x_j|c,x_i)

  P(c∣x)∝i=1∑mP(c,xi)j=1∏mP(xj∣c,xi)同樣的,利用頻率估計概率的方法可以得到:

  P(xj∣c,xi)=∣Dc,xi,xj∣∣Dc,xi∣

  P(x_j|c,x_i)=\frac{|D_{c,x_i,x_j}|}{|D_{c,x_i}|}

  P(xj∣c,xi)=∣Dc,xi∣∣Dc,xi,xj∣與樸素貝葉斯分類相同,實現時也要引入拉普拉斯修正,我還是分子分母都 +1 了。

  通過觀察xxx屬于類別ccc的概率公式就能看出,這個方法的時間復雜度很高,實際上,對于每一個樣本,計算出分別屬于哪一個類的概率一共有三層循環(不知是否有優化方法,但是時間復雜度幾乎不可能降低了)。實現之后,這個方法并沒有進行實驗結果的驗證,因為時間代價太大,所以我猜測,這也是為什么sklearn中有樸素貝葉斯卻沒有AODE半樸素貝葉斯方法的原因了。

  三、實驗結果與代碼

  3.1 實驗結果

  對于樸素貝葉斯分類器的實現,我只實現了離散型樣本屬性的分類(連續性屬性也比較容易,只要把條件概率函數換成高斯核即可),使用了MNIST、Yale和COIL20這三個數據對其進行了實驗,使用ACC評價標準對其進行評價。(注:由于AODE時間成本過高,不太適合屬性維度較多數據,我沒有進行數據實驗,所以我也不知道對不對,不過按照樸素貝葉斯的思路來應該也不會錯吧。。。)

  方法\數據  MNIST  Yale  COIL20

  McQueen_NBC  0.95  1  1

  GaussianNB  0.55  0.8  1

  這里我就沒有將數據集劃分成測試集和訓練集了,這三組數據測試集是在訓練集中每個類別數據分別抽取前0.005%,0.1%,0.01%得到的。McQueen_NBC方法是我自己實現的樸素貝葉斯分類器(實際上是多項式貝葉斯),適用于離散屬性樣本,而GaussianNB是調用的sklearn庫的方法,這個方法是基于連續型屬性的,由結果可以看出,在MNIST和Yale這兩個數據上,連續型準確率不如離散型(因為這兩個數據是離散型樣本數據)。

  3.2 完整代碼

  datadvi.py

  from scipy.io import loadmat

  import numpy as np

  def divdata():

  filename = 'C:/Users/ALIENWARE/Documents/作業/機器學習/datasets/' + input("input name of data file: ")

  data = loadmat(filename)

  # print(data['X'])

  if filename == 'C:/Users/ALIENWARE/Documents/作業/機器學習/datasets/COIL20.mat':

  dataX = data['fea']

  dataY = data['gnd'][0]

  else:

  dataX = data['X']

  dataY = data['Y'].T[0]

  print(len(dataX[0]))

  divideornot = input("divide data or not?(Yes/No): ")

  if divideornot == 'Yes':

  dataX_train = []

  dataX_predict = []

  dataY_train = []

  dataY_predict = []

  num_Y = np.unique(dataY).astype(int)

  for i in range(len(num_Y)):

  temp = dataY == num_Y[i]

  temp.astype(float)

  num_Y[i] = np.sum(temp)

  flag = 0

  for j in range(len(dataY)):

  if temp[j] == 1:

  if flag < int(round(0.9 * num_Y[i])):

  dataX_train.append(dataX[j])

  dataY_train.append(dataY[j])

  flag += 1

  else:

  dataX_predict.append(dataX[j])

  dataY_predict.append(dataY[j])

  dataX_train = np.array(dataX_train)

  dataX_predict = np.array(dataX_predict)

  dataY_train = np.array(dataY_train)

  dataY_predict = np.array(dataY_predict)

  return dataX_train,dataX_predict,dataY_train,dataY_predict

  else:

  return dataX,dataX,dataY,dataY

  def decreaseData(dataX,dataY):

  dataX_train = []

  dataY_train = []

  num_Y = np.unique(dataY).astype(int)

  print("this data has {} samples".format(len(dataX)))

  ratio = float(input("input the ratio you want to decrease: "))

  for i in range(len(num_Y)):

  temp = dataY == num_Y[i]

  temp.astype(float)

  num_Y[i] = np.sum(temp)

  flag = 0

  for j in range(len(dataY)):

  if temp[j] == 1:

  if flag < round(ratio * num_Y[i]):

  dataX_train.append(dataX[j])

  dataY_train.append(dataY[j])

  flag += 1

  dataX_train = np.array(dataX_train)

  dataY_train = np.array(dataY_train)

  print(dataX_train)

  return dataX_train,dataY_train

  Acc.py

  import numpy as np

  def acc(L1, L2):

  sum = np.sum(L1[:]==L2[:])

  return sum/len(L2)

  NBC.py

  import math

  import numpy as np

  import datadvi

  import Acc

  #加載數據

  def loadData(filename):

  return datadvi.divdata()

  #按標簽類別生成不同標簽樣本組成的集合,返回值為每種類別樣本的索引

  def divSamples(dataY):

  label = np.unique(dataY)

  D = []

  for i in label:

  D.append(np.argwhere(dataY==i).T[0])

  return np.array(D)

  # 計算第c類樣本在第i個屬性上取值的均值和標準差,smaple_cIndx是第c類樣本的索引(用于連續型屬性,此次未用到)

  def calcMuSig(sample_cIndx,i,D):

  mu = np.average(D[sample_cIndx][:,i])

  sigma = np.std(D[sample_cIndx][:,i])

  return mu,sigma

  #計算類先驗概率P(c),

  def beforeProb(sample_cIndx,D):

  return float(len(sample_cIndx)+1)/(D.shape[0]+1)

  #計算離散型條件概率P(xi|c)

  def condProb_disp(i,xi,sample_cIndx,D):

  numerator = np.sum(D[sample_cIndx][:,i]==xi)+1

  denominator = len(sample_cIndx)+1

  return float(numerator)/denominator

  #計算連續型條件概率P(xi|c)

  def condProb_cont(i,xi,sample_cIndx,D):

  mu,sigma = calcMuSig(sample_cIndx,i,D)

  prob = 1/(math.sqrt(2*3.14)*sigma)*math.exp(-float((xi-mu)*(xi-mu))/(2*sigma*sigma))

  return prob 鄭州婦科醫院哪家好 http://mobile.120zzzy.com/

  #計算類后驗概率P(c|x)

  def afterProb(sample_x,c,dataX,dataY):

  sample_c = divSamples(dataY)

  p = beforeProb(sample_c[c],dataX)

  #p = beforeProb(sample_c[c],dataX)

  p1 = 0

  for i in range(len(sample_x)):

  p1 += math.log10(condProb_disp(i,sample_x[i],sample_c[c],dataX))

  #p1 *= condProb_cont(i,sample_x[i],sample_c[c],dataX) #會下溢

  return p*p1

  #計算大概率對應的類

  def argMaxProb_c(sample_x,dataX,dataY):

  label = np.unique(dataY)

  argProb1 = []

  for c in label:

  temp_prob = afterProb(sample_x,c-1,dataX,dataY)

  argProb1.append(temp_prob)

  argProb = np.array(argProb1)

  return label[np.argmax(argProb)]

  #將所有數據分類

  def bayesClassifier(dataPredict,dataX,dataY):

  pred = []

  for sample_x in dataPredict:

  pred.append(argMaxProb_c(sample_x,dataX,dataY))

  print(len(pred))

  return pred

  dataX_train, dataX_predict, dataY_train, dataY_predict = datadvi.divdata()

  dataX_predict,dataY_predict = datadvi.decreaseData(dataX_predict,dataY_predict)

  print(len(dataX_predict))

  sample_c = divSamples(dataY_train)

  pred = bayesClassifier(dataX_predict,dataX_train,dataY_train)

  print(pred)

  print(Acc.acc(pred,dataY_predict))

  AODE.py

  import math

  import numpy as np

  import datadvi

  import Acc

  import RBFNN

  #加載數據

  def loadData(filename):

  return datadvi.divdata()

  #按標簽類別生成不同標簽樣本組成的集合,返回值為每種類別樣本的索引

  def divSamples(dataY):

  label = np.unique(dataY)

  D = []

  for i in label:

  D.append(np.argwhere(dataY==i).T[0])

  return np.array(D)

  #計算先驗概率P(c,xi)

  def beforeProb(sample_cIndx,i,xi,D):

  numerator = len(np.argwhere(D[sample_cIndx][:,i]==xi).T[0])+1 #索引改變了,但是數量沒變

  denominator = D.shape[0]+1 #此處1需被替換為N*Ni

  return float(numerator)/denominator

  #計算條件概率P(xj|c,xi)

  def condProb(i,xi,j,xj,sample_cIndx,D):

  D_c = D[sample_cIndx]

  D_c_xi = D_c[np.argwhere(D_c[:,i]==xi).T[0]]

  D_c_xi_xj = D_c_xi[np.argwhere(D_c_xi[:,j]==xj).T[0]]

  numerator = len(D_c_xi_xj)+1

  denominator = len(D_c_xi)+1

  return float(numerator)/denominator

  #計算后驗概率P(c|x)

  def afterProb(sample_x,c,dataX,dataY):

  sample_c = divSamples(dataY)

  prob = 0

  for i in range(len(sample_x)):

  p1 = 0

  p = beforeProb(sample_c[c],i,sample_x[i],dataX)

  for j in range(len(sample_x)):

  p1 += math.log10(condProb(i,sample_x[i],j, sample_x[j],sample_c[c], dataX)) #防止下溢

  prob += p*p1

  return prob

  #計算大概率對應的類

  def argMaxProb_c(sample_x,dataX,dataY):

  label = np.unique(dataY)

  argProb1 = []

  for c in label:

  temp_prob = afterProb(sample_x, c - 1, dataX, dataY)

  argProb1.append(temp_prob)

  argProb = np.array(argProb1)

  return label[np.argmax(argProb)]

  #將所有數據分類

  def bayesClassifier(dataPredict,dataX,dataY):

  pred = []

  for sample_x in dataPredict:

  label_pred = argMaxProb_c(sample_x,dataX,dataY)

  pred.append(label_pred)

  print(len(pred))

  return pred

  dataX_train, dataX_predict, dataY_train, dataY_predict = datadvi.divdata()

  dataX_predict,dataY_predict = datadvi.decreaseData(dataX_predict,dataY_predict)

  print(len(dataX_predict))

  pred = bayesClassifier(dataX_predict,dataX_train,dataY_train)

  print(Acc.acc(pred,dataY_predict))

當前題目:樸素貝葉斯和半樸素貝葉斯(AODE)分類器Python實現-創新互聯
文章轉載:http://vcdvsql.cn/article42/pjihc.html

成都網站建設公司_創新互聯,為您提供服務器托管電子商務做網站網站設計公司品牌網站制作網頁設計公司

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都seo排名網站優化