UCI数据集+机器学习+十折交叉验证
? ? ? ?本文為本學(xué)期《生物醫(yī)學(xué)信息》課程作業(yè),第一次發(fā)文,希望可以記錄自己的學(xué)習(xí)狀態(tài),和大家一起學(xué)習(xí)進(jìn)步。?
作業(yè)要求:
背景介紹:
? ? ? ? UCI?數(shù)據(jù)集是加州大學(xué)歐文分校(University of CaliforniaIrvine)提出的用于機(jī)器學(xué)習(xí)的?
數(shù)據(jù)庫(kù)。目前共有?622?個(gè)數(shù)據(jù)集,是一個(gè)常用的機(jī)器學(xué)習(xí)標(biāo)準(zhǔn)測(cè)試數(shù)據(jù)集。本文選取?UCI?
數(shù)據(jù)集中第?196?號(hào)數(shù)據(jù)集進(jìn)行處理分析。?
? ? ? ? ?sklearn?是一個(gè)?Python?第三方提供的非常強(qiáng)力的機(jī)器學(xué)習(xí)庫(kù),它建立在?NumPy, SciPy,?
Pandas?和?Matplotlib?之上,在?sklearn?里面有六大任務(wù)模塊:分別是分類、回歸、聚類、?
降維、模型選擇和預(yù)處理。合理的使用?sklearn?可以減少代碼量與編程時(shí)間,使我們有更多?
的精力去分析數(shù)據(jù)分布,調(diào)整模型和修改超參。
數(shù)據(jù)集介紹:
? ? ? ? ?本實(shí)驗(yàn)使用的數(shù)據(jù)集來(lái)自?UCI machine learning?數(shù)據(jù)集生命科學(xué)類中的?Localization?
Data for Person Activity Data Set,此數(shù)據(jù)集共有?164860?個(gè)樣本以及?8?個(gè)特征,樣本數(shù)×?
特征數(shù)?> 50?萬(wàn),包含了五個(gè)人的左右腳踝、腰部和胸部在不同時(shí)間點(diǎn)的位置坐標(biāo)等屬性,?
根據(jù)這些屬性,將受試者分為行走、躺下、站立等?11?種不同的行為狀態(tài)。
數(shù)據(jù)下載地址為:
UCI Machine Learning Repository: Localization Data for Person Activity Data Set?
數(shù)據(jù)實(shí)例:?
A01,020-000-033-111,633790226057226795,27.05.2009 14:03:25:723,4.292500972747803,?
2.0738532543182373,1.36650812625885, walking?
第一列?SequenceName:{A01,A02,A03,A04,A05,B01,B02,B03,B04,B05,C01,C02,?
C03,C04,C05,D01,D02,D03,D04,D05,E01,E02,E03,E04,E05} (Nominal)?,代表?A, B, C, D,?
E 5?個(gè)人。?
第二列?TagIdentificator:{010-000-024-033,020-000-033-111,020-000-032-221,?
010-000-030-096} (Nominal)?,使用不同的數(shù)字序列,代表人體的不同部位,分別為?
ANKLE_LEFT、ANKLE_RIGHT、CHEST、BELT。第三列?Timestamp:時(shí)間戳。?
第四列?date:符合?dd.MM.yyyy HH:mm:ss:SSS?形式的日期數(shù)據(jù)。?
第五列-第七列分別為?x、y、z?坐標(biāo)。?
第八列?activity:{walking, falling, lying down, lying, sitting down, sitting, standing up?
from lying, on all fours, sitting on the ground, standing up from sitting, standing up from?
sitting on the ground},表示人的行為狀態(tài),共有以上?11?種。
K折交叉驗(yàn)證:
K?次交叉驗(yàn)證(K-fold cross-validation),將訓(xùn)練集分割成?K?個(gè)子樣本,一個(gè)單獨(dú)的?
子樣本被保留作為驗(yàn)證模型的數(shù)據(jù),其他?K-1?個(gè)樣本用來(lái)訓(xùn)練。交叉驗(yàn)證重復(fù)?K?次,每個(gè)?
子樣本驗(yàn)證一次,平均?K?次的結(jié)果或者使用其它結(jié)合方式,最終得到一個(gè)單一估測(cè)。這個(gè)?
方法的優(yōu)勢(shì)在于,同時(shí)重復(fù)運(yùn)用隨機(jī)產(chǎn)生的子樣本進(jìn)行訓(xùn)練和驗(yàn)證,每次的結(jié)果驗(yàn)證一次,?
10?次交叉驗(yàn)證是最常用的。
?相關(guān)操作:
代碼需要import的包:
import pandas as pd from sklearn import preprocessing,tree,model_selection,svm,naive_bayes import time from sklearn.model_selection import KFold, train_test_split from sklearn.ensemble import BaggingClassifier, RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier from sklearn.neighbors import KNeighborsClassifier讀入數(shù)據(jù),獲取數(shù)據(jù)集基本信息,并顯示前五行數(shù)據(jù)。代碼如下:
path = "./ConfLongDemo_JSI.txt" df = pd.read_table(path, sep=',', names=['SequenceName', 'TagIdentificator','Timestamp', 'date', 'x', 'y', 'z', 'activity']) print(df.head()) df.info()運(yùn)行結(jié)果:
# 對(duì)類別型特征進(jìn)行啞變量的制作 cat_features = ['SequenceName', 'TagIdentificator'] for col in cat_features:df[col] = df[col].astype('object') X_cat = df[cat_features] X_cat = pd.get_dummies(X_cat) # print(X_cat.head())# 對(duì)數(shù)值型特征進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化和歸一化 scale_X = preprocessing.StandardScaler() num_features = ['Timestamp', 'x', 'y', 'z'] X_num = scale_X.fit_transform(df[num_features]) X_num = preprocessing.normalize(X_num, norm='l2') X_num = pd.DataFrame(data=X_num, columns=num_features, index=df.index) # print(X_num.head())觀察到?Timestamp?和?date?都為時(shí)間數(shù)據(jù),存在強(qiáng)相關(guān)的冗余,因此可將?date?屬性去?
除,只對(duì)?Timestamp?進(jìn)行分析。?
進(jìn)行數(shù)據(jù)預(yù)處理,挑選出類別型特征(SequenceName, TagIdentificator),將其轉(zhuǎn)換為啞變
量。挑選出數(shù)值型特征(Timestamp,x,y,z),進(jìn)行數(shù)據(jù)的標(biāo)準(zhǔn)化和歸一化。標(biāo)準(zhǔn)化??
(?Z-Score?) 的 公 式 為 :?(X-mean)/std?計(jì) 算 時(shí) 對(duì) 每 個(gè) 屬 性?/?每 列 分 別 進(jìn) 行 , 使 用?
sklearn.preprocessing.scale()函數(shù),可以直接將給定數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化。標(biāo)準(zhǔn)化的目的在于避?
免原始特征值差異過(guò)大,導(dǎo)致訓(xùn)練得到的參數(shù)權(quán)重不歸一,無(wú)法比較各特征的重要性。在數(shù)?
據(jù)標(biāo)準(zhǔn)化之后進(jìn)行數(shù)據(jù)的歸一化,查看結(jié)果的前五行。代碼如下:
# 對(duì)類別型特征進(jìn)行啞變量的制作 cat_features = ['SequenceName', 'TagIdentificator'] for col in cat_features:df[col] = df[col].astype('object') X_cat = df[cat_features] X_cat = pd.get_dummies(X_cat) # print(X_cat.head())# 對(duì)數(shù)值型特征進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化和歸一化 scale_X = preprocessing.StandardScaler() num_features = ['Timestamp', 'x', 'y', 'z'] X_num = scale_X.fit_transform(df[num_features]) X_num = preprocessing.normalize(X_num, norm='l2') X_num = pd.DataFrame(data=X_num, columns=num_features, index=df.index) # print(X_num.head())合并數(shù)據(jù),在分別對(duì)數(shù)值型數(shù)據(jù)已經(jīng)類別型數(shù)據(jù)進(jìn)行數(shù)據(jù)預(yù)處理后,將它們合并組成?
Sam,顯示?Sam?的前?5?行與形狀,代碼如下:
# 合并數(shù)據(jù) Sam = pd.concat([X_cat, X_num,df['activity']], axis=1, ignore_index=False) # print(Sam.head()) # print(Sam.shape)設(shè)置十折交叉,對(duì)數(shù)據(jù)集進(jìn)行劃分,并查看測(cè)試數(shù)據(jù)集。代碼如下:
# 十折交叉 kf = KFold(n_splits=10) for train_index, test_index in kf.split(Sam): print("Train:", train_index, "Validation:",test_index) print(len(train_index),len(test_index)) print(Sam.iloc[train_index, 0:34])根據(jù)十折交叉所得訓(xùn)練集及測(cè)試集的索引,從?Sam?中取得實(shí)際用于訓(xùn)練和測(cè)試的部分。?
代碼如下:
X_train, X_test = Sam.iloc[train_index, 0:33], Sam.iloc[test_index, 0:33] y_train, y_test = Sam.iloc[train_index, 33], Sam.iloc[test_index, 33]共使用8種算法進(jìn)行訓(xùn)練,分別測(cè)試其準(zhǔn)確率和用時(shí)。分別是K近鄰算法、決策樹(shù)算法、先驗(yàn)為高斯分布的樸素貝葉斯算法、支持向量機(jī)算法、Tree Bagging算法、隨機(jī)森林算法、adaboost算法、GBDT算法。
采用十折交叉驗(yàn)證的方法代碼如下:
clfs = {'K_neighbor': KNeighborsClassifier(),'decision_tree': tree.DecisionTreeClassifier(),'naive_gaussian': naive_bayes.GaussianNB(),'svm': svm.SVC(),'bagging_tree': BaggingClassifier(tree.DecisionTreeClassifier(), max_samples=0.5,max_features=0.5),'random_forest': RandomForestClassifier(n_estimators=50),'adaboost': AdaBoostClassifier(n_estimators=50),'gradient_boost': GradientBoostingClassifier(n_estimators=50, learning_rate=1.0,max_depth=1, random_state=0)}# 合并數(shù)據(jù) Sam = pd.concat([X_cat, X_num,df['activity']], axis=1, ignore_index=False) # print(Sam.head()) # print(Sam.shape)for clf_key in clfs.keys():print('\nthe classifier is:', clf_key)Sum_score = 0Sum_elapsed = 0# K折交叉n_splits = 5kf = KFold(n_splits)for train_index, test_index in kf.split(Sam):# print("Train:", train_index, "Validation:",test_index)# print(len(train_index),len(test_index))# print(Sam.iloc[train_index, 0:33])# # print(Sam.iloc[train_index,33])X_train, X_test = Sam.iloc[train_index, 0:33], Sam.iloc[test_index, 0:33]y_train, y_test = Sam.iloc[train_index, 33], Sam.iloc[test_index, 33]clf = clfs[clf_key]begin = time.perf_counter()clf.fit(X_train, y_train.ravel())elapsed = time.perf_counter() - beginscore = clf.score(X_test, y_test.ravel())Sum_score = Sum_score + scoreSum_elapsed = Sum_elapsed + elapsedprint('the score is:', score)# print('the elapsed is:', elapsed)print('The score is:', Sum_score / n_splits)print('The elapsed is:', Sum_elapsed / n_splits)使用如參考文章中劃分獨(dú)立測(cè)試集的方法代碼為:
# 合并數(shù)據(jù) X = pd.concat([X_cat, X_num], axis=1, ignore_index=False) y = df['activity'] # print(X.head()) # print(X.shape) # print(y.shape)# 劃分訓(xùn)練集測(cè)試集 X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.20, shuffle=True) # print(X_train.shape, y_train.shape) # print(X_test.shape, y_test.shape)for clf_key in clfs.keys():print('\nthe classifier is:', clf_key)clf = clfs[clf_key]begin = time.perf_counter()clf.fit(X_train, y_train.ravel())elapsed = time.perf_counter() - beginscore = clf.score(X_test, y_test.ravel())print('the score is:', score)print('the elapsed is:', elapsed)結(jié)果討論:
十折交叉驗(yàn)證運(yùn)行結(jié)果如下:
?
劃分獨(dú)立測(cè)試集的結(jié)果如下:
可以看到,機(jī)器學(xué)習(xí)模型的復(fù)雜度并不直接與準(zhǔn)確度成正比。?
在十折交叉驗(yàn)證中,最簡(jiǎn)單的?KNN?模型都可以達(dá)到?0.411?的準(zhǔn)確度,而集成方法?adaboost?的準(zhǔn)
確度卻只有?0.327?左右。在這?8?中算法中,隨機(jī)森林算法的準(zhǔn)確度最高,同時(shí)?SVM?和?Bagging
Tree?的表現(xiàn)也較為良好。?
以?KNN?為例,分別輸出十折交叉驗(yàn)證過(guò)程每一次實(shí)驗(yàn)的準(zhǔn)確度如下圖,可以看出,不?
同訓(xùn)練集測(cè)試集對(duì)于同一模型的準(zhǔn)確度存在一定影響,準(zhǔn)確度最小為?0.361,最大為?0.489,?
相差?0.128。因此采用十折交叉驗(yàn)證得到的結(jié)果可以更加準(zhǔn)確體現(xiàn)這一模型的性能與好壞,?
更加具有說(shuō)服力。
在獨(dú)立測(cè)試集中,最簡(jiǎn)單的?KNN?模型能達(dá)到?0.789?的準(zhǔn)確度,而?adaboost、gradient_boost?等
集成方法卻連?0.4?的準(zhǔn)確度都達(dá)不到。在這?8?種算法中,準(zhǔn)確度最高的是?三個(gè)算法是決策樹(shù)、
Bagging Tree?和隨機(jī)森林,都達(dá)到了?0.85?以上,樹(shù)模型可能更加適合這個(gè)數(shù)據(jù)集。?
同一模型在獨(dú)立測(cè)試集的的表現(xiàn)優(yōu)于十折交叉驗(yàn)證中的表現(xiàn)。為排除訓(xùn)練集以及測(cè)試集?
大小對(duì)實(shí)驗(yàn)結(jié)果的影響,由于獨(dú)立測(cè)試集是是按照?8 : 2?劃分的,所以采用五折交叉驗(yàn)證重?
新測(cè)試,即將?K?折交叉驗(yàn)證中的?n_splits?參數(shù)賦值為 5,再次運(yùn)行代碼。結(jié)果如下圖:
?
可以看到即使訓(xùn)練集測(cè)試集大小相同(訓(xùn)練集:測(cè)試集?= 8?:?2),獨(dú)立測(cè)試集的結(jié)果都遠(yuǎn)勝于K折交叉驗(yàn)證的結(jié)果,觀察ConfLongDemo_JSI.txt文件,發(fā)現(xiàn)作為輸出y的‘a(chǎn)ctivity’字段,分布不是無(wú)序的,而是有聚集有按類別排序的分布,對(duì)于K折交叉驗(yàn)證的方法,其劃分?jǐn)?shù)據(jù)集采用的方式是按照索引大小整塊取出的方法,因此用于訓(xùn)練和測(cè)試的數(shù)據(jù)集其‘a(chǎn)ctivity’字段都有一定規(guī)律性存在。而使用sklearn的train_test_split()函數(shù)進(jìn)行劃分的訓(xùn)練集和測(cè)試集都是隨機(jī)劃分的,因此對(duì)于此數(shù)據(jù)集在同一模型下,使用獨(dú)立測(cè)試集的表現(xiàn)更好。
?
?模型和測(cè)試方法沒(méi)有優(yōu)劣之分,只有適不適合的區(qū)別,具體使用什么方法或模型取決于具體的問(wèn)題。
由于剛剛?cè)腴T(mén),自己獨(dú)立完成存在一定困難。所以在網(wǎng)上借鑒(copy)了相關(guān)文章的處理方法。并自己進(jìn)行一定修改。主要體現(xiàn)在十折交叉驗(yàn)證這一方法的應(yīng)用。
參考文章:
使用sklearn進(jìn)行UCI machine learning數(shù)據(jù)集的機(jī)器學(xué)習(xí)實(shí)戰(zhàn) - 簡(jiǎn)書(shū)
3.1. Cross-validation: evaluating estimator performance — scikit-learn 1.1.dev0 documentation交叉驗(yàn)證法(?cross validation) - 云+社區(qū) - 騰訊云
3.1. Cross-validation: evaluating estimator performance — scikit-learn 1.1.dev0 documentation
文章資源及源代碼:
數(shù)據(jù)文件及py文件已上傳至百度網(wǎng)盤(pán),可以按需下載。歡迎大家交流。
鏈接: https://pan.baidu.com/s/1U6VkgPesWcVGR285iLL-WQ?pwd=8sng 提取碼: 8sng 復(fù)制這段內(nèi)容后打開(kāi)百度網(wǎng)盤(pán)手機(jī)App,操作更方便哦
總結(jié)
以上是生活随笔為你收集整理的UCI数据集+机器学习+十折交叉验证的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C++ cout的使用,看这一篇就够了
- 下一篇: 进程通信例子