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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

实战 | Kaggle竞赛:华盛顿特区首都自行车租赁预测

發布時間:2023/12/14 编程问答 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实战 | Kaggle竞赛:华盛顿特区首都自行车租赁预测 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,我是木木~?

今天為大家帶來一篇關于Kaggle競賽的實戰!話不多說,直接上代碼

01

準備數據

使用數據集:

華盛頓特區首都自行車租賃數據集

背景描述:

自行車共享系統是租用自行車的一種方式,在這種情況下,獲得會員資格、租賃和自行車返回的過程通過遍布城市的亭址網絡實現自動化。使用這些系統,人們可以從一個地點租一輛自行車,并根據需要將它歸還到另一個地方。目前,世界各地有500多個自行車共享項目

數據說明:

datetime - 如:2011/1/1 19:00:00格式
season - 1 = 春天, 2 = 夏天, 3 = 秋天, 4 = 冬天
holiday - 0或者1,是否是假期
workingday - 0或者1 ,是否是工作日
weather - 1: 晴,少云,部分云,多云
2: 薄霧+云,薄霧+碎云,薄霧+少量云,薄霧
3: 輕雪,輕雨+雷暴+散云,輕雨+散云
4: 大雨+冰盤+雷雨+薄霧,雪+霧
temp - 攝氏溫度
atemp -體感溫度
humidity -相對濕度
windspeed - 風速
casual - 已啟動的未注冊用戶租金數目
registered - 已啟動的注冊用戶租金數目
count - 租金總額

數據來源:

https://www.kaggle.com/c/bike-sharing-demand/data


問題描述:

提供兩年的每小時租金數據,訓練集由每月的前19天組成,而測試集是第20天到月底。預測在測試集涵蓋的每一小時內租用的自行車總數,僅使用租期之前可用的信息。

import?pylab import?calendar import?numpy?as?np import?pandas?as?pd import?seaborn?as?sn from?scipy?import?stats import?missingno?as?msno from?datetime?import?datetime import?matplotlib.pyplot?as?plt import?warnings pd.options.mode.chained_assignment?=?None warnings.filterwarnings("ignore",?category=DeprecationWarning) %matplotlib?inline #讀取數據 dailyData?=?pd.read_csv('../train.csv')

02

特征工程

通過describe, info, head 等函數可以看出如下問題

“season”、“holiday”、“workingday”和“weather”等欄應該是“類別”數據類型,但目前的數據類型是“int”。讓我們以以下方式轉換數據集,以便我們可以開始使用EDA,并且數據無空值,這點非常棒。

  • 從“datatime”欄中創建新列

  • 將“int”的數據類型強制轉換成分類類型

  • 刪除datetime列,因為我們已經從其中提取了有用的特性

dailyData["data"]?=?dailyData.datetime.apply(lambda?x?:?x.split()[0]) dailyData["hour"]?=?dailyData.datetime.apply(lambda?x?:?x.split()[1].split(":")[0]) dailyData["weekday"]?=?dailyData.data.apply(lambda?dataString?:?calendar.day_name[datetime.strptime(dataString,"%Y-%m-%d").weekday()]) dailyData["month"]?=?dailyData.data.apply(lambda?dataString?:?calendar.month_name[datetime.strptime(dataString,"%Y-%m-%d").month]) dailyData["season"]?=?dailyData.season.map({1:?"Spring",?2:"Summer",?3:?"Fall",?4:?"Winter"}) dailyData["weather"]?=?dailyData.weather.map({1:?"?Clear?+?Few?clouds?+?Partly?cloudy?+?Partly?cloudy",\2?:?"?Mist?+?Cloudy,?Mist?+?Broken?clouds,?Mist?+?Few?clouds,?Mist?",?\3?:?"?Light?Snow,?Light?Rain?+?Thunderstorm?+?Scattered?clouds,?Light?Rain?+?Scattered?clouds",?\4?:"?Heavy?Rain?+?Ice?Pallets?+?Thunderstorm?+?Mist,?Snow?+?Fog?"?})

03

數據分布分析

異常值分析

fig,?axes?=?plt.subplots(nrows=2,ncols=2) fig.set_size_inches(12,?10) sn.boxplot(data=dailyData,y="count",orient="v",ax=axes[0][0]) sn.boxplot(data=dailyData,y="count",x="season",orient="v",ax=axes[0][1]) sn.boxplot(data=dailyData,y="count",x="hour",orient="v",ax=axes[1][0]) sn.boxplot(data=dailyData,y="count",x="workingday",orient="v",ax=axes[1][1])axes[0][0].set(ylabel='Count',title="Box?Plot?On?Count") axes[0][1].set(xlabel='Season',?ylabel='Count',title="Box?Plot?On?Count?Across?Season") axes[1][0].set(xlabel='Hour?Of?The?Day',?ylabel='Count',title="Box?Plot?On?Count?Across?Hour?Of?The?Day") axes[1][1].set(xlabel='Working?Day',?ylabel='Count',title="Box?Plot?On?Count?Across?Working?Day") [Text(0,?0.5,?'Count'),Text(0.5,?0,?'Working?Day'),Text(0.5,?1.0,?'Box?Plot?On?Count?Across?Working?Day')]

輸出

乍一看,“count”變量包含了許多異常值數據點,這些數據點使分布向右傾斜(因為有更多的數據點超出了外部四分位數的限制),但除此之外,還可以從下面給出的簡單方框圖中進行以下推斷。

  • 春季的數量相對較少,方塊中的中值下降就證明了這一點。

  • “一天中的每一小時”的盒式情節很有趣,上午7時至上午8時和下午5時至下午6時的中值相對較高。這可歸因于當時的正規學校和辦公室用戶。

  • 大多數異常點主要來自“工作日”而不是“非工作日”。從圖4可以看到。

移除計數列中的異常值

dailyDataWithoutOutliers?=?dailyData[np.abs(dailyData["count"]-dailyData["count"].mean())<=(3*dailyData["count"].std())]?

關聯性分析

要理解因變量如何受到特征(數值)的影響,一個常見的方法是在它們之間建立一個相關矩陣。讓我們在“計數”和“溫度”、“溫度”、“濕度”、“風速”之間繪制一個相關圖。

  • 溫度和濕度特征分別與計數呈正相關和負相關,盡管兩者之間的相關性不顯著,但計數變量對“溫度”和“濕度”的依賴性較小。

  • 風速將不是真正有用的數值特征,從它與“計數”的相關值中可以看到它。

  • 由于“temp”和“temp”之間有很強的相關性,所以“temp”是變量。在建模過程中,任何一個變量都必須被刪除,因為它們將在數據中表現出多重共線性。

  • “Casual”和“Registered”也沒有被考慮在內,因為它們在性質上是泄漏變量,在建模過程中需要下降。

  • 回歸圖是描述兩個特征之間關系的有效方法之一。這里我們考慮“計數”與“溫度”、“濕度”、“風速”。

corrMatt?=?dailyData[["temp","atemp","casual","registered","humidity","windspeed","count"]].corr() mask?=?np.array(corrMatt) mask[np.tril_indices_from(mask)]?=?False fig,ax=?plt.subplots() fig.set_size_inches(20,10) sn.heatmap(corrMatt,?mask=mask,vmax=.8,?square=True,annot=True)

輸出

可視化數據分布

如下圖所示,“計數”變量向右傾斜。有正態分布是可取的,因為大多數機器學習技術都要求因變量為正態分布。一種可能的解決方案是刪除異常數據點后對“計數”變量進行日志轉換。在轉換之后,數據看起來好多了,但仍然不理想地遵循正態分布。

可視化計數VS(月、季、小時、工作日、用戶類型)

  • 很明顯,在夏季,人們傾向于租自行車,因為在那個季節騎自行車是非常有利的,所以六月、七月和八月對自行車的需求相對較高。

  • 在平日,更多的人傾向于在早上7點到早上8點左右和下午5點到下午6點租自行車。正如我們前面提到的,這可歸因于普通學校和辦公室的上班族。

  • 在“星期六”和“星期日”沒有出現上述現象。更多的人傾向于在上午10點到下午4點之間租自行車。

  • 繁忙時間約早上七時至上午八時及下午五時至六時,純粹由注冊用戶貢獻。

fig,(ax1,ax2,ax3,ax4)=?plt.subplots(nrows=4) fig.set_size_inches(12,20) sortOrder?=?["January","February","March","April","May","June","July","August","September","October","November","December"] hueOrder?=?["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]monthAggregated?=?pd.DataFrame(dailyData.groupby("month")["count"].mean()).reset_index() monthSorted?=?monthAggregated.sort_values(by="count",ascending=False) sn.barplot(data=monthSorted,x="month",y="count",ax=ax1,order=sortOrder) ax1.set(xlabel='Month',?ylabel='Avearage?Count',title="Average?Count?By?Month")hourAggregated?=?pd.DataFrame(dailyData.groupby(["hour","season"],sort=True)["count"].mean()).reset_index() sn.pointplot(x=hourAggregated["hour"],?y=hourAggregated["count"],hue=hourAggregated["season"],?data=hourAggregated,?join=True,ax=ax2) ax2.set(xlabel='Hour?Of?The?Day',?ylabel='Users?Count',title="Average?Users?Count?By?Hour?Of?The?Day?Across?Season",label='big')hourAggregated?=?pd.DataFrame(dailyData.groupby(["hour","weekday"],sort=True)["count"].mean()).reset_index() sn.pointplot(x=hourAggregated["hour"],?y=hourAggregated["count"],hue=hourAggregated["weekday"],hue_order=hueOrder,?data=hourAggregated,?join=True,ax=ax3) ax3.set(xlabel='Hour?Of?The?Day',?ylabel='Users?Count',title="Average?Users?Count?By?Hour?Of?The?Day?Across?Weekdays",label='big')hourTransformed?=?pd.melt(dailyData[["hour","casual","registered"]],?id_vars=['hour'],?value_vars=['casual',?'registered']) hourAggregated?=?pd.DataFrame(hourTransformed.groupby(["hour","variable"],sort=True)["value"].mean()).reset_index() sn.pointplot(x=hourAggregated["hour"],?y=hourAggregated["value"],hue=hourAggregated["variable"],hue_order=["casual","registered"],?data=hourAggregated,?join=True,ax=ax4) ax4.set(xlabel='Hour?Of?The?Day',?ylabel='Users?Count',title="Average?Users?Count?By?Hour?Of?The?Day?Across?User?Type",label='big')

輸出:

04

建立模型

利用隨機森林填充0的風速

from?sklearn.ensemble?import?RandomForestRegressordataWind0?=?data[data["windspeed"]==0] dataWindNot0?=?data[data["windspeed"]!=0] rfModel_wind?=?RandomForestRegressor() windColumns?=?["season","weather","humidity","month","temp","year","atemp"] rfModel_wind.fit(dataWindNot0[windColumns],?dataWindNot0["windspeed"])wind0Values?=?rfModel_wind.predict(X=?dataWind0[windColumns]) dataWind0["windspeed"]?=?wind0Values data?=?dataWindNot0.append(dataWind0) data.reset_index(inplace=True) data.drop('index',inplace=True,axis=1)

分割訓練和測試數據

categoricalFeatureNames?=?["season","holiday","workingday","weather","weekday","month","year","hour"] numericalFeatureNames?=?["temp","humidity","windspeed","atemp"] dropFeatures?=?['casual',"count","datetime","date","registered"] for?var?in?categoricalFeatureNames:data[var]?=?data[var].astype("category") dataTrain?=?data[pd.notnull(data['count'])].sort_values(by=["datetime"]) dataTest?=?data[~pd.notnull(data['count'])].sort_values(by=["datetime"]) datetimecol?=?dataTest["datetime"] yLabels?=?dataTrain["count"] yLablesRegistered?=?dataTrain["registered"] yLablesCasual?=?dataTrain["casual"] dataTrain??=?dataTrain.drop(dropFeatures,axis=1) dataTest??=?dataTest.drop(dropFeatures,axis=1)

使用線性回歸模型

def?rmsle(y,?y_,convertExp=True):if?convertExp:y?=?np.exp(y),y_?=?np.exp(y_)log1?=?np.nan_to_num(np.array([np.log(v?+?1)?for?v?in?y]))log2?=?np.nan_to_num(np.array([np.log(v?+?1)?for?v?in?y_]))calc?=?(log1?-?log2)?**?2return?np.sqrt(np.mean(calc)) from?sklearn.linear_model?import?LinearRegression,Ridge,Lasso from?sklearn.model_selection?import?GridSearchCV from?sklearn?import?metrics import?warnings pd.options.mode.chained_assignment?=?None warnings.filterwarnings("ignore",?category=DeprecationWarning)#?Initialize?logistic?regression?model lModel?=?LinearRegression()#?Train?the?model yLabelsLog?=?np.log1p(yLabels) lModel.fit(X?=?dataTrain,y?=?yLabelsLog)#?Make?predictions preds?=?lModel.predict(X=?dataTrain) print?("RMSLE?Value?For?Linear?Regression:?",rmsle(np.exp(yLabelsLog),np.exp(preds),False)) 0.9779516580409092

使用集成模型

from?sklearn.ensemble?import?GradientBoostingRegressor gbm?=?GradientBoostingRegressor(n_estimators=4000,alpha=0.01);?###?Test?0.41 yLabelsLog?=?np.log1p(yLabels) gbm.fit(dataTrain,yLabelsLog) preds?=?gbm.predict(X=?dataTrain) print?("RMSLE?Value?For?Gradient?Boost:?",rmsle(np.exp(yLabelsLog),np.exp(preds),False)) 0.19084027408592402

結論:顯然GradientBoostingRegressor算法比LR取得更好的預測效果!

你可能還想讀的往期精彩實戰(點擊圖片跳轉)

? ? ? ??? ?? ?

? ? ?? ? ? ??

長按二維碼關注我們

有趣的靈魂在等你

好看你就點點我

總結

以上是生活随笔為你收集整理的实战 | Kaggle竞赛:华盛顿特区首都自行车租赁预测的全部內容,希望文章能夠幫你解決所遇到的問題。

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