kaggle房价预测特征意思_机器学习-kaggle泰坦尼克生存预测(一)-数据清洗与特征构建...
1、背景:
1.1 關(guān)于kaggle:
谷歌旗下的 Kaggle 是一個(gè)數(shù)據(jù)建模和數(shù)據(jù)分析競賽平臺(tái)。該平臺(tái)是當(dāng)下最流行的數(shù)據(jù)科研賽事平臺(tái),其組織的賽事受到全球數(shù)據(jù)科學(xué)愛好者追捧。 如果學(xué)生能夠在該平臺(tái)的一些比賽中獲得較好的名次,不僅可以贏得大量的獎(jiǎng)金,還可以收獲 Google 、 Amazon 等知名互聯(lián)網(wǎng)公司的面試邀請(qǐng)。
1.2 關(guān)于泰坦尼克災(zāi)難(Titanic: Machine Learning from Disaster)
以下是關(guān)于泰坦尼克生存預(yù)測的說明,在‘data’處可以點(diǎn)擊下載預(yù)測數(shù)據(jù)。
1.3泰坦尼克問題的背景:
- 這是一個(gè)大家都非常熟悉的故事,泰坦尼克號(hào)郵輪航行途中不行撞擊冰山,導(dǎo)致船翻了,在救援的過程中,船長的要求是女士與小孩優(yōu)先上游艇,所以最終是否存活并不是隨機(jī)事件,而是有一定的決定因素的。
- 訓(xùn)練和測試數(shù)據(jù)是一些乘客的個(gè)人信息以及存貨狀況,要嘗試根據(jù)它生成合適的模型并預(yù)測其他人的生存狀況
- 這是一個(gè)二分類的問題,在監(jiān)督模型中,邏輯回歸,支持向量機(jī),決策樹,隨機(jī)森林,KNN等算法都?jí)蜻M(jìn)行處理,本篇文章中,主要內(nèi)容還是處理數(shù)據(jù)構(gòu)建特征,對(duì)于模型的選擇與調(diào)優(yōu)將放到后續(xù)的文章中。
2、 怎么做?
- 手把手教程馬上就來,先來兩條我看到的,覺得很重要的經(jīng)驗(yàn):
- 印象中Andrew Ng老師似乎在coursera上說過,應(yīng)用機(jī)器學(xué)習(xí),千萬不要一上來就試圖做到完美,先擼一個(gè)baseline的model出來,再進(jìn)行后續(xù)的分析步驟,一步步提高,所謂后續(xù)步驟可能包括『分析model現(xiàn)在的狀態(tài)(欠/過擬合),分析我們使用的feature的作用大小,進(jìn)行feature selection,以及我們模型下的bad case和產(chǎn)生的原因』等等。
- Kaggle上的大神們,也分享過一些experience,說幾條我記得的哈:
- 對(duì)數(shù)據(jù)的認(rèn)識(shí)太重要了!
- 數(shù)據(jù)中的特殊點(diǎn)/離群點(diǎn)的分析和處理太重要了!
- 特征工程(feature engineering)太重要了!在很多Kaggle的場景下,甚至比model本身還要重要
- 要做模型融合(model ensemble)
3、初步的數(shù)據(jù)認(rèn)知
官方提供的數(shù)據(jù)文件一共有三個(gè),一個(gè)是帶標(biāo)簽的訓(xùn)練數(shù)據(jù),一個(gè)是不帶標(biāo)簽的預(yù)測數(shù)據(jù),第三個(gè)是結(jié)果的提交格式。下面就將訓(xùn)練數(shù)據(jù)與預(yù)測數(shù)據(jù)都讀進(jìn)來,并合并查看。在這多說一句,將訓(xùn)練數(shù)據(jù)與預(yù)測數(shù)據(jù)合并進(jìn)行統(tǒng)一的清洗,可以減少許多的重復(fù)性工作
import pandas as pdimport matplotlib.pyplot as pltimport numpy as nptrain=pd.read_excel(r'E:huawei我的作品泰坦尼數(shù)據(jù)rain.xlsx')test=pd.read_excel(r'E:huawei我的作品泰坦尼數(shù)據(jù)est.xlsx')data=pd.concat([train,test]) #將訓(xùn)練數(shù)據(jù)與預(yù)測數(shù)據(jù)進(jìn)行合并data_1=data.copy()如下圖為數(shù)據(jù)結(jié)果:
Age,Fare,Parch,Pclass,SibSp等字段為數(shù)值型數(shù)據(jù),Cabin,Embarked,Name,Sex,Ticket等字段為字符型數(shù)據(jù)
對(duì)數(shù)據(jù)進(jìn)行初步的了解
data_describe=data_1.describe() #查看數(shù)值型數(shù)據(jù)的統(tǒng)計(jì)指標(biāo)從上邊的數(shù)據(jù)我們可以得到什么樣的結(jié)論呢
- 乘客的平均年齡是29歲
- 平均票價(jià)是33.9,最高票價(jià)是512
- 二等艙、三等艙要比一等艙的乘客多很多
- 約有38.3%的乘客獲救了
- 以上計(jì)算都忽略掉缺失值
各字段缺失情況如下
data_null=data_1.isnull().sum() #查看缺失值初步假設(shè):
- Cabin字段的缺失值最多,將近80%的記錄都為空,假設(shè)缺失值有實(shí)際意義,在處理時(shí)將空值作為新的一類
- Age字段缺失值占比20%,也不能建單的通過平均值/中位數(shù)/眾數(shù)來填充,填充的方法可以采用對(duì)不同乘客屬性的中位數(shù)進(jìn)行填充。
- Embarked與Fare的缺失值較少,簡單的中位數(shù)/平均數(shù)填充即ok
乘客的各屬性分布以及與獲救結(jié)果的關(guān)聯(lián)統(tǒng)計(jì)
分別查看性別,倉位等級(jí),上船港口以及倉位編號(hào)與是否生存的關(guān)系
fig=plt.figure(figsize=(15,10))###Sex與Survived關(guān)系axes_1=fig.add_subplot(2,2,1)sur_sex=pd.pivot_table(train,index='Survived',columns='Sex',values='PassengerId',aggfunc='count')sur_sex.plot(kind='bar',stacked=True,ax=axes_1)plt.title('Sex-Survived')##pclass與是否存活svi_p=pd.pivot_table(train,index='Survived',columns='Pclass',values='PassengerId',aggfunc='count')axes_2=fig.add_subplot(2,2,2)svi_p.plot(kind='bar',stacked=True,ax=axes_2)plt.title('Pclass-Survived')###embarked與是否存活axes_3=fig.add_subplot(2,2,3)sur_emb=pd.pivot_table(train,index='Survived',columns='Embarked',values='PassengerId',aggfunc='count')sur_emb.plot(kind='bar',stacked=True,ax=axes_3)plt.title('Embarked-Survived')##cabin與survived關(guān)系axes_6=fig.add_subplot(2,2,4)train['Cabin'].fillna('N',inplace=True)train['Cabin_c']=train['Cabin'].map(lambda x : x[0])sur_ca=pd.pivot_table(train,index='Survived',columns='Cabin_c',values='PassengerId',aggfunc='count')sur_ca.T.plot(kind='bar',stacked=True,ax=axes_6)結(jié)論:
- 圖一,性別與生存的有著強(qiáng)關(guān)系,在生存的乘客中,女性的比例明顯要高很多。
- 圖二,倉位等級(jí)與生存有著強(qiáng)關(guān)系,一等艙的乘客生存的概率明顯要高很多。
- 圖三、登錄港口與生存有著一定的關(guān)系,并不是很明顯,在生存的乘客中,C港口登錄的乘客要多一些。
- 圖四、A~G的倉位中,生存的概率是差不多的,而N倉的生存率明顯會(huì)低很多。
年齡與船票價(jià)格的的概率密度曲線
結(jié)論:
- 圖一、死亡的乘客中低Fare的比例明顯要比生存的乘客比例高
- 圖二、死亡的乘客中20-30歲的比例要比生存的乘客高,在0-10歲的乘客明顯生存概率要高一些
4、缺失值填充
除去要預(yù)測的Survived字段,一共有四個(gè)字段有缺失值,下邊將按照缺失值從少到多的順序來填充
4.1 Fare字段的缺失值填充
Fare只有一個(gè)記錄的缺失值
Fare的整體分布:Fare主要分布在100以下,如果用全局平均數(shù)或中位數(shù)填充,受高于100值的影響會(huì)比較大,所以我們看一下,能不能從其他的字段中找出一點(diǎn)相關(guān)性
在這一條記錄中,Cabin的字段是缺失的,Pclass的字段是有的,那么先用Pclass=3的Fare的中位數(shù)填充
data_fare=pd.pivot_table(data_1,index='Pclass',values='Fare',aggfunc='median')data_1['Fare'].fillna(data_fare.loc[3,'fare'],inplace=True)4.2 填充Embarked的缺失值
在Embarked-Survived的圖中可以看出,相比未生存下來的人,生存者中C港口登錄的占比要高很多,同時(shí),缺失的這兩條記錄都是生存者,那么久很簡單了額,直接用C來填充缺失值
data_1['Embarked'].fillna('C',inplace=True)4.3 最簡單的兩個(gè)缺失值填充已經(jīng)完成了,下面要來填充年齡的缺失值了
由于年齡的缺失值相對(duì)較多,也不能直接使用全局均值/平均數(shù)來填充,跟Fare字段的填充邏輯一致,先在現(xiàn)有數(shù)據(jù)中尋找與Age相關(guān)的字段,在現(xiàn)有字段中與年齡最相關(guān)的就是Name中的title了,先在決定使用不同title對(duì)應(yīng)的年齡的中位數(shù)進(jìn)行填充
由下圖的Title-Age的密度曲線可以看出,除了‘Miss’外,其他的各個(gè)title的年齡密度曲線都比較集中,將‘Miss’中Parch是否大于零劃分為兩類,繼續(xù)觀察密度曲線,如右圖。現(xiàn)在來看Miss的年齡目睹曲線將會(huì)平滑一些。
##Age字段缺失值填充def name(x): #先對(duì)Name字段進(jìn)行處理,構(gòu)造解析title函數(shù) str_1=x.split(',')[1] str_2=str_1.split('.')[0] str_3=str_2.strip() return str_3data_1['title']=data_1['Name'].map(lambda x: name(x))fig=plt.figure(figsize=(15,7))axes=fig.add_subplot(1,2,1)data_1.loc[data_1['title']=='Mr','Age'].plot(kind='kde',ax=axes)data_1.loc[data_1['title']=='Miss','Age'].plot(kind='kde',ax=axes)data_1.loc[data_1['title']=='Mrs','Age'].plot(kind='kde',ax=axes)data_1.loc[data_1['title']=='Master','Age'].plot(kind='kde',ax=axes)data_1.loc[data_1['title']=='Dr','Age'].plot(kind='kde',ax=axes)plt.legend(('Mr','Miss','Mrs','Master','Dr'),loc='best')plt.title('Title-Age')plt.xlabel('Age')axes_2=fig.add_subplot(1,2,2)data_1.loc[(data_1['title']=='Miss')&(data_1['Parch']>0),'Age'].plot(kind='kde',ax=axes_2)data_1.loc[(data_1['title']=='Miss')&(data_1['Parch']==0),'Age'].plot(kind='kde',ax=axes_2)plt.legend(('Parch>0','Parch=0'))plt.title('Miss/Parch-Age')plt.xlabel('Age')#先輸出除去'Miss'字段的各Title的年齡中位數(shù)data_age=pd.pivot_table(data_1,index='title',values='Age',aggfunc='median')data_age.drop(['Miss'],axis=0,inplace=True)title_sex=data_age.to_dict()['Age']data_1.set_index('title',inplace=True)data_1['Age'].fillna(title_sex,inplace=True)data_1.reset_index(inplace=True)##對(duì)miss中age的缺失值進(jìn)行填充data_1['Parch>0']=0data_1.loc[(data_1['title']=='Miss')&(data_1['Parch']>0),'Parch>0']=1miss_age=pd.pivot_table(data_1.loc[data_1['title']=='Miss'],index='title',values='Age',columns='Parch>0',aggfunc='median')data_1.loc[(data_1['title']=='Miss')&(data_1['Parch']>0)]=9.5data_1['Age'].fillna(25.5,inplace=True)Miss分Parch是否大于零的Age的中位數(shù)分別為25.5與9.5
4.4 現(xiàn)在對(duì)最后一個(gè)缺失值Cabin進(jìn)行填充
Cabin的數(shù)據(jù)比較特殊,字符類型,分類也比較多,經(jīng)觀察,倉位的首字母是可以提取出來作為特征使用的。Cabin空值較多,用N來代替空值,空值的產(chǎn)生應(yīng)該是這一部分人本身就沒有倉位導(dǎo)致的。
data_1['Cabin'].fillna('N',inplace=True)data_1['cabin_1']=data_1['Cabin'].map(lambda x : x[0])cabin_s=pd.pivot_table(data_1,index='cabin_1',columns='Survived',values='PassengerId',aggfunc='count')cabin_s['存活率']=cabin_s[1.0]/(cabin_s[0.0]+cabin_s[1.0])data_1['cabin_1'].replace({'G':'A','F':'C','E':'B','D':'B','T':'N'},inplace=True)倉位的分類有點(diǎn)過多,且各倉位的存活率是有相似性的,將A,G倉歸為A類,C,F倉歸為C類,將B,E,D倉歸為B類,T倉歸為N類。其中歸為N類的記錄有點(diǎn)多,看看能不能再優(yōu)化一下。下面看一下各倉位類型和Fare的密度曲線。
fig=plt.figure(figsize=(8,8))axes=fig.add_subplot(1,1,1)data_1.loc[data_1['cabin_1']=='A','Fare'].plot(kind='kde',ax=axes)data_1.loc[data_1['cabin_1']=='B','Fare'].plot(kind='kde',ax=axes)data_1.loc[data_1['cabin_1']=='C','Fare'].plot(kind='kde',ax=axes)data_1.loc[data_1['cabin_1']=='N','Fare'].plot(kind='kde',ax=axes)plt.legend(('A','B','C','N'),loc='best')通過曲線可以看出,填充的N倉是有一部分凸起的,且部分高價(jià)票的乘客也是N倉的,現(xiàn)在將N倉中Fare>240的改為B倉,Fare>80的改為C倉。
data_1.loc[(data_1['cabin_1']=='N')&(data_1['Fare']>240),'cabin_1']='B'data_1.loc[(data_1['cabin_1']=='N')&(data_1['Fare']>80),'cabin_1']='B'優(yōu)化后的曲線
5、構(gòu)造新特征
以上已經(jīng)將各變量的缺失值填充完畢,現(xiàn)在就來到了最考驗(yàn)創(chuàng)造力的時(shí)刻:構(gòu)造新特征。在上文中,我們還有幾個(gè)變量沒有用到:Name,Parch,SibSp等字段。
5.1Name字段清洗
思路:現(xiàn)有title分類過多,對(duì)title進(jìn)行分類,聚類的規(guī)則就是按照title的實(shí)際意義進(jìn)行分類,分類規(guī)則如下:
title_dict={'Mlle':'Miss','Ms':'Mrs','Dr':'Officer','Dona':'Royalty', 'Lady':'Royalty','Mme':'Mrs','the Countess':'Royalty', 'Rev':'Officer','Col':'Officer','Major':'Officer','Capt':'Officer', 'Don':'Royalty','Jonkheer':'Royalty','Sir':'Royalty'}data_1['title'].replace(title_dict,inplace=True)5.2 Parch與SibSp字段的清洗
data_1['family_size']=data_1['Parch']+data_1['SibSp']+1data_1['family_size'].value_counts()def f_size(x): if x==1: a='single' elif x<=3 and x>=2: a='small' elif x<=6: a='media' else: a='large' return adata_1['family_size_']=data_1['family_size'].map(lambda x :f_size(x))5.3 構(gòu)造‘兒童’與‘母親’字段
將年齡<12的作為兒童,將title=Mrs,parch>1的作為母親
data_1['child']=0data_1.loc[data_1['Age']<12,'child']=1data_1['mother']=0data_1.loc[(data_1['Parch']>1)&(data_1['title']=='Mrs'),'mother']=15.4 構(gòu)造高票價(jià)的字段
將Fare大于高于200的構(gòu)造一個(gè)新字段
data_1['high_fare']=0data_1.loc[data_1['Fare']>200,'high_fare']=16 特征已經(jīng)構(gòu)造完了,最后一步需要將one-hot編碼了
finall_df=data_1[['PassengerId','Survived','Age','Fare','family_size','child', 'mother','high_fare']].copy()title_df=pd.get_dummies(data_1['title'],prefix='title')embarked_df=pd.get_dummies(data_1['Embarked'],prefix='Embarked')pclass_df=pd.get_dummies(data_1['Pclass'],prefix='pclass')sex_df=pd.get_dummies(data_1['Sex'],prefix='sex')cabin_df=pd.get_dummies(data_1['cabin_1'],prefix='cabin')family_df=pd.get_dummies(data_1['family_size_'],prefix='family')finall_df=pd.concat([finall_df,title_df,embarked_df,pclass_df,sex_df,cabin_df,family_df],axis=1)7 數(shù)據(jù)基本已經(jīng)清洗完了,還有最后一步,數(shù)值型數(shù)據(jù)的規(guī)范化
在選擇分類器的時(shí)候會(huì)有一部分分類器是基于距離的,所以數(shù)值型數(shù)據(jù)需要進(jìn)行標(biāo)準(zhǔn)化,一方面能夠加快收斂的速度,另一方面在計(jì)算距離的避免不同量綱帶來的距離不統(tǒng)一的問題
在此對(duì)‘Age’,‘Family_size’采用最大最小化歸一,由于Fare的值分布不均勻,采用z-score規(guī)范化
finall_df['Age']=(finall_df['Age']-finall_df['Age'].min())/(finall_df['Age'].max()-finall_df['Age'].min())finall_df['family_size']=(finall_df['family_size']-finall_df['family_size'].min())/(finall_df['family_size'].max()-finall_df['family_size'].min())x_=finall_df['Fare'].max()finall_df['Fare']=finall_df['Fare'].map(lambda x: math.log(x+1,10)/math.log(x_,10))finall_df['cabin']=finall_df['cabin_n']/finall_df['cabin_n'].max()總結(jié)
以上是生活随笔為你收集整理的kaggle房价预测特征意思_机器学习-kaggle泰坦尼克生存预测(一)-数据清洗与特征构建...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: split函数python统计英文单词_
- 下一篇: python搭建selenium_自动化