1. 程式人生 > >【sklearn例項】1-貝葉斯演算法

【sklearn例項】1-貝葉斯演算法

問題

在這裡插入圖片描述

樸素貝葉斯求解

  • 樸素貝葉斯公式:
    在這裡插入圖片描述
  • 求解思想:即求先驗概率與條件概率乘積的最大值
    在這裡插入圖片描述
  • 求解
    在這裡插入圖片描述

注意:
本人求解過程中忘記了 Laplace 平滑 (⊙︿⊙),但好在預測值裡面沒有學歷為博士的一項,所以不平滑也不影響預測,但這樣是不規範的。

程式碼

  • 分析

1 讀取資料
2 資料切片,轉換(將字元型資料編碼)
3 劃分訓練集和測試集
4 匯入 sklearn 貝葉斯方法,擬合
5 預測輸入值

#匯入資料 read_csv

import pandas as pd
import numpy as np
c=pd.read_csv('career_data.csv')
print c

# 將特徵的離散資料 編碼 用 LabelEncoder()對標籤進行了編碼

from sklearn.preprocessing import LabelEncoder
class_le = LabelEncoder()
y=class_le.fit_transform(c['enrolled'].values)

# 特徵編碼時直接用了 DataFrame 替換
c['985'].replace(['Yes','No'],[1,0],inplace=True)
c['education'].replace(['bachlor','master','phd'],[0,1,2],inplace=True)
c['skill'].replace(['C++','Java'],[0,1],inplace=True)
b=c.values[:,:-1]
print '\n','特徵值','\n', b
print '標籤值','\n',y

在這裡插入圖片描述

# 匯入貝葉斯方法進行擬合

#from sklearn.cross_validation import train_test_split
from sklearn.naive_bayes import  GaussianNB
#train_X,test_X, train_y, test_y = train_test_split(b,y,test_size=0.1) # test_size:測試集比例20%
clf = GaussianNB()
#clf.fit(train_X, train_y)
clf.fit(b,y)
prediction6=clf.predict(b)
print '兩個類別的先驗概率:',clf.class_prior_   #獲取兩個類別的先驗概率
#print(clf.feature_prob_)
print('The accuracy of the NaiveBayes is',metrics.accuracy_score(prediction6,y))
print clf.predict([[1,1,0]])
print clf.predict_proba([[1,1,0]])

在這裡插入圖片描述
可以看到,先驗概率與之前的計算相同,預測結果也是未錄取,但最後的預測出的兩個類別的概率與計算不同,分析主要是因為之前計算的僅僅是貝葉斯公式的分子,而程式計算的可能是是包含分母的完整的後驗概率。

總結:
1 資料讀取DataFrame 方法,read_csv 與read_table 還是不同的
2 標籤的編碼,通常都用LabelEnconder,有n類就用0~ n-1 表示出來
3 屬性編碼的辦法太笨,我考慮過用OneHotEncoder 方法,但該方法只能進行二值轉換(非0 即1 ),不適合本例,學歷屬性裡有三類;即便可以,我還是沒搞懂獨熱編碼的原理,編完後相當於給資料擴維了,比如學歷一項就會用[1,0] 與 [0,1] 來表示Yes 和 No ,那後續該如何擬合呢,維度和原來不一樣了啊?還有pandas 裡面的 pd.get_dummies(c[‘skill’]),結果也是一樣,如何把編碼後的每個屬性再組合為原始資料的維度?
4 嘗試了將資料劃分為訓練集和測試集,但是先驗類別與計算的不一樣了,是因為此時的先驗概率是訓練集的,而非原始資料集了。
5 嘗試了用BonulliNB 和 MultinormialNB 方法,前者預測一致,而多項式貝葉斯方法預測相反,查了一下:多項式NB以樣本出現的次數為特徵值,主要用於離散特徵分類,例如文字分類單詞統計。

希望得到指點。