# Data wrangling packages
import pandas as pd
import numpy as np

# ML packages
from sklearn.cross_validation import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor 
from sklearn.ensemble import RandomForestRegressor

# Visualizations packages
import matplotlib.pylab as plt
import seaborn as sns


%matplotlib inline

"""
Explanation: A notebook that explores the Whashingthon DC bikeshare rentals
End of explanation
"""


bike_rentals = pd.read_csv('bike_rental_hour.csv')

bike_rentals.head()

"""
Explanation: Exploring the data
End of explanation
"""


bike_rentals.cnt.hist()

sns.distplot(bike_rentals['cnt'])

"""
Explanation: Exploring the cnt column (the target)
End of explanation
"""


data = bike_rentals.corr()
df = pd.DataFrame(np.tril(data), index=data.index, 
                  columns=data.columns)
sns.heatmap(df)

"""
Explanation: Explore the data correlations
End of explanation
"""


def assign_label(hour):
    hour_segments = {1: range(6,12), 
                     2: range(12, 18),
                    3: range(18, 24),
                    4: range(0,6)}
    for label, hours in hour_segments.items():
        if hour in hours:
            return int(label)

bike_rentals['time_label'] = bike_rentals['hr'].apply(
    assign_label)

"""
Explanation: Feature engineering
Create time related features
End of explanation
"""


def rmse(pred, true):
    return np.sqrt(mean_squared_error(pred, true))

"""
Explanation: Choosing the metric
Since this is a regression problem, the RMSE error seems a 
reasonable first choice. Another metric could be 
chosen later if better alternatives appear.
End of explanation
"""


feature_columns = bike_rentals.columns.drop(['cnt', 'casual', 'registered',
                                             'dteday'])

features = bike_rentals[feature_columns]
target = bike_rentals['cnt']

f_train, f_test, t_train, t_test = train_test_split(features, 
                                                    target, 
                                                    train_size=0.8,
                                                   random_state=314)

"""
Explanation: Train/Test split
End of explanation
"""


linear_model = LinearRegression()
linear_model.fit(f_train, t_train)
rmse(linear_model.predict(f_test), t_test)

"""
Explanation: Try different models
Linear model
End of explanation
"""


decision_trees = DecisionTreeRegressor(random_state=314159265, 
                                       min_samples_leaf=3)
decision_trees.fit(f_train, t_train)
rmse(decision_trees.predict(f_test), t_test)

"""
Explanation: => The linear model perfroms poorly since a lot of non-linearities
are involved in the decision of renting a bike. 
Decision trees
End of explanation
"""


random_forests = RandomForestRegressor(random_state=314159265, 
                                       min_samples_leaf=3)
random_forests.fit(f_train, t_train)
rmse(random_forests.predict(f_test), t_test)

"""
Explanation: => The decision trees model perfroms better compared to the linear model.
In fact, this model works well with non-linearities.
Random forests
End of explanation
"""


