共享單車騎行數據預測
任務說明
1、 任務描述 請在Capital Bikeshare (美國Washington, D.C.的一個共享單車公司)提供的自行車數據上進行迴歸分析。根據每天的天氣信息,預測該天的單車共享騎行量。
原始數據集地址:http://archive.ics.uci.edu/ml/datasets/Bike+Sharing+Dataset 1) 文件說明 day.csv: 按天計的單車共享次數(作業只需使用該文件) hour.csv: 按小時計的單車共享次數(無需理會) readme:數據說明文件
- 字段說明 Instant記錄號 Dteday:日期 Season:季節(1=春天、2=夏天、3=秋天、4=冬天) yr:年份,(0: 2011, 1:2012) mnth:月份( 1 to 12) hr:小時 (0 to 23) (只在hour.csv有,作業忽略此字段) holiday:是否是節假日 weekday:星期中的哪天,取值爲0~6 workingday:是否工作日 1=工作日 (是否爲工作日,1爲工作日,0爲非週末或節假日 weathersit:天氣(1:晴天,多雲 2:霧天,陰天 3:小雪,小雨 4:大雨,大雪,大霧) temp:氣溫攝氏度 atemp:體感溫度 hum:溼度 windspeed:風速 casual:非註冊用戶個數 registered:註冊用戶個數 cnt:給定日期(天)時間(每小時)總租車人數,響應變量y (cnt = casual + registered)
casual、registered和cnt三個特徵均爲要預測的y,作業裏只需對cnt進行預測
第一步 數據探索
做機器學習預測,我們拿到數據之後的第一步是查看數據,查看數據由很多種方法,下面簡單介紹:
首先使用pd.read_csv函數讀入數據
# 數據讀取及基本處理
import pandas as pd
import numpy as np
# 讀入數據
train = pd.read_csv("day.csv")
print(train.head())
#print("train : " + str(train.shape))
我們可以看到數據的前5頁,大概看一下數據的結構
使用:
print(train.info())
我們可以看到數據的總體信息
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 731 entries, 0 to 730
Data columns (total 16 columns):
instant 731 non-null int64
dteday 731 non-null object
season 731 non-null int64
yr 731 non-null int64
mnth 731 non-null int64
holiday 731 non-null int64
weekday 731 non-null int64
workingday 731 non-null int64
weathersit 731 non-null int64
temp 731 non-null float64
atemp 731 non-null float64
hum 731 non-null float64
windspeed 731 non-null float64
casual 731 non-null int64
registered 731 non-null int64
cnt 731 non-null int64
dtypes: float64(4), int64(11), object(1)
memory usage: 91.4+ KB
觀察數據的統計信息:
#對數據值型特徵,用常用統計量觀察其分佈
print(train.describe())
第二步 數據預處理
對於數據可以分爲兩類,一類是數值型數據,一類是類別型數據;也就是連續數據和離散型數據,這兩種數據需要分開處理
類別型數據:
對於類別型數據需要進行獨熱編碼
#對類別型特徵,觀察其取值範圍及直方圖
categorical_features = ['season','mnth','weathersit','weekday']
#數據類型變爲object,才能被get_dummies處理
for col in categorical_features:
train[col] = train[col].astype('object')
X_train_cat = train[categorical_features]
X_train_cat = pd.get_dummies(X_train_cat)
print(X_train_cat)
運行結果爲:
season_1 season_2 season_3 ... weekday_4 weekday_5 weekday_6
0 1 0 0 ... 0 0 1
1 1 0 0 ... 0 0 0
2 1 0 0 ... 0 0 0
3 1 0 0 ... 0 0 0
4 1 0 0 ... 0 0 0
[5 rows x 26 columns]
數值型數據
對於數值型數據進行歸一化處理
#數值型變量預處理,
from sklearn.preprocessing import MinMaxScaler
mn_X = MinMaxScaler()
numerical_features = ['temp','atemp','hum','windspeed']
temp = mn_X.fit_transform(train[numerical_features])
X_train_num = pd.DataFrame(data=temp, columns=numerical_features, index =train.index)
print(X_train_num.head())
得到的結果爲:
temp atemp hum windspeed
0 0.355170 0.373517 0.828620 0.284606
1 0.379232 0.360541 0.715771 0.466215
2 0.171000 0.144830 0.449638 0.465740
3 0.175530 0.174649 0.607131 0.284297
4 0.209120 0.197158 0.449313 0.339143
合併數據
對於以上兩個數據需要進行合併,然後存入文件“FE_day.csv”
# 合併數據
X_train = pd.concat([X_train_cat, X_train_num, train['holiday'], train['workingday']], axis = 1, ignore_index=False)
#print(X_train.head())
# 合併數據
FE_train = pd.concat([train['instant'], X_train, train['yr'],train['cnt']], axis = 1)
FE_train.to_csv('FE_day.csv', index=False) #保存數據
#print(FE_train.head())
print(FE_train.info())
第三步 訓練模型
如下程序爲導入數據訓練模型:
import pandas as pd
import numpy as np
from test_bick import Data_preprocessing
from sklearn.model_selection import train_test_split
import os
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import RidgeCV
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
from sklearn.metrics import r2_score#R square
from sklearn.metrics import mean_squared_error #均方誤差
from sklearn.metrics import mean_absolute_error #平方絕對誤差
import matplotlib.pyplot as plt
def load_data():#導入數據
global x_data,y_data,name_data
if not os.path.isfile("FE_day.csv"):#調用已經做好特徵工程的文件,如果文件不存在,就調用函數生成該文件
Data_preprocessing()
data = pd.read_csv("FE_day.csv")
data = data.drop(['instant','hum','windspeed'], axis = 1)#去掉編號、溼度、風速等不相關數據
## print(data)
y_data = data['cnt']
x_data = data.drop('cnt', axis = 1)
y_data=np.array(y_data)
x_data=np.array(x_data)
name_data =list(data.columns)#返回對象列索引
## print(x_data)
## print(y_data)
## print(name_data)
def traintestsplit():#數據分割,一部分用於驗證、一部分用於訓練
global x_data,y_data,name_data
X_train,X_test,y_train,y_test=train_test_split(x_data,y_data,random_state=0,test_size=0.20)#分割數據,20%用於測試,80%用於訓練
return X_train,X_test,y_train,y_test
load_data() #數據導入
X_train,X_test,y_train,y_test=traintestsplit() #數據分割
#使用線性迴歸模型LinearRegression對數據進行訓練及預測
#lr=LinearRegression()#最小二乘線性迴歸模型
#lr=Ridge()#嶺迴歸模型
#lr=RidgeCV()#
lr=Lasso()#Lasso模型
#lr=ElasticNet()
#使用訓練數據進行參數估計
lr.fit(X_train,y_train) #訓練模型
#R2評價指標
lr_y_predict=lr.predict(X_test)
score = r2_score(y_test, lr_y_predict)
print("R2:{}".format(score))
#MSE評價指標
mse_test=mean_squared_error(y_test,lr_y_predict)
print("MSE:{}".format(mse_test))
#RMSE評價指標
Rmse_test=mean_absolute_error(y_test,lr_y_predict)
print("RMSE:{}".format(Rmse_test))
導入處理好的數據集
def load_data():#導入數據
global x_data,y_data,name_data
if not os.path.isfile("FE_day.csv"):#調用已經做好特徵工程的文件,如果文件不存在,就調用函數生成該文件
Data_preprocessing()
data = pd.read_csv("FE_day.csv")
data = data.drop(['instant','hum','windspeed'], axis = 1)#去掉編號、溼度、風速等不相關數據
## print(data)
y_data = data['cnt']
x_data = data.drop('cnt', axis = 1)
y_data=np.array(y_data)
x_data=np.array(x_data)
name_data =list(data.columns)#返回對象列索引
對導入的數據集進行分割,一部分用於訓練,一部分用於測試
def traintestsplit():#數據分割,一部分用於驗證、一部分用於訓練
global x_data,y_data,name_data
X_train,X_test,y_train,y_test=train_test_split(x_data,y_data,random_state=0,test_size=0.20)#分割數據,20%用於測試,80%用於訓練
return X_train,X_test,y_train,y_test
使用最小二乘線性迴歸模型、嶺迴歸模型、Lasso模型訓練數據集,並使用MSE、RMSE、R2評價模型
#使用線性迴歸模型LinearRegression對數據進行訓練及預測
#lr=LinearRegression()#最小二乘線性迴歸模型
#lr=Ridge()#嶺迴歸模型
#lr=RidgeCV()#
lr=Lasso()#Lasso模型
#lr=ElasticNet()
#使用訓練數據進行參數估計
lr.fit(X_train,y_train) #訓練模型
#R2評價指標
lr_y_predict=lr.predict(X_test)
score = r2_score(y_test, lr_y_predict)
print("R2:{}".format(score))
#MSE評價指標
mse_test=mean_squared_error(y_test,lr_y_predict)
print("MSE:{}".format(mse_test))
#RMSE評價指標
Rmse_test=mean_absolute_error(y_test,lr_y_predict)
print("RMSE:{}".format(Rmse_test))
得到結果爲:
最小二乘線性迴歸模型
R2:0.8539847000931238
MSE:621023.925170068
RMSE:594.6054421768707
嶺迴歸模型
R2:0.854636684725367
MSE:618250.9414092939
RMSE:589.2949841711451
Lasso模型訓練數據集
R2:0.853814736719781
MSE:621746.8036719494
RMSE:590.9812536346217
模型解析
根據以上模型評價參數發現,各回歸模型的差異不大,均能達到85%左右的準確率,模型已經可以用於預測。
參看各模型的coef_分佈:
#分別使用線性迴歸,嶺迴歸,Lasso迴歸進行數據預測
lrg=LinearRegression()
ridge=Ridge()
lasso=Lasso()
lrg.fit(X_train,y_train)
ridge.fit(X_train,y_train)
lasso.fit(X_train,y_train)
#數據視圖,此處獲取各個算法的訓練數據的coef_:係數,coef_可以理解爲係數
plt.figure(figsize=(12,9))
#線性迴歸 得到的coef
axes=plt.subplot(221)
axes.plot(lrg.coef_)
axes.set_title('lrg_coef')
#l嶺迴歸 得到的coef
axes=plt.subplot(222)
axes.plot(ridge.coef_)
axes.set_title('ridge_coef')
#lasso迴歸 得到的coef
axes=plt.subplot(223)
axes.plot(lasso.coef_)
axes.set_title('lasso_coef')
plt.show()
項目源代碼:共享單車數據預測