日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

kaggle實戰(zhàn):6大回歸模型預測航班票價

 禁忌石 2022-04-14

大家好,我是老班~

今天給大家?guī)硪黄猭aggle案例文章:基于6大回歸模型預測航空公司機票的價格

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

文章圖片1

導入庫

文章圖片2

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

先把數(shù)據(jù)導進來:

df = pd.read_excel('data_air.xlsx')df.head()
文章圖片3

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

文章圖片4
# 字段類型df.dtypesAirline            objectDate_of_Journey    objectSource             objectDestination        objectRoute              objectDep_Time           objectArrival_Time       objectDuration           objectTotal_Stops        objectAdditional_Info    objectPrice               int64dtype: 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:旅客的旅行開始日期
  • Source:旅客出發(fā)地
  • Destination:旅客目的地
  • Route:航班路線
  • Dep_Time:出發(fā)時間
  • Arrival_Time:抵達時間
  • Duration:持續(xù)時間;指的是航班完成從出發(fā)到目的地的旅程的整個時間
  • Total_Stops:總共停留地
  • Additional_Info:其他信息,比如:食物、設備信息等
  • Price:整個旅程的航班票價

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

文章圖片5

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

文章圖片6

缺失值處理

通過上面的缺失值檢查,我們看到有兩個字段是存在缺失值的,進行可視化。

missingno是一個可視化缺失值得庫,方便使用,我們可以用pip install missingno 即可下載該庫

import missingno as msomso.bar(df,color='blue')plt.show()
文章圖片7

缺失值刪除

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

文章圖片8

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

時間處理

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

對3個字段實施轉(zhuǎn)換:

# 3個字段的轉(zhuǎn)換for col in ['Date_of_Journey','Dep_Time', 'Arrival_Time']: change_to_datetime(col)

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

df.dtypes
Airline objectDate_of_Journey datetime64[ns]Source objectDestination objectRoute objectDep_Time datetime64[ns]Arrival_Time datetime64[ns]Duration objectTotal_Stops objectAdditional_Info objectPrice int64dtype: object

提取天和月

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

df['day'] = df['Date_of_Journey'].dt.daydf['month'] = df['Date_of_Journey'].dt.monthdf.head()

最終生成了兩個新的字段:

文章圖片9
# 刪除字段df.drop('Date_of_Journey', axis=1, inplace=True)

起飛時間和抵達時間處理

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

文章圖片10

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

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()
文章圖片11

航班持續(xù)時間duration

1、將持續(xù)時間規(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]

下面是個人版本寫法:

文章圖片12
文章圖片13

2、從Duration字段中提取小時和分鐘:

文章圖片14
df.drop('Duration',inplace=True,axis=1)

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

文章圖片15

字段編碼

字段類型區(qū)分

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

1、針對字符型的字段

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 encodingordinal data -- Data are in order --> labelEncoder
  • 標稱數(shù)據(jù):沒有任何順序,使用獨熱編碼oneot encoding
  • 有序數(shù)據(jù):存在一定的順序,使用類型編碼labelEncoder

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

文章圖片16

不同字段編碼處理

航空公司-Airline

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

文章圖片17
文章圖片18

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

plt.figure(figsize=(15,8))sns.boxplot(x='Airline',            y='Price',            data=df.sort_values('Price',ascending=False)           )plt.show()
文章圖片19

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

從上面的圖形中可以看出來:

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

4、實現(xiàn)獨熱編碼

由于航空公司屬性是一個標稱數(shù)據(jù)的字段,我們進行獨熱編碼,通過啞變量的方式來實現(xiàn):

文章圖片20

停留地-Total_Stops

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

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

plt.figure(figsize=(15,8))sns.boxplot(x='Total_Stops', y='Price', data=df.sort_values('Price',ascending=False))plt.show()
文章圖片21

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

文章圖片22

出發(fā)地source

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

plt.figure(figsize=(18,12))sns.catplot(x='Source',            y='Price',            data=df.sort_values('Price',ascending=False),kind='boxen')plt.show()
文章圖片23

獨熱編碼的過程:

文章圖片24

目的地-destination

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

文章圖片25

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

文章圖片26

獨熱編碼的實現(xiàn):

文章圖片27

路線Route

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

文章圖片28

2、路線名稱提取

從上面的結(jié)果中看出來,最長的路線中有5個地名,我們一次提取。

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

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()
文章圖片29

3、缺失值字段

文章圖片30
for i in ['Route3', 'Route4', 'Route5']:    categorical[i].fillna('None',inplace=True)

4、類型編碼LabelEncoder

from sklearn.preprocessing import LabelEncoderle = LabelEncoder()for i in ['Route1', 'Route2', 'Route3', 'Route4', 'Route5']: categorical[i]=le.fit_transform(categorical[i]) categorical.head()
文章圖片31

抵達時間/小時-Arrival_Time_hour

抵達目的地時間和價格的關(guān)系:

df.plot.hexbin(x='Arrival_Time_hour',               y='Price',               gridsize=15)plt.show()
文章圖片32

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

刪除無效字段

生成的全部字段信息:

categorical.columnsIndex(['Airline', 'Source', 'Destination', 'Total_Stops', 'Additional_Info', 'Route1', 'Route2', 'Route3', 'Route4', 'Route5'], dtype='object')

將原始的無效字段直接刪除:

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

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

將多個DataFrame進行拼接,組成最終的建模,其中Price進行最終的輸出特征

final_df=pd.concat([categorical,Airline,source,destination,df[continuous_col]],axis=1)final_df.head()
文章圖片33

離群點檢測

對上面生成的最終數(shù)據(jù)進行離群點檢測:

文章圖片34
文章圖片35

對離群點填充均值,查看填充后的效果:

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

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

X=final_df.drop('Price',axis=1)y=final_df['Price']from sklearn.model_selection import train_test_splitX_train,X_test,y_train,y_test = train_test_split(X,y, test_size=0.20, random_state=123)

特征選擇

本文中特征選擇使用的是 mutual_info_classif 庫:

from sklearn.feature_selection import mutual_info_classifimp = pd.DataFrame(mutual_info_classif(X,y),                  index=X.columns)imp.columns=['importance']imp.sort_values(by='importance',ascending=False)
文章圖片37

評價指標

本次建模中引入3個評價指標:

  • r2_score(重點關(guān)注)
  • mean_absolute_error
  • mean_squared_error
文章圖片38
from sklearn.metrics import r2_score,mean_absolute_error,mean_squared_errordef 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))) # 真實值和預測值的差值 sns.distplot(y_test - predictions)

建模

導入多種模型:

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

隨機森林回歸樹-RandomForestRegressor

文章圖片39

邏輯回歸-LogisticRegression

文章圖片40

K近鄰回歸-KNeighborsRegressor

文章圖片41

決策樹回歸DecisionTreeRegressor

文章圖片42

支持向量機回歸-SVR

文章圖片43

梯度提升回歸-GradientBoostingRegressor

文章圖片44

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

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

# 采用隨機搜索調(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)

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

文章圖片45

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

文章圖片46

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

補充:如何理解回歸模型的r2_score指標

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

回歸平方和:SSR

SSR可以表示為;

文章圖片47

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

殘差平方和:SSE

SSE可以表示為:

文章圖片48

即估計值與真實值的誤差,反映的是整個模型擬合程度

總離差平方和:SST

文章圖片49

R2_score計算公式

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

文章圖片50

也可以寫成:

文章圖片51

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

文章圖片52

此時分子就變成了我們常用的評價指標均方誤差MSE,分母就變成了方差Var。r2_score在0-1之間,越接近1越好。

兩種常見的求解r2的方式:

# 1、利用python間接求解from sklearn.metrics import mean_squared_error1 - mean_squared_error(y_test, y_pred)/ np.var(y_test)# 2、sklearn直接求解from sklearn.metrics import r2_scorey_test = [1, 2, 3]y_pred = [1.3, 2.1, 3.5]r2_score(y_test,y_pred)  

原文鏈接:

https://mp.weixin.qq.com/s/OVEtwlEjVIQS2TgAPE_Rkw

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多