"""
# Real Estate Valuation

Here I am using the dataset on Real estate valuation, which I have downloaded from UCI Machine Learning Reposiroty.
Alternatively you could also use directly from Kaggle as I have upload here.

Links to Data Set : 

https://www.kaggle.com/dskagglemt/real-estate-valuation-by-uci

https://archive.ics.uci.edu/ml/datasets/Real+estate+valuation+data+set

"""
"""
This is a real estate valuation and is a regression problem. The market historical data set of real estate valuation are collected from Sindian Dist., New Taipei City, Taiwan.

* Problem Type : Regression
* Algorithm : SVR (Support Vector Regression)
"""
"""
# Import Library
"""
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
%matplotlib inline
"""
# Load the dataset
"""
df = pd.read_excel('../input/real-estate-valuation-by-uci/UCI_Real_Estate_Valuation.xlsx', sheet_name = 'Sheet1', index_col = 'No')
df.head()
"""
We could see that the feature names are too big, so lets make it short (rename them) to use it with ease.
"""
df.rename(
    columns={
        "X1 transaction date": "Transaction_Date", 
        "X2 house age": "House_Age", 
        "X3 distance to the nearest MRT station": "Distance",
        "X4 number of convenience stores": "Num_Stores_NearBy",
        "X5 latitude": "Latitude",
        "X6 longitude": "Longitude",
        "Y house price of unit area": "Target",
    },
    inplace = True
)
df.shape
"""
So there are 414 data points and 7 columns (6 Features and 1 Target)
"""
df.describe()
"""
Lets get the correlation of the features w.r.t the target.
"""
df.corr()
"""
Just sort the correlation of each feature w.r.t the target. Will select the top correlated feature which is `DIstance` with 67% correlated.

And will use this single feature to work with SVR.
"""
abs(df.corr())['Target'].sort_values(ascending=False)
"""
Scatter plot with one predictor (feature) w.r.t target.
"""
plt.figure(figsize=(15,10))
plt.scatter(x=df['Distance'], y=df['Target'])
plt.xlabel('The distance to the nearest MRT station (unit: meter)')
plt.ylabel('House price of unit area')
plt.title('Real Estate Valuation')
plt.show()
"""
# Split the data into Training and Validation set
"""
from sklearn.model_selection import train_test_split
X = np.array(df['Distance']).reshape(-1,1)
y = np.array(df['Target']).reshape(-1,1)
X[1]
y[1]
len(X), len(y)
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=99)

y_train = y_train.reshape(len(y_train),)
y_valid = y_valid.reshape(len(y_valid),)

X_train.shape, X_valid.shape, y_train.shape, y_valid.shape
X_train[1:3]
y_train[1:3]
"""
# Scaling
From the data description we know that the units for each feature is different, so lets scale it to one common unit.
"""
from sklearn.preprocessing import StandardScaler
# Standardisation replaces the values by their Z scores.

# Initialise the Scaler 
scaler = StandardScaler() 
  
# To scale data 
X_train_Scaled = scaler.fit_transform(X_train) 
# y_train_Scaled = scaler.fit_transform(y_train) 

X_valid_Scaled = scaler.transform(X_valid) 
# y_valid_Scaled = scaler.transform(y_valid) 
X_train_Scaled[1]
"""
# Linear Regression
"""
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(X_train, y_train)
from sklearn.metrics import mean_absolute_error 

print("Intercept: {:,.3f}".format(lr.intercept_))
print("Coefficient: {:,.3f}".format(lr.coef_[0]))
    
mae = mean_absolute_error(y_valid, lr.predict(X_valid))
print("MAE = {:,.2f}".format(1000*mae))

# Plot outputs
plt.figure(figsize=(10,7))
plt.scatter(x=df['Distance'], y=df['Target'])
plt.plot(X_valid, lr.predict(X_valid), color='red')
plt.xlabel('The distance to the nearest MRT station (unit: meter)')
plt.ylabel('House price of unit area')
plt.title('Real Estate Valuation - Linear Regression Prediction')

plt.show()
"""
# SVR

"""
def svr_results(X_valid, y_valid, model, title):
    
    print("C: {}".format(model.C))
    print("Epsilon: {}".format(model.epsilon))
    
    print("Intercept: {:,.3f}".format(model.intercept_[0]))
    print("Coefficient: {:,.3f}".format(model.coef_[0]))
    
    mae = mean_absolute_error(y_valid, model.predict(X_valid))
    print("MAE = {:,.2f}".format(1000*mae))
    
    perc_within_eps = 100*np.sum(y_valid - model.predict(X_valid) < eps) / len(y_valid)
    print("Percentage within Epsilon = {:,.2f}%".format(perc_within_eps))
    
    # Plot outputs
    plt.figure(figsize=(10,7))
    plt.scatter(x=df['Distance'], y=df['Target'])
    plt.plot(X_valid, model.predict(X_valid), color='red')
    plt.plot(X_valid, model.predict(X_valid)-eps, color='black')
    plt.plot(X_valid, model.predict(X_valid)+eps, color='black')
    plt.xlabel('The distance to the nearest MRT station (unit: meter)')
    plt.ylabel('house price of unit area')
    plt.title(title)
    plt.show()
"""
## Simple LinearSVR
"""
from sklearn.svm import LinearSVR
eps = 5
l_svr = LinearSVR(epsilon=eps, C=0.01, fit_intercept=True)
l_svr.fit(X_train, y_train)

svr_results(X_valid, y_valid, l_svr, 'Real Estate Valuation - Simple Linear SVR Prediction')
"""
## Simple LinearSVR with Larger Penalty (C = 1.0)
"""
eps = 5
lsvr_high_C = LinearSVR(epsilon=eps, C=1.0, fit_intercept=True)

lsvr_high_C.fit(X_train, y_train)

svr_results(X_valid, y_valid, lsvr_high_C, 'Real Estate Valuation - Simple Linear SVR (High Penality) Prediction')

"""
## Use Grid Search 
"""
from sklearn.model_selection import GridSearchCV
grid = {
    'C': np.linspace(0.01, 10),
    'epsilon': np.linspace(0.01, 10)
}
    
svr_gridsearch =  LinearSVR(fit_intercept=True, max_iter=10000)
# svr_gridsearch =  LinearSVR(fit_intercept=True, max_iter=100000)

grid_svr = GridSearchCV(svr_gridsearch, grid, scoring='neg_mean_absolute_error', cv=5)


grid_svr.fit(X_train, y_train)
"""
In-case if you have warning ""
https://stackoverflow.com/questions/52670012/convergencewarning-liblinear-failed-to-converge-increase-the-number-of-iterati 
"""
best_grid_svr_mae = grid_svr.best_estimator_
best_grid_svr_mae.fit(X_train, y_train)
svr_results(X_valid, y_valid, best_grid_svr_mae, 'Real Estate Valuation - Simple Linear SVR (Best MAE) Prediction')