接下来按照原计划,开始由易到难的打卡kaggle 机器学习项目
# coding: utf-8
# # 项目的背景
# 科技已经改变交通
# 提供了一个城市一年20130701-20140630 的运行轨迹的数据
#
# trip_id: 每一个性成的标识符号
# call_type: A 预定taxi的时候,电话打到 taxi 管理中心,B电话接听指定地点范围内的司机 C电话连接到随机任意一个线路上
# origin call:当call_type=A的时候,它标识旅行的客户,否则为空
# origin stand: call_type='B',标识的是旅行的起点
# taxi_id:出租车司机的唯一标识符号
# daytype:三种类型,B表示节假日,C表示节假日的前一天,A则表示普通日,或者工作日
# missing_data:False 表示GPS经纬度坐标存在,反之数据丢失
# Polyline: 每15s行程的一对经纬度坐标
#
# 本次比赛的总行程时间(本次比赛的预测目标)定义为(点数-1)×15秒。例如,在POLYLINE中包含101个数据点的行程长度为(101-1)* 15 = 1500秒。有些trip在POLYLINE中缺少数据点(由MISSING_DATA列表示),如何利用这些知识是一个挑战。
#
# 这是一个回归问题,我们需要预测总共的时间,从出发到到达目的地
#
# In[1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
from numpy import sqrt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error as mse
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.svm import SVR
from xgboost import XGBRegressor
# In[2]:
df=pd.read_csv(r'C:\\Users\\Lenovo\\Desktop\\hands-on-machine-learning\\ml of finding job\\train.csv')
df.head(10)
df.isnull().sum(axis=0)##origin call 和stand 的数据丢失比较严重,一般并不在车站或者通过打taxi 中心的电话约车
# In[16]:
df.info()#可以看到每一列的数据类型
# In[19]:
##当数据类型为numeric 的时候,那么就会返回count,mean,std,min,,1/4分位,1/2,3/4等,
"""
include
来限定数据类型
object---categories,就是'a','b','c'等
"""
df.describe(include=['object'])#出现的不同值的数量,只出现一次的值的个数,出现次数最高的是,出现最高的值出现的次数
"""
结果显示,关于出行时间
数据显示都是在工作日
而且5901 没法算其出行的时间
"""
# In[3]:
##将时间转变为年月日的形式,学习fromtimesstamp的用法
df.sort_values(by='TIMESTAMP',axis=0,inplace=True)
df['year'] = df['TIMESTAMP'].apply(lambda x :datetime.datetime.fromtimestamp(x).year)
df['month'] = df['TIMESTAMP'].apply(lambda x :datetime.datetime.fromtimestamp(x).month)
df['month_day'] = df['TIMESTAMP'].apply(lambda x :datetime.datetime.fromtimestamp(x).day)
df['hour'] = df['TIMESTAMP'].apply(lambda x :datetime.datetime.fromtimestamp(x).hour)
df['week_day'] = df['TIMESTAMP'].apply(lambda x :datetime.datetime.fromtimestamp(x).weekday())
df.head(10)
type(df["year"].value_counts())# series类型
df['year'].value_counts().keys()#注意两者连用
# In[36]:
##饼形图
plt.figure(figsize=(10,10))
plt.pie(df["year"].value_counts(),labels=df["year"].value_counts().keys(),autopct='%.1f%%')
plt.show()#数据每年各占一半
# In[40]:
plt.figure(figsize=(5,5))
plt.title('count of trips of per day of week')
sns.countplot(x="week_day",data=df)#第一个参数为x,或者y,表示显示在x轴上还是y轴上,是数据的列名,data 为传入的数据
#一般为dataFrame 类型
plt.xlabel("the day of week")
plt.ylabel("counts")
plt.show()
# In[41]:
plt.figure(figsize = (10,10))
plt.title('Count of trips per month')
sns.countplot(y = 'month', data = df)
plt.xlabel('Count')
plt.ylabel('Month')
##On an average we can say that every month has atleast 120000 taxi trips planned.
# In[42]:
plt.figure(figsize = (10,10))
plt.title('Count of trips per hour')
sns.countplot(x = 'hour', data = df)
plt.xlabel('Count')
plt.ylabel('Hours')
# In[4]:
##来看一下丢失的数据有多少
df["MISSING_DATA"].value_counts()
"""
10个数据丢失
"""
#将这些所在的行去掉
"""
关于 drop 的参数的使用
labels : single label or list-like
Index or column labels to drop.
axis : {0 or ‘index’, 1 or ‘columns’}, default 0
Whether to drop labels from the index (0 or ‘index’) or columns (1 or ‘columns’).
index : single label or list-like
Alternative to specifying axis (labels, axis=0 is equivalent to index=labels).#去除一些行,肯定用index 索引,
或者label指定索引
New in version 0.21.0.
columns : single label or list-like
Alternative to specifying axis (labels, axis=1 is equivalent to columns=labels).
#去除一些列(一行中的某些字段),肯定用列名 索引,
或者label指定列名
"""
df.drop(df[df["MISSING_DATA"]==True].index,axis=0,inplace=True)
df["MISSING_DATA"].unique()
df.drop(df[df["POLYLINE"]=='[]'].index,axis=0,inplace=True)
df["POLYLINE"].value_counts()
# In[8]:
##下面将形成换算成时间
df["polyline length"]=df["POLYLINE"].apply(lambda x :len(eval(x))-1)##一共列表中的有几组数据
df["trip_time"]=df["polyline length"].apply(lambda x:x*15)
df.head(10)
# In[5]:
#one hot encoidng for call type
df = pd.get_dummies(df, columns=['CALL_TYPE'])#先转化,然后在和原来的表进行连接,并不会影响行数,其实就是将一列的值转化为多列
"""
Desktop/到的结果是增加了3列
CALL_TYPE_A,B,C
CALL_TYPE_A ,对应的三列值为【0,0,1】,B为【0,1,0】,C为【1,0,0】
"""
df.head(10)### 可以将非向量形式的object 转化为向量形式便于研究
# In[7]:
df
"""
存在3个参数
subset 指定要去重的列名,列表的形式传入,比如['A','B'],就是表示 A,B两类列重复的去掉,默认为全部列
inplace 是否在原来的基础上修改
keep first,last False 三个值,表示留下重复列的第一个,最后一个,全部删除
"""
df.head(10)
# In[6]:
####构建机器学习模型
x=df[['polyline length','CALL_TYPE_A','CALL_TYPE_B','CALL_TYPE_C']]
y=df['trip_time']
# data standization
s=StandardScaler()
x=s.fit_transform(x)##采用的是z-score的方法,每一个参数减去其平均值 除以相应的标准差
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
print("The size of training input is", x_train.shape)
print("The size of training output is", y_train.shape)
print(50 *'*')
print("The size of testing input is", x_test.shape)
print("The size of testing output is", y_test.shape)
x_train
# In[31]:
#下面提供了集中预测模型
"""
第一种利用均值进行预测
r2_score, 1-MSE/(实际值-平均值)^2 x 1/(样本个数),值越接近于1,说明模型越好
"""
y_train_pred=np.ones(x_train.shape[0])*y_train.mean() #以平均值作为预测值,训练集的预测
y_test_pred=np.ones(x_train.shape[0])*y_test.mean() #以平均值作为预测值,测试集的预测
print("Train Results for Baseline Model:")
print(50 * '-')
print("root mean squared error as rmse", sqrt(mse(y_train.values,y_train_pred)))
print("R-squared: ", r2_score(y_train.values, y_train_pred))
# In[1]:
##knn 算法
"""
存在两种分类请器,一种为 kneighborclassifier 原理如下
1)计算测试数据与各个训练数据之间的距离;
2)按照距离的递增关系进行排序;
3)选取距离最小的K个点;(k的值,采用GridSearchCV的交叉验证)
4)确定前K个点所在类别的出现频率;
5)返回前K个点中出现频率最高的类别作为测试数据的预测分类
另外 一种为 kneighborregressor 主要思想:选取样本的K个近邻样本,用近邻样本的响应值(y)的均值作为该样本的预测值
同样的 也有 DecisionTreeRegressor, SVM 中的SVR
"""
"""
GridSearchCV
可以一次性的限定预测模型以及打分标准(score 参数)
GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, iid=’warn’,
refit=True, cv=’warn’, verbose=0, pre_dispatch=‘2*n_jobs’,
error_score=’raise-deprecating’, return_train_score=False)
其中 param_grid 可以传入一个列表或者字典
字典的话以参数为键名称
KNeighborsRegressor(n_neighbors=5, weights=’uniform’, algorithm=’auto’,
leaf_size=30, p=2, metric=’minkowski’, metric_params=None, n_jobs=None, **kwargs)
"""
k_range=list(range(1,30))
param=dict(n_neighbors=k_range)#以KNeighborsRegressor 的参数 n_neighbors 为键名
knn_regressor=GridSearchCV(KNeighborsRegressor(),param,cv=10)
knn_regressor.fit(x_train,y_train)
print (knn_regressor.best_estimator_)
print(knn_regressor.best_params_)
# ## 交叉验证
#
# 第一种是简单交叉验证,所谓的简单,是和其他交叉验证方法相对而言的。首先,我们随机的将样本数据分为两部分(比如: 70%的训练集,30%的测试集),然后用训练集来训练模型,在测试集上验证模型及参数。接着,我们再把样本打乱,重新选择训练集和测试集,继续训练数据和检验模型。最后我们选择损失函数评估最优的模型和参数。
#
# 第二种是S折交叉验证(S-Folder Cross Validation)。和第一种方法不同,S折交叉验证会把样本数据随机的分成S份,每次随机的选择S-1份作为训练集,剩下的1份做测试集。当这一轮完成后,重新随机选择S-1份来训练数据。若干轮(小于S)之后,选择损失函数评估最优的模型和参数。
#
# 第三种是留一交叉验证(Leave-one-out Cross Validation),它是第二种情况的特例,此时S等于样本数N,这样对于N个样本,每次选择N-1个样本来训练数据,留一个样本来验证模型预测的好坏。此方法主要用于样本量非常少的情况,比如对于普通适中问题,N小于50时,我一般采用留一交叉验证。
# In[ ]:
params ={'alpha' :[0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000, 100000]}
ridge_regressor =GridSearchCV(Ridge(), params ,cv =5,scoring = 'neg_mean_absolute_error', n_jobs =-1)
ridge_regressor.fit(X_train ,y_train)
y_train_pred =ridge_regressor.predict(X_train) ##Predict train result
y_test_pred =ridge_regressor.predict(X_test) ##Predict test result
print("Train Results for Ridge Regressor Model:")
print(50 * '-')
print("Root mean squared error: ", sqrt(mse(y_train.values, y_train_pred)))
print("R-squared: ", r2_score(y_train.values, y_train_pred))
# In[ ]:
##Lasso Regression
params ={'alpha' :[0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000, 100000]}
lasso_regressor =GridSearchCV(Lasso(), params ,cv =15,scoring = 'neg_mean_absolute_error', n_jobs =-1)
lasso_regressor.fit(X_train ,y_train)
y_train_pred =lasso_regressor.predict(X_train) ##Predict train result
y_test_pred =lasso_regressor.predict(X_test) ##Predict test result
print("Train Results for Lasso Regressor Model:")
print(50 * '-')
print("Root mean squared error: ", sqrt(mse(y_train.values, y_train_pred)))
print("R-squared: ", r2_score(y_train.values, y_train_pred))
# In[ ]:
#Decision Tree Regression
depth =list(range(3,30))
param_grid =dict(max_depth =depth)
tree =GridSearchCV(DecisionTreeRegressor(),param_grid,cv =10)
tree.fit(X_train,y_train)
y_train_pred =tree.predict(X_train) ##Predict train result
y_test_pred =tree.predict(X_test) ##Predict test result
print("Train Results for Decision Tree Regressor Model:")
print(50 * '-')
print("Root mean squared error: ", sqrt(mse(y_train.values, y_train_pred)))
print("R-squared: ", r2_score(y_train.values, y_train_pred))
# In[ ]:
tuned_params = {'max_depth': [1, 2, 3, 4, 5], 'learning_rate': [0.01, 0.05, 0.1], 'n_estimators': [100, 200, 300, 400, 500], 'reg_lambda': [0.001, 0.1, 1.0, 10.0, 100.0]}
model = RandomizedSearchCV(XGBRegressor(), tuned_params, n_iter=20, scoring = 'neg_mean_absolute_error', cv=5, n_jobs=-1)
model.fit(X_train, y_train)
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)
print("Train Results for XGBoost Regressor Model:")
print(50 * '-')
print("Root mean squared error: ", sqrt(mse(y_train.values, y_train_pred)))
print("R-squared: ", r2_score(y_train.values, y_train_pred))
数据下载及原项目地址:https://www.kaggle.com/akshaychavan123/taxi-trip-time-prediction
感兴趣的朋友可以动手去实现一下,这个项目也是入门级别的实操项目