基于人口普查数据的收入预测模型构建及比较分析(Python数据分析分类器模型实践)
基于人口普查數(shù)據(jù)的收入預(yù)測模型構(gòu)建及比較分析
這篇文章是上學(xué)期數(shù)據(jù)分析課程的作業(yè),本來想等成績出來后再分享出來,但是因為疫情原因成績遲遲沒有上傳,所以這里就先分享出來,如果有分析的不對的地方,歡迎一起分析討論,共同學(xué)習(xí)
摘要
收入是反映人民生活水平和國家經(jīng)濟發(fā)展狀況的重要指標,改善收入水平,提高生活質(zhì)量是各國政府和人民共同的奮斗目標。探索收入的影響因素,不僅對國家具有重要意義,對個人提升自我,企業(yè)識別目標消費群體也具有重要的參考價值。為了研究年齡、受教育程度、職業(yè)等諸多因素對個體收入的影響,本文以UCI Machine Learning Repository網(wǎng)站提供的人口普查數(shù)據(jù)Adult Data Set作為數(shù)據(jù)樣本,遵循CRISP-DM的數(shù)據(jù)挖掘流程,對數(shù)據(jù)中可能存在的規(guī)律進行探索和分析,構(gòu)建決策樹、Logistic回歸、K近鄰、線性支持向量機、隨機森林、AdaBoost等十個分類模型探究各項指標對個體收入的影響和對個體收入進行預(yù)測,并通過多個模型評價指標,對不同的分類模型的分類效果進行比較和評價。
關(guān)鍵詞:數(shù)據(jù)分析;分類算法;預(yù)測;模型評價;數(shù)據(jù)可視化;
一、業(yè)務(wù)理解
對于個人來說,收入可以一定程度上反映個體的生活水平和消費能力,影響個人對于商品、服務(wù)需求的種類和數(shù)量,影響個人的社會地位、健康狀況和幸福水平。
對于企業(yè)而言,不同收入人群的購買力和產(chǎn)品偏好不同,對價格的敏感程度也不同,識別不同收入人群,有助于幫助企業(yè)有針對性地設(shè)計、生產(chǎn)、推廣產(chǎn)品和提供差異化的服務(wù),從而提高產(chǎn)品和服務(wù)的銷售量,節(jié)約銷售費用,降低企業(yè)生產(chǎn)和運營成本,更好地塑造企業(yè)形象,為企業(yè)帶來更大的市場份額和更多的利潤。
對于國家而言,個人收入水平能夠直接反應(yīng)人民的生活水平和國家的經(jīng)濟發(fā)展狀況,個人收入的提高能夠顯著提高人民的購買力,提高國民生產(chǎn)總值,促進各行各業(yè)的平穩(wěn)健康發(fā)展。分析人民收入的影響因素,探索不同指標對收入的影響情況,有助于國家對提高人民生活水平、改善社會福利、提高國民素質(zhì)制定更加有效和更加有針對性的措施。
國內(nèi)外的大量研究已充分證明,受教育程度和工作經(jīng)驗是影響一個人工作收入的重要因素。但實際上,我們發(fā)現(xiàn)僅憑這兩個變量并不能完全解釋個人的收入差異問題。比如,即使兩個受過同等教育的人,在同一時間進入職場,他們的收入也可能存在明顯差異;而工作經(jīng)驗相同的兩個人,即使他們的受教育程度相同,并且在同一個行業(yè)、同一個企業(yè),甚至同一生產(chǎn)部門,其收入也可能存在一定差異。在社交媒體上,既有人宣揚“知識改變命運”,也有人大力鼓吹“讀書無用論”,由此可見,影響收入的因素是多種多樣、錯綜復(fù)雜的。
二、數(shù)據(jù)理解
2.1 數(shù)據(jù)收集
收入的影響因素是復(fù)雜多樣的,不僅涉及到個人,還受到家庭乃至國家不同因素的影響,涉及的指標數(shù)量龐大且難以獲取,為簡化模型和分析過程,本文數(shù)據(jù)來自UCI Machine Learning Repository網(wǎng)站的Adult Data Set數(shù)據(jù)集(https://archive.ics.uci.edu/ml/datasets/adult)。Adult Data Set數(shù)據(jù)集是Barry Becker從1994年的人口普查數(shù)據(jù)庫中整理篩選得到的,數(shù)據(jù)收集和整理過程規(guī)范統(tǒng)一,數(shù)據(jù)質(zhì)量和可信度高,樣本量充足且缺失值、異常值較少,能夠一定程度上保證模型的質(zhì)量和可信度。
2.2數(shù)據(jù)描述
本文選用的數(shù)據(jù)集共包含3個文件,adult.names包含了數(shù)據(jù)集的說明和對數(shù)據(jù)集各項指標的解釋,adult.data和adult.test為數(shù)據(jù)集作者劃分的訓(xùn)練集和測試集,為便于對數(shù)據(jù)進行整理和分析,本文將adult.data和adult.test兩個數(shù)據(jù)集進行合并,在訓(xùn)練模型時對訓(xùn)練集和測試集進行重新分割。本文采用的數(shù)據(jù)集共包含48842個樣本15個指標。15個指標中6個指標為連續(xù)型指標,其余9個指標為離散型指標,其名稱及屬性如下表所示:
| age | 年齡 | 連續(xù)型 | |
| workclass | 工作類型 | 離散型 | Private(私人); Self-emp-not-inc(自由職業(yè)非公司); Self-emp-inc(自由職業(yè)公司); Federal-gov(聯(lián)邦政府); Local-gov(地方政府); State-gov(州政府); Without-pay(無薪); Never-worked(無工作經(jīng)驗) |
| final-weight | 樣本權(quán)重 | 連續(xù)型 | |
| education | 受教育程度 | 離散型 | Bachelors(學(xué)士); Some-college(大學(xué)未畢業(yè)); 11th(高二); HS-grad(高中畢業(yè)); Prof-school(職業(yè)學(xué)校); Assoc-acdm(大學(xué)專科); Assoc-voc(準職業(yè)學(xué)位); 9th(初三),7th-8th(初中1-2年級); 12th(高三); Masters(碩士); 1st-4th(小學(xué)1-4年級); 10th(高一); Doctorate(博士); 5th-6th(小學(xué)5-6年級); Preschool(幼兒園) |
| education-num | 受教育時長 | 連續(xù)型 | |
| marital-status | 婚姻情況 | 離散型 | Married-civ-spouse(已婚平民配偶); Divorced(離婚); Never-married(未婚); Separated(分居); Widowed(喪偶); Married-spouse-absent(已婚配偶異地); arried-AF-spouse(已婚軍屬) |
| occupation | 職業(yè) | 離散型 | Tech-support(技術(shù)支持); Craft-repair(手工藝維修); Other-service(其他職業(yè)); Sales(銷售); Exec-managerial(執(zhí)行主管); Prof-specialty(專業(yè)技術(shù)); Handlers-cleaners(勞工保潔); Machine-op-inspct(機械操作); Adm-clerical(管理文書); Farming-fishing(農(nóng)業(yè)捕撈); Transport-moving(運輸); Priv-house-serv(家政服務(wù)); Protective-serv(保安); Armed-Forces(軍人) |
| relationship | 家庭角色 | 離散型 | Wife(妻子); Own-child(孩子); Husband(丈夫); Not-in-family(離家); Other-relative(其他關(guān)系); Unmarried(未婚) |
| race | 種族 | 離散型 | White(白人); Asian-Pac-Islander(亞裔、太平洋島裔); Amer-Indian-Eskimo(美洲印第安裔、愛斯基摩裔); Black(非裔); Other(其他) |
| sex | 性別 | 離散型 | Female(女); Male(男) |
| capital-gain | 資本收益 | 連續(xù)型 | |
| capital-loss | 資本支出 | 連續(xù)型 | |
| hours-per-week | 周工作小時數(shù) | 連續(xù)型 | |
| country | 國籍 | 離散型 | United-States(美國); Cambodia(柬埔寨); England(英國); Puerto-Rico(波多黎各); Canada(加拿大); Germany(德國); Outlying-US(Guam-USVI-etc) (美國海外屬地); India(印度); Japan(日本); Greece(希臘); South(南美); China(中國); Cuba(古巴); Iran(伊朗); Honduras(洪都拉斯); Philippines(菲律賓); Italy(意大利); Poland(波蘭); Jamaica(牙買加),Vietnam(越南); Mexico(墨西哥); Portugal(葡萄牙); Ireland(愛爾蘭); France(法國); Dominican-Republic(多米尼加共和國); Laos(老撾); Ecuador(厄瓜多爾); Taiwan(臺灣); Haiti(海地); Columbia(哥倫比亞); Hungary(匈牙利); Guatemala(危地馬拉); Nicaragua(尼加拉瓜); Scotland(蘇格蘭); Thailand(泰國); Yugoslavia(南斯拉夫); El-Salvador(薩爾瓦多); Trinadad&Tobago(特立尼達和多巴哥); Peru(秘魯); Hong(香港); Holand-Netherlands(荷蘭) |
| income-level | 收入等級 | 離散型 | <=50K; >50K |
三、數(shù)據(jù)準備
本文采用基于Python3的Jupyter Notebook作為模型和分析工具。Jupyter Notebook是一個基于Web的交互式數(shù)據(jù)科學(xué)和科學(xué)計算工具,因為其功能強大,使用靈活,已廣泛被亞馬遜、谷歌、微軟等互聯(lián)網(wǎng)企業(yè)應(yīng)用于科學(xué)計算,并已經(jīng)成為云計算的一個流行的用戶界面。而Python作為一門新興的編程語言,其語法簡潔,易于部署,功能強大,在數(shù)據(jù)挖掘和機器學(xué)習(xí)領(lǐng)域已得到廣泛的應(yīng)用。
3.1 數(shù)據(jù)導(dǎo)入
(1)首先下載本文用到的Adult Data Set的兩個數(shù)據(jù)集,存放于dataset目錄中。
(2)新建文檔并導(dǎo)入本文分析所用到的工具包
1. ## 導(dǎo)入相關(guān)數(shù)據(jù)包 2. # 數(shù)據(jù)處理 3. import time, datetime, math, random 4. from io import StringIO 5. import numpy as np 6. import pandas as pd 7. from sklearn.model_selection import train_test_split 8. # 可視化 9. import matplotlib.pyplot as plt # 繪圖 10. import missingno # 缺失值可視化 11. import seaborn as sns # 繪圖庫 12. from pandas.plotting import scatter_matrix #繪制散布矩陣圖 13. # 分類模型 14. # import sklearn.ensemble as ske # 包含了一套分類算法 15. from sklearn import datasets, model_selection, tree, preprocessing, metrics, linear_model 16. from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier 17. from sklearn.neighbors import KNeighborsClassifier 18. from sklearn.naive_bayes import GaussianNB 19. from sklearn.linear_model import LinearRegression, LogisticRegression, Ridge, Lasso, SGDClassifier 20. from sklearn.tree import DecisionTreeClassifier 21. from sklearn.ensemble import AdaBoostClassifier 22. from sklearn.ensemble import VotingClassifier 23. from sklearn.svm import SVC 24. # 自動調(diào)參器 - 隨機探索 25. import scipy.stats as st 26. from scipy.stats import randint as sp_randint # 隨機變量 27. from sklearn.model_selection import RandomizedSearchCV # 自動調(diào)參工具(隨機采樣) 28. # 計算模型評價指標 29. from sklearn.metrics import precision_recall_fscore_support, roc_curve, auc 30. from sklearn.metrics import precision_recall_curve 31. from sklearn.metrics import average_precision_score, f1_score, precision_score, recall_score 32. # 控制提示信息 33. import warnings 34. warnings.filterwarnings('ignore') 35. # 便于在notebook中顯示圖形并可省略plt.show(),簡化代碼 36. %matplotlib inline(3)導(dǎo)入兩個數(shù)據(jù)集并進行合并
使用panda的read_csv()方法讀取兩個數(shù)據(jù)集至DataFrame,將其合并。
headers = ['age', 'workclass', 'final-weight', 'education', 'education-num', 'marital-status', 'occupation', 'relationship', 'race', 'sex', 'capital-gain', 'capital-loss', 'hours-per-week', 'country', 'income-level'] # 定義數(shù)據(jù)表頭即參數(shù)名 adult_data = pd.read_csv('dataset/adult.data', header=None, names=headers, sep=',\s', na_values=["?"], engine='python') # 導(dǎo)入數(shù)據(jù)集給出的訓(xùn)練集 adult_test = pd.read_csv('dataset/adult.test', header=None, names=headers, sep=',\s', na_values=["?"], engine='python', skiprows=1) # 導(dǎo)入數(shù)據(jù)集給出的測試集 dataset = adult_data.append(adult_test) # 合并兩個數(shù)據(jù)集 # 由于導(dǎo)入時分別為兩數(shù)據(jù)集添加了索引,故對合并后的DataFrame重新創(chuàng)建索引并覆蓋原索引 dataset.reset_index(inplace=True, drop=True)3.2 數(shù)據(jù)預(yù)處理
3.2.1 查看數(shù)據(jù)缺失情況
(1)繪制缺失值矩陣圖
對數(shù)據(jù)的缺失情況可視化,使用方塊代表指標,方塊中的留白代表數(shù)據(jù)缺失及缺失的位置,便于觀察各指標數(shù)據(jù)缺失以及數(shù)據(jù)缺失的分布情況。
missingno.matrix(dataset, figsize = (20,5))由表中可以看出,工作類型(workclass)、職業(yè)(occupation)和國籍(country)存在的缺失值較多。工作類型和職業(yè)的缺失具有一定的相關(guān)性。
(2)繪制缺失值柱狀圖
缺失值柱狀圖通過統(tǒng)計各指標缺失值情況,并以條形圖展現(xiàn)指標缺失值數(shù)量。
missingno.bar(dataset, sort='ascending', figsize = (20,5))
通過缺失值柱狀圖可以看出,工作類型(workclass)、職業(yè)(occupation)和國籍(country)均存在不同程度的缺失,其余指標無缺失值,其中工作類型缺失值最多,其次為職業(yè)(occupation)和國籍(country)。
3.2.2 處理缺失值
通過3.2.1對缺失值情況的分析我們可以看出數(shù)據(jù)集的缺失值數(shù)量較少,忽略含有缺失值的樣本對整體數(shù)據(jù)影響很小,故采取直接刪除含有缺失值樣本的方法對缺失值進行處理,并對處理后的數(shù)據(jù)進行描述。
dataset.dropna(axis=0, how='any', inplace=True) dataset.describe(include='all')由下表可見,去除缺失值后的數(shù)據(jù)集共包含45222個有效樣本,刪除含有缺失值的樣本3620個,占原樣本量的7.4%。
3.2.3 處理數(shù)據(jù)異常
通過3.2.2刪除缺失值后的數(shù)據(jù)描述,我們注意到離散型變量收入等級指標(income-level)存在4種類型的值,與樣本給出的說明不符。通過對數(shù)據(jù)集進行觀察,我們發(fā)現(xiàn)在adult.data中標簽為“<=50K”和“>50K”,而在adult.test中的標簽為 “<=50K.”和“>50K.”。因此,我們對這種不一致問題進行處理,合并同義標簽。
此外,樣本權(quán)重(final-weight)指標對于本題目來說無實際意義,故刪除該指標。
# 處理年收入指標 dataset.loc[dataset['income-level'] == '>50K.', 'income-level'] = '>50K' dataset.loc[dataset['income-level'] == '<=50K.', 'income-level'] = '<=50K' # 刪除無用的final-weight指標 dataset = dataset.drop(['final-weight'],axis=1)3.3 數(shù)據(jù)整體描述
3.3.1 預(yù)覽數(shù)據(jù)
通過預(yù)覽數(shù)據(jù)的一部分,可以大致了解數(shù)據(jù)各指標的類型。
dataset.head(5) # 預(yù)覽數(shù)據(jù)前5行3.3.2 描述性統(tǒng)計
對數(shù)據(jù)進行描述性統(tǒng)計,對于連續(xù)型變量,計算其有效值數(shù)量、平均值、標準差、最小值,25%分位數(shù)、50%分位數(shù)、75%分位數(shù)以及最大值;對于離散型變量,統(tǒng)計其有效值數(shù)量、類別數(shù)量、出現(xiàn)最多的類別及其頻次。
# 對數(shù)值變量進行描述 dataset.describe(include='all')3.3.3 繪制變量的分布情況
繪制條形圖對各指標的分析情況進行描述。
# 繪制每個變量的分布狀況 def plot_distribution(dataset, cols, width, height, hspace, wspace): plt.style.use('seaborn-whitegrid') fig = plt.figure(figsize=(width,height)) fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=wspace, hspace=hspace) rows = math.ceil(float(dataset.shape[1]) / cols) for i, column in enumerate(dataset.columns): ax = fig.add_subplot(rows, cols, i + 1) ax.set_title(column) if dataset.dtypes[column] == np.object: g = sns.countplot(y=column, data=dataset) substrings = [s.get_text()[:18] for s in g.get_yticklabels()] g.set(yticklabels=substrings) plt.xticks(rotation=25) else: g = sns.distplot(dataset[column]) plt.xticks(rotation=25) plot_distribution(dataset, cols=3, width=20, height=20, hspace=0.45, wspace=0.5)從圖中我們可以看出,樣本的年齡主要集中在20~40歲之間,呈現(xiàn)出正偏態(tài)的分布狀態(tài);工作類型主要為個人,其他工作類型的樣本相對較少;教育程度以高中和大學(xué)為主;教育時長以9-10年為主,大部分均達到了7.5年以上;職業(yè)類型中執(zhí)行主管、專業(yè)技術(shù)和手工藝維修居多,而以軍人為職業(yè)的樣本較少;家庭角色指標中樣本多數(shù)為丈夫,其次為離家狀態(tài);調(diào)查的對象中白人占據(jù)了大多數(shù),而其他族裔的數(shù)量較少;樣本的性別以男性為主,占到總樣本的約2/3;數(shù)據(jù)中的大多數(shù)樣本均來自美國,沒有資本收入和資本支出,每周工作40小時左右;樣本中收入水平小于$50K的數(shù)量較多,約為收入水平大于$50K樣本的3倍。
此外,我們還發(fā)現(xiàn)部分分類指標類別過多,且部分指標樣本數(shù)過少,為解決此問題,對部分類別過多的分類指標進行處理。
3.4 對分類指標進行調(diào)整
3.4.1 工作類型
本數(shù)據(jù)集中,工作類型(workclass)指標共有8種類別:私人(Private)、自由職業(yè)非公司(Self-emp-not-inc)、自由職業(yè)公司(Self-emp-inc)、聯(lián)邦政府(Federal-gov)、地方政府(Local-gov)、州政府(State-gov)、無薪(Without-pay)、無工作經(jīng)驗(Never-worked)。繪制條形圖查看各類樣本數(shù)量。
plt.style.use('seaborn-whitegrid') plt.figure(figsize=(15, 4)) sns.countplot(y="workclass", data=dataset);
從上述條形圖可見,私營工作在樣本中占比較大,不工作和無收入工作樣本數(shù)量極小,結(jié)合實際情況,將其歸納為5類。
3.4.2 職業(yè)
本數(shù)據(jù)集中職業(yè)共有14種類型如下:Tech-support(技術(shù)支持), Craft-repair(手工藝維修), Other-service(其他職業(yè)),Sales(銷售), Exec-managerial(執(zhí)行主管), Prof-specialty(專業(yè)技術(shù)),Handlers-cleaners(勞工保潔), Machine-op-inspct(機械操作), Adm-clerical(管理文書),Farming-fishing(農(nóng)業(yè)捕撈), Transport-moving(運輸), Priv-house-serv(家政服務(wù)),Protective-serv(保安), Armed-Forces(軍人)。
plt.style.use('seaborn-whitegrid') plt.figure(figsize=(15,5)) sns.countplot(y="occupation", data=dataset);
為便于后續(xù)分析,將其合并為6類。
3.4.3 國籍
數(shù)據(jù)說明里共列出41個國家和地區(qū),除美國外大部分國家和地區(qū)的樣本都很少,故在此按照地域?qū)@些國家和地區(qū)進行合并。
dataset.loc[dataset['country'] == 'China', 'country'] = 'East-Asia' dataset.loc[dataset['country'] == 'Hong', 'country'] = 'East-Asia' dataset.loc[dataset['country'] == 'Taiwan', 'country'] = 'East-Asia' dataset.loc[dataset['country'] == 'Japan', 'country'] = 'East-Asia' dataset.loc[dataset['country'] == 'Thailand', 'country'] = 'Southeast-Asia' dataset.loc[dataset['country'] == 'Vietnam', 'country'] = 'Southeast-Asia' dataset.loc[dataset['country'] == 'Laos', 'country'] = 'Southeast-Asia' dataset.loc[dataset['country'] == 'Philippines', 'country'] = 'Southeast-Asia' dataset.loc[dataset['country'] == 'Cambodia', 'country'] = 'Southeast-Asia' dataset.loc[dataset['country'] == 'Columbia', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Cuba', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Dominican-Republic', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Ecuador', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Guatemala', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'El-Salvador', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Haiti', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Honduras', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Mexico', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Nicaragua', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Outlying-US(Guam-USVI-etc)' , 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Peru', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Jamaica', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Puerto-Rico', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Trinadad&Tobago', 'country'] = 'South-America' dataset.loc[dataset['country'] == 'Canada', 'country'] = 'British-Commonwealth' dataset.loc[dataset['country'] == 'England', 'country'] = 'British-Commonwealth' dataset.loc[dataset['country'] == 'India', 'country'] = 'British-Commonwealth' dataset.loc[dataset['country'] == 'Ireland', 'country'] = 'British-Commonwealth' dataset.loc[dataset['country'] == 'Scotland', 'country'] = 'British-Commonwealth' dataset.loc[dataset['country'] == 'France', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Germany', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Italy', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Holand-Netherlands', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Greece', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Hungary', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Iran', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Yugoslavia', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Poland', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'Portugal', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'South', 'country'] = 'Europe' dataset.loc[dataset['country'] == 'United-States', 'country'] = 'United-States' plt.style.use('seaborn-whitegrid') fig = plt.figure(figsize=(15,4)) sns.countplot(y="country", data=dataset);將國家合并為地區(qū)后,雖然與美國相比仍差異較大,但是各類別樣本數(shù)量更加均勻。
3.4.4 受教育程度
繪制受教育程度條形圖,觀察數(shù)據(jù)分布情況。
plt.style.use('seaborn-whitegrid') plt.figure(figsize=(15,5)) sns.countplot(y="education", data=dataset);
從上圖可見,受教育程度類別多達16個,通過生成條形圖可以看出低教育水平的各類別數(shù)量較少,故以高中為界,將其整合為一類(dropout),對兩類高中(HS-Graduate)和兩類專科(Associate)也進行合并。
3.4.5 婚姻狀態(tài)
數(shù)據(jù)說明里共列出7種婚姻狀態(tài)Married-civ-spouse(已婚平民配偶), Divorced(離婚), Never-married(未婚), Separated(分居), Widowed(喪偶), Married-spouse-absent(已婚配偶異地), arried-AF-spouse(已婚軍屬)。
plt.style.use('seaborn-whitegrid') plt.figure(figsize=(10,3)) sns.countplot(y="marital-status", data=dataset);
本文將其合并為4類:從未結(jié)婚、離異、分居和已婚。
3.5 查看調(diào)整后各指標分布情況
由于plot_distribution()函數(shù)在上文中已定義,故在此直接調(diào)用
plot_distribution(dataset, cols=3, width=20, height=20, hspace=0.45, wspace=0.5)
從上圖可見,經(jīng)過調(diào)整后,部分分類指標存在的類別過于復(fù)雜、部分類別樣本數(shù)量過少的問題得到了一定程度的緩解。
3.6 檢查變量間相關(guān)關(guān)系
為了探索變量間可能存在的相互影響的問題,本文通過計算變量間的相關(guān)系數(shù)對其可能存在的交互作用進行檢查。
(1)復(fù)制原數(shù)據(jù)集,并將其中離散的字符串變量轉(zhuǎn)化為數(shù)值,以便進行后續(xù)分析。
dataset_num = dataset.copy() # 復(fù)制數(shù)據(jù)集 dataset_num['workclass'] = dataset_num['workclass'].factorize()[0] dataset_num['education'] = dataset_num['education'].factorize()[0] dataset_num['marital-status'] = dataset_num['marital-status'].factorize()[0] dataset_num['occupation'] = dataset_num['occupation'].factorize()[0] dataset_num['relationship'] = dataset_num['relationship'].factorize()[0] dataset_num['race'] = dataset_num['race'].factorize()[0] dataset_num['sex'] = dataset_num['sex'].factorize()[0] dataset_num['country'] = dataset_num['country'].factorize()[0] dataset_num['income-level'] = dataset_num['income-level'].factorize()[0](2)繪制變量間的相關(guān)關(guān)系圖譜,探索變量間的相關(guān)性。
plt.style.use('seaborn-whitegrid') fig = plt.figure(figsize=(15, 15)) mask = np.zeros_like(dataset_num.corr(), dtype=np.bool) mask[np.triu_indices_from(mask)] = True sns.heatmap(dataset_num.corr(), vmin=-1, vmax=1, square=True, cmap=sns.color_palette("RdBu_r", 100), mask=mask, annot=True, linewidths=.5);
通過相關(guān)關(guān)系分析,我們可以看出變量間沒有較為明顯的共線性,故不對變量進行篩選。
3.7 切分數(shù)據(jù)集
完成數(shù)據(jù)集的清洗和處理后,即可對數(shù)據(jù)集進行切分,為后續(xù)訓(xùn)練和測試模型分類能力做準備。
(1)切分自變量和因變量
本文目的為通過人口普查數(shù)據(jù)對個體的收入水平進行預(yù)測,故因變量為收入水平(income-level),其余變量作為自變量,分別存入y_data和x_data。
# 切分自變量和因變量 y_data=dataset_num['income-level'] # 取收入水平income-level列 x_data=dataset_num.drop(['income-level'],axis=1) # 排除收入水平income-level列,剩下的列作為X_data(2)切分訓(xùn)練集和測試集
在切分數(shù)據(jù)集方面,本文參考了Agarwal和Saxena(2018)[1]在利用機器學(xué)習(xí)進行惡性腫瘤分析中使用的方法,使用scikit-learn提供的train_test_split()將數(shù)據(jù)集切分為訓(xùn)練集和測試集,測試集占整個數(shù)據(jù)集的20%,訓(xùn)練集占整個數(shù)據(jù)集的80%。并按照因變量中各類別的比例進行均分,得到訓(xùn)練集變量x_train和y_train,以及測試集變量x_test和y_test。
# 切分訓(xùn)練集和測試集 x_train,x_test,y_train,y_test = train_test_split( x_data, y_data, test_size=0.2, random_state=1, stratify=y_data)四、建模
本數(shù)據(jù)集作為當前較為熱門的分類數(shù)據(jù)集,從其發(fā)布至今,已有眾多學(xué)者圍繞本數(shù)據(jù)集開展不同分類器的研究,如Kohavi(1996)[2]使用樸素貝葉斯方法對模型進行了分析,Deepajothi和Selvarajan(2012)[3]比較了貝葉斯分類器和決策樹分類器在收入水平分類上的預(yù)測效果,Mangasarian和Musicant(1999)[4]則構(gòu)建了使用支持向量機對收入進行分類的方法。
為了實現(xiàn)較高的分類準確率,本文結(jié)合課程所學(xué),并參考引用本數(shù)據(jù)集進行分析的相關(guān)文獻的方法,一共構(gòu)建了10種不同類型的分類器,使用同一組訓(xùn)練集進行訓(xùn)練,對于構(gòu)建模型的超參數(shù),借助Python中scikit-learn庫提供的隨機搜索器RandomizedSearchCV()通過多輪訓(xùn)練篩選最優(yōu)參數(shù),模型建構(gòu)完成后,使用同一組測試集對10個模型進行測試,保證模型比較的公平性,并從中篩選出表現(xiàn)最優(yōu)的模型。
4.1 構(gòu)建模型訓(xùn)練測試函數(shù)
本文采用的各個模型均借助Python3下的Scikit-learn庫構(gòu)建。Scikit-learn是用Python編寫的通用機器學(xué)習(xí)庫[5],是機器學(xué)習(xí)領(lǐng)域最知名的Python模塊之一,提供通用性、模塊化的算法實現(xiàn)[6],其模型構(gòu)建靈活,種類豐富,模型構(gòu)建和分析的相關(guān)工具較為齊全,故各分類器間除參數(shù)不一致外,訓(xùn)練模型、測試模型以及生成各類評價參數(shù)的步驟大致相同[7],為簡化程序代碼本文首先構(gòu)建模型訓(xùn)練的方法fit_ml_algo()、超參數(shù)報告report()以及計算TPR、FPR并繪制ROC曲線的方法plot_roc_curve()。
4.1.1 構(gòu)建模型訓(xùn)練方法fit_ml_algo()
該方法用于構(gòu)建統(tǒng)一的模型訓(xùn)練過程,傳入設(shè)置好超參數(shù)的模型、訓(xùn)練集、測試集以及k折交叉驗證的折數(shù)(cv)后,即使用訓(xùn)練集對模型進行訓(xùn)練,使用訓(xùn)練好的模型對x_test進行預(yù)測得到test_pred,使用predict_proba計算測試樣本屬于不同類別的概率,并使用K折交叉檢驗再次對模型進行訓(xùn)練,并返回訓(xùn)練結(jié)果和模型評價指標。
# 構(gòu)造一個模型套用的樣板,自動調(diào)用訓(xùn)練集對傳入的模型進行訓(xùn)練,使用驗證集對模型進行檢驗,并輸出相關(guān)指標 def fit_ml_algo(algo, X_train, y_train, X_test, cv): model = algo.fit(X_train, y_train) test_pred = model.predict(X_test) try: probs = model.predict_proba(X_test)[:,1] except Exception as e: probs = "Unavailable" print('Warning: Probs unavaliable.') print('Reason: ', e) acc = round(model.score(X_test, y_test) * 100, 2) # CV train_pred = model_selection.cross_val_predict(algo, X_train, y_train, cv=cv, n_jobs = -1) acc_cv = round(metrics.accuracy_score(y_train, train_pred) * 100, 2) return train_pred, test_pred, acc, acc_cv, probs4.1.2 構(gòu)建超參數(shù)報告方法report()
本方法用于對調(diào)參工具RandomizedSearchCV()運算得到的候選模型進行排序,并匯報效果較為優(yōu)秀的模型的超參數(shù)。相較于采用網(wǎng)格搜索的模型調(diào)參方法GridSearchCV(),RandomizedSearchCV()不會評估所有可能的超參數(shù)組合,所以它的計算開銷和耗時較少,能夠更高效快速地篩選更適合所研究問題的超參數(shù)[8]。
# 匯報候選模型參數(shù) def report(results, n_top=5): for i in range(1, n_top + 1): candidates = np.flatnonzero(results['rank_test_score'] == i) for candidate in candidates: print("Model with rank: {0}".format(i)) print("Mean validation score: {0:.3f} (std: {1:.3f})".format( results['mean_test_score'][candidate], results['std_test_score'][candidate])) print("Parameters: {0}\n".format(results['params'][candidate]))4.1.3 構(gòu)建ROC曲線方法plot_roc_curve()
該方法用于計算TPR(True Positive Rate)和FPR(False Positive Rate)并繪制ROC曲線。
# 構(gòu)建函數(shù)用于計算TPR(True Positive Rate)和FPR(False Positive Rate)并繪制ROC曲線 def plot_roc_curve(y_test, preds): fpr, tpr, threshold = metrics.roc_curve(y_test, preds) roc_auc = metrics.auc(fpr, tpr) plt.title('ROC') plt.plot(fpr, tpr, 'b', label = 'AUC = %0.2f' % roc_auc) plt.legend(loc = 'lower right') plt.plot([0, 1], [0, 1],'r--') plt.xlim([-0.01, 1.01]) plt.ylim([-0.01, 1.01]) plt.ylabel('TPR') plt.xlabel('FPR') plt.show()4.1.4 構(gòu)建P-R曲線方法plot_pr_curve()
# 構(gòu)建繪制P-R曲線方法 def plot_pr_curve(y_test, probs): precision, recall, _ = precision_recall_curve(y_test, probs) plt.step(recall, precision, color='b', alpha=0.2, where='post') plt.fill_between(recall, precision, step='post', alpha=0.2, color='b') plt.xlabel('Recall') plt.ylabel('Precision') plt.ylim([0.0, 1.05]) plt.xlim([0.0, 1.0]) plt.title('2-class Precision-Recall curve: AP={0:0.2f}'.format( average_precision_score(y_test, probs)))4.2 構(gòu)建Logistic回歸分類模型
(1)使用隨機搜索器RandomizedSearchCV()進行自動調(diào)參
# Logistic回歸 # 設(shè)置超參數(shù)并構(gòu)建隨機搜索器 n_iter_search = 10 # 訓(xùn)練10次,數(shù)值越大,獲得的參數(shù)精度越大,但是搜索時間越長 param_dist = {'penalty': ['l2', 'l1'], 'class_weight': [None, 'balanced'], 'C': np.logspace(-20, 20, 10000), 'intercept_scaling': np.logspace(-20, 20, 10000)} random_search = RandomizedSearchCV(LogisticRegression(), # 使用的分類器 n_jobs=-1, # 使用所有的CPU進行訓(xùn)練,默認為1,使用1個CPU param_distributions=param_dist, n_iter=n_iter_search) # 訓(xùn)練次數(shù) start = time.time() random_search.fit(x_train, y_train) print("RandomizedSearchCV took %.2f seconds for %d candidates" " parameter settings." % ((time.time() - start), n_iter_search)) report(random_search.cv_results_)運行上述代碼,隨機搜索器通過多輪隨機搜索確定不同超參數(shù)下的模型表現(xiàn),并輸出表現(xiàn)排名前5的模型參數(shù)集。
(2)使用上述隨機搜索器調(diào)參后表現(xiàn)最佳的模型random_search.best_estimator_進行訓(xùn)練并輸出模型評價參數(shù)。
從輸出可以看出,直接訓(xùn)練的準確度為79.1%,使用十折交叉驗證得到的模型準確度為78.86%,模型運行時間為1s。
(3)評估訓(xùn)練集的模型表現(xiàn)
上表中,列表左邊的一列為分類的標簽名;precision列表示模型預(yù)測的結(jié)果中有多少是預(yù)測正確的,即精度;recall列和f1-score分別為模型的召回率和F1參數(shù),support列為每個標簽的出現(xiàn)次數(shù);accuracy為模型的準確度;macro avg和weighted avg分別是加權(quán)平均前后的平均值,后續(xù)表格同理。
(4)評估訓(xùn)練集的模型表現(xiàn)
# 測試集樣本表現(xiàn) print(metrics.classification_report(y_test, test_pred_log))
(5)繪制ROC曲線
(6)繪制P-R曲線
4.3 構(gòu)建KNN分類模型
(1)將K近鄰的K值設(shè)為3,運行該模型
# k-Nearest Neighbors start_time = time.time() train_pred_knn, test_pred_knn, acc_knn, acc_cv_knn, probs_knn\ = fit_ml_algo(KNeighborsClassifier(n_neighbors = 3, n_jobs = -1), x_train, y_train, x_test, 10) knn_time = (time.time() - start_time) print("Accuracy: %s" % acc_knn) print("Accuracy CV 10-Fold: %s" % acc_cv_knn) print("Running Time: %s s" % datetime.timedelta(seconds=knn_time))KNN模型的預(yù)測準確率為82.74%,十折交叉驗證的準確率為82.64%,運算時長48s。
(2)評估訓(xùn)練集的模型表現(xiàn)
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
(5)繪制P-R曲線
4.4 構(gòu)建樸素貝葉斯分類模型
Scikit-learn的naive_bayes 模塊共包含三種樸素貝葉斯實現(xiàn)方式:Gaussian Naive Bayes、Multinomial Naive Bayes、Bernoulli Naive Bayes。Gaussian Naive Bayes多用于一般的分類問題,本題目即屬于此類情況;Multinomial Naive Bayes多適用于文本數(shù)據(jù)(特征表示的是次數(shù),例如某個詞語的出現(xiàn)次數(shù));適用于伯努利分布,也適用于文本數(shù)據(jù)(此時特征表示的是是否出現(xiàn),例如某個詞語的出現(xiàn)為1,不出現(xiàn)為0),絕大多數(shù)情況下表現(xiàn)不如多項式分布,但有的時候伯努利分布表現(xiàn)得要比多項式分布要好,尤其是對于小數(shù)量級的文本數(shù)據(jù)。因此,本文采用Gaussian Naive Bayes構(gòu)建樸素貝葉斯分類模型。
(1)訓(xùn)練和測試樸素貝葉斯模型。
該模型預(yù)測的準確度達到80.19%,十折交叉驗證的準確度為79.88%,運算時間為3s。
(2)評估訓(xùn)練集的模型表現(xiàn)
# 訓(xùn)練集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_gaussian))
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
(5)繪制P-R曲線
4.5 構(gòu)建支持向量機分類模型
(1)訓(xùn)練并測試支持向量機模型
在構(gòu)建模型的過程中,本文嘗試了Scikit-learn提供的六種不同的SVC內(nèi)核,模型效果均不太理想且運算速度較慢,相對而言線性內(nèi)核表現(xiàn)略好,且Mangasarian和Musicant(1999)[4]在基于本文數(shù)據(jù)集構(gòu)建SVC模型時,也主要采用了線性內(nèi)核,故使用線性支持向量機構(gòu)建本文分類模型。
從分析結(jié)果可以看出,支持向量機分類器的預(yù)測準確度為53.29%,十折交叉驗證的準確度為35.68%,模型運算時間74s。
(2)評估訓(xùn)練集的模型表現(xiàn)
# 訓(xùn)練集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_svc))
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
(5)繪制P-R曲線
4.6 構(gòu)建隨機梯度下降分類模型
隨機梯度下降模型采用mini-batch來做梯度下降,在處理大數(shù)據(jù)的情況下收斂更快。
(1)訓(xùn)練兵測試隨機梯度下降模型
# Stochastic Gradient Descent 隨機梯度下降 start_time = time.time() train_pred_sgd, test_pred_sgd, acc_sgd, acc_cv_sgd, probs_sgd\ = fit_ml_algo( SGDClassifier(n_jobs = -1, loss='log'), x_train, y_train, x_test, 10) sgd_time = (time.time() - start_time) print("Accuracy: %s" % acc_sgd) print("Accuracy CV 10-Fold: %s" % acc_cv_sgd) print("Running Time: %s s" % datetime.timedelta(seconds=sgd_time).seconds)
隨機梯度下降分類器模型的預(yù)測準確度為77.29%,使用十折交叉檢驗的準確度為77.94%,運算耗費3s。
(2)評估訓(xùn)練集的模型表現(xiàn)
# 訓(xùn)練集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_sgd))
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
(5)繪制P-R曲線
4.7 構(gòu)建決策樹分類模型
(1)訓(xùn)練和測試決策樹分類模型
# Decision Tree Classifier start_time = time.time() train_pred_dt, test_pred_dt, acc_dt, acc_cv_dt, probs_dt\ = fit_ml_algo(DecisionTreeClassifier(), x_train, y_train, x_test, 10) dt_time = (time.time() - start_time) print("Accuracy: %s" % acc_dt) print("Accuracy CV 10-Fold: %s" % acc_cv_dt) print("Running Time: %s s" % datetime.timedelta(seconds=dt_time).seconds)
決策樹分類模型的預(yù)測準確度為82.37%,十折交叉驗證的準確度為81.76%,運算耗時1s。
(2)評估訓(xùn)練集的模型表現(xiàn)
# 訓(xùn)練集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_dt))
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
# 繪制ROC plot_roc_curve(y_test, probs_dt)
(5)繪制P-R曲線
4.8 構(gòu)建隨機森林分類模型
(1)使用隨機調(diào)參工具查找隨機森林算法最優(yōu)超參數(shù)
# 從中調(diào)參的超參數(shù)集合 param_dist = {"max_depth": [10, None], "max_features": sp_randint(1, 11), "min_samples_split": sp_randint(2, 20), "min_samples_leaf": sp_randint(1, 11), "bootstrap": [True, False], "criterion": ["gini", "entropy"]} # Run Randomized Search n_iter_search = 10 random_search = RandomizedSearchCV( RandomForestClassifier(n_estimators=10), n_jobs = -1, param_distributions=param_dist, n_iter=n_iter_search) start = time.time() random_search.fit(x_train, y_train) print("RandomizedSearchCV took %.2f seconds for %d candidates" " parameter settings." % ((time.time() - start), n_iter_search)) report(random_search.cv_results_)
(2)使用隨機搜索器得到的最優(yōu)參數(shù)模型進行訓(xùn)練和測試。
訓(xùn)練后的隨機森林模型預(yù)測的準確度為85.85%,十折交叉檢驗的準確度為85.65%,運行耗費時間2s。
(3)評估訓(xùn)練集的模型表現(xiàn)
# 測試集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_rf))
(4)評估訓(xùn)練集的模型表現(xiàn)
(5)繪制ROC曲線
(6)繪制P-R曲線
4.9 構(gòu)建內(nèi)梯度提升決策樹分類模型
(1)訓(xùn)練和測試梯度提升決策樹分類模型
# Gradient Boosting Trees 梯度提升決策樹 start_time = time.time() train_pred_gbt, test_pred_gbt, acc_gbt, acc_cv_gbt, probs_gbt\ = fit_ml_algo(GradientBoostingClassifier(), x_train, y_train, x_test, 10) gbt_time = (time.time() - start_time) print("Accuracy: %s" % acc_gbt) print("Accuracy CV 10-Fold: %s" % acc_cv_gbt) print("Running Time: %s s" % datetime.timedelta(seconds=gbt_time).seconds)
訓(xùn)練后的梯度提升決策樹預(yù)測準確度為86.2%,十折交叉檢驗的準確度為85.97%,訓(xùn)練耗時15s。
(2)評估訓(xùn)練集的模型表現(xiàn)
# 訓(xùn)練集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_gbt))
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
(5)繪制P-R曲線
4.10 構(gòu)建AdaBoost分類模型
(1)訓(xùn)練和測試AdaBoost分類模型
# AdaBoost Classifier start_time = time.time() train_pred_adb, test_pred_adb, acc_adb, acc_cv_adb, probs_adb\ = fit_ml_algo(AdaBoostClassifier(), x_train, y_train, x_test, 10) adb_time = (time.time() - start_time) print("Accuracy: %s" % acc_adb) print("Accuracy CV 10-Fold: %s" % acc_cv_adb) print("Running Time: %s s" % datetime.timedelta(seconds=adb_time).seconds)
AdaBoost模型訓(xùn)練后的預(yù)測準確度為85.86%,十折交叉驗證的準確度為85.41%,運算耗時6s。
(2)評估訓(xùn)練集的模型表現(xiàn)
# 訓(xùn)練集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_adb))
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
(5)繪制P-R曲線
4.11 構(gòu)建投票法分類模型
投票法(Voting Classifier)是集成學(xué)習(xí)里面針對分類問題的一種結(jié)合策略。基本思想是選擇所有機器學(xué)習(xí)算法當中輸出最多的那個類。
分類的機器學(xué)習(xí)算法輸出有兩種類型:一種是直接輸出類標簽,另外一種是輸出類概率,使用前者進行投票叫做硬投票(Majority/Hard voting),使用后者進行分類叫做軟投票(Soft voting)。經(jīng)過測試,對于本文選用的數(shù)據(jù)集,Soft Voting模型效果較好,故使用Soft Voting作為投票法分類器的投票模型。
在機器學(xué)習(xí)算法中,通過比較不同分類器組合的效果,最終選用了Logistic回歸分類器、樸素貝葉斯(Gaussian Native Bayes)、隨機森林分類器、梯度提升分類器和決策樹分類器作為投票算法。
(1)構(gòu)建、訓(xùn)練和測試投票分類器模型
# Voting Classifier start_time = time.time() voting_clf = VotingClassifier(estimators=[ ('log_clf', LogisticRegression()), ('gnb_clf', GaussianNB()), ('rf_clf', RandomForestClassifier(n_estimators=10)), ('gb_clf', GradientBoostingClassifier()), ('dt_clf', DecisionTreeClassifier(random_state=666))], voting='soft', n_jobs = -1) train_pred_vot, test_pred_vot, acc_vot, acc_cv_vot, probs_vot\ = fit_ml_algo(voting_clf, x_train, y_train, x_test, 10) vot_time = (time.time() - start_time) print("Accuracy: %s" % acc_vot) print("Accuracy CV 10-Fold: %s" % acc_cv_vot) print("Running Time: %s s" % datetime.timedelta(seconds=vot_time).seconds)
訓(xùn)練后的投票法分類模型預(yù)測準確度為84.72%,十折交叉檢驗的準確度為84.73%,模型運算耗時21s。
(2)評估訓(xùn)練集的模型表現(xiàn)
# 訓(xùn)練集樣本表現(xiàn) print(metrics.classification_report(y_train, train_pred_vot))
(3)評估訓(xùn)練集的模型表現(xiàn)
(4)繪制ROC曲線
(5)繪制P-R曲線
五、評估
5.1 指標評估
結(jié)合課本內(nèi)容和Powers(2011)[9]對各項模型評價指標的對比分析和介紹,本文最終選用準確率(Accuracy)、精確率(Precision)、召回率(Recall)、F1分數(shù)、作為主要的評價指標。準確率(Accuracy)表示分類模型所有判斷正確的結(jié)果占總觀測值的比重;精確率(Precision)表示模型觀測是Positive的所有結(jié)果中,模型預(yù)測對的比重;召回率(Recall)表示真實值是Positive的所有結(jié)果中,模型預(yù)測對的比重;F1分數(shù)綜合了Precision和Recall的結(jié)果,是精確率和召回率的調(diào)和平均數(shù),取值越高,模型效果越好.
models = pd.DataFrame({ 'Model': ['KNN', 'Logistic Regression', 'Random Forest', 'Naive Bayes', 'Stochastic Gradient Decent', 'Linear SVC', 'Decision Tree', 'Gradient Boosting Trees', 'AdaBoost', 'Voting'], 'Acc': [ acc_knn, acc_log, acc_rf, acc_gaussian, acc_sgd, acc_linear_svc, acc_dt, acc_gbt, acc_adb, acc_vot ], 'Acc_cv': [ acc_cv_knn, acc_cv_log, acc_cv_rf, acc_cv_gaussian, acc_cv_sgd, acc_cv_linear_svc, acc_cv_dt, acc_cv_gbt, acc_cv_adb, acc_cv_vot ], 'precision': [ round(precision_score(y_test,test_pred_knn), 3), round(precision_score(y_test,test_pred_log), 3), round(precision_score(y_test,test_pred_rf), 3), round(precision_score(y_test,test_pred_gaussian), 3), round(precision_score(y_test,test_pred_sgd), 3), round(precision_score(y_test,test_pred_svc), 3), round(precision_score(y_test,test_pred_dt), 3), round(precision_score(y_test,test_pred_gbt), 3), round(precision_score(y_test,test_pred_adb), 3), round(precision_score(y_test,test_pred_vot), 3), ], 'recall': [ round(recall_score(y_test,test_pred_knn), 3), round(recall_score(y_test,test_pred_log), 3), round(recall_score(y_test,test_pred_rf), 3), round(recall_score(y_test,test_pred_gaussian), 3), round(recall_score(y_test,test_pred_sgd), 3), round(recall_score(y_test,test_pred_svc), 3), round(recall_score(y_test,test_pred_dt), 3), round(recall_score(y_test,test_pred_gbt), 3), round(recall_score(y_test,test_pred_adb), 3), round(recall_score(y_test,test_pred_vot), 3), ], 'F1': [ round(f1_score(y_test,test_pred_knn,average='binary'), 3), round(f1_score(y_test,test_pred_log,average='binary'), 3), round(f1_score(y_test,test_pred_rf,average='binary'), 3), round(f1_score(y_test,test_pred_gaussian,average='binary'), 3), round(f1_score(y_test,test_pred_sgd,average='binary'), 3), round(f1_score(y_test,test_pred_svc,average='binary'), 3), round(f1_score(y_test,test_pred_dt,average='binary'), 3), round(f1_score(y_test,test_pred_gbt,average='binary'), 3), round(f1_score(y_test,test_pred_adb,average='binary'), 3), round(f1_score(y_test,test_pred_vot,average='binary'), 3), ], }) models.sort_values(by='Acc', ascending=False)得到各模型評價參數(shù)如下表所示:
從上表可見,本文所用到的十個模型中,梯度提升決策樹(Gradient Boosting Trees)、AdaBoost、隨機森林(Random Forest)三個模型的準確率均表現(xiàn)良好,達到了85%以上,F1值相較于其他模型也處于較為優(yōu)秀的水平,故從指標角度來看,這三個模型更適用于本文所研究的問題。
5.2 ROC曲線
ROC曲線全稱Receiver Operating Characteristic Curve,即接受者操作特征曲線,ROC曲線越接近左上角,其對應(yīng)模型的分類效果越好。參數(shù)AUC(Area Under Curve)代表了ROC曲線下的面積,能夠定量地衡量分類器的好壞,AUC值越大,模型表現(xiàn)效果越好[10]。
plt.style.use('seaborn-whitegrid') fig = plt.figure(figsize=(10,10)) models = [ 'KNN', 'Logistic Regression', 'Random Forest', 'Naive Bayes', 'Decision Tree', 'Gradient Boosting Trees', 'AdaBoost', 'Linear SVC', 'Voting', 'Stochastic Gradient Decent' ] probs = [ probs_knn, probs_log, probs_rf, probs_gau, probs_dt, probs_gbt, probs_adb, probs_svc, probs_vot, probs_sgd ] colormap = plt.cm.tab10 #nipy_spectral, Set1, Paired, tab10, gist_ncar colors = [colormap(i) for i in np.linspace(0, 1,len(models))] plt.title('Receiver Operating Characteristic') plt.plot([0, 1], [0, 1],'r--') plt.xlim([-0.01, 1.01]) plt.ylim([-0.01, 1.01]) plt.ylabel('True Positive Rate') plt.xlabel('False Positive Rate') def plot_roc_curves(y_test, prob, model): fpr, tpr, threshold = metrics.roc_curve(y_test, prob) roc_auc = metrics.auc(fpr, tpr) label = model + ' AUC = %0.2f' % roc_auc plt.plot(fpr, tpr, 'b', label=label, color=colors[i]) plt.legend(loc = 'lower right') for i, model in list(enumerate(models)): plot_roc_curves(y_test, probs[i], models[i])將本文所用的10個模型的ROC曲線匯集到一張表上如下:
通過觀察圖像和對比AUC值,本文中梯度提升決策樹(Gradient Boosting Trees)和AdaBoost兩個模型表現(xiàn)最優(yōu),AUC值均達到了0.92,線性支持向量機模型表現(xiàn)最差,幾乎無法起到有效的分類作用。
5.3 P-R曲線
P-R曲線是比較分類器的一個有效的工具,P-R曲線越靠近圖像右上角的分類器表現(xiàn)越好,若一個分類器的P-R曲線被另一個分類器的P-R曲線完全“包住”,則后者的性能優(yōu)于前者[11]。
# 構(gòu)建繪制P-R曲線方法 fig = plt.figure(figsize=(10,10)) plt.xlabel('Recall') plt.ylabel('Precision') plt.ylim([0.0, 1.05]) plt.xlim([0.0, 1.0]) plt.title('2-class Precision-Recall Curve') colormap = plt.cm.Set1 #nipy_spectral, Set1, Paired, gist_ncar colors = [colormap(i) for i in np.linspace(0, 1,len(models))] def plot_pr_curve_overall(y_test, probs, model): precision, recall, _ = precision_recall_curve(y_test, probs) label = (model + ' AP={0:0.2f}'.format(average_precision_score(y_test, probs))) plt.step(recall, precision, color=colors[i], where='post', label=label) # plt.fill_between(recall, precision, step='post', alpha=0.2, color=colors[i]) plt.legend(bbox_to_anchor=(1.05, 0), loc=3, borderaxespad=0) for i, model in list(enumerate(models)): plot_pr_curve_overall(y_test, probs[i], models[i])繪制出的P-R曲線如下圖所示。
從P-R曲線可以看出,梯度提升決策樹分類器的表現(xiàn)效果最好,其次為AdaBoost和隨機森林,與ROC曲線和觀察相關(guān)評價指標得出的結(jié)果大致一致。
參考文獻
[1] Agarwal A, Saxena A. Malignant Tumor Detection Using Machine Learning through Scikit-learn[J]. International Journal of Pure and Applied Mathematics, 2018, 119(15): 2863-2874.
[2] Kohavi R. Scaling up the accuracy of naive-bayes classifiers: A decision-tree hybrid[C]//Kdd. 1996, 96: 202-207.
[3] Deepajothi S, Selvarajan S. A comparative study of classification techniques on adult data set[J]. International Journal of Engineering Research and Technology, 2012, 1(8): 1-8.
[4] Mangasarian O L, Musicant D R. Successive overrelaxation for support vector machines[J]. IEEE Transactions on Neural Networks, 1999, 10(5): 1032-1037.
[5] Pedregosa F, Varoquaux G, Gramfort A, et al. Scikit-learn: Machine learning in Python[J]. Journal of machine learning research, 2011, 12(Oct): 2825-2830.
[6] Abraham A, Pedregosa F, Eickenberg M, et al. Machine learning for neuroimaging with scikit-learn[J]. Frontiers in neuroinformatics, 2014, 8: 14.
[7] Buitinck L, Louppe G, Blondel M, et al. API design for machine learning software: experiences from the scikit-learn project[J]. arXiv preprint arXiv:1309.0238, 2013.
[8] Paper D, Paper D. Scikit-Learn Classifier Tuning from Simple Training Sets[J]. Hands-on Scikit-Learn for Machine Learning Applications: Data Science Fundamentals with Python, 2020: 137-163.
[9] Powers D M. Evaluation: from precision, recall and F-measure to ROC, informedness, markedness and correlation[J]. 2011.
[10] Rosset S. Model selection via the AUC[C]//Proceedings of the twenty-first international conference on Machine learning. 2004: 89.
[11] Boyd K, Eng K H, Page C D. Area under the precision-recall curve: point estimates and confidence intervals[C]//Joint European conference on machine learning and knowledge discovery in databases. Springer, Berlin, Heidelberg, 2013: 451-466.
總結(jié)
以上是生活随笔為你收集整理的基于人口普查数据的收入预测模型构建及比较分析(Python数据分析分类器模型实践)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win7 dos窗口输入命令必须加后缀问
- 下一篇: python爬虫英文单词_Python_