In [ ]:
 

Purple%20Sky%20Profile%20Header.png

PROPUESTA:

El siguiente trabajo que realice fue en base a trabajos de investigación donde muestran que el random forest. Permite trabajar de forma adecuada el tipo de datos, primero contra la regresión lineal en forma de trabajos de investigación, hasta llegar a random forest.

En el paper: Predicting Bike-Sharing Demand Using Random Forest https://doi.org/10.1111/coin.12287 Los resultados muestran que el modelo de RF tiene una alta precisión predictiva. El rendimiento del modelo de RF también se compara con un modelo de regresión lineal y muestra precisión superior.

En cuanto al modelo de RNN podríamos decir lo siguiente:

Para resolver este problema, aportamos dos nuevos enfoques basados en la memoria estándar a largo plazo (LSTM), que no solo puede aprovechar las entradas de funciones múltiples y las salidas de múltiples tiempos para mejorar la precisión de la predicción de bicicletas disponibles en una sola vez. Estos enfoques ayudarán a las agencias de bicicletas compartidas a tomar una mejor decisión para distribuir sus bicicletas a cada estibador de manera eficiente. Los resultados experimentales confirmaron que los modelos de pasos de múltiples funciones y de múltiples tiempos superan al modelo LSTM estándar.

https://www.kdnuggets.com/2019/06/random-forest-vs-neural-network.html

En comparación con LSTM y GBM ligero, Random Forest mostró una mayor precisión y se desempeñó mejor con respecto a los parámetros estadísticos utilizados para evaluar las predicciones (RMSE, MAE y R2).

https://meetingorganizer.copernicus.org/EGU2019/EGU2019-3121-1.pdf#:~:text=Compared%20to%20LSTM%20and%20light%20GBM%2C%20Random%20Forests,among%20all%20the%20four%20air%20pollutants%20ex-%20amined.

Las librerias para crear Random Forest son: from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor

para probar las metricas: from sklearn.metrics import accuracy_score

para los dataframes: pandas

para los calculos matemáticos: numpy

RANDOM FOREST

Bagging: Es un algoritmo de conjunto que ajusta múltiples modelos en diferentes subconjuntos de un conjunto de datos de entrenamiento, luego combina las predicciones de todos los modelos.

example-of-random-forest-classifier.png

Ventajas:

  • Es un modelo muy preciso y robusto, por el número de árboles de desición que participan en el proceso. -No sufre de overfitting, porque toma el promedio de todas las predicciones, que cancela el bias o sesgo ( bias es cuando no ha tenido en cuenta toda la información disponible). -El algoritmo puede ser usado en clasificación como en problemas de regresión.

Desventajas:

  • Es difícil de interpretar comparado con un arból de regresión. -Es lento en generar predicciones porque tiene múltiples árboles de decisión para el mismo input, por lo cual toma bastante tiempo.
In [160]:
import pandas as pd
import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor

import seaborn as sn
import matplotlib.pyplot as plt

from scipy import stats
import warnings
pd.options.mode.chained_assignment = None
warnings.filterwarnings("ignore", category=DeprecationWarning)

El siguiente código presenta el dataframe de entrenamiento bike:

In [161]:
train_df = pd.read_csv('bike_train.csv')
train_df['data_set'] = 'train'
train_df.head(5)
Out[161]:
instant dteday season yr mnth hr holiday weekday workingday weathersit temp atemp hum windspeed casual registered cnt data_set
0 1 1/1/2011 1 0 1 0 0 6 0 1 0.24 0.2879 0.81 0.0 3 13 16 train
1 2 1/1/2011 1 0 1 1 0 6 0 1 0.22 0.2727 0.80 0.0 8 32 40 train
2 3 1/1/2011 1 0 1 2 0 6 0 1 0.22 0.2727 0.80 0.0 5 27 32 train
3 4 1/1/2011 1 0 1 3 0 6 0 1 0.24 0.2879 0.75 0.0 3 10 13 train
4 5 1/1/2011 1 0 1 4 0 6 0 1 0.24 0.2879 0.75 0.0 0 1 1 train

En el código de abajo, se esta convirtiendo la fecha agregandole horas y minutos también se busca si hay valores nan.

In [162]:
train_df["dteday"]= pd.to_datetime(train_df["dteday"])
train_df["dteday"]=pd.to_datetime(train_df["dteday"]) + pd.to_timedelta(train_df['hr'], unit='h')
train_df.head(5)
train_df.isna().sum()
Out[162]:
instant       0
dteday        0
season        0
yr            0
mnth          0
hr            0
holiday       0
weekday       0
workingday    0
weathersit    0
temp          0
atemp         0
hum           0
windspeed     0
casual        0
registered    0
cnt           0
data_set      0
dtype: int64
In [163]:
train_df.dtypes
Out[163]:
instant                int64
dteday        datetime64[ns]
season                 int64
yr                     int64
mnth                   int64
hr                     int64
holiday                int64
weekday                int64
workingday             int64
weathersit             int64
temp                 float64
atemp                float64
hum                  float64
windspeed            float64
casual                 int64
registered             int64
cnt                    int64
data_set              object
dtype: object
In [164]:
print(train_df.head(5))

train_df = train_df.drop('data_set',axis=1)
train_df = train_df.drop('instant',axis=1)
   instant              dteday  season  yr  mnth  hr  holiday  weekday  \
0        1 2011-01-01 00:00:00       1   0     1   0        0        6   
1        2 2011-01-01 01:00:00       1   0     1   1        0        6   
2        3 2011-01-01 02:00:00       1   0     1   2        0        6   
3        4 2011-01-01 03:00:00       1   0     1   3        0        6   
4        5 2011-01-01 04:00:00       1   0     1   4        0        6   

   workingday  weathersit  temp   atemp   hum  windspeed  casual  registered  \
0           0           1  0.24  0.2879  0.81        0.0       3          13   
1           0           1  0.22  0.2727  0.80        0.0       8          32   
2           0           1  0.22  0.2727  0.80        0.0       5          27   
3           0           1  0.24  0.2879  0.75        0.0       3          10   
4           0           1  0.24  0.2879  0.75        0.0       0           1   

   cnt data_set  
0   16    train  
1   40    train  
2   32    train  
3   13    train  
4    1    train  
In [165]:
categoryVariableList = ["hr","weekday","mnth","season","weathersit","holiday","workingday"]
for var in categoryVariableList:
    train_df[var] = train_df[var].astype("category")
In [ ]:
 
In [166]:
dailyData  = train_df.drop(["dteday"],axis=1)
In [ ]:
 
In [167]:
fig, axes = plt.subplots(nrows=2,ncols=2)
fig.set_size_inches(12, 10)
sn.boxplot(data=train_df,y="cnt",orient="v",ax=axes[0][0])
sn.boxplot(data=train_df,y="cnt",x="season",orient="v",ax=axes[0][1])
sn.boxplot(data=train_df,y="cnt",x="hr",orient="v",ax=axes[1][0])
sn.boxplot(data=train_df,y="cnt",x="workingday",orient="v",ax=axes[1][1])

axes[0][0].set(ylabel='Contados',title="Diagrama de caja de Bicicletas contadas registradas o no registradas")
axes[0][1].set(xlabel='Estaciones', ylabel='Contados',title=" Diagrama de cajas a lo largo de la temporada")
axes[1][0].set(xlabel='Horas del día', ylabel='Contados',title="Diagrama de cajas a lo largo del día")
axes[1][1].set(xlabel='Días laborables', ylabel='Contados',title="Diagrama de cajas a lo largo de días laborales")
Out[167]:
[Text(0.5, 0, 'Días laborables'),
 Text(0, 0.5, 'Contados'),
 Text(0.5, 1.0, 'Diagrama de cajas a lo largo de días laborales')]
In [168]:
train_dfWithoutOutliers = train_df[np.abs(train_df["cnt"]-train_df["cnt"].mean())<=(3*train_df["cnt"].std())]
In [169]:
print ("Forma de los outliers en un inicio: ",train_df.shape)
print ("Forma de los outliers después: ",train_dfWithoutOutliers.shape)
Forma de los outliers en un inicio:  (11999, 16)
Forma de los outliers después:  (11846, 16)
In [170]:
corrMatt = train_df[["temp","atemp","casual","registered","hum","windspeed","cnt"]].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)
Out[170]:
<AxesSubplot:>
In [171]:
fig,(ax1,ax2,ax3) = plt.subplots(ncols=3)
fig.set_size_inches(12, 5)
sn.regplot(x="temp", y="cnt", data=train_df,ax=ax1)
sn.regplot(x="windspeed", y="cnt", data=train_df,ax=ax2)
sn.regplot(x="hum", y="cnt", data=train_df,ax=ax3)
Out[171]:
<AxesSubplot:xlabel='hum', ylabel='cnt'>
In [ ]:
 
In [172]:
categoricalFeatureNames = ["season","holiday","workingday","weathersit","weekday","mnth","yr","hr"]
numericalFeatureNames = ["temp","hum","windspeed","atemp"]
dropFeatures = ['casual',"cnt","dtetime","registered"]
In [173]:
#from sklearn.ensemble import RandomForestRegressor
#rfModel = RandomForestRegressor(n_estimators=25)
#yLabelsLog = np.log1p(yLabels)
#print(yLabelsLog.shape)
#print(dataTrain.shape)
#rfModel.fit(dataTrain,yLabelsLog)
#preds = rfModel.predict(X= dataTrain)
#print ("RMSLE Value For Random Forest: ",rmsle(np.exp(yLabelsLog),np.exp(preds),False))
In [174]:
print(train_df.head(5))
               dteday season  yr mnth hr holiday weekday workingday  \
0 2011-01-01 00:00:00      1   0    1  0       0       6          0   
1 2011-01-01 01:00:00      1   0    1  1       0       6          0   
2 2011-01-01 02:00:00      1   0    1  2       0       6          0   
3 2011-01-01 03:00:00      1   0    1  3       0       6          0   
4 2011-01-01 04:00:00      1   0    1  4       0       6          0   

  weathersit  temp   atemp   hum  windspeed  casual  registered  cnt  
0          1  0.24  0.2879  0.81        0.0       3          13   16  
1          1  0.22  0.2727  0.80        0.0       8          32   40  
2          1  0.22  0.2727  0.80        0.0       5          27   32  
3          1  0.24  0.2879  0.75        0.0       3          10   13  
4          1  0.24  0.2879  0.75        0.0       0           1    1  
In [ ]:
 

En el código de abajo se prueba el dataset bike para hacer el testing.

In [175]:
test_df = pd.read_csv('bike_test.csv')
test_df.head(5)
Out[175]:
instant dteday season yr mnth hr holiday weekday workingday weathersit temp atemp hum windspeed
0 12000 20/05/2012 2 1 5 4 0 0 0 1 0.52 0.5000 0.68 0.0896
1 12001 20/05/2012 2 1 5 5 0 0 0 1 0.50 0.4848 0.72 0.1045
2 12002 20/05/2012 2 1 5 6 0 0 0 1 0.50 0.4848 0.63 0.1343
3 12003 20/05/2012 2 1 5 7 0 0 0 1 0.52 0.5000 0.68 0.1940
4 12004 20/05/2012 2 1 5 8 0 0 0 1 0.56 0.5303 0.56 0.1642
In [176]:
test_df.head(5)
test_df.isna().sum()
Out[176]:
instant       0
dteday        0
season        0
yr            0
mnth          0
hr            0
holiday       0
weekday       0
workingday    0
weathersit    0
temp          0
atemp         0
hum           0
windspeed     0
dtype: int64
In [177]:
print(test_df.head(5))
   instant      dteday  season  yr  mnth  hr  holiday  weekday  workingday  \
0    12000  20/05/2012       2   1     5   4        0        0           0   
1    12001  20/05/2012       2   1     5   5        0        0           0   
2    12002  20/05/2012       2   1     5   6        0        0           0   
3    12003  20/05/2012       2   1     5   7        0        0           0   
4    12004  20/05/2012       2   1     5   8        0        0           0   

   weathersit  temp   atemp   hum  windspeed  
0           1  0.52  0.5000  0.68     0.0896  
1           1  0.50  0.4848  0.72     0.1045  
2           1  0.50  0.4848  0.63     0.1343  
3           1  0.52  0.5000  0.68     0.1940  
4           1  0.56  0.5303  0.56     0.1642  
In [ ]:
 
In [178]:
print(test_df.head(5))
   instant      dteday  season  yr  mnth  hr  holiday  weekday  workingday  \
0    12000  20/05/2012       2   1     5   4        0        0           0   
1    12001  20/05/2012       2   1     5   5        0        0           0   
2    12002  20/05/2012       2   1     5   6        0        0           0   
3    12003  20/05/2012       2   1     5   7        0        0           0   
4    12004  20/05/2012       2   1     5   8        0        0           0   

   weathersit  temp   atemp   hum  windspeed  
0           1  0.52  0.5000  0.68     0.0896  
1           1  0.50  0.4848  0.72     0.1045  
2           1  0.50  0.4848  0.63     0.1343  
3           1  0.52  0.5000  0.68     0.1940  
4           1  0.56  0.5303  0.56     0.1642  
In [179]:
byday = train_df.groupby('weekday')
byday['casual'].sum().reset_index()
Out[179]:
weekday casual
0 0 83768
1 1 41792
2 2 34122
3 3 30481
4 4 34358
5 5 45278
6 6 90769
In [180]:
byday['registered'].sum().reset_index()
Out[180]:
weekday registered
0 0 174946
1 1 221902
2 2 242865
3 3 232363
4 4 243990
5 5 239590
6 6 186757
In [181]:
 #create binary features which show if day is Saturday/Sunday
train_df['Saturday']=0
train_df.Saturday[train_df.weekday==5]=1

train_df['Sunday']=0
train_df.Sunday[train_df.weekday==6]=1
print(train_df.head(5))
               dteday season  yr mnth hr holiday weekday workingday  \
0 2011-01-01 00:00:00      1   0    1  0       0       6          0   
1 2011-01-01 01:00:00      1   0    1  1       0       6          0   
2 2011-01-01 02:00:00      1   0    1  2       0       6          0   
3 2011-01-01 03:00:00      1   0    1  3       0       6          0   
4 2011-01-01 04:00:00      1   0    1  4       0       6          0   

  weathersit  temp   atemp   hum  windspeed  casual  registered  cnt  \
0          1  0.24  0.2879  0.81        0.0       3          13   16   
1          1  0.22  0.2727  0.80        0.0       8          32   40   
2          1  0.22  0.2727  0.80        0.0       5          27   32   
3          1  0.24  0.2879  0.75        0.0       3          10   13   
4          1  0.24  0.2879  0.75        0.0       0           1    1   

   Saturday  Sunday  
0         0       1  
1         0       1  
2         0       1  
3         0       1  
4         0       1  
In [182]:
dataRel = train_df.drop(['dteday', 'cnt'], axis=1)
In [183]:
#print(train_df.head(4))
print(train_df['temp'])
0        0.24
1        0.22
2        0.22
3        0.24
4        0.24
         ... 
11994    0.60
11995    0.58
11996    0.56
11997    0.56
11998    0.54
Name: temp, Length: 11999, dtype: float64
In [184]:
#en este codigo se busca encontrar tb. los Nan

test_df.isna().sum()
Out[184]:
instant       0
dteday        0
season        0
yr            0
mnth          0
hr            0
holiday       0
weekday       0
workingday    0
weathersit    0
temp          0
atemp         0
hum           0
windspeed     0
dtype: int64
In [185]:
print(test_df.head(5))
   instant      dteday  season  yr  mnth  hr  holiday  weekday  workingday  \
0    12000  20/05/2012       2   1     5   4        0        0           0   
1    12001  20/05/2012       2   1     5   5        0        0           0   
2    12002  20/05/2012       2   1     5   6        0        0           0   
3    12003  20/05/2012       2   1     5   7        0        0           0   
4    12004  20/05/2012       2   1     5   8        0        0           0   

   weathersit  temp   atemp   hum  windspeed  
0           1  0.52  0.5000  0.68     0.0896  
1           1  0.50  0.4848  0.72     0.1045  
2           1  0.50  0.4848  0.63     0.1343  
3           1  0.52  0.5000  0.68     0.1940  
4           1  0.56  0.5303  0.56     0.1642  

En este código se busca concatenar ambos datasets para lluego separar por horas

Luego de haber concatenado todo, buscamos mostrar en el histograma la distribución de los datos. Esto nos permite de forma analítica conocer el contenido. Si realmente afecta el clima, el horario laboral o la humedad, etc.

In [186]:
fig, ax = plt.subplots()
ax.hist(train_df['temp'],edgecolor='yellow', label="Rowing",bins=10)
ax.set_xlabel("Temperatura")
ax.set_ylabel("valores")
plt.title('Distribucici&oacute;n de la temperatura')

fig, ax = plt.subplots(1)
ax.hist(train_df['atemp'], label="Rowing",bins=10,color='black',edgecolor='green')
ax.set_xlabel("grados Celsius")
ax.set_ylabel("valores")
plt.title('Sensaci&oacute;n térmica en grados Celsius')


fig, ax = plt.subplots()
ax.hist(train_df['hum'], label="Rowing",bins=10,color='orange',edgecolor='green')
ax.set_xlabel("Humedad")
ax.set_ylabel("valores")
plt.title('Distribucici&oacute;n de la Humedad')

fig, ax = plt.subplots()
ax.hist(train_df['windspeed'], label="Rowing",bins=10,color='green',edgecolor='pink')
ax.set_xlabel("Velocidad del viento")
ax.set_ylabel("valores")
plt.title('Distribucici&oacute;n de la velocidad del viento')

fig, ax = plt.subplots()
ax.hist(train_df['workingday'], label="Rowing",bins=10,color='pink',edgecolor='green')
ax.set_xlabel("D&iacute;as laborables")
ax.set_ylabel("valores")
plt.title('Distribucici&oacute;n de d&iacute;as laborables')
plt.tight_layout();

fig, ax = plt.subplots()
ax.hist(train_df['holiday'], label="Rowing",bins=10,color='grey',edgecolor='green')
ax.set_xlabel("D&iacute;as feriados")
ax.set_ylabel("valores")
plt.title('Distribucici&oacute;n de d&iacute;as feriados')
plt.tight_layout();

fig, ax = plt.subplots()
ax.hist(train_df['season'], label="Rowing",bins=10,color='purple',edgecolor='green')
ax.set_xlabel("Estaci&oacute;n")
ax.set_ylabel("valores")
plt.title('Estaciones en el estado de Washignton')
plt.tight_layout();

fig, ax = plt.subplots()
ax.hist(train_df['weathersit'], label="Rowing",bins=10,color='magenta',edgecolor='green')
ax.set_xlabel("Clima")
ax.set_ylabel("valores")
plt.title('Clima en Washignton D.C.')
plt.tight_layout();

Distribución de las bicicletas que han sido rentadas:

In [187]:
train_df['cnt'].plot.hist(bins=20, figsize=(12,8))
Out[187]:
<AxesSubplot:ylabel='Frequency'>

La primera prueba que se ha realizado, ha sido la siguiente: Utilizar solamente algunas columnas basandonos en el histograma. Los cuales nos pueden ayudar a predecir.

In [188]:
print(train_df['temp'])
0        0.24
1        0.22
2        0.22
3        0.24
4        0.24
         ... 
11994    0.60
11995    0.58
11996    0.56
11997    0.56
11998    0.54
Name: temp, Length: 11999, dtype: float64

Programación

-n_stimators es el número de arboles que queremos construir antes de tomar el promedio de los votos.

-random_State es la semilla utilizada por el número generados aleatorio.

-En este caso tomamos el valor del test que decida la libreria, como el valor del train.

In [189]:
rf = RandomForestRegressor(n_estimators=25,
                           random_state=5)
                           
# Fit rf to the training set
X_train=train_df[['windspeed','hum','workingday','weathersit','hr']]
print(X_train)
y_train= train_df['temp']
#print(y_train)
#print(X_train)
grid_rf=(rf.fit(X_train, y_train))
print(grid_rf)
       windspeed   hum workingday weathersit  hr
0         0.0000  0.81          0          1   0
1         0.0000  0.80          0          1   1
2         0.0000  0.80          0          1   2
3         0.0000  0.75          0          1   3
4         0.0000  0.75          0          1   4
...          ...   ...        ...        ...  ..
11994     0.1642  0.56          0          1  23
11995     0.1045  0.53          0          1   0
11996     0.0000  0.52          0          1   1
11997     0.0000  0.52          0          1   2
11998     0.0896  0.56          0          1   3

[11999 rows x 5 columns]
RandomForestRegressor(n_estimators=25, random_state=5)

Luego, una vez que se construye el modelo Random Forest, podemos extraer directamente la importancia de las características con random forest, utilizando el atributo featureimportances del modelo RandomForestClassifier En la gráfica retorna los valores que considera más importante al tomar la temperatura lo cual nos dio 0.19, pero se reduce al tomar ahora la velocidad del aire.

In [190]:
importances = pd.Series(data=rf.feature_importances_,
                        index= X_train.columns)

# Sort importances
importances_sorted = importances.sort_values()

# Draw a horizontal barplot of importances_sorted
importances_sorted.plot(kind='barh', color='purple')
plt.title('Características Importantes para considerarse')
plt.show()

Para el test, utilizamos las mismas columnas.

In [191]:
X_train=train_df[['hum','workingday','weathersit','hr','temp']]
print(X_train)
X_test=test_df[['hum','workingday','weathersit','hr','temp']]

y_train= train_df['windspeed']
y_test= test_df['windspeed']
        hum workingday weathersit  hr  temp
0      0.81          0          1   0  0.24
1      0.80          0          1   1  0.22
2      0.80          0          1   2  0.22
3      0.75          0          1   3  0.24
4      0.75          0          1   4  0.24
...     ...        ...        ...  ..   ...
11994  0.56          0          1  23  0.60
11995  0.53          0          1   0  0.58
11996  0.52          0          1   1  0.56
11997  0.52          0          1   2  0.56
11998  0.56          0          1   3  0.54

[11999 rows x 5 columns]

PARA MEJORAR LA PUNTUACIÓN AJUSTAR DOS VECES EL MODELO:

In [196]:
from sklearn.metrics import mean_squared_error
from math import sqrt
# Predict the test set labels
y_pred = rf.predict(X_test)

# Evaluate the test set RMSE
rmse_test = sqrt(mean_squared_error(y_test, y_pred))

# Print rmse_test
print('Prueba de RMSE rf: {:.2f}'.format(rmse_test))
Prueba de RMSE rf: 0.13
In [197]:
from sklearn.ensemble import RandomForestRegressor
 
rf = RandomForestRegressor().fit(X_train, y_train)
 

print(np.sqrt(mean_squared_error(y_test, y_pred)))
0.12557948913384465
In [ ]:
 
In [ ]:
 
In [ ]: