丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時鏈接,僅用于文章預(yù)覽,將在時失效
人工智能開發(fā)者 正文
發(fā)私信給AI研習(xí)社
發(fā)送

0

一個實(shí)例告訴你:Kaggle 數(shù)據(jù)競賽都有哪些套路

本文作者: AI研習(xí)社 2017-05-01 17:06
導(dǎo)語:一個數(shù)據(jù)競賽的整個流程以及其中最常見的一些套路。

雷鋒網(wǎng)按:本文作者成達(dá),原文載于作者個人博客,雷鋒網(wǎng)已獲授權(quán)。

一個實(shí)例告訴你:Kaggle 數(shù)據(jù)競賽都有哪些套路

前面寫了很多篇理論,大家愿意一篇一篇堅持看下來其實(shí)挺不容易的,雖然理論很重要,但脫離了實(shí)踐還是空中樓閣啊,算法科學(xué)家也不可能不代碼啊,所以呀,今天我們就插播一期實(shí)踐,和大家聊一聊實(shí)際過程當(dāng)中機(jī)器學(xué)習(xí)算法的應(yīng)用。

對于我們這些初學(xué)者或者說外行來說,因?yàn)槲覀儧]機(jī)會接觸到機(jī)器學(xué)習(xí)真正的應(yīng)用項目,所以一些比賽平臺往往是我們不錯的選擇,比如說這個Kaggle啊,前一段時間被Google收購還挺火的,還有國內(nèi)的天池啊,DataFountain啊,上面都有不少比賽可以選擇,但是入門嘛,我們就從最簡單的開始,就是那個被無數(shù)文章博客提到過的泰坦尼克幸存者估計,我自己也看過一些,但是覺得很多文章把一開始數(shù)據(jù)探索部分寫得太重了,反而后面特征選擇和模型調(diào)參講的很少,我感覺這樣有些本末倒置的感覺,數(shù)據(jù)和特征決定了我們的上限。這里呢,我主要想講的就是完成一個數(shù)據(jù)競賽的整個流程以及其中最常見的一些套路,希望可以幫助大家可以快速入門競賽,以期取得好成績或者給自己求職增添砝碼。

下面進(jìn)入正題:

首先我們先觀察一下我們的數(shù)據(jù),看看哪些可以構(gòu)建為我們的特征

import pandas as pd  

data=pd.read_csv('E:\Blog\Titanic\Train.csv')  

data.info()  

data.describe()  

一個實(shí)例告訴你:Kaggle 數(shù)據(jù)競賽都有哪些套路

所有的數(shù)據(jù)中一共包括12個變量,其中7個是數(shù)值變量,5個是屬性變量,接下來我們具體來看一看。

PassengerId:這是乘客的編號,顯然對乘客是否幸存完全沒有任何作用,僅做區(qū)分作用,所以我們就不考慮它了。

Survived:乘客最后的生存情況,這個是我們預(yù)測的目標(biāo)變量。不過從平均數(shù)可以看出,最后存活的概率大概是38%。

Pclass:社會經(jīng)濟(jì)地位,這個很明顯和生存結(jié)果相關(guān)啊,有錢人住著更加高級船艙可能會享受著更加高級的服務(wù),因此遇險時往往會受到優(yōu)待。所以這顯然是我們要考慮的一個變量。

Name:這個變量看起來好像是沒什么用啊,因?yàn)楫吘箯拿帜阋膊荒芸闯瞿懿荒塬@救,但是仔細(xì)觀察數(shù)據(jù)我們可以看到,所有人的名字里都包括了Mr,Mrs和Miss,從中是不是隱約可以看出來一些性別和年齡的信息呢,所以干脆把名字這個變量變成一個狀態(tài)變量,包含Mr,Mrs和Miss這三種狀態(tài),但是放到機(jī)器學(xué)習(xí)里面我們得給它一個編碼啊,最直接的想法就是0,1,2,但是這樣真的合理嗎?因?yàn)閺木嚯x的角度來說,這樣Mr和Mrs的距離要小于Mr和Miss的距離,顯然不合適,因?yàn)槲覀儼阉闯善綑?quán)的三個狀態(tài)。

所以,敲黑板,知識點(diǎn)來了,對于這種狀態(tài)變量我們通常采取的措施是one-hot編碼,什么意思呢,有幾種狀態(tài)就用一個幾位的編碼來表示狀態(tài),每種狀態(tài)對應(yīng)一個一位是1其余各位是0的編碼,這樣從向量的角度來講,就是n維空間的n個基準(zhǔn)向量,它們相互明顯是平權(quán)的,此例中,我們分別用100,010,001來表示Mr,Mrs和Miss。

Sex:性別這個屬性肯定是很重要的,畢竟全人類都講究Lady First,所以遇到危險的時候,紳士們一定會先讓女士逃走,因此女性的生存幾率應(yīng)該會大大提高。類似的,性別也是一個平權(quán)的狀態(tài)變量,所以到時候我們同樣采取one-hot編碼的方式進(jìn)行處理。

Age:這個變量和性別類似,都是明顯會發(fā)揮重要作用的,因?yàn)闊o論何時,尊老愛幼總是為人們所推崇,但年齡對是否會獲救的影響主要體現(xiàn)在那個人處在哪個年齡段,因此我們選擇將它劃分成一個狀態(tài)變量,比如18以下叫child,18以上50以下叫adult,50以上叫elder,然后利用one-hot編碼進(jìn)行處理。不過這里還有一個問題就是年齡的值只有714個,它不全!這么重要的東西怎么能不全呢,所以我們只能想辦法補(bǔ)全它。

又敲黑板,知識點(diǎn)又來了,缺失值我們怎么處理呢?最簡單的方法,有缺失值的樣本我們就扔掉,這種做法比較適合在樣本數(shù)量很多,缺失值樣本舍棄也可以接受的情況下,這樣雖然信息用的不充分,但也不會引入額外的誤差。然后,假裝走心的方法就是用平均值或者中位數(shù)來填充缺失值,這通常是最簡便的做法,但通常會帶來不少的誤差。最后,比較負(fù)責(zé)任的方法就是利用其它的變量去估計缺失變量的值,這樣通常會更靠譜一點(diǎn),當(dāng)然也不能完全這樣說,畢竟只要是估計值就不可避免的帶來誤差,但心理上總會覺得這樣更好……

SibSp:船上兄弟姐妹或者配偶的數(shù)量。這個變量對最后的結(jié)果到底有什么影響我還真的說不準(zhǔn),但是預(yù)測年紀(jì)的時候說不定有用。

Parch:船上父母或者孩子的數(shù)量。這個變量和上個變量類似,我確實(shí)沒有想到特別好的應(yīng)用它的辦法,同樣的,預(yù)測年齡時這個應(yīng)該挺靠譜的。

Ticket:船票的號碼。恕我直言,這個謎一樣的數(shù)字真的是不知道有什么鬼用,果斷放棄了。

Fare:船票價格,這個變量的作用其實(shí)類似于社會地位,船票價格越高,享受的服務(wù)越高檔,所以遇難獲救的概率肯定相對較高,所以這是一個必須要考慮進(jìn)去的變量。

Cabin:船艙號,這個變量或許透露出了一點(diǎn)船艙等級的信息,但是說實(shí)話,你的缺失值實(shí)在是太多了,我要是把它補(bǔ)全引入的誤差感覺比它提供的信息還多,所以忍痛割愛,和你say goodbye!

Embarked:登船地點(diǎn),按道理來說,這個變量應(yīng)該是沒什么卵用的,但介于它是一個只有三個狀態(tài)的狀態(tài)變量,那我們就把它處理一下放進(jìn)模型,萬一有用呢對吧。另外,它有兩個缺失值,這里我們就不大動干戈的去預(yù)測了,就直接把它定為登船人數(shù)最多的S吧。

好的,到這里我們對所有變量應(yīng)該如何處理大致有譜了,狀態(tài)變量進(jìn)行one-hot編碼,那數(shù)值變量呢,直接用嗎?

知識點(diǎn)!對于數(shù)值變量,我們通常會先進(jìn)行歸一化處理,這樣有利于我們加快收斂速度,將各個維度限制在差不多的區(qū)間內(nèi),對一些基于距離的分類器有著非常大的好處,但是對于決策樹一類的算法其實(shí)就沒有意義了,不過這邊我們就對所有的數(shù)值變量都做一個歸一化處理吧。

到了這里,想必思路已經(jīng)很清晰了,下面我們再梳理一下過程:

1 剔除PassengerId,Ticket這兩個個變量,我們不用。

2 將Embarked變量補(bǔ)全,然后對Survived,Name,Sex, Embarked進(jìn)行one-hot編碼。

3對Pclass,F(xiàn)are,Sibsp和Parch進(jìn)行歸一化處理。

3 根據(jù)Name,Sex,SibSp,Parch預(yù)測age將其補(bǔ)全。

4 對age進(jìn)行歸一化處理。

5 將未編碼的Survived提出當(dāng)做目標(biāo)變量。

具體的代碼實(shí)現(xiàn)如下:

import pandas as pd  

data=pd.read_csv('E:\Blog\Titanic\Train.csv')  

#剔除變量  

data.drop(['PassengerId','Ticket'],axis=1,inplace=True)  

#補(bǔ)全Embarked變量  

data.loc[data.Embarked.isnull(),'Embarked']='S'  

#one-hot編碼  

from sklearn.preprocessing import OneHotEncoder  

from sklearn.preprocessing import LabelEncoder  

#ohe_pclass=OneHotEncoder(sparse=False).fit(data[['Pclass']])  

#Pclass_ohe=ohe_pclass.transform(data[['Pclass']])  

le_sex=LabelEncoder().fit(data['Sex'])  

Sex_label=le_sex.transform(data['Sex'])  

ohe_sex=OneHotEncoder(sparse=False).fit(Sex_label.reshape(-1,1))  

Sex_ohe=ohe_sex.transform(Sex_label.reshape(-1,1))  

le_embarked=LabelEncoder().fit(data['Embarked'])  

Embarked_label=le_embarked.transform(data['Embarked'])  

ohe_embarked=OneHotEncoder(sparse=False).fit(Embarked_label.reshape(-1,1))  

Embarked_ohe=ohe_embarked.transform(Embarked_label.reshape(-1,1))  

def replace_name(x):  

    if 'Mrs' in x:  

       return 'Mrs'  

    elif 'Mr' in x:  

        return 'Mr'  

    else:  

        return 'Miss'  

data['Name']=data['Name'].map(lambda x:replace_name(x))  

le_name=LabelEncoder().fit(data['Name'])  

Name_label=le_name.transform(data['Name'])  

ohe_name=OneHotEncoder(sparse=False).fit(Name_label.reshape(-1,1))  

Name_ohe=ohe_name.transform(Name_label.reshape(-1,1))  

data['Sex_0']=Sex_ohe[:,0]  

data['Sex_1']=Sex_ohe[:,1]  

data['Embarked_0']=Embarked_ohe[:,0]  

data['Embarked_1']=Embarked_ohe[:,1]  

data['Embarked_2']=Embarked_ohe[:,2]  

data['Name_0']=Name_ohe[:,0]  

data['Name_1']=Name_ohe[:,1]  

data['Name_2']=Name_ohe[:,2]  

#歸一化處理  

from sklearn.preprocessing import StandardScaler  

Pclass_scale=StandardScaler().fit(data['Pclass'])  

data['Pclass_scaled']=StandardScaler().fit_transform(data['Pclass'].reshape(-1,1),Pclass_scale)  

Fare_scale=StandardScaler().fit(data['Fare'])  

data['Fare_scaled']=StandardScaler().fit_transform(data['Fare'].reshape(-1,1),Fare_scale)  

SibSp_scale=StandardScaler().fit(data['SibSp'])  

data['SibSp_scaled']=StandardScaler().fit_transform(data['SibSp'].reshape(-1,1),SibSp_scale)  

Parch_scale=StandardScaler().fit(data['Parch'])  

data['Parch_scaled']=StandardScaler().fit_transform(data['Parch'].reshape(-1,1),Parch_scale)  

#預(yù)測年紀(jì)并補(bǔ)全  

from sklearn.ensemble import RandomForestRegressor  

def set_missing_age(data):  

    train=data[['Age','SibSp_scaled','Parch_scaled','Name_0','Name_1','Name_2','Sex_0','Sex_1']]  

    known_age=train[train.Age.notnull()].as_matrix()  

    unknown_age=train[train.Age.isnull()].as_matrix()  

    y=known_age[:,0]  

    x=known_age[:,1:]  

    rf=RandomForestRegressor(random_state=0,n_estimators=200,n_jobs=-1)  

    rf.fit(x,y)  

    print rf.score(x,y)  

    predictage=rf.predict(unknown_age[:,1:])  

    data.loc[data.Age.isnull(),'Age']=predictage  

    return data,rf  

data,rf=set_missing_age(data)  

Age_scale=StandardScaler().fit(data['Age'])  

data['Age_scaled']=StandardScaler().fit_transform(data['Age'].reshape(-1,1),Age_scale)  

train_x=data[['Sex_0','Sex_1','Embarked_0','Embarked_1','Embarked_2','Name_0','Name_1','Name_2','Pclass_scaled','Age_scaled','Fare_scaled']].as_matrix()  

train_y=data['Survived'].as_matrix()  

完成了我們的數(shù)據(jù)預(yù)處理和特征工程之后,就開始選擇合適的機(jī)器學(xué)習(xí)模型來進(jìn)行學(xué)習(xí)就ok了。

這很顯然是個分類問題,那么我們現(xiàn)在可以的選擇有邏輯回歸(一個名字叫回歸卻干著分類器的活的家伙),決策樹以及決策樹提升的一些算法(包括什么GDBT,AdaBoost,RandomForest等等),還有SVC,甚至聚類算法我們都可以試試……不過呢,花板子我們就不玩了,這里我們就選擇邏輯回歸,支持向量分類器,隨機(jī)森林分類器和梯度提升分類器來做一下,看看它們在訓(xùn)練集上的表現(xiàn)如何:

#模型構(gòu)造  

from sklearn.model_selection import train_test_split  

from sklearn.linear_model import LogisticRegression  

x_tr,x_te,y_tr,y_te=train_test_split(train_x,train_y,test_size=0.3,random_state=0)  

lr=LogisticRegression(C=1.0,tol=1e-6)  

lr.fit(x_tr,y_tr)  

print lr.score(x_te,y_te)  

from sklearn.svm import SVC  

svc=SVC(C=2, kernel='rbf', decision_function_shape='ovo')  

svc.fit(x_tr,y_tr)  

print svc.score(x_te,y_te)  

from sklearn.ensemble import RandomForestClassifier  

randomf=RandomForestClassifier(n_estimators=500,max_depth=5,random_state=0)  

randomf.fit(x_tr,y_tr)  

print randomf.score(x_te,y_te)  

from sklearn.ensemble import GradientBoostingClassifier  

gdbt=GradientBoostingClassifier(n_estimators=600,max_depth=5,random_state=0)  

gdbt.fit(x_tr,y_tr)  

print gdbt.score(x_te,y_te)  

輸出的結(jié)果為

0.783582089552

0.832089552239

0.824626865672

0.813432835821

我們可以看出SVC的效果最好,當(dāng)然這有一定的隨機(jī)性在里面,那我們就改變一下劃分訓(xùn)練集和測試集的種子,看看結(jié)果是否會發(fā)生變化,將Random_state的值改為1,輸出為

0.768656716418

0.787313432836

0.779850746269

0.768656716418

整體的正確率都發(fā)生了下降,但SVC的效果依然是做好的,所以我們不妨用SVC做一個結(jié)果先提交了看看正確率如何。那要想用這個模型進(jìn)行預(yù)測,那我們要對測試集的數(shù)據(jù)做和訓(xùn)練集數(shù)據(jù)同樣的事兒,包括補(bǔ)全無效值,預(yù)測年齡,one-hot編碼以及歸一化等等,只有這樣我們的訓(xùn)練模型才能最大限度的發(fā)揮它的作用。完成預(yù)測之后,我們要將對應(yīng)的ID和預(yù)測結(jié)果寫入一個csv文件提交,實(shí)現(xiàn)的代碼如下:

#預(yù)測數(shù)據(jù)  

data_test=pd.read_csv('test.csv')  

data_test.drop(['Ticket'],axis=1,inplace=True)  

data_test.loc[data_test.Embarked.isnull(),'Embarked']='S'  

Sex_label_test=le_sex.transform(data_test['Sex'])  

Sex_ohe_test=ohe_sex.transform(Sex_label_test.reshape(-1,1))  

Embarked_label_test=le_embarked.transform(data_test['Embarked'])  

Embarked_ohe_test=ohe_embarked.transform(Embarked_label_test.reshape(-1,1))  

data_test['Name']=data_test['Name'].map(lambda x:replace_name(x))  

Name_label_test=le_name.transform(data_test['Name'])  

Name_ohe_test=ohe_name.transform(Name_label_test.reshape(-1,1))  

data_test['Sex_0']=Sex_ohe_test[:,0]  

data_test['Sex_1']=Sex_ohe_test[:,1]  

data_test['Embarked_0']=Embarked_ohe_test[:,0]  

data_test['Embarked_1']=Embarked_ohe_test[:,1]  

data_test['Embarked_2']=Embarked_ohe_test[:,2]  

data_test['Name_0']=Name_ohe_test[:,0]  

data_test['Name_1']=Name_ohe_test[:,1]  

data_test['Name_2']=Name_ohe_test[:,2]  

data_test['Pclass_scaled']=StandardScaler().fit_transform(data_test['Pclass'].reshape(-1,1),Pclass_scale)  

data_test.loc[data_test.Fare.isnull(),'Fare']=0  

data_test['Fare_scaled']=StandardScaler().fit_transform(data_test['Fare'].reshape(-1,1),Fare_scale)  

data_test['SibSp_scaled']=StandardScaler().fit_transform(data_test['SibSp'].reshape(-1,1),SibSp_scale)  

data_test['Parch_scaled']=StandardScaler().fit_transform(data_test['Parch'].reshape(-1,1),Parch_scale)  

train_test=data_test[['Age','SibSp_scaled','Parch_scaled','Name_0','Name_1','Name_2','Sex_0','Sex_1']]  

unknown_age_test=train_test[train_test.Age.isnull()].as_matrix()  

x_test=unknown_age_test[:,1:]  

predictage=rf.predict(x_test)  

data_test.loc[data_test.Age.isnull(),'Age']=predictage  

data_test['Age_scaled']=StandardScaler().fit_transform(data_test['Age'].reshape(-1,1),Age_scale)  

test_x=data_test[['Sex_0','Sex_1','Embarked_0','Embarked_1','Embarked_2','Name_0','Name_1','Name_2','Pclass_scaled','Age_scaled','Fare_scaled']].as_matrix()  

predictions=model.predict(test_x).astype(np.int32)  

result=pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(),'Survived':predictions})  

result.to_csv('svc.csv',index=False)  

將結(jié)果提交到Kaggle的網(wǎng)站之后,我們發(fā)現(xiàn)我們的準(zhǔn)確率是79.904%,居然已經(jīng)進(jìn)了20%了,還是蠻順利的嘛,那么如何繼續(xù)提升我們的成績呢?最有效的方法莫過于構(gòu)建新的特征,尋找更有效的特征永遠(yuǎn)是提升正確率的王道。當(dāng)然了,也有一些簡單的辦法有可能能幫助我們提高成績,那就是三個臭皮匠頂個諸葛亮。我們選擇幾個相關(guān)性不是很大的分類器,用它們預(yù)測的結(jié)果進(jìn)行投票,往往一定程度上也能提高我們的成績,比如下面這種做法:

from sklearn.ensemble import VotingClassifier  

model=VotingClassifier(estimators=[('lr',lr),('svc',svc),('rf',randomf),('GDBT',gdbt)],voting='hard',weights=[0.5,1.5,0.6,0.6])  

model.fit(x_tr,y_tr)  

print model.score(x_te,y_te)  

輸出為:

0.860830527497

測試集上的表現(xiàn)可真棒啊?。。∵@一下很大的鼓舞了我的信心,所以趕緊用這個模型做個結(jié)果提交一下看看。

結(jié)果,正確率變成了78.649%,正確率下降了,整段垮掉?。?!前面說的那么有模有樣,結(jié)果被無情的現(xiàn)實(shí)狠甩一記耳光啊……

不過最重要的還是這個思路,比如你可以和你的小伙伴各做一個模型,你們構(gòu)建模型的思路肯定不一樣啊,那么模型的相關(guān)性比較低,這樣組合起來提升效果應(yīng)該比較明顯,我就強(qiáng)行這樣圓一下吧。

其實(shí)我相信到這里大家也看出來了,做的這個模型我們還是把絕大數(shù)的時間花在了模型的構(gòu)造上了,真正模型訓(xùn)練啥的并沒有占據(jù)我們太多的時間。所以還是那句話,數(shù)據(jù)和特征決定了機(jī)器學(xué)習(xí)的上限,而模型和方法只能是逼近這個上限,好好做特征吧。

TensorFlow & 神經(jīng)網(wǎng)絡(luò)算法高級應(yīng)用班” 要開課啦!

從初級到高級,理論 + 實(shí)戰(zhàn),一站式深度了解 TensorFlow!

本課程面向深度學(xué)習(xí)開發(fā)者,講授如何利用 TensorFlow 解決圖像識別、文本分析等具體問題。課程跨度為 10 周,將從 TensorFlow 的原理與基礎(chǔ)實(shí)戰(zhàn)技巧開始,一步步教授學(xué)員如何在 TensorFlow 上搭建 CNN、自編碼、RNN、GAN 等模型,并最終掌握一整套基于 TensorFlow 做深度學(xué)習(xí)開發(fā)的專業(yè)技能。

兩名授課老師佟達(dá)、白發(fā)川身為 ThoughtWorks 的資深技術(shù)專家,具有豐富的大數(shù)據(jù)平臺搭建、深度學(xué)習(xí)系統(tǒng)開發(fā)項目經(jīng)驗(yàn)。

時間:每周二、四晚 20:00-21:00

開課時長:總學(xué)時 20 小時,分 10 周完成,每周 2 次,每次 1 小時

線上授課地址:http://www.mooc.ai/

雷鋒網(wǎng)相關(guān)閱讀:

加入 Kaggle 大數(shù)據(jù)競賽,總共分幾步?

詳解 Kaggle 房價預(yù)測競賽優(yōu)勝方案:用 Python 進(jìn)行全面數(shù)據(jù)探索

從 Kaggle 困局,看國內(nèi)數(shù)據(jù)競賽平臺如何突圍

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。

一個實(shí)例告訴你:Kaggle 數(shù)據(jù)競賽都有哪些套路

分享:
相關(guān)文章

編輯

聚焦數(shù)據(jù)科學(xué),連接 AI 開發(fā)者。更多精彩內(nèi)容,請訪問:yanxishe.com
當(dāng)月熱門文章
最新文章
請?zhí)顚懮暾埲速Y料
姓名
電話
郵箱
微信號
作品鏈接
個人簡介
為了您的賬戶安全,請驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號信息
您的賬號已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說