Proyecto Optativa

Last updated: August 15th, 20202020-08-15Project preview

Proyecto final de asignatura

Alumno: Werlen Alexander

In [1]:
#importando las librerias necesarias

import numpy as np 
import pandas as pd 
%matplotlib inline
import matplotlib.pyplot as plt  
import seaborn as sns
color = sns.color_palette()
sns.set_style('darkgrid')

#Truquillo para evitar que se loggeen warningns, y así conseguir que el notebook quede más estético
import warnings
def ignore_warn(*args, **kwargs):
    pass
warnings.warn = ignore_warn 

from scipy import stats
from scipy.stats import norm, skew

pd.set_option('display.float_format', lambda x: '{:.3f}'.format(x)) #Limitando float outputs a 3 decimales

from subprocess import check_output

Recolección de datos

In [2]:
#Transformando los datasets de los csv a data frames de pandas

train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')

1. Limpieza de datos

1A. Analisando la estructura del data set

In [3]:
#Mostrando las 5 primeras filas del data set train
train.head()
Out[3]:
Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour Utilities ... PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold SaleType SaleCondition SalePrice
0 1 60 RL 65.000 8450 Pave NaN Reg Lvl AllPub ... 0 NaN NaN NaN 0 2 2008 WD Normal 208500
1 2 20 RL 80.000 9600 Pave NaN Reg Lvl AllPub ... 0 NaN NaN NaN 0 5 2007 WD Normal 181500
2 3 60 RL 68.000 11250 Pave NaN IR1 Lvl AllPub ... 0 NaN NaN NaN 0 9 2008 WD Normal 223500
3 4 70 RL 60.000 9550 Pave NaN IR1 Lvl AllPub ... 0 NaN NaN NaN 0 2 2006 WD Abnorml 140000
4 5 60 RL 84.000 14260 Pave NaN IR1 Lvl AllPub ... 0 NaN NaN NaN 0 12 2008 WD Normal 250000

5 rows × 81 columns

In [4]:
#Mostrando las 5 primeras filas del dataset test
test.head()
Out[4]:
Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour Utilities ... ScreenPorch PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold SaleType SaleCondition
0 1461 20 RH 80.000 11622 Pave NaN Reg Lvl AllPub ... 120 0 NaN MnPrv NaN 0 6 2010 WD Normal
1 1462 20 RL 81.000 14267 Pave NaN IR1 Lvl AllPub ... 0 0 NaN NaN Gar2 12500 6 2010 WD Normal
2 1463 60 RL 74.000 13830 Pave NaN IR1 Lvl AllPub ... 0 0 NaN MnPrv NaN 0 3 2010 WD Normal
3 1464 60 RL 78.000 9978 Pave NaN IR1 Lvl AllPub ... 0 0 NaN NaN NaN 0 6 2010 WD Normal
4 1465 120 RL 43.000 5005 Pave NaN IR1 HLS AllPub ... 144 0 NaN NaN NaN 0 1 2010 WD Normal

5 rows × 80 columns

In [5]:
train.shape
Out[5]:
(1460, 81)
In [6]:
test.shape
Out[6]:
(1459, 80)

1B. Eliminando outliers

La documentación del dataset que se está utilizando avisa sobre la existencia de outliers (valores atípicos). Por lo que debemos de analizar la data para encontrar algunos.

In [7]:
fig, ax = plt.subplots()
ax.scatter(x = train['GrLivArea'], y = train['SalePrice'])
plt.ylabel('SalePrice', fontsize=13)
plt.xlabel('GrLivArea', fontsize=13)
plt.show()

Podemos ver que a la derecha del gráfico encontramos dos valores que claramente no siguen la misma tendencia que la data general, por lo que resulta beneficioso el eliminarlos.

In [8]:
train = train.drop(train[(train['GrLivArea']>4000) & (train['SalePrice']<300000)].index)

#revisando el gráfico de nuevo
fig, ax = plt.subplots()
ax.scatter(train['GrLivArea'], train['SalePrice'])
plt.ylabel('SalePrice', fontsize=13)
plt.xlabel('GrLivArea', fontsize=13)
plt.show()

Hay más outliers en el dataset, pero no son de suficiente magnitud como para que concideremos el eliminar de la muestra esas casas.

1D. Manipulando la data faltante

En todo dataset puede haber información faltante o corrupta que es capaz de crashear el proceso de entrenamiento del modelo.

In [9]:
ntrain = train.shape[0]
ntest = test.shape[0]
y_train = train.SalePrice.values
all_data = pd.concat((train, test)).reset_index(drop=True)
In [10]:
#Buscando información faltante
all_data_na = (all_data.isnull().sum() / len(all_data)) * 100
all_data_na = all_data_na.drop(all_data_na[all_data_na == 0].index).sort_values(ascending=False)[:30]
missing_data = pd.DataFrame({'Missing Ratio' :all_data_na})

#plotting
f, ax = plt.subplots(figsize=(15, 12))
plt.xticks(rotation='90')
sns.barplot(x=all_data_na.index, y=all_data_na)
plt.xlabel('Features', fontsize=15)
plt.ylabel('Porcentaje de valores faltantes', fontsize=15)
plt.title('Features', fontsize=15)
Out[10]:
Text(0.5,1,'Features')

Encontramos que hay 5 variables con un enorme ratio de información faltante, por lo que decidimos el analizar la documentación para entender cual es el problema. Encontramos lo siguiente:

In [11]:
#En la variable PoolQC (calidad de pileta) encontramos que NA significa que, como la casa no tiene pileta esta no posee una calidad de pileta
#Por lo que vamos a rellenar todos estos espacios en blanco con None
all_data["PoolQC"] = all_data["PoolQC"].fillna("None")

#Hacemos lo mismo con demas variables que tiene el mismo problema
all_data["MiscFeature"] = all_data["MiscFeature"].fillna("None")
all_data["Alley"] = all_data["Alley"].fillna("None")
all_data["Fence"] = all_data["Fence"].fillna("None")
all_data["FireplaceQu"] = all_data["FireplaceQu"].fillna("None")
In [12]:
#En LotFrontage, podemos rellenar estos espacios con el promedio de cada barrio
all_data["LotFrontage"] = all_data.groupby("Neighborhood")["LotFrontage"].transform(
    lambda x: x.fillna(x.median()))
In [13]:
#En GarageType, GarageFinish, GarageQual y GarageCond remplazamos por None
for col in ('GarageType', 'GarageFinish', 'GarageQual', 'GarageCond'):
    all_data[col] = all_data[col].fillna('None')
In [14]:
#En GarageYrBlt, GarageArea y GarageCars remplazamos por 0
for col in ('GarageYrBlt', 'GarageArea', 'GarageCars'):
    all_data[col] = all_data[col].fillna(0)
In [15]:
#En BsmtFinSF1, BsmtFinSF2, BsmtUnfSF, TotalBsmtSF, BsmtFullBath y BsmtHalfBath seguramente el valor sea 0 debido a que no existe un sotano
for col in ('BsmtFinSF1', 'BsmtFinSF2', 'BsmtUnfSF','TotalBsmtSF', 'BsmtFullBath', 'BsmtHalfBath'):
    all_data[col] = all_data[col].fillna(0)
In [16]:
#En BsmtQual, BsmtCond, BsmtExposure, BsmtFinType1 and BsmtFinType2 debe de significar que no existe un sótano
for col in ('BsmtQual', 'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinType2'):
    all_data[col] = all_data[col].fillna('None')
In [17]:
#En Functional la documentacion dice que NA significa típico
all_data["Functional"] = all_data["Functional"].fillna("Typ")
In [18]:
#En MasVnrArea y MasVnrType seguramente signifique que debe de ser 0
all_data["MasVnrType"] = all_data["MasVnrType"].fillna("None")
all_data["MasVnrArea"] = all_data["MasVnrArea"].fillna(0)
In [19]:
#En MSZoning seguramente el valor más comun es "RL"
all_data['MSZoning'] = all_data['MSZoning'].fillna(all_data['MSZoning'].mode()[0])
In [20]:
#En Utilities (Servicios disponibles(gas, electricidad, agua)), decidimos que podemos prescindir de esta, ya que al ser una ciudad casi todas las casas van a tener todos los servicios, por lo que no hay forma en la que esta variable ayude en el entrenamiento del modelo
all_data = all_data.drop(['Utilities'], axis=1)
In [21]:
#En las siguientes variables solo se tuvo 1 valor en blanco por cada una, por lo que se las remplazará por el valor más frecuente de cada variable
all_data['Electrical'] = all_data['Electrical'].fillna(all_data['Electrical'].mode()[0])
all_data['KitchenQual'] = all_data['KitchenQual'].fillna(all_data['KitchenQual'].mode()[0])
all_data['Exterior1st'] = all_data['Exterior1st'].fillna(all_data['Exterior1st'].mode()[0])
all_data['Exterior2nd'] = all_data['Exterior2nd'].fillna(all_data['Exterior2nd'].mode()[0])
all_data['SaleType'] = all_data['SaleType'].fillna(all_data['SaleType'].mode()[0])
all_data['MSSubClass'] = all_data['MSSubClass'].fillna("None")

Chequeando si siguen existiendo valores en blanco

In [22]:
#Check remaining missing values if any 
all_data_na = (all_data.isnull().sum() / len(all_data)) * 100
all_data_na = all_data_na.drop(all_data_na[all_data_na == 0].index).sort_values(ascending=False)
missing_data = pd.DataFrame({'Missing Ratio' :all_data_na})
missing_data.head()
Out[22]:
Missing Ratio
SalePrice 50.017

Podemos ver que ya no existen valores faltantes (Ademas del coste de venta de las casas correspondientes al dataset de testing)

2 Análisis de datos

Mediante diferentes herramientas vamos a divisar las variables que pueden ayudarnos a construir nuestro modelo.

2A. Integrando variables que pueden ser utiles

Nos parece beneficioso el crear una variable que represente a la superficie total de la casa, esto puede evitar que utilizemos demas variables redundantes.

In [23]:
#Creando variable que represente la superficie total de la casa
all_data['TotalSF'] = all_data['TotalBsmtSF'] + all_data['1stFlrSF'] + all_data['2ndFlrSF']

2B. Separando dataset en una porcion para entrenar al modelo y otra para testearlo

In [24]:
train = all_data[:ntrain]
test = all_data[ntrain:]
In [25]:
train.shape
Out[25]:
(1458, 81)
In [26]:
test.shape
Out[26]:
(1459, 81)

De esta manera tenemos el dataframe de entrenamiento con 1458 casas las cuales le entregaremos al modelo para que aprenda, y con las restantes testearemos la fidelidad del modelo.

In [27]:
train.head()
Out[27]:
1stFlrSF 2ndFlrSF 3SsnPorch Alley BedroomAbvGr BldgType BsmtCond BsmtExposure BsmtFinSF1 BsmtFinSF2 ... SaleType ScreenPorch Street TotRmsAbvGrd TotalBsmtSF WoodDeckSF YearBuilt YearRemodAdd YrSold TotalSF
0 856 854 0 None 3 1Fam TA No 706.000 0.000 ... WD 0 Pave 8 856.000 0 2003 2003 2008 2566.000
1 1262 0 0 None 3 1Fam TA Gd 978.000 0.000 ... WD 0 Pave 6 1262.000 298 1976 1976 2007 2524.000
2 920 866 0 None 3 1Fam TA Mn 486.000 0.000 ... WD 0 Pave 6 920.000 0 2001 2002 2008 2706.000
3 961 756 0 None 3 1Fam Gd No 216.000 0.000 ... WD 0 Pave 7 756.000 0 1915 1970 2006 2473.000
4 1145 1053 0 None 4 1Fam TA Av 655.000 0.000 ... WD 0 Pave 9 1145.000 192 2000 2000 2008 3343.000

5 rows × 81 columns

In [28]:
test.head()
Out[28]:
1stFlrSF 2ndFlrSF 3SsnPorch Alley BedroomAbvGr BldgType BsmtCond BsmtExposure BsmtFinSF1 BsmtFinSF2 ... SaleType ScreenPorch Street TotRmsAbvGrd TotalBsmtSF WoodDeckSF YearBuilt YearRemodAdd YrSold TotalSF
1458 896 0 0 None 2 1Fam TA No 468.000 144.000 ... WD 120 Pave 5 882.000 140 1961 1961 2010 1778.000
1459 1329 0 0 None 3 1Fam TA No 923.000 0.000 ... WD 0 Pave 6 1329.000 393 1958 1958 2010 2658.000
1460 928 701 0 None 3 1Fam TA No 791.000 0.000 ... WD 0 Pave 6 928.000 212 1997 1998 2010 2557.000
1461 926 678 0 None 3 1Fam TA No 602.000 0.000 ... WD 0 Pave 7 926.000 360 1998 1998 2010 2530.000
1462 1280 0 0 None 2 TwnhsE TA No 263.000 0.000 ... WD 144 Pave 5 1280.000 0 1992 1992 2010 2560.000

5 rows × 81 columns

2.C Eligiendo variables a utilizar

Es razonable el pensar que hay variables que no necesariamente influyen en el precio final de la casa, por lo que es de nuestro interes el realizar un analisis que evidencie cuales son los parámetros a tener en cuenta para la creacion de nuestro modelo.

In [29]:
#Generando un mapa que muestra la correlación entre diferentes variables
corrmat = train.corr()
plt.subplots(figsize=(12,9))
sns.heatmap(corrmat, vmax=0.9, square=True)
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fd4de4589b0>
In [30]:
#Matriz de correlación de SalePrice
k = 10 #numero de variables a conciderar en el heatmap
cols = corrmat.nlargest(k, 'SalePrice')['SalePrice'].index
cm = np.corrcoef(train[cols].values.T)
sns.set(font_scale=1.25)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
plt.show()

Al ver este ultimo heatmap podemos concluir que las 9 categorias más influyentes en el precio de la casa son: "TotalSF", "OverallQual", "GrLivArea", "TotalBsmtSF", "GarageCars", "GarageArea", "1stFlrSF", "Fullbath", "TotRmsAbvgrd"

Pero muchas de estas variables tambien están correlaciondas entre sí, por ejemplo "GarageCars" y "GarageArea". Ya que a mayor area de garage obviamente van poder entrar más autos. Por lo que decidimos incluir una variable representativa de cada conjunto de variables fuertemente correlacionadas:

Entre "GarageCars" y "GarageArea" decidimos tomar "GarageCars", ya que en el heatmap se ve que es la que posee mayor incidencia en el precio de venta

Entre "TotalSF" "GrLivArea" "TotalBsmtSF" y "1stFlrSF" decidimos elegir "TotalSF"

Por lo que las variables a utilizar en nuestro modelo serán: "TotalSF" "GarageCars" "OverallQual" "Fullbath" y "TotRmsAbvGrd"

In [31]:
#Diagramas de dispersión
sns.set()
cols = ['SalePrice', 'OverallQual', 'TotalSF', 'GarageCars', 'FullBath', 'TotRmsAbvGrd']
sns.pairplot(train[cols], size = 2.5)
plt.show();

Aplicando selección de variables:

In [32]:
train = train[['SalePrice', 'OverallQual', 'TotalSF', 'GarageCars', 'TotRmsAbvGrd', 'FullBath']]
In [33]:
test = test[['OverallQual', 'TotalSF', 'GarageCars', 'TotRmsAbvGrd', 'FullBath']]

3. Modeling

In [34]:
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

3A. Separando la data

In [35]:
training = train[:1000]
testing = train[1000:]
In [36]:
y_train = training.pop("SalePrice")
In [37]:
y_test = testing.pop("SalePrice")
In [38]:
X_train = training
In [39]:
X_test = testing

3B. Regresión linear simple

In [40]:
#Entrenando el modelo
linreg = LinearRegression()
linreg.fit(X_train, y_train)

#Precisión
print("Puntuacion de distancia media cuadrática del Training Set: {:.3f}".format(linreg.score(X_train, y_train)))
print("Puntuación de distancia media cuadrática del Testing Set: {:.3f}".format(linreg.score(X_test, y_test)))
Puntuacion de distancia media cuadrática del Training Set: 0.809
Puntuación de distancia media cuadrática del Testing Set: 0.788

Vemos que conseguimos una fidelidad de 78.8% con nuestro modelo de regresión linear (Notese también que el overfitting es bastante reducido)

Probando con algunas casas

In [41]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = linreg.predict([X_test.iloc[200, :]])[0]
valorReal = y_test.iloc[200]
var = (pred/valorReal - 1) * 100
print("Características de la casa: ")
print(X_test.iloc[200, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       7.000
TotalSF        2645.000
GarageCars        2.000
TotRmsAbvGrd      6.000
FullBath          2.000
Name: 1200, dtype: float64

Valor REAL de la casa: 197900
Calor PREDECIDO de la casa: 207930
Variación del 5.07%
In [42]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = linreg.predict([X_test.iloc[303, :]])[0]
valorReal = y_test.iloc[303]
var = abs((pred/valorReal - 1) * 100)
print("Características de la casa: ")
print(X_test.iloc[303, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       9.000
TotalSF        3304.000
GarageCars        2.000
TotRmsAbvGrd      6.000
FullBath          2.000
Name: 1303, dtype: float64

Valor REAL de la casa: 325000
Calor PREDECIDO de la casa: 285399
Variación del 12.18%
In [43]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = linreg.predict([X_test.iloc[0, :]])[0]
valorReal = y_test.iloc[0]
var = abs((pred/valorReal - 1) * 100)
print("Características de la casa: ")
print(X_test.iloc[0, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       5.000
TotalSF        1382.000
GarageCars        1.000
TotRmsAbvGrd      4.000
FullBath          1.000
Name: 1000, dtype: float64

Valor REAL de la casa: 86000
Calor PREDECIDO de la casa: 84585
Variación del 1.64%
In [44]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = linreg.predict([X_test.iloc[3, :]])[0]
valorReal = y_test.iloc[3]
var = abs((pred/valorReal - 1) * 100)
print("Características de la casa: ")
print(X_test.iloc[3, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       7.000
TotalSF        2850.000
GarageCars        2.000
TotRmsAbvGrd      7.000
FullBath          2.000
Name: 1003, dtype: float64

Valor REAL de la casa: 181000
Calor PREDECIDO de la casa: 219437
Variación del 21.24%
In [45]:
#Crando una lista donde almacenaremos los resultados de precición que conseguiremos con los metodos de modeleado utilizados
dic = {}
dic["Linear"] = 0.788

3C. XGBoost

In [46]:
!pip install xgboost
Collecting xgboost
  Downloading https://files.pythonhosted.org/packages/7c/32/a11befbb003e0e6b7e062a77f010dfcec0ec3589be537b02d2eb2ff93b9a/xgboost-1.1.1-py3-none-manylinux2010_x86_64.whl (127.6MB)
     |████████████████████████████████| 127.6MB 3.4MB/s 
Requirement already satisfied: scipy in /usr/local/lib/python3.6/site-packages (from xgboost) (1.1.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.6/site-packages (from xgboost) (1.14.5)
Installing collected packages: xgboost
Successfully installed xgboost-1.1.1
WARNING: You are using pip version 19.1.1, however version 20.2.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [47]:
import xgboost
In [48]:
from sklearn.ensemble import RandomForestRegressor

regressor = RandomForestRegressor()
from sklearn.model_selection import RandomizedSearchCV

Modeling

In [49]:
n_estimators = [100, 500, 900]
depth = [3,5,10,15]
min_split=[2,3,4]
min_leaf=[2,3,4]
bootstrap = ['True', 'False']
verbose = [0]

hyperparameter_grid = {
    'n_estimators': n_estimators,
    'max_depth':depth,
    #'criterion':criterion,
    'bootstrap':bootstrap,
    'verbose':verbose,
    'min_samples_split':min_split,
    'min_samples_leaf':min_leaf
    }

random_cv = RandomizedSearchCV(estimator=regressor,
                               param_distributions=hyperparameter_grid,
                               cv=5, 
                               scoring = 'neg_mean_absolute_error',
                               n_jobs = -1, 
                               return_train_score = True,
                               random_state=42)
In [50]:
random_cv.fit(X_train,y_train);
In [51]:
random_cv.best_estimator_
Out[51]:
RandomForestRegressor(bootstrap='False', criterion='mse', max_depth=10,
                      max_features='auto', max_leaf_nodes=None,
                      min_impurity_decrease=0.0, min_impurity_split=None,
                      min_samples_leaf=4, min_samples_split=2,
                      min_weight_fraction_leaf=0.0, n_estimators=900,
                      n_jobs=None, oob_score=False, random_state=None,
                      verbose=0, warm_start=False)
In [52]:
regressor = RandomForestRegressor(bootstrap='False', max_depth=15, min_samples_leaf=3,
                      min_samples_split=4, n_estimators=500, verbose=0)
regressor.fit(X_train,y_train)
Out[52]:
RandomForestRegressor(bootstrap='False', criterion='mse', max_depth=15,
                      max_features='auto', max_leaf_nodes=None,
                      min_impurity_decrease=0.0, min_impurity_split=None,
                      min_samples_leaf=3, min_samples_split=4,
                      min_weight_fraction_leaf=0.0, n_estimators=500,
                      n_jobs=None, oob_score=False, random_state=None,
                      verbose=0, warm_start=False)

Testeando:

In [53]:
regressor.fit(X_train,y_train)
print('R-squared score (training): {:.3f}'.format(regressor.score(X_train, y_train)))
regressor.fit(X_test,y_test)
print('R-squared score (test): {:.3f}'.format(regressor.score(X_test, y_test)))
R-squared score (training): 0.926
R-squared score (test): 0.911
In [54]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = regressor.predict([X_test.iloc[200, :]])[0]
valorReal = y_test.iloc[200]
var = (pred/valorReal - 1) * 100
print("Características de la casa: ")
print(X_test.iloc[200, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       7.000
TotalSF        2645.000
GarageCars        2.000
TotRmsAbvGrd      6.000
FullBath          2.000
Name: 1200, dtype: float64

Valor REAL de la casa: 197900
Calor PREDECIDO de la casa: 199294
Variación del 0.70%
In [55]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = regressor.predict([X_test.iloc[0, :]])[0]
valorReal = y_test.iloc[0]
var = abs((pred/valorReal - 1) * 100)
print("Características de la casa: ")
print(X_test.iloc[0, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       5.000
TotalSF        1382.000
GarageCars        1.000
TotRmsAbvGrd      4.000
FullBath          1.000
Name: 1000, dtype: float64

Valor REAL de la casa: 86000
Calor PREDECIDO de la casa: 99011
Variación del 15.13%
In [56]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = regressor.predict([X_test.iloc[303, :]])[0]
valorReal = y_test.iloc[303]
var = abs((pred/valorReal - 1) * 100)
print("Características de la casa: ")
print(X_test.iloc[303, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       9.000
TotalSF        3304.000
GarageCars        2.000
TotRmsAbvGrd      6.000
FullBath          2.000
Name: 1303, dtype: float64

Valor REAL de la casa: 325000
Calor PREDECIDO de la casa: 334871
Variación del 3.04%
In [57]:
#Calculando la diferencia entre el valor real y predecido de una casa cualquiera
pred = regressor.predict([X_test.iloc[3, :]])[0]
valorReal = y_test.iloc[3]
var = abs((pred/valorReal - 1) * 100)
print("Características de la casa: ")
print(X_test.iloc[3, :])
print()
print("Valor REAL de la casa: {}".format(int(valorReal)))
print("Calor PREDECIDO de la casa: {}".format(int(pred)))
print("Variación del {0:.2f}%".format(var))
Características de la casa: 
OverallQual       7.000
TotalSF        2850.000
GarageCars        2.000
TotRmsAbvGrd      7.000
FullBath          2.000
Name: 1003, dtype: float64

Valor REAL de la casa: 181000
Calor PREDECIDO de la casa: 192882
Variación del 6.56%
In [58]:
#Agregando a xgboost al diccionário de modelos
dic["xgboost"] = 0.912

3D. Ridge Regression

In [59]:
from sklearn.linear_model import Ridge

ridge = Ridge()
ridge.fit(X_train, y_train)

print('R-squared score (training): {:.3f}'.format(ridge.score(X_train, y_train)))
print('R-squared score (test): {:.3f}'.format(ridge.score(X_test, y_test)))

dic["Ridge"] = 0.788
R-squared score (training): 0.809
R-squared score (test): 0.788

3E. Min-Max Scaler

In [60]:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()

X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

ridge = Ridge(alpha=20)
ridge.fit(X_train_scaled, y_train)

print('R-squared score (training): {:.3f}'.format(ridge.score(X_train_scaled, y_train)))
print('R-squared score (test): {:.3f}'.format(ridge.score(X_test_scaled, y_test)))

dic["Min-Max Scaler"] = 0.700
R-squared score (training): 0.727
R-squared score (test): 0.700

Resultados finales:

(Precisión)

In [61]:
for i in dic:
    print("{}: {:.3f}".format(i, dic[i]))
Linear: 0.788
xgboost: 0.912
Ridge: 0.788
Min-Max Scaler: 0.700
Notebooks AI
Notebooks AI Profile20060