Regresión lineal de TensorFlow con faceta y término de interacción
En este tutorial, aprenderá a comprobar los datos y prepararlos para crear una tarea de regresión lineal simple.
Este tutorial se divide en dos partes:
- Buscar interacción
- Probar el modelo
En el aprendizaje anterior, utilizó el dataset de Boston para estimar el precio medio de una casa. El conjunto de datos de Boston tiene un tamaño pequeño, con sólo 506 observaciones. Este conjunto de datos se considera como un punto de referencia para probar nuevos algoritmos de regresión lineal.
El conjunto de datos se compone de:
Variable | Descripción |
zn | Proporción de terrenos residenciales en zonas para lotes de más de 25.000 pies cuadrados |
indus | Proporción de acres comerciales no minoristas por ciudad. |
nox | concentración de óxidos nítricos |
rm | número medio de habitaciones por vivienda |
age | la proporción de unidades ocupadas por sus propietarios construidas antes de 1940 |
dis | distancias ponderadas a cinco centros de empleo de Boston |
tax | tasa de impuesto a la propiedad valor completo por dólares 10.000 |
ptratio | la proporción alumnos/maestro por ciudad |
medv | El valor medio de las casas ocupadas por sus propietarios en miles de dólares |
crim | tasa de criminalidad per cápita por ciudad |
chas | Charles River variable ficticia (1 si limita el río; 0 en caso contrario) |
B | la proporción de negros por la ciudad |
En este tutorial, vamos a estimar el precio medio usando un regresor lineal, pero el enfoque está en un proceso particular de aprendizaje automático: “preparación de datos”.
Un modelo generaliza el patrón en los datos. Para capturar tal patrón, primero debe encontrarlo. Una buena práctica es realizar un análisis de datos antes de ejecutar cualquier algoritmo de aprendizaje automático.
Elegir las características correctas marca la diferencia en el éxito de su modelo. Imagine que intenta estimar el salario de un pueblo, si no incluye el género como una covariable, termina con una estimación pobre.
Otra forma de mejorar el modelo es mirar la correlación entre la variable independiente. Volviendo al ejemplo, se puede pensar en la educación como un excelente candidato para predecir el salario, pero también la ocupación. Es justo decir, la ocupación depende del nivel de educación, es decir, la educación superior a menudo conduce a una mejor ocupación. Si generalizamos esta idea, podemos decir que la correlación entre la variable dependiente y una variable explicativa se puede ampliar de otra variable explicativa.
Para captar el efecto limitado de la educación sobre la ocupación, podemos usar un término de interacción.
Si nos fijamos en la ecuación salarial, se convierte en:
Si es positivo, entonces implica que un nivel adicional de educación produce un aumento mayor en el valor medio de una casa para un alto nivel de ocupación. En otras palabras, existe un efecto de interacción entre la educación y la ocupación.
En este tutorial, vamos a tratar de ver qué variables pueden ser un buen candidato para términos de interacción. Vamos a probar si agregar este tipo de información conduce a una mejor predicción de precios.
En este tutorial, aprenderá
- Resumen de estadísticas
- Descripción general de las facetas
- Facetas Buceo Profundo
- Instalar faceta
- Resumen
- Gráfico
- Facetas Buceo Profundo
- TensorFlow
- Datos de preparación
- regresión básica:punto de referencia
- Mejorar el modelo: término de interacción
Resumen de estadísticas
Hay algunos pasos que puede seguir antes de continuar con el modelo. Como se mencionó anteriormente, el modelo es una generalización de los datos. La mejor práctica de ajuste es entender los datos y hacer una predicción. Si no conoce sus datos, tiene pocas posibilidades de mejorar su modelo.
Como primer paso, cargue los datos como un marco de datos pandas y cree un conjunto de entrenamiento y un conjunto de pruebas.
Consejos: Para este tutorial, es necesario tener matplotlit y seaborn instalado en Python. Puede instalar el paquete Python sobre la marcha con Jupyter. No deberías hacer esto
1 |
!conda install -- yes matplotlib |
pero
1 2 3 |
import sys !{sys.executable} -m pip install matplotlib # Already installed !{sys.executable} -m pip install seaborn |
Tenga en cuenta que este paso no es necesario si tiene instalado matplotlib y seaborn.
Matplotlib es la biblioteca para crear un gráfico en Python. Seaborn es una biblioteca de visualización estadística construida sobre matplotlib. Proporciona parcelas atractivas y hermosas.
El siguiente código importa las bibliotecas necesarias.
1 2 3 4 5 |
import pandas as pd from sklearn import datasets import tensorflow as tf from sklearn.datasets import load_boston import numpy as np |
La biblioteca sklearn incluye el conjunto de datos de Boston. Puede llamar a su API para importar los datos.
1 2 |
boston = load_boston() df = pd.DataFrame(boston.data) |
El nombre de la entidad se almacena en el objeto feature_names de una matriz.
1 |
boston.feature_names |
Salida
1 2 |
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7') |
Puede cambiar el nombre de las columnas.
1 2 3 |
df.columns = boston.feature_names df['PRICE'] = boston.target df.head(2) |
Convertir la variable CHAS como una variable de cadena y etiquetarla con yes si CHAS = 1 y no si CHAS = 0
1 2 3 4 5 6 7 8 |
df['CHAS'] = df['CHAS'].map({1:'yes', 0:'no'}) df['CHAS'].head(5) 0 no 1 no 2 no 3 no 4 no Name: CHAS, dtype: object |
Con los pandas, es sencillo dividir el conjunto de datos. Divide aleatoriamente el conjunto de datos con un 80 por ciento conjunto de entrenamiento y un 20 por ciento conjunto de pruebas. Los pandas tienen una función de costo integrada para dividir una muestra de marco de datos.
El primer parámetro frac es un valor de 0 a 1. Se establece en 0.8 para seleccionar aleatoriamente el 80 por ciento del marco de datos.
Random_state permite tener el mismo marco de datos devuelto para todos.
1 2 3 |
### Create train/test set df_train=df.sample(frac=0.8,random_state=200) df_test=df.drop(df_train.index) |
Puede obtener la forma de los datos. Debería ser:
- Conjunto de tren: 506*0,8 = 405
- Conjunto de prueba: 506*0.2 = 101
1 |
print(df_train.shape, df_test.shape) |
Salida
1 |
(405, 14) (101, 14) |
1 |
df_test.head(5) |
Salida
CRIM | ZN | INDUS | CHAS | NOX | RM | AGE | DIS | RAD | TAX | PTRATIO | B | LSTAT | PRICE | |
0 | 0.00632 | 18.0 | 2.31 | no | 0.538 | 6.575 | 65.2 | 4.0900 | 1.0 | 296.0 | 15.3 | 396.90 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | no | 0.469 | 6.421 | 78.9 | 4.9671 | 2.0 | 242.0 | 17.8 | 396.90 | 9.14 | 21.6 |
3 | 0.03237 | 0.0 | 2.18 | no | 0.458 | 6.998 | 45.8 | 6.0622 | 3.0 | 222.0 | 18.7 | 394.63 | 2.94 | 33.4 |
6 | 0.08829 | 12.5 | 7.87 | no | 0.524 | 6.012 | 66.6 | 5.5605 | 5.0 | 311.0 | 15.2 | 395.60 | 12.43 | 22.9 |
7 | 0.14455 | 12.5 | 7.87 | no | 0.524 | 6.172 | 96.1 | 5.9505 | 5.0 | 311.0 | 15.2 | 396.90 | 19.15 | 27.1 |
Los datos son desordenados; a menudo están mal equilibrados y salpicados de valores atípicos que descartan el análisis y la formación de aprendizaje automático.
El primer paso para limpiar el conjunto de datos es comprender dónde necesita limpieza. Limpiar un conjunto de datos puede ser difícil de hacer, especialmente de cualquier manera generalizable
El equipo de Investigación de Google ha desarrollado una herramienta para este trabajo llamada Facets que ayuda a visualizar los datos y cortarlos de todo tipo de maneras. Este es un buen punto de partida para comprender cómo se presenta el conjunto de datos.
Las facetas le permiten encontrar dónde los datos no se ven del todo de la forma en que está pensando.
Excepto por su aplicación web, Google hace que sea fácil incrustar el kit de herramientas en un cuaderno Jupyter.
Hay dos partes a Facetas:
- Descripción general de las facetas
- Facetas Buceo Profundo
Descripción general de las facetas
Facets Overview ofrece una visión general del conjunto de datos. Facets Overview divide las columnas de los datos en filas de información sobresaliente que muestra
- el porcentaje de observación faltante
- valores mínimos y máximos
- estadísticas como la media, la mediana y la desviación estándar.
- También agrega una columna que muestra el porcentaje de valores que son ceros, lo que resulta útil cuando la mayoría de los valores son ceros.
- Es posible ver estas distribuciones en el dataset de prueba, así como el conjunto de entrenamiento para cada entidad. Esto significa que puede comprobar que la prueba tiene una distribución similar a la de los datos de entrenamiento.
Esto es al menos lo mínimo que debe hacer antes de cualquier tarea de aprendizaje automático. Con esta herramienta, no te pierdas este paso crucial, y resalta algunas anormalidades.
Facetas Buceo Profundo
Facets Deep Dive es una herramienta genial. Permitetener algo de claridad en su conjunto de datos y ampliar todo el camino para ver una pieza individual de datos. Significa que puede facetar los datos por fila y columna en cualquiera de las entidades del dataset.
Utilizaremos estas dos herramientas con el conjunto de datos de Boston.
Nota: No puede utilizar la vista general de facetas y la inmersión profunda de facetas al mismo tiempo. Primero debe borrar el bloc de notas para cambiar la herramienta.
Instalar faceta
Puede usar la aplicación web Facet para la mayor parte del análisis. En este tutorial, verá cómo usarlo dentro de un cuaderno Jupyter.
En primer lugar, debe instalar nbextensions. Se hace con este código. Copie y pegue el siguiente código en el terminal de su equipo.
1 |
pip install jupyter_contrib_nbextensions |
Justo después de eso, debe clonar los repositorios en su computadora. Tienes dos opciones:
Opción 1) Copie y pegue este código en el terminal (recomendado)
Si no tiene Git instalado en su máquina, vaya a esta URL https://git-scm.com/download/win y siga las instrucciones. Una vez que haya terminado, puede usar el comando git en el terminal para Mac User o Anaconda prompt para el usuario de Windows
1 |
git clone https://github.com/PAIR-code/facets |
Opción 2) Vaya a https://github.com/PAIR-code/facets y descargue los repositorios.
Si elige la primera opción, el archivo termina en el archivo de descarga. Puede dejar que el archivo se descargue o arrastrarlo a otra ruta.
Puede comprobar dónde se almacena Facets con esta línea de comandos:
1 |
echo `pwd`/`ls facets` |
Ahora que ha localizado Facets, debe instalarlo en Jupyter Notebook. Debe establecer el directorio de trabajo en la ruta donde se encuentran las facetas.
Su directorio de trabajo actual y la ubicación de Facets zip deben ser los mismos.
Debe apuntar el directorio de trabajo a Facet:
1 |
cd facets |
Para instalar Facets en Jupyter, tiene dos opciones. Si instaló Jupyter con Conda para todos los usuarios, copie este código:
puede usar jupyter nbextension install facets-dist/
1 |
jupyter nbextension install facets-dist/ |
De lo contrario, use:
1 |
jupyter nbextension install facets-dist/ --user |
Está bien, ya está listo. Vamos a abrir Facet Overview.
Resumen
Overview utiliza una secuencia de comandos de Python para calcular las estadísticas. Necesita importar el script llamado generic_feature_statistics_generator a Jupyter. No se preocupe; el script se encuentra en los archivos de facetas.
Necesitas localizar su ruta. Es fácil de hacer. Abra facetas, abra el archivo facets_overview y luego python. Copiar la ruta
Después de eso, regrese a Jupyter y escriba el siguiente código. Cambie la ruta ‘/Users/thomas/facets/facets_overview/Python’ a su ruta.
1 2 3 |
# Add the facets overview python code to the python path# Add t import sys sys.path.append('/Users/Thomas/facets/facets_overview/python') |
Puede importar el script con el siguiente código.
1 2 |
from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator |
En Windows, el mismo código se convierte en
1 2 3 4 |
import sys sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python") from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator |
Para calcular las estadísticas de entidades, debe utilizar la función
GenericFeatureStatisticsGenerator () y utilizar el objeto ProtoFromDataFrams. Puede pasar el marco de datos en un diccionario. Por ejemplo, si queremos crear una estadística de resumen para el conjunto de trenes, podemos almacenar la información en un diccionario y usarla en el objeto ProtoFromDataFrames
`
-
1'name': 'train', 'table': df_train
Nombre es el nombre de la tabla que se muestra y se utiliza el nombre de la tabla en la que se desea calcular el resumen. En su ejemplo, la tabla que contiene los datos es df_train
1 2 3 4 5 6 7 8 9 10 |
# Calculate the feature statistics proto from the datasets and stringify it for use in facets overview import base64 gfsg = GenericFeatureStatisticsGenerator() proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train}, {'name': 'test', 'table': df_test}]) #proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train}]) protostr = base64.b64encode(proto.SerializeToString()).decode("utf-8") |
Por último, simplemente copia y pega el código a continuación. El código viene directamente de GitHub. Debería poder ver esto:
1 2 3 4 5 6 7 8 9 10 |
# Display the facets overview visualization for this data# Displ from IPython.core.display import display, HTML HTML_TEMPLATE = """<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html" > <facets-overview id="elem"></facets-overview> <script> document.querySelector("#elem").protoInput = "{protostr}"; </script>""" html = HTML_TEMPLATE.format(protostr=protostr) display(HTML(html)) |
Gráfico
Después de comprobar los datos y su distribución, puede trazar una matriz de correlación. La matriz de correlación calcula el coeficiente de Pearson. Este coeficiente está unido entre -1 y 1, con un valor positivo indica una correlación positiva y un valor negativo una correlación negativa.
Le interesa ver qué variables pueden ser un buen candidato para términos de interacción.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
## Choose important feature and further check with Dive %matplotlib inline import matplotlib.pyplot as plt import seaborn as sns sns.set(style="ticks") # Compute the correlation matrix corr = df.corr('pearson') # Generate a mask for the upper triangle mask = np.zeros_like(corr, dtype=np.bool) mask[np.triu_indices_from(mask)] = True # Set up the matplotlib figure f, ax = plt.subplots(figsize=(11, 9)) # Generate a custom diverging colormap cmap = sns.diverging_palette(220, 10, as_cmap=True) # Draw the heatmap with the mask and correct aspect ratio sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,annot=True, square=True, linewidths=.5, cbar_kws={"shrink": .5}) |
Salida
1 |
<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518> |
png
Desde la matriz, puede ver:
- LSTAT
- RM
Están fuertemente correlacionados con PRECIO. Otra característica interesante es la fuerte correlación positiva entre NOX e INDUS, lo que significa que esas dos variables se mueven en la misma dirección. Además, también están correlacionados con el PRECIO. El DIS también está muy correlacionado con el IND y el NOX.
Tiene alguna primera pista de que IND y NOX pueden ser buenos candidatos para el término de interceptación y DIS también podría ser interesante centrarse en.
Puede ir un poco más profundo trazando una cuadrícula de par. Ilustrará con más detalle el mapa de correlación que trazó antes.
El par de rejilla que se componen de la siguiente manera:
- Parte superior: Parcela de dispersión con línea ajustada
- Diagonal: trazado de densidad del núcleo
- Parte inferior: diagrama de densidad de kernel multivariante
Usted elige el enfoque en cuatro variables independientes. La elección corresponde a las variables con fuerte correlación con PRICE
- INDUS
- NOX
- RM
- LSTAT
por otra parte, el PRECIO.
Nota Tenga en cuenta que el error estándar se agrega por defecto al diagrama de dispersión.
1 2 3 4 5 6 |
attributes = ["PRICE", "INDUS", "NOX", "RM", "LSTAT"] g = sns.PairGrid(df[attributes]) g = g.map_upper(sns.regplot, color="g") g = g.map_lower(sns.kdeplot,cmap="Reds", shade=True, shade_lowest=False) g = g.map_diag(sns.kdeplot) |
Salida
Comencemos con la parte superior:
- El precio se correlaciona negativamente con INDUS, NOX y LSTAT; se correlaciona positivamente con RM.
- Hay una ligera no linealidad con LSTAT y PRICE
- Hay como una línea recta cuando el precio es igual a 50. A partir de la descripción del conjunto de datos, PRICE se ha truncado en el valor de 50
Diagonal
- NOX parece tener dos grupos, uno alrededor de 0,5 y uno alrededor de 0,85.
Para verificar más al respecto, puede mirar la parte inferior. La Densidad Multivariante del Núcleo es interesante en un sentido que colorea donde se encuentran la mayoría de los puntos. La diferencia con el diagrama de dispersión dibuja una densidad de probabilidad, aunque no haya ningún punto en el dataset para una coordenada dada. Cuando el color es más fuerte, indica una alta concentración de punto alrededor de esta área.
Si comprueba la densidad multivariante para INDUS y NOX, puede ver la correlación positiva y los dos clusters. Cuando la participación de la industria es superior a 18, la concentración de óxidos nítricos es superior a 0,6.
Puede pensar en agregar una interacción entre INDUS y NOX en la relación lineal.
Por último, puede utilizar las segundas herramientas creadas por Google, Facets Deep Dive. La interfaz se divide en cuatro secciones principales. El área central del centro es una visualización con zoom de los datos. En la parte superior del panel, se encuentra el menú desplegable donde puede cambiar la disposición de los datos para controlar el facetado, el posicionamiento y el color. A la derecha, hay una vista detallada de una fila específica de datos. Esto significa que puede hacer clic en cualquier punto de datos en la visualización del centro para ver los detalles sobre ese punto de datos en particular.
Durante el paso de visualización de datos, usted está interesado en buscar la correlación de pares entre la variable independiente sobre el precio de la casa. Sin embargo, implica al menos tres variables, y los gráficos 3D son complicados de trabajar.
Una forma de abordar este problema es crear una variable categórica. Es decir, podemos crear un trazado 2D de un color el punto. Puede dividir la variable PRECIO en cuatro categorías, con cada categoría es un cuartil (es decir, 0,25, 0,5, 0,75). Usted llama a esta nueva variable Q_PRICE.
1 2 3 4 |
## Check non linearity with important features df['Q_PRICE'] = pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"]) ## Show non linearity between RM and LSTAT ax = sns.lmplot(x="DIS", y="INDUS", hue="Q_PRICE", data=df, fit_reg = False,palette="Set3") |
Facetas Buceo Profundo
Para abrir Deep Dive, necesita transformar los datos en un formato json. Pandas como un objeto para eso. Puede usar to_json después del dataset de Pandas.
La primera línea de código maneja el tamaño del dataset.
1 2 3 |
df['Q_PRICE'] = pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"]) sprite_size = 32 if len(df.index)>50000 else 64 jsonstr = df.to_json(orient='records') |
El siguiente código proviene de Google GitHub. Después de ejecutar el código, debería poder ver esto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Display thde Dive visualization for this data from IPython.core.display import display, HTML # Create Facets template HTML_TEMPLATE = """<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html"> <facets-dive sprite-image-width="{sprite_size}" sprite-image-height="{sprite_size}" id="elem" height="600"></facets-dive> <script> document.querySelector("#elem").data = {jsonstr}; </script>""" # Load the json dataset and the sprite_size into the template html = HTML_TEMPLATE.format(jsonstr=jsonstr, sprite_size=sprite_size) # Display the template display(HTML(html)) |
Usted está interesado en ver si hay una conexión entre la tasa de la industria, la concentración de óxido, la distancia al centro de trabajo y el precio de la casa.
Para ello, primero divide los datos por rango de sector y color con el cuartil de precio:
- Seleccione facetas X y elija INDUS.
- Seleccione Mostrar y elija DIS. Coloreará los puntos con el cuartil del precio de la casa
aquí, los colores más oscuros significan que la distancia al primer centro de trabajo está lejos.
Hasta ahora, muestra de nuevo lo que usted sabe, menor tasa de la industria, mayor precio. Ahora puedes ver el desglose por INDUX, por NOX.
- Seleccione la facetación Y y elija NOX.
Ahora se puede ver la casa lejos del primer centro de trabajo tiene la cuota más baja de la industria y por lo tanto la menor concentración de óxido. Si elige mostrar el tipo con Q_PRICE y ampliar la esquina inferior izquierda, puede ver qué tipo de precio es.
Tiene otra pista de que la interacción entre IND, NOX y DIS puede ser un buen candidato para mejorar el modelo.
TensorFlow
En esta sección, calculará el clasificador lineal con la API de estimadores de TensorFlow. Procederás de la siguiente manera:
- Preparar los datos
- Estimar un modelo de referencia: Sin interacción
- Estimar un modelo con interacción
Recuerde, el objetivo del aprendizaje automático es minimizar el error. En este caso, el modelo con el error cuadrado medio más bajo ganará. El estimador TensorFlow calcula automáticamente esta métrica.
Datos de preparación
En la mayoría de los casos, necesita transformar sus datos. Es por eso que Facets Overview es fascinante. De la estadística de resumen, ha visto que hay valores atípicos. Esos valores afectan a las estimaciones porque no se parecen a la población que está analizando. Los valores atípicos generalmente sesgados los resultados. Por ejemplo, un valor atípico positivo tiende a sobreestimar el coeficiente.
Una buena solución para abordar este problema es estandarizar la variable. Estandarización significa una desviación estándar de uno y media de cero. El proceso de estandarización implica dos pasos. En primer lugar, resta el valor medio de la variable. En segundo lugar, se divide por la varianza para que la distribución tenga una varianza de unidad
La biblioteca sklearn es útil para estandarizar variables. Puede utilizar el preprocesamiento del módulo con la escala de objetos para este propósito.
Puede utilizar la siguiente función para escalar un dataset. Tenga en cuenta que no se escala la columna de etiqueta ni las variables categóricas.
1 2 3 4 5 6 7 8 9 10 |
from sklearn import preprocessing def standardize_data(df): X_scaled = preprocessing.scale(df[['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']]) X_scaled_df = pd.DataFrame(X_scaled, columns = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']) df_scale = pd.concat([X_scaled_df, df['CHAS'], df['PRICE']],axis=1, join='inner') return df_scale |
Puede utilizar la función para construir el tren escalado/conjunto de pruebas.
1 2 |
df_train_scale = standardize_data(df_train) df_test_scale = standardize_data(df_test) |
regresión básica:punto de referencia
En primer lugar, entrena y prueba un modelo sin interacción. El objetivo es ver la métrica de rendimiento del modelo.
La forma de entrenar el modelo es exactamente como el tutorial sobre API de alto nivel. Utilizará el estimador de TensorFlow LinearRegresor.
Como recordatorio, debe elegir:
- las características para poner en el modelo
- transformar las entidades
- construir el regresor lineal
- construir la función input_fn
- entrenar el modelo
- probar el modelo
Utilice todas las variables del dataset para entrenar el modelo. En total, hay variables continuas elevel y una variable categórica
1 2 3 4 |
## Add features to the bucket: ### Define continuous list CONTI_FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'] CATE_FEATURES = ['CHAS'] |
Convertir las entidades en una columna numérica o columna categórica
1 2 3 4 5 |
continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES] #categorical_features = tf.feature_column.categorical_column_with_hash_bucket (CATE_FEATURES, hash_bucket_size=1000) categorical_features = [tf.feature_column.categorical_column_with_vocabulary_list ('CHAS', ['yes','no'])] |
El modelo se crea con LinearRegressor. Almacenar el modelo en la carpeta Train_Boston
1 2 3 |
model = tf.estimator.LinearRegressor( model_dir="train_Boston", feature_columns=categorical_features + continuous_features) |
Salida
1 2 3 4 5 6 7 8 9 10 |
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train_Boston', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a19e76ac8>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_ replicas': 1} |
Cada columna en el tren o datos de prueba se convierte en un tensor con la función get_input_fn
1 2 3 4 5 6 7 8 9 |
FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT', 'CHAS'] LABEL= 'PRICE' def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True): return tf.estimator.inputs.pandas_input_fn( x=pd.DataFrame({k: data_set[k].values for k in FEATURES}), y = pd.Series(data_set[LABEL].values), batch_size=n_batch, num_epochs=num_epochs, shuffle=shuffle) |
Estima el modelo en los datos del tren.
1 2 3 4 5 |
model.train(input_fn=get_input_fn(df_train_scale, num_epochs=None, n_batch = 128, shuffle=False), steps=1000) |
Salida
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train_Boston/model.ckpt. INFO:tensorflow:loss = 56417.703, step = 1 INFO:tensorflow:global_step/sec: 144.457 INFO:tensorflow:loss = 76982.734, step = 101 (0.697 sec) INFO:tensorflow:global_step/sec: 258.392 INFO:tensorflow:loss = 21246.334, step = 201 (0.383 sec) INFO:tensorflow:global_step/sec: 227.998 INFO:tensorflow:loss = 30534.78, step = 301 (0.439 sec) INFO:tensorflow:global_step/sec: 210.739 INFO:tensorflow:loss = 36794.5, step = 401 (0.477 sec) INFO:tensorflow:global_step/sec: 234.237 INFO:tensorflow:loss = 8562.981, step = 501 (0.425 sec) INFO:tensorflow:global_step/sec: 238.1 INFO:tensorflow:loss = 34465.08, step = 601 (0.420 sec) INFO:tensorflow:global_step/sec: 237.934 INFO:tensorflow:loss = 12241.709, step = 701 (0.420 sec) INFO:tensorflow:global_step/sec: 220.687 INFO:tensorflow:loss = 11019.228, step = 801 (0.453 sec) INFO:tensorflow:global_step/sec: 232.702 INFO:tensorflow:loss = 24049.678, step = 901 (0.432 sec) INFO:tensorflow:Saving checkpoints for 1000 into train_Boston/model.ckpt. INFO:tensorflow:Loss for final step: 23228.568. <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a19e76320> |
Por fin, se estima el rendimiento del modelo en el conjunto de pruebas
1 2 3 4 5 |
model.evaluate(input_fn=get_input_fn(df_test_scale, num_epochs=1, n_batch = 128, shuffle=False), steps=1000) |
Salida
1 2 3 4 5 6 7 8 9 10 11 12 13 |
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-29-02:40:43 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train_Boston/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-29-02:40:43 INFO:tensorflow:Saving dict for global step 1000: average_loss = 86.89361, global_step = 1000, loss = 1650.9785 {'average_loss': 86.89361, 'global_step': 1000, 'loss': 1650.9785} |
La pérdida del modelo es 1650. Esta es la métrica a batir en la siguiente sección
Mejorar el modelo: término de interacción
Durante la primera parte del tutorial, vio una relación interesante entre las variables. Las diferentes técnicas de visualización revelaron que INDUS y NOS están unidos y giran para magnificar el efecto sobre el precio. No sólo la interacción entre INDUS y NOS afecta el precio, sino que también este efecto es más fuerte cuando interactúa con DIS.
Es hora de generalizar esta idea y ver si se puede mejorar el modelo predicho modelo.
Debe agregar dos columnas nuevas a cada conjunto de conjuntos de datos: prueba de tren +. Para ello, se crea una función para calcular el término de interacción y otra para calcular el término de interacción triple. Cada función produce una sola columna. Una vez creadas las nuevas variables, puede concatenarlas al dataset de entrenamiento y al dataset de prueba.
En primer lugar, es necesario crear una nueva variable para la interacción entre INDUS y NOX.
La siguiente función devuelve dos dataframes, tren y prueba, con la interacción entre var_1 y var_2, en su caso INDUS y NOX.
1 2 3 4 5 6 |
def interaction_term(var_1, var_2, name): t_train = df_train_scale[var_1]*df_train_scale[var_2] train = t_train.rename(name) t_test = df_test_scale[var_1]*df_test_scale[var_2] test = t_test.rename(name) return train, test |
Almacena las dos nuevas columnas
1 2 3 |
interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS') interation_ind_ns_train.shape (325,) |
En segundo lugar, se crea una segunda función para calcular el término de interacción triple.
1 2 3 4 5 6 7 |
def triple_interaction_term(var_1, var_2,var_3, name): t_train = df_train_scale[var_1]*df_train_scale[var_2]*df_train_scale[var_3] train = t_train.rename(name) t_test = df_test_scale[var_1]*df_test_scale[var_2]*df_test_scale[var_3] test = t_test.rename(name) return train, test interation_ind_ns_dis_train, interation_ind_ns_dis_test= triple_interaction_term('INDUS', 'NOX', 'DIS','INDUS_NOS_DIS') |
Ahora que tiene todas las columnas necesarias, puede agregarlas al conjunto de datos de entrenamiento y prueba. Nombra estos dos nuevos marcos de datos:
- df_train_new
- df_test_new
1 2 3 4 5 6 7 8 9 |
df_train_new = pd.concat([df_train_scale, interation_ind_ns_train, interation_ind_ns_dis_train], axis=1, join='inner') df_test_new = pd.concat([df_test_scale, interation_ind_ns_test, interation_ind_ns_dis_test], axis=1, join='inner') df_train_new.head(5) |
Salida
Eso es todo; puede estimar el nuevo modelo con los términos de interacción y ver cómo es la métrica de rendimiento.
1 2 3 4 5 6 7 8 9 |
CONTI_FEATURES_NEW = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', TAX', 'PTRATIO', 'B', 'LSTAT', 'INDUS_NOS', 'INDUS_NOS_DIS'] ### Define categorical list continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW] model = tf.estimator.LinearRegressor( model_dir="train_Boston_1", feature_columns= categorical_features + continuous_features_new) |
Salida
1 2 3 4 5 6 7 8 9 10 |
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train_Boston_1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a1a5d5860>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1} |
CÓDIGO
1 2 3 4 5 6 7 8 9 |
FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT','INDUS_NOS', 'INDUS_NOS_DIS','CHAS'] LABEL= 'PRICE' def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True): return tf.estimator.inputs.pandas_input_fn( x=pd.DataFrame({k: data_set[k].values for k in FEATURES}), y = pd.Series(data_set[LABEL].values), batch_size=n_batch, num_epochs=num_epochs, shuffle=shuffle) |
1 2 3 4 5 |
model.train(input_fn=get_input_fn(df_train_new, num_epochs=None, n_batch = 128, shuffle=False), steps=1000) |
Salida
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train_Boston_1/model.ckpt. INFO:tensorflow:loss = 56417.703, step = 1 INFO:tensorflow:global_step/sec: 124.844 INFO:tensorflow:loss = 65522.3, step = 101 (0.803 sec) INFO:tensorflow:global_step/sec: 182.704 INFO:tensorflow:loss = 15384.148, step = 201 (0.549 sec) INFO:tensorflow:global_step/sec: 208.189 INFO:tensorflow:loss = 22020.305, step = 301 (0.482 sec) INFO:tensorflow:global_step/sec: 213.855 INFO:tensorflow:loss = 28208.812, step = 401 (0.468 sec) INFO:tensorflow:global_step/sec: 209.758 INFO:tensorflow:loss = 7606.877, step = 501 (0.473 sec) INFO:tensorflow:global_step/sec: 196.618 INFO:tensorflow:loss = 26679.76, step = 601 (0.514 sec) INFO:tensorflow:global_step/sec: 196.472 INFO:tensorflow:loss = 11377.163, step = 701 (0.504 sec) INFO:tensorflow:global_step/sec: 172.82 INFO:tensorflow:loss = 8592.07, step = 801 (0.578 sec) INFO:tensorflow:global_step/sec: 168.916 INFO:tensorflow:loss = 19878.56, step = 901 (0.592 sec) INFO:tensorflow:Saving checkpoints for 1000 into train_Boston_1/model.ckpt. INFO:tensorflow:Loss for final step: 19598.387. <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1a5d5e10> |
1 2 3 4 5 |
model.evaluate(input_fn=get_input_fn(df_test_new, num_epochs=1, n_batch = 128, shuffle=False), steps=1000) |
Salida
1 2 3 4 5 6 7 8 9 10 11 12 |
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-29-02:41:14 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train_Boston_1/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-29-02:41:14 INFO:tensorflow:Saving dict for global step 1000: average_loss = 79.78876, global_step = 1000, loss = 1515.9863 {'average_loss': 79.78876, 'global_step': 1000, 'loss': 1515.9863} |
La nueva pérdida es 1515. Con solo agregar dos nuevas variables, usted fue capaz de disminuir la pérdida. Significa que puede hacer una mejor predicción que con el modelo de referencia.
Leave a Reply
Want to join the discussion?Feel free to contribute!