# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# +
import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
import seaborn as sns

# %matplotlib inline
# -

from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import roc_auc_score
from sklearn.tree import export_text
from sklearn.ensemble import RandomForestRegressor

data = 'https://raw.githubusercontent.com/alexeygrigorev/datasets/master/AB_NYC_2019.csv'
# !curl $data > AB_NYC_2019.csv

# +
columns = [
    'neighbourhood_group', 'room_type', 'latitude', 'longitude',
    'minimum_nights', 'number_of_reviews','reviews_per_month',
    'calculated_host_listings_count', 'availability_365',
    'price'
]

df = pd.read_csv('AB_NYC_2019.csv', usecols=columns)
df.reviews_per_month = df.reviews_per_month.fillna(0)
# -

df.price = np.log1p(df.price)

# +
df_full_train, df_test = train_test_split(df, test_size=0.2, random_state=1)
df_train, df_val = train_test_split(df_full_train, test_size=0.25, random_state=1)

df_train = df_train.reset_index(drop=True)
df_val = df_val.reset_index(drop=True)
df_test = df_test.reset_index(drop=True)

y_train = df_train.price.values
y_val = df_val.price.values
y_test = df_test.price.values

del df_train['price']
del df_val['price']
del df_test['price']
# -

categorical = list(df.dtypes[df.dtypes == 'object'].index)
numerical = df.select_dtypes(include=[np.number]).columns



categorical_columns = ['neighbourhood_group','room_type']
numerical_columns   = ['latitude',
           'longitude',
           'minimum_nights',
           'number_of_reviews',
           'reviews_per_month',
           'calculated_host_listings_count',
           'availability_365']
target_column = 'price'

# +
dv = DictVectorizer(sparse=False)

train_dict = df_train[categorical_columns + numerical_columns].to_dict(orient='records')
X_train = dv.fit_transform(train_dict)

val_dict = df_val[categorical_columns + numerical_columns].to_dict(orient='records')
X_val = dv.transform(val_dict)
# -

##Question 1
#Let's train a decision tree regressor to predict the price variable.
#Train a model with max_depth=1


dt = DecisionTreeRegressor(max_depth=1)
dt.fit(X_train, y_train)

print(export_text(dt, feature_names=dv.get_feature_names()))

#Which feature is used for splitting the data?
 #room_type *** 
 #neighbourhood_group
 #number_of_reviews
 #reviews_per_month

##Question 2
#Train a random forest model with these parameters:
 #n_estimators=10
 #random_state=1
 #n_jobs=-1 (optional - to make training faster)

# +

from sklearn.ensemble import RandomForestRegressor
# -

rf = RandomForestRegressor(n_estimators=10,
                            random_state=1,
                            n_jobs = -1)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_val)


def rmse(y, y_pred):
    se = (y - y_pred) ** 2
    mse = se.mean()
    return np.sqrt(mse)



rmse(y_val, y_pred)

#What's the RMSE of this model on validation?
 #0.059
 #0.259
 #0.459 ***** 
 #0.659

# +
##Question 3
#Now let's experiment with the n_estimators parameter
#Try different values of this parameter from 10 to 200 with step 10
#Set random_state to 1
#Evaluate the model on the validation dataset
# -



# +
scores = []

for n in range(10, 200, 10):
    rf = RandomForestRegressor(n_estimators=n, 
                               random_state=1)
    rf.fit(X_train, y_train)

    y_pred = rf.predict(X_val)

    e = rmse(y_val, y_pred)
    
    print(n,e)
# -

#After which value of n_estimators does RMSE stop improving?
 #10 ******
 #50
 #70
 #120

# +
#Question 4
#Let's select the best max_depth:
#Try different values of max_depth: [10, 15, 20, 25]
#For each of these values, try different values of n_estimators from 10 till 200 (with step 10)
#Fix the random seed: random_state=1

# +
scores = []

for d in [10, 15, 20, 25]:
    for n in range(10, 200, 10):
        rf = RandomForestRegressor(n_estimators=n,
                                    max_depth=d,
                                    random_state=1)
        rf.fit(X_train, y_train)

        y_pred = rf.predict(X_val)

        f = rmse(y_val, y_pred)
    
        print(n,d,f)

# +
scores = []

for d in [10, 15, 20, 25]:
    for n in range(10, 200, 10):
        rf = RandomForestRegressor(n_estimators=n,
                                    max_depth=d,
                                    random_state=1)
        rf.fit(X_train, y_train)

        y_pred = rf.predict(X_val)

        f = rmse(y_val, y_pred)
    
        scores.append((d,n,f))
# -

columns = [ 'max_depth','n_estimators', 'rmse']
df_scores = pd.DataFrame(scores, columns=columns)



# +
for d in [10, 15, 20, 25]:
    df_subset = df_scores[df_scores.max_depth == d]
    
    plt.plot(df_subset.n_estimators, df_subset.rmse,
             label='max_depth=%d' % d)

plt.legend()
# -

#What's the best max_depth:
 #10
 #15
 #20
 #25

#Question 5
#We can extract feature importance information from tree-based models.
#At each step of the decision tree learning algorith, it finds the best split. When doint it, we can calculate "gain" - the reduction in impurity before and after the split. This gain is quite useful in understanding what are the imporatant features for tree-based models.
#In Scikit-Learn, tree-based models contain this information in the feature_importances_ field.
#For this homework question, we'll find the most important feature:
 #Train the model with these parametes:
  #n_estimators=10,
  #max_depth=20,
  #random_state=1,
  #n_jobs=-1 (optional)
  #Get the feature importance information from this model

dt = DecisionTreeRegressor(n_estimators=10, 
                            max_depth=20, 
                            random_state=1,
                            n_jobs=-1)
dt.fit(X_train, y_train)

print(export_text(dt, feature_names=dv.get_feature_names()))

#What's the most important feature?
 #neighbourhood_group=Manhattan
 #room_type=Entire home/apt
 #longitude
 #latitude

# +
#Question 6
#Now let's train an XGBoost model! For this question, we'll tune the eta parameter
#Install XGBoost
#Create DMatrix for train and validation
#Create a watchlist
#Train a model with these parameters for 100 rounds:
#xgb_params = {
#    'eta': 0.3, 
#    'max_depth': 6,
#    'min_child_weight': 1,

#    'objective': 'reg:squarederror',
#    'nthread': 8,

#    'seed': 1,
#    'verbosity': 1,
#}
# -

# !pip install xgboost

import xgboost as xgb

StarcoderdataJupyterScriptsDedupFiltered