贝叶斯分类python代码调试_数据挖掘实验2python编写贝叶斯分类器 – FindSpace
1. Introduction
本文基于前文說的樸素貝葉斯原理,參考圣地亞哥州立大學的實驗編寫了一個簡單的樸素貝葉斯分類器,并利用測試數據進行了測試。
項目地址:
2. 分類器編寫
2.1數據說明
采用“adult”數據集,輸入文件是adult.data,測試文件是adult.test。數據中一行為一個條目,表示一個人
數據集中的變量
變量名
意義
age
年齡
type_employer
職業類型,個體,政府等等
fnlwgt
該變量將被我們忽略
education
學歷
education_num
學歷的數字等級(和上一個一樣,將被忽略)
marital
婚姻狀況
occupation
職業
relationship
不清楚如何表述
race
人種
sex
生理性別
capital_gain
資本收益
capital_loss
資本支出
hr_per_week
每周工作時長
country
國籍
income
年收入是否>50k
由于參考文章中使用的是R語言進行處理,R語言在數據挖掘和統計上優勢極大,幾乎就是為其而生。python中也有numpy庫,但是這里僅用了numpy庫的median取中位數功能,其他還是以python原生類型來處理。
2.2 框架規劃
參考使用Python編寫樸素貝葉斯分類器,我們也主要使用字典來實現統計,但是可以分成兩個字典,一個是>50k的dataset_high,一個是<=50k的dataset_low。
class DataSet:
def __init__(self):
# 存儲讀入的原始數據
self.data = []
# 支出的中位數
self.loss_mid = 0
# 收入的中位數
self.gain_mid = 0
# 工作時長的中位數
self.hours_mid = 0
# 年齡的中位數
self.age_mid = 0
# 統計的數據,主要部分
self.classfied_dataset = None
# 總數據條目
self.len_data = 0
最后的計算是前文說的:
輸入數據的特征年齡職業類型國籍輸入數據的特征輸入數據的特征年齡職業類型國籍輸入數據的特征
最后兩者取大者,則就是所建模型的判定,是否大于50k。
公式化簡:
由于P(輸入數據的特征)對于一條數據,兩個公式來說,是相同的,所以略去計算。
2.3 輸入數據預處理
a = ["age", "type_employer", "fnlwgt", "education", "education_num", "marital", "occupation", "relationship", "race",
"sex", "capital_gain", "capital_loss", "hr_per_week", "country", "income"]
classfiled_data = {}
loss_median = loss
gain_median = gain
for node in a:
classfiled_data[node] = {}
for line in data:
if len(line) < 10:
continue
for node in a:
if line[a.index(node)] in classfiled_data[node]:
classfiled_data[node][line[a.index(node)]] += 1
else:
classfiled_data[node][line[a.index(node)]] = 1
列表a就是所有的字段,將所有的數據都按照對應字段,統計到classfiled_data上去,最后形成的形式如下:
# 打印classfiled_data的輸出,這是已經簡化過的輸出
,
marital:
{'Widowed': 908, 'Never-married': 10192, 'not-married': 5323, 'Married': 8297},
country:
{'other': 133, 'United-States': 21999, 'British-Commonwealth': 230, 'SE-Asia': 242, 'Euro_1': 159, 'Euro_2': 122, '?': 437, 'South': 64, 'China': 100, 'Latin-America': 1027, 'South-America': 207},
income:
{'<=50K': 24720},
capital_gain:
{'low': 0, 'none': 23685, 'high': 1035},
relationship:
{'Not-in-family': 7449, 'Own-child': 5001, 'Other-relative': 944, 'Husband': 7275, 'Wife': 823, 'Unmarried': 3228},}
即classfiled_data的第一層字段是a里面的字段,每個字段又對應不同類型的子字段,數字是統計所有數據的出現次數。
2.4 字段簡化
舍棄沒用的fnlwgt和重復的education_num字段
對于職業類型字段,Never-worked和without-Pay可以合并為Not-working字段,類似的,也可以把其他一些字段進行合并,合并的步驟是先在classfiled_data['type_employer']里新建一個'not-working'的key,然后其value就是原來['Never-worked', 'Without-pay']的數值之和。在寫了很長的代碼以后,我將其提取出來做成了一個函數:
def tiny(a_list, category, new_name):
if new_name not in classfiled_data[category]:
classfiled_data[category][new_name] = 0
for key in list(classfiled_data[category]):
if key in a_list and key != new_name:
classfiled_data[category][new_name] += classfiled_data[category][key]
del classfiled_data[category][key]
tiny(['Never-worked', 'Without-pay'], 'type_employer', 'not-working')
tiny(['Local-gov', 'State-gov'], 'type_employer', 'other-govt')
tiny(['Self-emp-inc', 'Self-emp-not-inc'], 'type_employer', 'self-employed')
同樣對其他字段也進行了類似的化簡。
這里有這樣幾個字段需要單獨處理:
capital_gain 利用中位數劃分成三部分:(-INF, 0] (0, mid] (mid, INF]
capital_loss 同上
hr_per_week 工作時間按照10小時間隔劃分了。最大值99,映射到100s上
age 按照5為間隔劃分了20組,
3. 測試數據
由于前面對數據進行了化簡,所以測試數據的輸入也需要按照上面的劃分進行映射,我代碼里直接使用生成好的字典進行映射。
針對每條數據,計算P(輸入數據的特征|>50k) 和P(輸入數據的特征|<=50k),取大的返回結果。
最后測試結果如下:
模型的判斷正確的次數: 13206
錯誤的次數3075
正確率: 0.811130
總結
以上是生活随笔為你收集整理的贝叶斯分类python代码调试_数据挖掘实验2python编写贝叶斯分类器 – FindSpace的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: ROG 掌机发布 BIOS 333 更新
- 下一篇: XMEMS 推出全球首个超声波固态扬声器
