日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

kaggle房价预测特征意思_机器学习-kaggle泰坦尼克生存预测(一)-数据清洗与特征构建...

發布時間:2025/3/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 kaggle房价预测特征意思_机器学习-kaggle泰坦尼克生存预测(一)-数据清洗与特征构建... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、背景:

1.1 關于kaggle:

谷歌旗下的 Kaggle 是一個數據建模和數據分析競賽平臺。該平臺是當下最流行的數據科研賽事平臺,其組織的賽事受到全球數據科學愛好者追捧。 如果學生能夠在該平臺的一些比賽中獲得較好的名次,不僅可以贏得大量的獎金,還可以收獲 Google 、 Amazon 等知名互聯網公司的面試邀請。

1.2 關于泰坦尼克災難(Titanic: Machine Learning from Disaster)

以下是關于泰坦尼克生存預測的說明,在‘data’處可以點擊下載預測數據。

1.3泰坦尼克問題的背景:

  • 這是一個大家都非常熟悉的故事,泰坦尼克號郵輪航行途中不行撞擊冰山,導致船翻了,在救援的過程中,船長的要求是女士與小孩優先上游艇,所以最終是否存活并不是隨機事件,而是有一定的決定因素的。
  • 訓練和測試數據是一些乘客的個人信息以及存貨狀況,要嘗試根據它生成合適的模型并預測其他人的生存狀況
  • 這是一個二分類的問題,在監督模型中,邏輯回歸,支持向量機,決策樹,隨機森林,KNN等算法都夠進行處理,本篇文章中,主要內容還是處理數據構建特征,對于模型的選擇與調優將放到后續的文章中。

2、 怎么做?

  • 手把手教程馬上就來,先來兩條我看到的,覺得很重要的經驗:
  • 印象中Andrew Ng老師似乎在coursera上說過,應用機器學習,千萬不要一上來就試圖做到完美,先擼一個baseline的model出來,再進行后續的分析步驟,一步步提高,所謂后續步驟可能包括『分析model現在的狀態(欠/過擬合),分析我們使用的feature的作用大小,進行feature selection,以及我們模型下的bad case和產生的原因』等等。
  • Kaggle上的大神們,也分享過一些experience,說幾條我記得的哈:
  • 對數據的認識太重要了!
  • 數據中的特殊點/離群點的分析和處理太重要了!
  • 特征工程(feature engineering)太重要了!在很多Kaggle的場景下,甚至比model本身還要重要
  • 要做模型融合(model ensemble)

3、初步的數據認知

官方提供的數據文件一共有三個,一個是帶標簽的訓練數據,一個是不帶標簽的預測數據,第三個是結果的提交格式。下面就將訓練數據與預測數據都讀進來,并合并查看。在這多說一句,將訓練數據與預測數據合并進行統一的清洗,可以減少許多的重復性工作

import pandas as pdimport matplotlib.pyplot as pltimport numpy as nptrain=pd.read_excel(r'E:huawei我的作品泰坦尼數據rain.xlsx')test=pd.read_excel(r'E:huawei我的作品泰坦尼數據est.xlsx')data=pd.concat([train,test]) #將訓練數據與預測數據進行合并data_1=data.copy()

如下圖為數據結果:

Age,Fare,Parch,Pclass,SibSp等字段為數值型數據,Cabin,Embarked,Name,Sex,Ticket等字段為字符型數據

對數據進行初步的了解

data_describe=data_1.describe() #查看數值型數據的統計指標

從上邊的數據我們可以得到什么樣的結論呢

  • 乘客的平均年齡是29歲
  • 平均票價是33.9,最高票價是512
  • 二等艙、三等艙要比一等艙的乘客多很多
  • 約有38.3%的乘客獲救了
  • 以上計算都忽略掉缺失值

各字段缺失情況如下

data_null=data_1.isnull().sum() #查看缺失值

初步假設:

  • Cabin字段的缺失值最多,將近80%的記錄都為空,假設缺失值有實際意義,在處理時將空值作為新的一類
  • Age字段缺失值占比20%,也不能建單的通過平均值/中位數/眾數來填充,填充的方法可以采用對不同乘客屬性的中位數進行填充。
  • Embarked與Fare的缺失值較少,簡單的中位數/平均數填充即ok

乘客的各屬性分布以及與獲救結果的關聯統計

分別查看性別,倉位等級,上船港口以及倉位編號與是否生存的關系

fig=plt.figure(figsize=(15,10))###Sex與Survived關系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關系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)

結論:

  • 圖一,性別與生存的有著強關系,在生存的乘客中,女性的比例明顯要高很多。
  • 圖二,倉位等級與生存有著強關系,一等艙的乘客生存的概率明顯要高很多。
  • 圖三、登錄港口與生存有著一定的關系,并不是很明顯,在生存的乘客中,C港口登錄的乘客要多一些。
  • 圖四、A~G的倉位中,生存的概率是差不多的,而N倉的生存率明顯會低很多。

年齡與船票價格的的概率密度曲線

結論:

  • 圖一、死亡的乘客中低Fare的比例明顯要比生存的乘客比例高
  • 圖二、死亡的乘客中20-30歲的比例要比生存的乘客高,在0-10歲的乘客明顯生存概率要高一些

4、缺失值填充

除去要預測的Survived字段,一共有四個字段有缺失值,下邊將按照缺失值從少到多的順序來填充

4.1 Fare字段的缺失值填充

Fare只有一個記錄的缺失值

Fare的整體分布:Fare主要分布在100以下,如果用全局平均數或中位數填充,受高于100值的影響會比較大,所以我們看一下,能不能從其他的字段中找出一點相關性

在這一條記錄中,Cabin的字段是缺失的,Pclass的字段是有的,那么先用Pclass=3的Fare的中位數填充

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港口登錄的占比要高很多,同時,缺失的這兩條記錄都是生存者,那么久很簡單了額,直接用C來填充缺失值

data_1['Embarked'].fillna('C',inplace=True)

4.3 最簡單的兩個缺失值填充已經完成了,下面要來填充年齡的缺失值了

由于年齡的缺失值相對較多,也不能直接使用全局均值/平均數來填充,跟Fare字段的填充邏輯一致,先在現有數據中尋找與Age相關的字段,在現有字段中與年齡最相關的就是Name中的title了,先在決定使用不同title對應的年齡的中位數進行填充

由下圖的Title-Age的密度曲線可以看出,除了‘Miss’外,其他的各個title的年齡密度曲線都比較集中,將‘Miss’中Parch是否大于零劃分為兩類,繼續觀察密度曲線,如右圖。現在來看Miss的年齡目睹曲線將會平滑一些。

##Age字段缺失值填充def name(x): #先對Name字段進行處理,構造解析title函數 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的年齡中位數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)##對miss中age的缺失值進行填充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的中位數分別為25.5與9.5

4.4 現在對最后一個缺失值Cabin進行填充

Cabin的數據比較特殊,字符類型,分類也比較多,經觀察,倉位的首字母是可以提取出來作為特征使用的。Cabin空值較多,用N來代替空值,空值的產生應該是這一部分人本身就沒有倉位導致的。

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)

倉位的分類有點過多,且各倉位的存活率是有相似性的,將A,G倉歸為A類,C,F倉歸為C類,將B,E,D倉歸為B類,T倉歸為N類。其中歸為N類的記錄有點多,看看能不能再優化一下。下面看一下各倉位類型和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倉是有一部分凸起的,且部分高價票的乘客也是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'

優化后的曲線

5、構造新特征

以上已經將各變量的缺失值填充完畢,現在就來到了最考驗創造力的時刻:構造新特征。在上文中,我們還有幾個變量沒有用到:Name,Parch,SibSp等字段。

5.1Name字段清洗

思路:現有title分類過多,對title進行分類,聚類的規則就是按照title的實際意義進行分類,分類規則如下:

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 構造‘兒童’與‘母親’字段

將年齡<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']=1

5.4 構造高票價的字段

將Fare大于高于200的構造一個新字段

data_1['high_fare']=0data_1.loc[data_1['Fare']>200,'high_fare']=1

6 特征已經構造完了,最后一步需要將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 數據基本已經清洗完了,還有最后一步,數值型數據的規范化

在選擇分類器的時候會有一部分分類器是基于距離的,所以數值型數據需要進行標準化,一方面能夠加快收斂的速度,另一方面在計算距離的避免不同量綱帶來的距離不統一的問題

在此對‘Age’,‘Family_size’采用最大最小化歸一,由于Fare的值分布不均勻,采用z-score規范化

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()

總結

以上是生活随笔為你收集整理的kaggle房价预测特征意思_机器学习-kaggle泰坦尼克生存预测(一)-数据清洗与特征构建...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。