kaggle小黃車競賽 得分:0.41038
在參與泰坦尼克競賽(https://zhuanlan.zhihu.com/p/27632002) 中得來的經驗,以及數據思維。也同樣可以用於小黃車的競賽中。n
首先先導入包
library(readr) nlibrary(plyr)nlibrary(stringr)n
其次導入數據
#setwd是設定路徑的意思nsetwd("C:/Users/wlh/Desktop/下載的數據")ntrain<-read.csv("train.csv")ntest<-read.csv("test.csv")n
觀測數據,發現測試數據比訓練數據少了三個觀測分別是註冊,臨時,計數。
怎麼辦呢?那就在測試數據里加上這哥仨吧
#在測試數據里加上缺失的三個值ntest$registered<-0ntest$casual<-0ntest$count<-0ndata<-rbind(train,test)n
用str()看看這裡面都包含什麼數據
str(data)n
結果如下
data.frame:t17379 obs. of 12 variables:n $ datetime : Factor w/ 17379 levels "2011-01-01 00:00:00",..: 1 2 3 4 5 6 7 8 9 10 ...n $ season : int 1 1 1 1 1 1 1 1 1 1 ...n $ holiday : int 0 0 0 0 0 0 0 0 0 0 ...n $ workingday: int 0 0 0 0 0 0 0 0 0 0 ...n $ weather : int 1 1 1 1 1 2 1 1 1 1 ...n $ temp : num 9.84 9.02 9.02 9.84 9.84 ...n $ atemp : num 14.4 13.6 13.6 14.4 14.4 ...n $ humidity : int 81 80 80 75 75 75 80 86 75 76 ...n $ windspeed : num 0 0 0 0 0 ...n $ casual : num 3 8 5 3 0 0 2 1 1 8 ...n $ registered: num 13 32 27 10 1 1 0 2 7 6 ...n $ count : num 16 40 32 13 1 1 2 3 8 14 ...n
可以看出共有觀測17379條,12條變數
日期時間(datetime):日期和時間以「mm-dd- yyyy hh:mm:ss」格式
季節(season):1為春,2為夏,3為秋,4為冬
假期(holiday):1/0
工作日(workingday):1/0
天氣(weather):四類天氣
1->清除,幾朵雲,部分多雲,部分多雲
2->迷霧+多雲,霧+破碎的雲霧,霧+少雲,霧
3->輕雪和雨+雷暴+分散的雲彩,小雨+分散的雲彩
4->大雨+冰托盤+雷雨+霧,雪+霧
溫度(temp):每小時攝氏溫度
??(atemp):像是一種加過權重之後的溫度,反正跟temp是強正相關
濕度(humidity):濕度
風速(windspeed):風速
casual :休閑用戶
registered:註冊用戶
count:共計數
ps:數據集顯示兩年(2011年和2012年)的數據。訓練數據集是每個月的前19天。測試數據集是從20日到次月。
找出缺失值
#找缺失值ntable(is.na(data))n
結果如下
FALSE n208548 n
其實木有缺失值
了解數值變數的分布,然後生成數值變數的頻率表。繪製每個數值變數的直方圖,並分析
#繪製每個觀測的直方圖並分析n#四行兩列npar(mfrow=c(4,2))n#寬度和長度npar(mar = rep(2, 4))nhist(data$season)nhist(data$weather)nhist(data$humidity)nhist(data$holiday)nhist(data$workingday)nhist(data$temp)nhist(data$atemp)nhist(data$windspeed)n
如圖:
通過觀察上圖可以看出一些影響
1.四季的影響不大
2.天氣的影響比較大,從好到不好,自行車的使用量越來越低
3.當假期為0,工作日為1時自行車的使用量就比較大
4.溫度太高或者太低了都會影響使用量
5.風速從5到20這個時候自行車使用量比較大,可以推測在這個風速里騎車是比價愉悅的
將離散型轉換為因子型的(季節,天氣,假期,工作日)
data$season=as.factor(data$season)ndata$weather=as.factor(data$weather)ndata$holiday=as.factor(data$holiday)ndata$workingday=as.factor(data$workingday)n
假設生成
現在你對數據已經有了一個大致的了解,下面讓我們來根據一些基本的經驗來對自行車的使用量進行假設
24小時趨勢:上下班高峰期使用量就很高。晚上10點到凌晨4點需求低
一周趨勢:平日用車比節假日高
有雨有雪:與晴天相比,下雨(雪)天的自行車需求將會下降。同樣,較高的濕度會降低需求,反之亦然。
溫度:溫度適宜的情況下使用量必加大
註冊用戶與時間:由於註冊用戶數量隨著時間的推移得增多,總需求應該趨向於升高
假設檢驗
下面來逐一分析上面的假設檢驗
每日趨勢:
data$hour=substr(data$datetime,12,13)ndata$hour=as.factor(data$hour)n
畫圖,判斷假設是否正確
#把訓練的前20天和測試的後10天左右提出來ntrain=data[as.integer(substr(data$datetime,9,10))<20,]ntest=data[as.integer(substr(data$datetime,9,10))>19,]n#畫圖nboxplot(train$count~train$hour,xlab="hour", ylab="count of users")n
如圖:
可以看出和我們的假設差不多
上下班時間是用車高峰,而低峰期是在晚上10點到次日凌晨6點。其他時間為平均用車量
然後我們再來看一下註冊用戶和臨時用戶的差別:
#臨時用戶nboxplot(train$casual~train$hour,xlab="hour", ylab="count of users")n
如圖:
可以看出臨時用戶傾向於在白天的時候隨便用用,基本上都是平均值
#註冊用戶nboxplot(train$registered~train$hour,xlab="hour", ylab="count of users")n
如圖:
註冊用戶更傾向於上下班高峰期用
但是你會發現,這倆圖有好些個異常值,應該不是由錯誤導致的。他們可能是同一群人騎自行車但是未註冊的結果,為了處理這些離群值,我們將使用對數變換。
boxplot(log(train$count)~train$hour,xlab="hour",ylab="log(count)")n
如圖:
一周趨勢:
#把date$datetime的年月日拆出來ndate<-substr(data$datetime,1,10)n#拆出來之後轉換成星期ndays<-weekdays(as.Date(date))ndata$day<-daysn
註冊用戶畫圖:
臨時用戶:
#畫臨時用戶的圖nboxplot(train$casual~train$day,xlab="day", ylab="users")n
如圖:
可以看出星期六星期天的用戶是增加的
雨(雪)的影響:在變數中雖然沒有專門的雨量數據,但是在天氣(weather)這裡面有響應的因素,3里有小雨(雪),4里有大雨(雪)
#畫圖,天氣和註冊用戶的關係nboxplot(train$registered~train$weather,xlab="weather", ylab="registered users")n
如圖:
#畫圖,天氣和休閑用戶的關係nboxplot(train$casual~train$weather,xlab="weather", ylab="casual users")n
如圖:
從圖中可以看出非常符合我們的預期
溫度,風速和濕度:這些不是離散型的,是連續的。所以我們用相關來驗證假設
#溫度,風速和濕度的相關關係nsub<-data.frame(train$registered,train$casual,train$count,train$temp,train$humidity,train$atemp,train$windspeed)nsubT<-cor(sub)n
如下表:
從表中可以看出,溫度和註冊,休閑,總計這三個變數差不多都是正相關關係,而濕度和風速跟這三兄弟的關係就不是很大了。溫度和atemp是高度相關。
時間:看看時間對於用戶數的影響
#隨著時間的推移,用戶數的變化ndata$year=substr(data$datetime,1,4)ndata$year=as.factor(data$year)ntrain=data[as.integer(substr(data$datetime,9,10))<20,]ntest=data[as.integer(substr(data$datetime,9,10))>19,]nboxplot(train$count~train$year,xlab="年", ylab="用戶總量")n
如圖:
結論是用戶數增加。
決策樹
讓我們用決策樹來增加模型的預測能力
第一步添加決策樹相應的包
#決策樹要用到的包nlibrary(rpart)#在我的泰坦尼克競賽里有對這個包的介紹nlibrary(rattle) #這些庫將用於為決策樹模型提供良好的可視化繪圖nlibrary(rpart.plot)#繪製「rpart」模型:「plot.rpart」的增強版本nlibrary(RColorBrewer)#配色方案n
然後話關於小時的決策樹的圖
#訓練數據轉換類型ntrain$hour=as.integer(train$hour)n#測試數據轉換類型ntest$hour=as.integer(test$hour)n#用小時生成決策樹nd=rpart(registered~hour,data=train)n#畫圖nfancyRpartPlot(d)n
如圖:
查看節點,手動添加倉位(註冊用戶)
data=rbind(train,test)ndata$dp_reg=0ndata$dp_reg[data$hour<8]=1ndata$dp_reg[data$hour>=22]=2ndata$dp_reg[data$hour>9 & data$hour<18]=3ndata$dp_reg[data$hour==8]=4ndata$dp_reg[data$hour==9]=5ndata$dp_reg[data$hour==20 | data$hour==21]=6ndata$dp_reg[data$hour==19 | data$hour==18]=7n
添加倉位(休閑用戶)
#休閑用戶nb=rpart(casual~hour,data=train)nfancyRpartPlot(b)n
如圖:
#手動添加ndata$dp_cas=0ndata$dp_cas[data$hour==9]=1ndata$dp_cas[data$hour<=8]=2ndata$dp_cas[data$hour>=10&data$hour<=19]=3ndata$dp_cas[data$hour>=20]=4n
溫度同上:
#溫度(註冊)nt=rpart(registered~temp,data=train)nfancyRpartPlot(t)n
如圖:
#添加註冊ndata$temp_reg=0ndata$temp_reg[data$temp<13]=1ndata$temp_reg[data$temp>=13&data$temp<23]=2ndata$temp_reg[data$temp>=23&data$temp<30]=3ndata$temp_reg[data$temp>=30]=4n
溫度(休閑)
#溫度(休閑)nt1=rpart(casual~temp,data=train)nfancyRpartPlot(t1)n
如圖:
#添加休閑ndata$temp_cas=0ndata$temp_cas[data$temp<15]=1ndata$temp_cas[data$temp>=15&data$temp<23]=2ndata$temp_cas[data$temp>=23&data$temp<30]=3ndata$temp_cas[data$temp>=30]=4n
添加年份:在這裡先把月份提取出來,然後按照每個季度一個倉位,建8個倉位
#提取月份ndata$month=substr(data$datetime,6,7)ndata$month=as.factor(data$month)ntrain=data[as.integer(substr(data$datetime,9,10))<20,]ntest=data[as.integer(substr(data$datetime,9,10))>19,]n#轉換類型ndata$month=as.integer(data$month)n
#手動添加ndata$year_part[data$year==2011]=1ndata$year_part[data$year==2011 & data$month>3]=2ndata$year_part[data$year==2011 & data$month>6]=3ndata$year_part[data$year==2011 & data$month>9]=4ndata$year_part[data$year==2012]=5ndata$year_part[data$year==2012 & data$month>3]=6ndata$year_part[data$year==2012 & data$month>6]=7ndata$year_part[data$year==2012 & data$month>9]=8ntable(data$year_part)n
日期:創建一個變數,有「平日」、「周末」和「假日」
data$day_type=""ndata$day_type[data$holiday==0 & data$workingday==0]="weekend"ndata$day_type[data$holiday==1]="holiday"ndata$day_type[data$holiday==0 & data$workingday==1]="working day"n
周末:為周末創建一個獨立的變數
data$weekend=0ndata$weekend[data$day=="Sunday" | data$day=="Saturday" ]=1n
開始建模
首先把character的數據類型都轉換成factor,否則隨機森林不支持
#轉換數據類型,否則隨機森林不支持ndata$day=as.factor(data$day)ndata$day_type=as.factor(data$day_type)n
我們之前分析過由於註冊,休閑,計數。這哥仨有很多自然離群值,所以這裡就把他們都轉換成對數。
#取對數ndata$logreg<-log(data$registered+1)ndata$logcas<-log(data$casual+1)n
加一是為了處理註冊和休閑這倆觀測的0值
#將data里的所有觀測和類型統統賦值給train,testntrain=data[as.integer(substr(data$datetime,9,10))<20,]ntest=data[as.integer(substr(data$datetime,9,10))>19,]n
預測
#預測註冊用戶的對數nset.seed(415)nfit1 <- randomForest(logreg ~ hour +workingday+day+holiday+ day_type +temp_reg+humidity+atemp+windspeed+season+weather+dp_reg+weekend+year+year_part, data=train,importance=TRUE, ntree=250)npred1=predict(fit1,test)ntest$logreg=pred1n
可能我的電腦比較渣,這裡運算了1個小時
#預測休閑用戶的對數nset.seed(415)nfit2 <- randomForest(logcas ~hour + day_type+day+humidity+atemp+temp_cas+windspeed+season+weather+holiday+workingday+dp_cas+weekend+year+year_part, data=train,importance=TRUE, ntree=250)npred2=predict(fit2,test)ntest$logcas=pred2n
啊,又小一個小時過去了。。。
寫入文件上傳
#重新轉換預測變數,然後將count的輸出寫入文件ntest$registered=exp(test$logreg)-1ntest$casual=exp(test$logcas)-1ntest$count=test$casual+test$registeredns<-data.frame(datetime=test$datetime,count=test$count)nwrite.csv(s,file="pre3.csv",row.names=FALSE)n
由於沒有排名系統所以只有得分......
得了0.41038分
推薦閱讀:
※Kaggle—So Easy!百行代碼實現排名Top 5%的圖像分類比賽
※Zillow簡介(二)如何重構經紀行業的產業鏈?
※用Python下載Kaggle數據
※Titanic: kaggle入門實踐-top10%(附Python代碼)
※Zillow Prize競賽系列--(一)競賽簡介