<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【機(jī)器學(xué)習(xí)】kaggle實(shí)戰(zhàn):6大回歸模型預(yù)測(cè)航班票價(jià)

          共 8853字,需瀏覽 18分鐘

           ·

          2022-03-15 15:50

          公眾號(hào):尤而小屋
          作者:Peter
          編輯:Peter

          今天給大家?guī)?lái)一篇新的kaggle案例文章:基于6大回歸模型預(yù)測(cè)航空公司機(jī)票的價(jià)格。

          這篇文章涉及到的知識(shí)點(diǎn)會(huì)比較多,關(guān)鍵是數(shù)據(jù)預(yù)處理特征工程部分:

          原notebook的學(xué)習(xí)地址為:

          https://www.kaggle.com/anshigupta01/flight-price-prediction/notebook

          kaggle文章

          基于LSTM模型實(shí)現(xiàn)共享自行車需求預(yù)測(cè)

          6大監(jiān)督學(xué)習(xí)模型:毒蘑菇分類

          基于隨機(jī)森林模型的心臟病患者預(yù)測(cè)分類

          從統(tǒng)計(jì)和數(shù)據(jù)角度出發(fā),如何看待房?jī)r(jià)?

          Plotly+Seaborn+Folium可視化探索愛(ài)彼迎租房數(shù)據(jù)

          Plotly+Pandas+Sklearn:實(shí)現(xiàn)用戶聚類分群!

          7000字,利用Python分析泰坦尼克數(shù)據(jù)!

          導(dǎo)入庫(kù)

          數(shù)據(jù)基本信息

          先把數(shù)據(jù)導(dǎo)進(jìn)來(lái):

          df?=?pd.read_excel("data_air.xlsx")
          df.head()

          查看數(shù)據(jù)的基本信息,包含:數(shù)據(jù)形狀、字段類型等

          #?字段類型
          df.dtypes

          Airline????????????object
          Date_of_Journey????object
          Source?????????????object
          Destination????????object
          Route??????????????object
          Dep_Time???????????object
          Arrival_Time???????object
          Duration???????????object
          Total_Stops????????object
          Additional_Info????object
          Price???????????????int64
          dtype:?object
          ??
          #?全部字段
          columns?=?df.columns.tolist()
          columns

          ['Airline',
          ?'Date_of_Journey',
          ?'Source',
          ?'Destination',
          ?'Route',
          ?'Dep_Time',
          ?'Arrival_Time',
          ?'Duration',
          ?'Total_Stops',
          ?'Additional_Info',
          ?'Price']

          具體字段的中文含義:

          • Airline:不同類型的航空公司
          • Date_of_Journey:旅客的旅行開(kāi)始日期
          • Source:旅客出發(fā)地
          • Destination:旅客目的地
          • Route:航班路線
          • Dep_Time:出發(fā)時(shí)間
          • Arrival_Time:抵達(dá)時(shí)間
          • Duration:持續(xù)時(shí)間;指的是航班完成從出發(fā)到目的地的旅程的整個(gè)時(shí)間
          • Total_Stops:總共停留地
          • Additional_Info:其他信息,比如:食物、設(shè)備信息等
          • Price:整個(gè)旅程的航班票價(jià)

          希望可以理解中文含義,幫助進(jìn)行數(shù)據(jù)分析~



          數(shù)值型字段的描述統(tǒng)計(jì)信息,這里主要是針對(duì)Price字段:

          缺失值處理

          通過(guò)上面的缺失值檢查,我們看到有兩個(gè)字段是存在缺失值的,進(jìn)行可視化。

          missingno是一個(gè)可視化缺失值的庫(kù),方便使用,我們可以用pip install missingno 即可下載該庫(kù)

          import?missingno?as?mso
          mso.bar(df,color="blue")
          plt.show()

          缺失值刪除

          正常的字段是10683條,其中兩個(gè)字段是10682條;缺失值的占比很小,考慮直接刪除的數(shù)據(jù)


          時(shí)間相關(guān)字段處理

          時(shí)間處理

          1. 通過(guò)pd.to_datetime()直接將字符型的數(shù)據(jù)轉(zhuǎn)成時(shí)間類型的數(shù)據(jù)
          2. 通過(guò)dt.day或者df.month 直接獲取天或者月的信息
          #?將字段類型轉(zhuǎn)成時(shí)間相關(guān)類型

          def?change_to_datetime(col):
          ????df[col]?=?pd.to_datetime(df[col])

          對(duì)3個(gè)字段實(shí)施轉(zhuǎn)換:

          #?3個(gè)字段的轉(zhuǎn)換

          for?col?in?['Date_of_Journey','Dep_Time',?'Arrival_Time']:
          ????change_to_datetime(col)

          查看轉(zhuǎn)換之后的字段類型:

          df.dtypes
          Airline????????????????????object
          Date_of_Journey????datetime64[ns]
          Source?????????????????????object
          Destination????????????????object
          Route??????????????????????object
          Dep_Time???????????datetime64[ns]
          Arrival_Time???????datetime64[ns]
          Duration???????????????????object
          Total_Stops????????????????object
          Additional_Info????????????object
          Price???????????????????????int64
          dtype:?object

          提取天和月

          乘客旅程日期中(Date_of_Journey)單獨(dú)提取天和月,作為兩個(gè)字段

          df["day"]?=?df["Date_of_Journey"].dt.day
          df["month"]?=?df["Date_of_Journey"].dt.month
          df.head()

          最終生成了兩個(gè)新的字段:

          #?刪除字段
          df.drop('Date_of_Journey',?axis=1,?inplace=True)

          起飛時(shí)間和抵達(dá)時(shí)間處理

          主要提取兩個(gè)時(shí)間中的“小時(shí)”和“分鐘”信息;同時(shí)刪除原字段:

          分別調(diào)用函數(shù)來(lái)提取信息:

          extract_hour(df,'Dep_Time')
          extract_minute(df,'Dep_Time')
          drop_col(df,'Dep_Time')??#?刪除原字段
          extract_hour(df,'Arrival_Time')
          extract_minute(df,'Arrival_Time')
          drop_col(df,'Arrival_Time')
          df.head()

          航班持續(xù)時(shí)間duration

          1、將持續(xù)時(shí)間規(guī)范化處理,統(tǒng)一變成0h 1m

          #?#?原文方法

          #?duration=list(df['Duration'])

          #?for?i?in?range(len(duration)):
          #?????if?len(duration[i].split('?'))==2:
          #?????????pass
          #?????else:
          #?????????if?'h'?in?duration[i]:?
          #??????????????duration[i]=duration[i]?+?'?0m'?
          #?????????else:
          #??????????????duration[i]='0h?'+?duration[i]

          下面是個(gè)人版本寫(xiě)法:


          2、從Duration字段中提取小時(shí)和分鐘:

          df.drop("Duration",inplace=True,axis=1)

          3、字段類型轉(zhuǎn)化:查看dur_hour和dur_minute的字段類型變化

          字段編碼

          字段類型區(qū)分

          主要是區(qū)分object和非object類型的字段信息。

          1、針對(duì)字符型的字段

          column?=?[column?for?column?in?df.columns?if?df[column].dtype?==?"object"]
          column
          ['Airline',?'Source',?'Destination',?'Route',?'Total_Stops',?'Additional_Info']

          2、數(shù)值型(連續(xù)型)字段

          continuous_col?=?[column?for?column?in?df.columns?if?df[column].dtype?!=?"object"]
          continuous_col
          ['Price',
          ?'day',
          ?'month',
          ?'Dep_Time_hour',
          ?'Dep_Time_minute',
          ?'Arrival_Time_hour',
          ?'Arrival_Time_minute',
          ?'dur_hour',
          ?'dur_minute']

          2種編碼技術(shù)

          Nominal?data?--?Data?that?are?not?in?any?order?-->one?hot?encoding
          ordinal?data?--?Data?are?in?order?-->?labelEncoder
          • 標(biāo)稱數(shù)據(jù):沒(méi)有任何順序,使用獨(dú)熱編碼oneot encoding
          • 有序數(shù)據(jù):存在一定的順序,使用類型編碼labelEncoder

          生成標(biāo)稱型字段組成的數(shù)據(jù)


          不同字段編碼處理

          航空公司-Airline

          1、不同航空公司的數(shù)量統(tǒng)計(jì):

          2、查看航空公司與價(jià)格關(guān)系

          plt.figure(figsize=(15,8))

          sns.boxplot(x="Airline",
          ????????????y="Price",
          ????????????data=df.sort_values('Price',ascending=False)
          ???????????)

          plt.show()

          3、2個(gè)明顯的結(jié)論

          從上面的圖形中看出來(lái):

          • Jet Airways Business公司的機(jī)票價(jià)格是最高的
          • 其他公司的價(jià)格中位數(shù)是比較接近的

          4、實(shí)現(xiàn)獨(dú)熱編碼

          由于航空公司屬性是一個(gè)標(biāo)稱數(shù)據(jù)的字段,我們進(jìn)行獨(dú)熱編碼,通過(guò)啞變量的方式來(lái)實(shí)現(xiàn):


          停留地-Total_Stops

          旅行期間的總共停留地,實(shí)施上面的同樣操作:

          1、和價(jià)格的關(guān)系

          plt.figure(figsize=(15,8))

          sns.boxplot(x='Total_Stops',
          ????????????y='Price',
          ????????????data=df.sort_values('Price',ascending=False))
          plt.show()

          2、實(shí)施硬編碼;區(qū)別于航空公司的獨(dú)熱編碼

          出發(fā)地source

          出發(fā)地和價(jià)格的關(guān)系:

          plt.figure(figsize=(18,12))

          sns.catplot(x='Source',
          ????????????y='Price',
          ????????????data=df.sort_values('Price',ascending=False),kind='boxen')

          plt.show()

          獨(dú)熱編碼的過(guò)程:

          目的地-destination

          目的地的數(shù)量統(tǒng)計(jì):

          目的地和價(jià)格的關(guān)系:

          獨(dú)熱編碼的實(shí)現(xiàn):

          路線Route

          1、不同路線的數(shù)量統(tǒng)計(jì):

          2、路線名稱提取

          從上面的結(jié)果中看出來(lái),最長(zhǎng)的路線中有5個(gè)地名,我們一次提取。

          沒(méi)有出現(xiàn)的數(shù)據(jù)則用NaN來(lái)表示:

          categorical['Route1']=categorical['Route'].str.split('→').str[0]
          categorical['Route2']=categorical['Route'].str.split('→').str[1]
          categorical['Route3']=categorical['Route'].str.split('→').str[2]
          categorical['Route4']=categorical['Route'].str.split('→').str[3]
          categorical['Route5']=categorical['Route'].str.split('→').str[4]
          categorical.head()

          3、缺失值字段

          for?i?in?['Route3',?'Route4',?'Route5']:
          ????categorical[i].fillna('None',inplace=True)

          4、類型編碼LabelEncoder

          from?sklearn.preprocessing?import?LabelEncoder
          le?=?LabelEncoder()

          for?i?in?['Route1',?'Route2',?'Route3',?'Route4',?'Route5']:
          ????categorical[i]=le.fit_transform(categorical[i])
          ????
          categorical.head()

          抵達(dá)時(shí)間/小時(shí)-Arrival_Time_hour

          抵達(dá)目的地時(shí)間和價(jià)格的關(guān)系:

          df.plot.hexbin(x='Arrival_Time_hour',
          ???????????????y='Price',
          ???????????????gridsize=15)
          plt.show()

          建模數(shù)據(jù)

          刪除無(wú)效字段

          生成的全部字段信息:

          categorical.columns

          Index(['Airline',?'Source',?'Destination',?'Total_Stops',?'Additional_Info',
          ???????'Route1',?'Route2',?'Route3',?'Route4',?'Route5'],
          ??????dtype='object')

          將原始的無(wú)效字段直接刪除:

          drop_col(categorical,'Airline')
          drop_col(categorical,'Source')
          drop_col(categorical,'Destination')
          drop_col(categorical,'Additional_Info')

          最終數(shù)據(jù)

          將多個(gè)DataFrame進(jìn)行拼接,組成最終的建模,其中Price進(jìn)行最終的輸出特征

          final_df=pd.concat([categorical,Airline,source,destination,df[continuous_col]],axis=1)

          final_df.head()

          離群點(diǎn)檢測(cè)

          對(duì)上面生成的最終數(shù)據(jù)進(jìn)行離群點(diǎn)檢測(cè):

          對(duì)離群點(diǎn)填充均值,查看填充后的效果:

          final_df['Price']=np.where(final_df['Price']>=40000,??#?替換部分
          ???????????????????????????final_df['Price'].median(),?#?替換數(shù)據(jù)
          ???????????????????????????final_df['Price'])?#?替換字段
          plot(final_df,?"Price")

          數(shù)據(jù)切分

          X=final_df.drop('Price',axis=1)
          y=final_df['Price']

          from?sklearn.model_selection?import?train_test_split

          X_train,X_test,y_train,y_test?=?train_test_split(X,y,
          ?????????????????????????????????????????????????test_size=0.20,
          ?????????????????????????????????????????????????random_state=123)

          特征選擇

          本文中特征選擇使用的是 mutual_info_classif 庫(kù):

          from?sklearn.feature_selection?import?mutual_info_classif
          imp?=?pd.DataFrame(mutual_info_classif(X,y),
          ??????????????????index=X.columns)

          imp.columns=['importance']
          imp.sort_values(by='importance',ascending=False)

          評(píng)價(jià)指標(biāo)

          本次建模中引入3個(gè)評(píng)價(jià)指標(biāo):

          • r2_score(重點(diǎn)關(guān)注)
          • mean_absolute_error
          • mean_squared_error
          from?sklearn.metrics?import?r2_score,mean_absolute_error,mean_squared_error

          def?predict(ml_model):
          ????print("Model?is:?",?ml_model)
          ????
          ????model?=?ml_model.fit(X_train,?y_train)
          ????
          ????print("Training?score:?",?model.score(X_train,y_train))
          ????
          ????predictions?=?model.predict(X_test)
          ????print("Predictions:?",?predictions)
          ????print('-----------------')
          ????r2score?=?r2_score(y_test,?predictions)
          ????print("r2?score?is:?",?r2score)
          ????
          ????print('MAE:{}',?mean_absolute_error(y_test,predictions))
          ????print('MSE:{}',?mean_squared_error(y_test,predictions))
          ????print('RMSE:{}',?np.sqrt(mean_squared_error(y_test,predictions)))
          ????
          ????#?真實(shí)值和預(yù)測(cè)值的差值
          ????sns.distplot(y_test?-?predictions)

          建模

          導(dǎo)入多種模型:

          #?邏輯回歸
          from?sklearn.linear_model?import?LogisticRegression???
          #?k近鄰回歸
          from?sklearn.neighbors?import?KNeighborsRegressor??
          #?決策樹(shù)回歸
          from?sklearn.tree?import?DecisionTreeRegressor??
          #?梯度提升回歸,隨機(jī)森林回歸
          from?sklearn.ensemble?import?GradientBoostingRegressor,RandomForestRegressor??

          隨機(jī)森林回歸樹(shù)-RandomForestRegressor

          邏輯回歸-LogisticRegression

          K近鄰回歸-KNeighborsRegressor

          決策樹(shù)回歸DecisionTreeRegressor

          支持向量機(jī)回歸-SVR

          梯度提升回歸-GradientBoostingRegressor

          模型調(diào)優(yōu)-Hypertunning the model

          調(diào)優(yōu)尋參

          #?采用隨機(jī)搜索調(diào)優(yōu)
          from?sklearn.model_selection?import?RandomizedSearchCV
          #?待調(diào)優(yōu)的參數(shù)
          random_grid?=?{
          ????'n_estimators'?:?[100,?120,?150,?180,?200,220],
          ????'max_features':['auto','sqrt'],
          ????'max_depth':[5,10,15,20],
          ????}
          #?建模擬合
          rf=RandomForestRegressor()
          rf_random=RandomizedSearchCV(
          ??estimator=rf,
          ??param_distributions=random_grid,
          ??cv=3,
          ??verbose=2,
          ??n_jobs=-1)

          rf_random.fit(X_train,y_train)

          多次運(yùn)行調(diào)優(yōu)后找到最佳的參數(shù)組合:

          調(diào)優(yōu)后結(jié)果

          通過(guò)r2_score指標(biāo)發(fā)現(xiàn):進(jìn)行參數(shù)調(diào)優(yōu)后,模型的效果得到提升~

          補(bǔ)充:如何理解回歸模型的r2_score指標(biāo)

          假設(shè)我們用表示數(shù)據(jù)真實(shí)的觀測(cè)值,用表示真實(shí)觀測(cè)值的平均值,用表示通過(guò)模型得到的預(yù)測(cè)值,則:

          回歸平方和:SSR

          SSR可以表示為;

          即估計(jì)值與平均值的誤差,反映自變量與因變量之間的相關(guān)程度的偏差平方和

          殘差平方和:SSE

          SSE可以表示為:

          即估計(jì)值與真實(shí)值的誤差,反映的是整個(gè)模型擬合程度

          總離差平方和:SST

          R2_score計(jì)算公式

          R^2 score,即決定系數(shù),反映因變量的全部變異能通過(guò)回歸關(guān)系被自變量解釋的比例。計(jì)算公式:

          也可以寫(xiě)成:

          進(jìn)一步可以轉(zhuǎn)成:

          此時(shí)分子就變成了我們常用的評(píng)價(jià)指標(biāo)均方誤差MSE,分母就變成了方差Var。r2_score在0-1之間,越接近1越好。

          兩種常見(jiàn)的求解r2的方式:

          #?1、利用python間接求解
          from?sklearn.metrics?import?mean_squared_error
          1?-?mean_squared_error(y_test,?y_pred)/?np.var(y_test)

          #?2、sklearn直接求解
          from?sklearn.metrics?import?r2_score
          y_test?=?[1,?2,?3]
          y_pred?=?[1.3,?2.1,?3.5]
          r2_score(y_test,y_pred)??


          往期精彩回顧




          瀏覽 116
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天堂网在线观看视频 | 日韩无码性爱 | 黄色美女特极A毛片 | a片在线电影网 | 视频三区 |