Está en la página 1de 11

PROYECTO: REGRESIÓN DEL

PRECIO DE LA VIVIENDA EN
LONDRES
Objetivo del Tutorial 2º y clase 7/7 del Curso de Deep Learning
-En este tutorial descubrirá cómo desarrollar y evaluar modelos de redes
neuronales usando Keras para un problema de regresión.

-Cómo cargar un conjunto de datos CSV y ponerlo a disposición de Keras.

-Cómo crear un modelo de red neuronal con Keras para un problema de


regresión.

-Cómo usar scikit-learn con Keras para evaluar modelos usando validación
cruzada.

-Cómo realizar la preparación de datos para mejorar la habilidad con los


modelos Keras.

-Cómo sintonizar la topología de red de los modelos con Keras.

Conjunto de datos de precios de


Pisos en Londres
El problema que veremos en este tutorial es el conjunto de datos del
precio de la vivienda en Londres. El conjunto de datos describe
propiedades de casas en los suburbios de Londres y queremos modelar el
precio de casas en estos barrios en miles de euros. Como tal, esto es un
modelo predictivo de regresión. Hay 13 variables de entrada que
describen las propiedades de un determinado barrio de Londres. La lista
completa de atributos en este conjunto de datos es la siguiente:
1. CRIM: tasa de criminalidad per cápita.
2. ZN: proporción de terreno residencial dividido en zonas para lotes de más
de 25,000 pies cuadrados.
3. INDUS: proporción de negocios no minoristas.
4. CHAS: Variable ficticia del río (= 1 si el tramo limita con el río; 0 en caso
contrario).
5. NOX: concentración de óxidos nítricos (10 ppm).
6. RM: número medio de habitaciones por vivienda.
7. EDAD: proporción de viviendas ocupadas por sus propietarios construidas
antes de 1940.
8. DIS: distancias ponderadas a los centros de empleo de Londres.
9. RAD: índice de accesibilidad a carreteras radiales.
10. IMPUESTO: tasa del impuesto sobre el valor total de la propiedad
por cada 10,000 euros.
11. PTRATIO: número de alumnos por docente y ciudad.
12. B: 1000(B 0:63) 2 donde B es la proporción de inmigrantes.
13. LSTAT: % de menor estatus de la población.
14. MEDV: Valor medio de las viviendas ocupadas por sus propietarios
en miles de euros.
Este es un problema bien estudiado en Machine Learning y es
conveniente trabajar con él porque todos los atributos de entrada y salida
son numéricos y hay 500 instancias con las que trabajar. A continuación se
presenta una muestra de las primeras 4 filas del conjunto de datos:

0.02731 0.00 7.070 0 0.4690 6.4210 78.90 4.9671 2 242.0


17.80 396.90 9.14 21.60

0.02729 0.00 7.070 0 0.4690 7.1850 61.10 4.9671 2 242.0


17.80 392.83 4.03 34.70

0.03237 0.00 2.180 0 0.4580 6.9980 45.80 6.0622 3 222.0


18.70 394.63 2.94 33.40
0.06905 0.00 2.180 0 0.4580 7.1470 54.20 6.0622 3 222.0
18.70 396.90 5.33 36.20

El conjunto de datos está disponible aquí. Un rendimiento razonable para


los modelos evaluados utilizando Mean Squared Error (MSE) son de
alrededor de 20 000 euros cuadrados (o 4.500 euros si usted toma la raíz
cuadrada). Este es un buen objetivo para apuntar con nuestro modelo de
red neuronal.

Desarrollar un Modelo de Red


Neuronal de Línea de Base
En esta sección crearemos un modelo básico de red neuronal para el
problema de regresión. Vamos a importar todas las funciones y objetos
que necesitaremos para este tutorial.

1
import numpy
2 from pandas import read_csv
3 from keras.models import Sequential
4 from keras.layers import Dense
5 from keras.wrappers.scikit_learn import KerasRegressor
6 from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
7 from sklearn.preprocessing import StandardScaler
8 from sklearn.pipeline import Pipeline
9
Ahora podemos cargar nuestro conjunto de datos. Podemos cargar esto
fácilmente usando la librería de Pandas. Entonces podemos dividir la
entrada (X) y los atributos de salida (Y) para que sean más fáciles de
modelar con Keras y scikit-learn.

1 # cargamos los datos


2 dataframe = read_csv("housing.csv", delim_whitespace=True, header=None)
3 dataset = dataframe.values
4 # dividimos los datos entre las entradas y las salidas
X = dataset[:,0:13]
5
Y = dataset[:,13]
6
Podemos crear modelos Keras y evaluarlos con scikit-learn usando un
práctico envoltorio de objetos proporcionados por la biblioteca Keras.
Esto es deseable, porque scikit-learn sobresale en la evaluación y nos
permitirá utilizar potentes esquemas de preparación de datos y
evaluación de modelos con muy pocas líneas de código. La clase de
envoltura Keras requiere una función como argumento. Esta función que
debemos definir es responsable de crear el modelo de red neuronal a
evaluar.
A continuación se detalla la función para crear el modelo a evaluar. Es un
simple modelo que tiene una sola capa oculta completamente conectada
con el mismo número de neuronas que la entrada (13). La red utiliza
buenas prácticas como la función de activación de rectier para la capa
oculta. No se utiliza ninguna función de activación para la capa de salida
porque es una regresión y estamos interesados en predecir valores
numéricos directamente sin transformación. Se utiliza el algoritmo de
optimización de ADAM y una función de pérdida de error media al
cuadrado optimizada. Esta será la misma métrica que usaremos para
evaluar el desempeño del modelo. Es una métrica deseable porque al
tomar la raíz cuadrada de un valor de error nos da un valor de resultado
que podemos entender directamente en el contexto del problema con las
unidades en miles de euros.

1 # define el modelo base


2 def baseline_model():
3 # crea el modelo
4 model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal',
5 activation='relu'))
6 model.add(Dense(1, kernel_initializer='normal'))
7 # Compila el modelo
8 model.compile(loss='mean_squared_error', optimizer='adam')
return model
9
El objeto envoltorio de Keras para usar en scikit-learn es como un
estimador de regresión y se llama KerasRegressor. Creamos una
instancia y le pasamos tanto el nombre de la función para crear el modelo
de red neuronal como algunos parámetros para pasar a la función fit() del
modelo más tarde, como el número de epoch y el batch_size. Ambos
están configurados con valores predeterminados razonables. También
inicializamos el generador de números aleatorios con una semilla
aleatoria constante, un proceso que repetiremos para cada modelo
evaluado en este tutorial. Esto es para asegurar que comparamos
modelos consistentemente y que los resultados sean reproducibles.
1 # semilla random
2 seed = 7
numpy.random.seed(seed)
3 # evaluamos el modelo
4 estimator = KerasRegressor(build_fn=baseline_model, epochs=100,
5 batch_size=5, verbose=0)
El paso fundamental es evaluar este modelo de línea de base. Usaremos
una validación cruzada 10 veces para evaluar el modelo.

1 kfold = KFold(n_splits=10, random_state=seed)


2 results = cross_val_score(estimator, X, Y, cv=kfold)
3 print("Baseline: %.2f (%.2f) MSE" % (results.mean(), results.std()))

El código completo de este post sobre la regresión con redes neuronales


es:

1
2 # Regresion con redes neuronales
3 import numpy
4 from pandas import read_csv
5 from keras.models import Sequential
from keras.layers import Dense
6 from keras.wrappers.scikit_learn import KerasRegressor
7 from sklearn.model_selection import cross_val_score
8 from sklearn.model_selection import KFold
9 # cargamos los datos
10 dataframe = read_csv("viviendalondres.csv", delim_whitespace=True,
header=None)
11 dataset = dataframe.values
12 # dividimos los datos entre los inputs y variables
13 X = dataset[:,0:13]
14 Y = dataset[:,13]
15 # se define el modelo base
def baseline_model():
16 # creamos el modelo
17 model = Sequential()
18 model.add(Dense(13, input_dim=13, kernel_initializer='normal',
19 activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
20 # Compilamos el modelo
21 model.compile(loss='mean_squared_error', optimizer='adam')
22 return model
23 # semilla de aletoriedad
24 seed = 7
numpy.random.seed(seed)
25 # evalua el modelo
26 estimator = KerasRegressor(build_fn=baseline_model, epochs=100,
27 batch_size=5, verbose=0)
28 kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(estimator, X, Y, cv=kfold)
29
print("Baseline: %.2f (%.2f) MSE" % (results.mean(), results.std()))
30
31
La ejecución de este código nos da una estimación del rendimiento del
modelo en el problema de los datos no vistos. El resultado reporta el error
promedio al cuadrado incluyendo el promedio y la desviación estándar
(varianza promedio) a través de los 10 pliegues de la evaluación de
validación cruzada.

Baseline: -27.63 (16.36) MSE

Elevar el rendimiento estandarizando


del conjunto de datos
Una preocupación importante con el conjunto de datos del precio de la
vivienda de Londres es que todos los atributos de entrada varían en sus
escalas porque miden cantidades diferentes. Casi siempre es una buena
práctica preparar sus datos antes de modelarlos utilizando un modelo de
red neuronal. Continuando desde el modelo Baseline, podemos reevaluar
el mismo modelo utilizando una versión estandarizada del conjunto de
datos de entrada.
Podemos usar el Pipeline de scikit-learn para llevar a cabo la
estandarización del proyecto durante el proceso de evaluación del
modelo, dentro de cada pliegue de la validación cruzada. Esto asegura que
no hay fugas de datos de cada pliegue de validación cruzada del conjunto
de pruebas en los datos de formación. El código a continuación crea
un Pipeline de scikit-learn que primero estandariza el conjunto de datos y
luego crea y evalúa el modelo de baseline de la red neuronal.

1 # Regresion ejemplo londresvivienda Dataset: Standardized


import numpy
2 from pandas import read_csv
3 from keras.models import Sequential
4 from keras.layers import Dense
5 from keras.wrappers.scikit_learn import KerasRegressor
6 from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
7 from sklearn.preprocessing import StandardScaler
8 from sklearn.pipeline import Pipeline
9 # cargamos los datos
10 dataframe = read_csv("viviendalondres.csv", delim_whitespace=True,
11 header=None)
dataset = dataframe.values
12 # dividimos entre entradas y salidas
13 X = dataset[:,0:13]
14 Y = dataset[:,13]
15 # se define el modelo base
def baseline_model():
16
17
18   # se crea el modelo
19   model = Sequential()
20   model.add(Dense(13, input_dim=13, kernel_initializer='normal',
21 activation='relu'))
  model.add(Dense(1, kernel_initializer='normal'))
22   # se Compila el modelo
23   model.compile(loss='mean_squared_error', optimizer='adam')
24   return model
25 # semilla aleatoria
26 seed = 7
numpy.random.seed(seed)
27 # se evalua el modelo con el standardized dataset
28 estimators = []
29 estimators.append(('standardize', StandardScaler()))
30 estimators.append(('mlp', KerasRegressor(build_fn=baseline_model,
epochs=50, batch_size=5,
31 verbose=0)))
32 pipeline = Pipeline(estimators)
33 kfold = KFold(n_splits=10, random_state=seed)
34 results = cross_val_score(pipeline, X, Y, cv=kfold)
35 print("Standardized: %.2f (%.2f) MSE" % (results.mean(),
results.std()))
36
37
La ejecución del ejemplo proporciona un rendimiento mejorado sobre el
modelo de línea de base sin datos estandarizados, eliminando el error.

Standardized: -27.79 (25.98) MSE

Otra ampliación de esta sección consistiría en aplicar de manera similar


un reajuste de la escala a la salida como normalizarlo al rango de 0 a 1 y
usar una activación Sigmoidea o similar en la capa de salida para reducir
las predicciones de salida al mismo rango.

Afinamos la topología de la red


neuronal
Hay muchas cosas que pueden ser optimizadas para un modelo de red
neuronal. Tal vez el punto de mayor apalancamiento es la estructura de la
propia red, incluyendo el número de capas y el número de neuronas en
cada capa. En esta sección evaluaremos dos redes adicionales para
mejorar aún más el rendimiento del modelo. Nos fijaremos tanto en un
una topología de red más profunda y más amplia.
Evaluar una topología de red más profunda
Una forma de mejorar el rendimiento de una red neuronal es añadir más
capas. Esto podría permitir que el modelo extraiga y recombine
características de orden superior incrustadas en los datos. En este
evaluaremos la posibilidad de añadir una capa oculta más al modelo. Esto
es tan fácil como como definir una nueva función que creará este modelo
más profundo, copiado de nuestro modelo de línea de base más arriba.
Podemos entonces insertar una nueva línea después de la primera capa
oculta. En este caso con aproximadamente la mitad del número de
neuronas. Nuestra topología de red ahora parece:

13 entradas –> [13 –> 6]]  –> 1 salida

Podemos evaluar esta topología de red de la misma manera que arriba, al


mismo tiempo que utilizamos la estandarización del conjunto de datos
que se ha demostrado que mejora el rendimiento.

1 # Regresion ejemplo con vivienda londres Dataset: Standardized y


topologia mas profunda
2 import numpy
3 from pandas import read_csv
4 from keras.models import Sequential
5 from keras.layers import Dense
6 from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
7 from sklearn.model_selection import KFold
8 from sklearn.preprocessing import StandardScaler
9 from sklearn.pipeline import Pipeline
10 # cargamos los datos
11 dataframe = read_csv("viviendalondres.csv", delim_whitespace=True,
header=None)
12 dataset = dataframe.values
13 # dividimos los datos de entrada (X) y los de salida (Y)
14 X = dataset[:,0:13]
15 Y = dataset[:,13]
# se define el modelo
16 def larger_model():
17   # creamos el modelo
18   model = Sequential()
19   model.add(Dense(13, input_dim=13, kernel_initializer='normal',
20 activation='relu'))
  model.add(Dense(6, kernel_initializer='normal', activation='relu'))
21   model.add(Dense(1, kernel_initializer='normal'))
22   # se Compila el modelo
23   model.compile(loss='mean_squared_error', optimizer='adam')
24   return model
25 # semilla aleatoria
26
27 seed = 7
28 numpy.random.seed(seed)
# se evalua el modelo con standardized
29 estimators = []
30 estimators.append(('standardize', StandardScaler()))
31 estimators.append(('mlp', KerasRegressor(build_fn=larger_model,
32 epochs=50, batch_size=5,
33 verbose=0)))
pipeline = Pipeline(estimators)
34 kfold = KFold(n_splits=10, random_state=seed)
35 results = cross_val_score(pipeline, X, Y, cv=kfold)
36 print("mas profunda: %.2f (%.2f) MSE" % (results.mean(),
37 results.std()))
38
La ejecución de este modelo muestra una mejora adicional en el
rendimiento de la MSE.

mas profunda: -23.26 (27.04) MSE

Evaluar una topología de red más amplia


Otro enfoque para aumentar la capacidad de representación del modelo
es crear una red más amplia. En esta sección evaluamos la posibilidad de
mantener una arquitectura de red poco profunda y casi duplicar el
número de neuronas en una capa oculta. Una vez más, todo lo que
tenemos que hacer es definir una nueva función que crea nuestro modelo
de red neuronal. En este sentido, hemos aumentado el número en la capa
oculta en comparación con el modelo base de 13 a 20. La topología para
nuestra red más amplia puede resumirse de la siguiente manera:

13 entradas –> [20]–> 1 salida

Ahora vamos a evaluar una topología de red mas amplia con el siguiente
código:

1 # Regresion ejemplo con viviendalondres Dataset: Standardized y red mas


amplia
2
import numpy
3 from pandas import read_csv
4 from keras.models import Sequential
5 from keras.layers import Dense
6 from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
7 from sklearn.model_selection import KFold
8
9 from sklearn.preprocessing import StandardScaler
10 from sklearn.pipeline import Pipeline
11 # cargamos los datos
12 dataframe = read_csv("viviendalondres.csv", delim_whitespace=True,
header=None)
13 dataset = dataframe.values
14 # dividimos entre las entradas (X) y las salidas (Y)
15 X = dataset[:,0:13]
16 Y = dataset[:,13]
# define tu modelo mas amplio
17
def wider_model():
18   # crea el modelo
19   model = Sequential()
20   model.add(Dense(20, input_dim=13, kernel_initializer='normal',
21 activation='relu'))
  model.add(Dense(1, kernel_initializer='normal'))
22   # Compila el modelo
23   model.compile(loss='mean_squared_error', optimizer='adam')
24   return model
25 # semilla aleatoria
26 seed = 7
numpy.random.seed(seed)
27 # evalua el modelo
28 estimators = []
29 estimators.append(('standardize', StandardScaler()))
30 estimators.append(('mlp', KerasRegressor(build_fn=wider_model,
epochs=100, batch_size=5,
31 verbose=0)))
32 pipeline = Pipeline(estimators)
33 kfold = KFold(n_splits=10, random_state=seed)
34 results = cross_val_score(pipeline, X, Y, cv=kfold)
35 print("Red mas amplia: %.2f (%.2f) MSE" % (results.mean(),
results.std()))
36
37
La construcción del modelo no ve una caída adicional en el error cerca de
21 mil euros cuadrados. Este no es un mal resultado para este problema.

Red mas amplia: -22.05 (22.77) MSE

Habría sido difícil adivinar que una red más amplia superaría a una red
más profunda en este problema. Los resultados demuestran la
importancia de las pruebas ensayo y error cuando se trata de desarrollar
modelos de redes neuronales.

Resumen del post de Regresión con


redes Neuronales
En esta lección descubrió la biblioteca de aprendizaje profundo de Keras
para modelar problemas de regresión. A través de este tutorial usted
aprendió a desarrollar y evaluar modelos de redes neuronales,
incluyendo:

 Cómo cargar datos y desarrollar un modelo de línea de base.


 Cómo mejorar el rendimiento utilizando técnicas de preparación de datos
como la estandarización.
 Cómo diseñar y evaluar redes con diferentes topologías sobre un
problema.

También podría gustarte