基于人口普查数据的收入预测模型构建及比较分析(Python数据分析分类器模型实践)
基于人口普查數據的收入預測模型構建及比較分析
這篇文章是上學期數據分析課程的作業,本來想等成績出來后再分享出來,但是因為疫情原因成績遲遲沒有上傳,所以這里就先分享出來,如果有分析的不對的地方,歡迎一起分析討論,共同學習
摘要
收入是反映人民生活水平和國家經濟發展狀況的重要指標,改善收入水平,提高生活質量是各國政府和人民共同的奮斗目標。探索收入的影響因素,不僅對國家具有重要意義,對個人提升自我,企業識別目標消費群體也具有重要的參考價值。為了研究年齡、受教育程度、職業等諸多因素對個體收入的影響,本文以UCI Machine Learning Repository網站提供的人口普查數據Adult Data Set作為數據樣本,遵循CRISP-DM的數據挖掘流程,對數據中可能存在的規律進行探索和分析,構建決策樹、Logistic回歸、K近鄰、線性支持向量機、隨機森林、AdaBoost等十個分類模型探究各項指標對個體收入的影響和對個體收入進行預測,并通過多個模型評價指標,對不同的分類模型的分類效果進行比較和評價。
關鍵詞:數據分析;分類算法;預測;模型評價;數據可視化;
一、業務理解
對于個人來說,收入可以一定程度上反映個體的生活水平和消費能力,影響個人對于商品、服務需求的種類和數量,影響個人的社會地位、健康狀況和幸福水平。
對于企業而言,不同收入人群的購買力和產品偏好不同,對價格的敏感程度也不同,識別不同收入人群,有助于幫助企業有針對性地設計、生產、推廣產品和提供差異化的服務,從而提高產品和服務的銷售量,節約銷售費用,降低企業生產和運營成本,更好地塑造企業形象,為企業帶來更大的市場份額和更多的利潤。
對于國家而言,個人收入水平能夠直接反應人民的生活水平和國家的經濟發展狀況,個人收入的提高能夠顯著提高人民的購買力,提高國民生產總值,促進各行各業的平穩健康發展。分析人民收入的影響因素,探索不同指標對收入的影響情況,有助于國家對提高人民生活水平、改善社會福利、提高國民素質制定更加有效和更加有針對性的措施。
國內外的大量研究已充分證明,受教育程度和工作經驗是影響一個人工作收入的重要因素。但實際上,我們發現僅憑這兩個變量并不能完全解釋個人的收入差異問題。比如,即使兩個受過同等教育的人,在同一時間進入職場,他們的收入也可能存在明顯差異;而工作經驗相同的兩個人,即使他們的受教育程度相同,并且在同一個行業、同一個企業,甚至同一生產部門,其收入也可能存在一定差異。在社交媒體上,既有人宣揚“知識改變命運”,也有人大力鼓吹“讀書無用論”,由此可見,影響收入的因素是多種多樣、錯綜復雜的。
二、數據理解
2.1 數據收集
收入的影響因素是復雜多樣的,不僅涉及到個人,還受到家庭乃至國家不同因素的影響,涉及的指標數量龐大且難以獲取,為簡化模型和分析過程,本文數據來自UCI Machine Learning Repository網站的Adult Data Set數據集(https://archive.ics.uci.edu/ml/datasets/adult)。Adult Data Set數據集是Barry Becker從1994年的人口普查數據庫中整理篩選得到的,數據收集和整理過程規范統一,數據質量和可信度高,樣本量充足且缺失值、異常值較少,能夠一定程度上保證模型的質量和可信度。
2.2數據描述
本文選用的數據集共包含3個文件,adult.names包含了數據集的說明和對數據集各項指標的解釋,adult.data和adult.test為數據集作者劃分的訓練集和測試集,為便于對數據進行整理和分析,本文將adult.data和adult.test兩個數據集進行合并,在訓練模型時對訓練集和測試集進行重新分割。本文采用的數據集共包含48842個樣本15個指標。15個指標中6個指標為連續型指標,其余9個指標為離散型指標,其名稱及屬性如下表所示:
| age | 年齡 | 連續型 | |
| workclass | 工作類型 | 離散型 | Private(私人); Self-emp-not-inc(自由職業非公司); Self-emp-inc(自由職業公司); Federal-gov(聯邦政府); Local-gov(地方政府); State-gov(州政府); Without-pay(無薪); Never-worked(無工作經驗) |
| final-weight | 樣本權重 | 連續型 | |
| education | 受教育程度 | 離散型 | Bachelors(學士); Some-college(大學未畢業); 11th(高二); HS-grad(高中畢業); Prof-school(職業學校); Assoc-acdm(大學專科); Assoc-voc(準職業學位); 9th(初三),7th-8th(初中1-2年級); 12th(高三); Masters(碩士); 1st-4th(小學1-4年級); 10th(高一); Doctorate(博士); 5th-6th(小學5-6年級); Preschool(幼兒園) |
| education-num | 受教育時長 | 連續型 | |
| marital-status | 婚姻情況 | 離散型 | Married-civ-spouse(已婚平民配偶); Divorced(離婚); Never-married(未婚); Separated(分居); Widowed(喪偶); Married-spouse-absent(已婚配偶異地); arried-AF-spouse(已婚軍屬) |
| occupation | 職業 | 離散型 | Tech-support(技術支持); Craft-repair(手工藝維修); Other-service(其他職業); Sales(銷售); Exec-managerial(執行主管); Prof-specialty(專業技術); Handlers-cleaners(勞工保潔); Machine-op-inspct(機械操作); Adm-clerical(管理文書); Farming-fishing(農業捕撈); Transport-moving(運輸); Priv-house-serv(家政服務); Protective-serv(保安); Armed-Forces(軍人) |
| relationship | 家庭角色 | 離散型 | Wife(妻子); Own-child(孩子); Husband(丈夫); Not-in-family(離家); Other-relative(其他關系); Unmarried(未婚) |
| race | 種族 | 離散型 | White(白人); Asian-Pac-Islander(亞裔、太平洋島裔); Amer-Indian-Eskimo(美洲印第安裔、愛斯基摩裔); Black(非裔); Other(其他) |
| sex | 性別 | 離散型 | Female(女); Male(男) |
| capital-gain | 資本收益 | 連續型 | |
| capital-loss | 資本支出 | 連續型 | |
| hours-per-week | 周工作小時數 | 連續型 | |
| 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 |
三、數據準備
本文采用基于Python3的Jupyter Notebook作為模型和分析工具。Jupyter Notebook是一個基于Web的交互式數據科學和科學計算工具,因為其功能強大,使用靈活,已廣泛被亞馬遜、谷歌、微軟等互聯網企業應用于科學計算,并已經成為云計算的一個流行的用戶界面。而Python作為一門新興的編程語言,其語法簡潔,易于部署,功能強大,在數據挖掘和機器學習領域已得到廣泛的應用。
3.1 數據導入
(1)首先下載本文用到的Adult Data Set的兩個數據集,存放于dataset目錄中。
(2)新建文檔并導入本文分析所用到的工具包
1. ## 導入相關數據包 2. # 數據處理 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. # 自動調參器 - 隨機探索 25. import scipy.stats as st 26. from scipy.stats import randint as sp_randint # 隨機變量 27. from sklearn.model_selection import RandomizedSearchCV # 自動調參工具(隨機采樣) 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)導入兩個數據集并進行合并
使用panda的read_csv()方法讀取兩個數據集至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'] # 定義數據表頭即參數名 adult_data = pd.read_csv('dataset/adult.data', header=None, names=headers, sep=',\s', na_values=["?"], engine='python') # 導入數據集給出的訓練集 adult_test = pd.read_csv('dataset/adult.test', header=None, names=headers, sep=',\s', na_values=["?"], engine='python', skiprows=1) # 導入數據集給出的測試集 dataset = adult_data.append(adult_test) # 合并兩個數據集 # 由于導入時分別為兩數據集添加了索引,故對合并后的DataFrame重新創建索引并覆蓋原索引 dataset.reset_index(inplace=True, drop=True)3.2 數據預處理
3.2.1 查看數據缺失情況
(1)繪制缺失值矩陣圖
對數據的缺失情況可視化,使用方塊代表指標,方塊中的留白代表數據缺失及缺失的位置,便于觀察各指標數據缺失以及數據缺失的分布情況。
missingno.matrix(dataset, figsize = (20,5))由表中可以看出,工作類型(workclass)、職業(occupation)和國籍(country)存在的缺失值較多。工作類型和職業的缺失具有一定的相關性。
(2)繪制缺失值柱狀圖
缺失值柱狀圖通過統計各指標缺失值情況,并以條形圖展現指標缺失值數量。
missingno.bar(dataset, sort='ascending', figsize = (20,5))
通過缺失值柱狀圖可以看出,工作類型(workclass)、職業(occupation)和國籍(country)均存在不同程度的缺失,其余指標無缺失值,其中工作類型缺失值最多,其次為職業(occupation)和國籍(country)。
3.2.2 處理缺失值
通過3.2.1對缺失值情況的分析我們可以看出數據集的缺失值數量較少,忽略含有缺失值的樣本對整體數據影響很小,故采取直接刪除含有缺失值樣本的方法對缺失值進行處理,并對處理后的數據進行描述。
dataset.dropna(axis=0, how='any', inplace=True) dataset.describe(include='all')由下表可見,去除缺失值后的數據集共包含45222個有效樣本,刪除含有缺失值的樣本3620個,占原樣本量的7.4%。
3.2.3 處理數據異常
通過3.2.2刪除缺失值后的數據描述,我們注意到離散型變量收入等級指標(income-level)存在4種類型的值,與樣本給出的說明不符。通過對數據集進行觀察,我們發現在adult.data中標簽為“<=50K”和“>50K”,而在adult.test中的標簽為 “<=50K.”和“>50K.”。因此,我們對這種不一致問題進行處理,合并同義標簽。
此外,樣本權重(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 數據整體描述
3.3.1 預覽數據
通過預覽數據的一部分,可以大致了解數據各指標的類型。
dataset.head(5) # 預覽數據前5行3.3.2 描述性統計
對數據進行描述性統計,對于連續型變量,計算其有效值數量、平均值、標準差、最小值,25%分位數、50%分位數、75%分位數以及最大值;對于離散型變量,統計其有效值數量、類別數量、出現最多的類別及其頻次。
# 對數值變量進行描述 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歲之間,呈現出正偏態的分布狀態;工作類型主要為個人,其他工作類型的樣本相對較少;教育程度以高中和大學為主;教育時長以9-10年為主,大部分均達到了7.5年以上;職業類型中執行主管、專業技術和手工藝維修居多,而以軍人為職業的樣本較少;家庭角色指標中樣本多數為丈夫,其次為離家狀態;調查的對象中白人占據了大多數,而其他族裔的數量較少;樣本的性別以男性為主,占到總樣本的約2/3;數據中的大多數樣本均來自美國,沒有資本收入和資本支出,每周工作40小時左右;樣本中收入水平小于$50K的數量較多,約為收入水平大于$50K樣本的3倍。
此外,我們還發現部分分類指標類別過多,且部分指標樣本數過少,為解決此問題,對部分類別過多的分類指標進行處理。
3.4 對分類指標進行調整
3.4.1 工作類型
本數據集中,工作類型(workclass)指標共有8種類別:私人(Private)、自由職業非公司(Self-emp-not-inc)、自由職業公司(Self-emp-inc)、聯邦政府(Federal-gov)、地方政府(Local-gov)、州政府(State-gov)、無薪(Without-pay)、無工作經驗(Never-worked)。繪制條形圖查看各類樣本數量。
plt.style.use('seaborn-whitegrid') plt.figure(figsize=(15, 4)) sns.countplot(y="workclass", data=dataset);
從上述條形圖可見,私營工作在樣本中占比較大,不工作和無收入工作樣本數量極小,結合實際情況,將其歸納為5類。
3.4.2 職業
本數據集中職業共有14種類型如下:Tech-support(技術支持), Craft-repair(手工藝維修), Other-service(其他職業),Sales(銷售), Exec-managerial(執行主管), Prof-specialty(專業技術),Handlers-cleaners(勞工保潔), Machine-op-inspct(機械操作), Adm-clerical(管理文書),Farming-fishing(農業捕撈), Transport-moving(運輸), Priv-house-serv(家政服務),Protective-serv(保安), Armed-Forces(軍人)。
plt.style.use('seaborn-whitegrid') plt.figure(figsize=(15,5)) sns.countplot(y="occupation", data=dataset);
為便于后續分析,將其合并為6類。
3.4.3 國籍
數據說明里共列出41個國家和地區,除美國外大部分國家和地區的樣本都很少,故在此按照地域對這些國家和地區進行合并。
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);將國家合并為地區后,雖然與美國相比仍差異較大,但是各類別樣本數量更加均勻。
3.4.4 受教育程度
繪制受教育程度條形圖,觀察數據分布情況。
plt.style.use('seaborn-whitegrid') plt.figure(figsize=(15,5)) sns.countplot(y="education", data=dataset);
從上圖可見,受教育程度類別多達16個,通過生成條形圖可以看出低教育水平的各類別數量較少,故以高中為界,將其整合為一類(dropout),對兩類高中(HS-Graduate)和兩類專科(Associate)也進行合并。
3.4.5 婚姻狀態
數據說明里共列出7種婚姻狀態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類:從未結婚、離異、分居和已婚。
3.5 查看調整后各指標分布情況
由于plot_distribution()函數在上文中已定義,故在此直接調用
plot_distribution(dataset, cols=3, width=20, height=20, hspace=0.45, wspace=0.5)
從上圖可見,經過調整后,部分分類指標存在的類別過于復雜、部分類別樣本數量過少的問題得到了一定程度的緩解。
3.6 檢查變量間相關關系
為了探索變量間可能存在的相互影響的問題,本文通過計算變量間的相關系數對其可能存在的交互作用進行檢查。
(1)復制原數據集,并將其中離散的字符串變量轉化為數值,以便進行后續分析。
dataset_num = dataset.copy() # 復制數據集 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)繪制變量間的相關關系圖譜,探索變量間的相關性。
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);
通過相關關系分析,我們可以看出變量間沒有較為明顯的共線性,故不對變量進行篩選。
3.7 切分數據集
完成數據集的清洗和處理后,即可對數據集進行切分,為后續訓練和測試模型分類能力做準備。
(1)切分自變量和因變量
本文目的為通過人口普查數據對個體的收入水平進行預測,故因變量為收入水平(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)切分訓練集和測試集
在切分數據集方面,本文參考了Agarwal和Saxena(2018)[1]在利用機器學習進行惡性腫瘤分析中使用的方法,使用scikit-learn提供的train_test_split()將數據集切分為訓練集和測試集,測試集占整個數據集的20%,訓練集占整個數據集的80%。并按照因變量中各類別的比例進行均分,得到訓練集變量x_train和y_train,以及測試集變量x_test和y_test。
# 切分訓練集和測試集 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)四、建模
本數據集作為當前較為熱門的分類數據集,從其發布至今,已有眾多學者圍繞本數據集開展不同分類器的研究,如Kohavi(1996)[2]使用樸素貝葉斯方法對模型進行了分析,Deepajothi和Selvarajan(2012)[3]比較了貝葉斯分類器和決策樹分類器在收入水平分類上的預測效果,Mangasarian和Musicant(1999)[4]則構建了使用支持向量機對收入進行分類的方法。
為了實現較高的分類準確率,本文結合課程所學,并參考引用本數據集進行分析的相關文獻的方法,一共構建了10種不同類型的分類器,使用同一組訓練集進行訓練,對于構建模型的超參數,借助Python中scikit-learn庫提供的隨機搜索器RandomizedSearchCV()通過多輪訓練篩選最優參數,模型建構完成后,使用同一組測試集對10個模型進行測試,保證模型比較的公平性,并從中篩選出表現最優的模型。
4.1 構建模型訓練測試函數
本文采用的各個模型均借助Python3下的Scikit-learn庫構建。Scikit-learn是用Python編寫的通用機器學習庫[5],是機器學習領域最知名的Python模塊之一,提供通用性、模塊化的算法實現[6],其模型構建靈活,種類豐富,模型構建和分析的相關工具較為齊全,故各分類器間除參數不一致外,訓練模型、測試模型以及生成各類評價參數的步驟大致相同[7],為簡化程序代碼本文首先構建模型訓練的方法fit_ml_algo()、超參數報告report()以及計算TPR、FPR并繪制ROC曲線的方法plot_roc_curve()。
4.1.1 構建模型訓練方法fit_ml_algo()
該方法用于構建統一的模型訓練過程,傳入設置好超參數的模型、訓練集、測試集以及k折交叉驗證的折數(cv)后,即使用訓練集對模型進行訓練,使用訓練好的模型對x_test進行預測得到test_pred,使用predict_proba計算測試樣本屬于不同類別的概率,并使用K折交叉檢驗再次對模型進行訓練,并返回訓練結果和模型評價指標。
# 構造一個模型套用的樣板,自動調用訓練集對傳入的模型進行訓練,使用驗證集對模型進行檢驗,并輸出相關指標 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 構建超參數報告方法report()
本方法用于對調參工具RandomizedSearchCV()運算得到的候選模型進行排序,并匯報效果較為優秀的模型的超參數。相較于采用網格搜索的模型調參方法GridSearchCV(),RandomizedSearchCV()不會評估所有可能的超參數組合,所以它的計算開銷和耗時較少,能夠更高效快速地篩選更適合所研究問題的超參數[8]。
# 匯報候選模型參數 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 構建ROC曲線方法plot_roc_curve()
該方法用于計算TPR(True Positive Rate)和FPR(False Positive Rate)并繪制ROC曲線。
# 構建函數用于計算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 構建P-R曲線方法plot_pr_curve()
# 構建繪制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 構建Logistic回歸分類模型
(1)使用隨機搜索器RandomizedSearchCV()進行自動調參
# Logistic回歸 # 設置超參數并構建隨機搜索器 n_iter_search = 10 # 訓練10次,數值越大,獲得的參數精度越大,但是搜索時間越長 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進行訓練,默認為1,使用1個CPU 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_)運行上述代碼,隨機搜索器通過多輪隨機搜索確定不同超參數下的模型表現,并輸出表現排名前5的模型參數集。
(2)使用上述隨機搜索器調參后表現最佳的模型random_search.best_estimator_進行訓練并輸出模型評價參數。
從輸出可以看出,直接訓練的準確度為79.1%,使用十折交叉驗證得到的模型準確度為78.86%,模型運行時間為1s。
(3)評估訓練集的模型表現
上表中,列表左邊的一列為分類的標簽名;precision列表示模型預測的結果中有多少是預測正確的,即精度;recall列和f1-score分別為模型的召回率和F1參數,support列為每個標簽的出現次數;accuracy為模型的準確度;macro avg和weighted avg分別是加權平均前后的平均值,后續表格同理。
(4)評估訓練集的模型表現
# 測試集樣本表現 print(metrics.classification_report(y_test, test_pred_log))
(5)繪制ROC曲線
(6)繪制P-R曲線
4.3 構建KNN分類模型
(1)將K近鄰的K值設為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模型的預測準確率為82.74%,十折交叉驗證的準確率為82.64%,運算時長48s。
(2)評估訓練集的模型表現
(3)評估訓練集的模型表現
(4)繪制ROC曲線
(5)繪制P-R曲線
4.4 構建樸素貝葉斯分類模型
Scikit-learn的naive_bayes 模塊共包含三種樸素貝葉斯實現方式:Gaussian Naive Bayes、Multinomial Naive Bayes、Bernoulli Naive Bayes。Gaussian Naive Bayes多用于一般的分類問題,本題目即屬于此類情況;Multinomial Naive Bayes多適用于文本數據(特征表示的是次數,例如某個詞語的出現次數);適用于伯努利分布,也適用于文本數據(此時特征表示的是是否出現,例如某個詞語的出現為1,不出現為0),絕大多數情況下表現不如多項式分布,但有的時候伯努利分布表現得要比多項式分布要好,尤其是對于小數量級的文本數據。因此,本文采用Gaussian Naive Bayes構建樸素貝葉斯分類模型。
(1)訓練和測試樸素貝葉斯模型。
該模型預測的準確度達到80.19%,十折交叉驗證的準確度為79.88%,運算時間為3s。
(2)評估訓練集的模型表現
# 訓練集樣本表現 print(metrics.classification_report(y_train, train_pred_gaussian))
(3)評估訓練集的模型表現
(4)繪制ROC曲線
(5)繪制P-R曲線
4.5 構建支持向量機分類模型
(1)訓練并測試支持向量機模型
在構建模型的過程中,本文嘗試了Scikit-learn提供的六種不同的SVC內核,模型效果均不太理想且運算速度較慢,相對而言線性內核表現略好,且Mangasarian和Musicant(1999)[4]在基于本文數據集構建SVC模型時,也主要采用了線性內核,故使用線性支持向量機構建本文分類模型。
從分析結果可以看出,支持向量機分類器的預測準確度為53.29%,十折交叉驗證的準確度為35.68%,模型運算時間74s。
(2)評估訓練集的模型表現
# 訓練集樣本表現 print(metrics.classification_report(y_train, train_pred_svc))
(3)評估訓練集的模型表現
(4)繪制ROC曲線
(5)繪制P-R曲線
4.6 構建隨機梯度下降分類模型
隨機梯度下降模型采用mini-batch來做梯度下降,在處理大數據的情況下收斂更快。
(1)訓練兵測試隨機梯度下降模型
# 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)
隨機梯度下降分類器模型的預測準確度為77.29%,使用十折交叉檢驗的準確度為77.94%,運算耗費3s。
(2)評估訓練集的模型表現
# 訓練集樣本表現 print(metrics.classification_report(y_train, train_pred_sgd))
(3)評估訓練集的模型表現
(4)繪制ROC曲線
(5)繪制P-R曲線
4.7 構建決策樹分類模型
(1)訓練和測試決策樹分類模型
# 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)
決策樹分類模型的預測準確度為82.37%,十折交叉驗證的準確度為81.76%,運算耗時1s。
(2)評估訓練集的模型表現
# 訓練集樣本表現 print(metrics.classification_report(y_train, train_pred_dt))
(3)評估訓練集的模型表現
(4)繪制ROC曲線
# 繪制ROC plot_roc_curve(y_test, probs_dt)
(5)繪制P-R曲線
4.8 構建隨機森林分類模型
(1)使用隨機調參工具查找隨機森林算法最優超參數
# 從中調參的超參數集合 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)使用隨機搜索器得到的最優參數模型進行訓練和測試。
訓練后的隨機森林模型預測的準確度為85.85%,十折交叉檢驗的準確度為85.65%,運行耗費時間2s。
(3)評估訓練集的模型表現
# 測試集樣本表現 print(metrics.classification_report(y_train, train_pred_rf))
(4)評估訓練集的模型表現
(5)繪制ROC曲線
(6)繪制P-R曲線
4.9 構建內梯度提升決策樹分類模型
(1)訓練和測試梯度提升決策樹分類模型
# 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)
訓練后的梯度提升決策樹預測準確度為86.2%,十折交叉檢驗的準確度為85.97%,訓練耗時15s。
(2)評估訓練集的模型表現
# 訓練集樣本表現 print(metrics.classification_report(y_train, train_pred_gbt))
(3)評估訓練集的模型表現
(4)繪制ROC曲線
(5)繪制P-R曲線
4.10 構建AdaBoost分類模型
(1)訓練和測試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模型訓練后的預測準確度為85.86%,十折交叉驗證的準確度為85.41%,運算耗時6s。
(2)評估訓練集的模型表現
# 訓練集樣本表現 print(metrics.classification_report(y_train, train_pred_adb))
(3)評估訓練集的模型表現
(4)繪制ROC曲線
(5)繪制P-R曲線
4.11 構建投票法分類模型
投票法(Voting Classifier)是集成學習里面針對分類問題的一種結合策略。基本思想是選擇所有機器學習算法當中輸出最多的那個類。
分類的機器學習算法輸出有兩種類型:一種是直接輸出類標簽,另外一種是輸出類概率,使用前者進行投票叫做硬投票(Majority/Hard voting),使用后者進行分類叫做軟投票(Soft voting)。經過測試,對于本文選用的數據集,Soft Voting模型效果較好,故使用Soft Voting作為投票法分類器的投票模型。
在機器學習算法中,通過比較不同分類器組合的效果,最終選用了Logistic回歸分類器、樸素貝葉斯(Gaussian Native Bayes)、隨機森林分類器、梯度提升分類器和決策樹分類器作為投票算法。
(1)構建、訓練和測試投票分類器模型
# 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)
訓練后的投票法分類模型預測準確度為84.72%,十折交叉檢驗的準確度為84.73%,模型運算耗時21s。
(2)評估訓練集的模型表現
# 訓練集樣本表現 print(metrics.classification_report(y_train, train_pred_vot))
(3)評估訓練集的模型表現
(4)繪制ROC曲線
(5)繪制P-R曲線
五、評估
5.1 指標評估
結合課本內容和Powers(2011)[9]對各項模型評價指標的對比分析和介紹,本文最終選用準確率(Accuracy)、精確率(Precision)、召回率(Recall)、F1分數、作為主要的評價指標。準確率(Accuracy)表示分類模型所有判斷正確的結果占總觀測值的比重;精確率(Precision)表示模型觀測是Positive的所有結果中,模型預測對的比重;召回率(Recall)表示真實值是Positive的所有結果中,模型預測對的比重;F1分數綜合了Precision和Recall的結果,是精確率和召回率的調和平均數,取值越高,模型效果越好.
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)得到各模型評價參數如下表所示:
從上表可見,本文所用到的十個模型中,梯度提升決策樹(Gradient Boosting Trees)、AdaBoost、隨機森林(Random Forest)三個模型的準確率均表現良好,達到了85%以上,F1值相較于其他模型也處于較為優秀的水平,故從指標角度來看,這三個模型更適用于本文所研究的問題。
5.2 ROC曲線
ROC曲線全稱Receiver Operating Characteristic Curve,即接受者操作特征曲線,ROC曲線越接近左上角,其對應模型的分類效果越好。參數AUC(Area Under Curve)代表了ROC曲線下的面積,能夠定量地衡量分類器的好壞,AUC值越大,模型表現效果越好[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兩個模型表現最優,AUC值均達到了0.92,線性支持向量機模型表現最差,幾乎無法起到有效的分類作用。
5.3 P-R曲線
P-R曲線是比較分類器的一個有效的工具,P-R曲線越靠近圖像右上角的分類器表現越好,若一個分類器的P-R曲線被另一個分類器的P-R曲線完全“包住”,則后者的性能優于前者[11]。
# 構建繪制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曲線可以看出,梯度提升決策樹分類器的表現效果最好,其次為AdaBoost和隨機森林,與ROC曲線和觀察相關評價指標得出的結果大致一致。
參考文獻
[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.
總結
以上是生活随笔為你收集整理的基于人口普查数据的收入预测模型构建及比较分析(Python数据分析分类器模型实践)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win7 dos窗口输入命令必须加后缀问
- 下一篇: Poj1207 The 3n + 1 p