Actividad 1: Modelo de regresión para predicción
Tópicos especiales en Machine Learning
Universidad Central de Venezuela
Junio 2024
Índice
1. Análisis exploratorio de los datos 2
1.1. Carga y preparación de los datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2. Análisis de variables objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3. Valores faltantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4. División de los datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Regresión 4
2.1. Regresión lineal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Entrenamiento del modelo de regresión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3. Predicción del precio 7
3.1. Solución básica simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2. RMSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3. Validación del modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4. Condiciones de entrega del proyecto 10
El problema que resolveremos en este proyecto es la predicción del precio de un automobil. Supon-
gamos que tenemos un sitio web donde la gente puede vender y comprar autos usados. Al publicar un
anuncio en nuestro sitio web, los vendedores a menudo luchan por conseguir un precio significativo. Que-
remos ayudar a nuestros usuarios con recomendaciones automáticas de precios. Pedimos a los vendedores
que especifiquen el modelo, la marca, el año, el kilometraje y otras caracterı́sticas importantes del auto,
y con esta información, queremos sugerir el mejor precio.
El proyecto se encontrará dividido en las siguientes etapas:
1) Realización de un primer análisis exploratorio de datos
2) Creación de un marco de validación
3) Implementación del modelo de regresión lineal
1
1. Análisis exploratorio de los datos
1.1. Carga y preparación de los datos
Vamos a utilizar el set de datos identificado como data.csv, en el cual, se encuentra la información
de los vehı́culos vendidos, para esto, utilice las librerás Pandas y Numpy.
Actividad 1:
Determine el tamaño de los datos y realice una vista parcial de los mismos.
Al inspeccionar los datos notará que hay algunas inconsistencias en este conjunto de datos: los nombres
de las columnas a veces tienen espacios, ya veces tienen guiones bajos ( ). Lo mismo ocurre con los valores
de las caracterı́sticas: a veces están en mayúsculas, y a veces son cadenas cortas con espacios. Esto es
incómodo y confuso, pero podemos solucionarlo normalizando, es decir,
df.columns = df.columns.str.lower().str.replace(’ ’, ’_’)
string_columns = list(df.dtypes[df.dtypes == ’object’].index)
for col in string_columns:
....df[col] = df[col].str.lower().str.replace(’ ’, ’_’)
Actividad 2:
Luego de correr la lines de código anteriores, ¿qué se está haciendo en cada una de ellas?.
Explique.
Realice la normalización y verifique que se realizaron los cambios, comente brevemente lo
observado.
1.2. Análisis de variables objetivo
La columna MSRP (precio de venta al público sugerido por el fabricante) es nuestra variable objetivo,
es decir, es el valor que queremos aprender a predecir.
Uno de los primeros pasos del análisis exploratorio de datos deberı́a ser siempre mirar cómo son los
valores de y (MSRP). Para ello, solemos comprobar la distribución de y(descripción visual de los posibles
valores de y) y la frecuencia con la que se producen.
Utilice Seaborn o Matplotlib para trazar un histograma de la varible objetivo.
Actividad 3:
Utilice Seaborn o Matplotlib para trazar un histograma de la varible objetivo.
Luego de graficar los datos, ¿qué observa?. Explique.
¿Es posible mejorar la visualización de los datos?, en caso afirmativo, explique por qué y
realice las modificaciones necesarias.
2
A los datos será necesaria realizarle la siguiente transformación,
ynueva = log(y + 1)
Actividad 4:
Explique por qué es necesaria esta transformación.
Con Numpy aplique la función log1p()
Realice el histograma para los datos transformados y compare con el histograma anterior.
1.3. Valores faltantes
Comprobemos si hay valores faltantes o perdidos en los datos. Este paso es importante porque, nor-
malmente, los modelos de aprendizaje automático no pueden tratar los valores faltantes automáticamente.
Pandas tiene una función conveniente que comprueba los valores faltantes:
df.isnull().sum()
Actividad 5:
¿Qué observa de la salida de la función aplicada?
1.4. División de los datos
Tenemos que dividir el conjunto de datos en tres partes: entrenamiento, validación y prueba.
Vamos a dividir el conjunto de datos de manera que
El 20 % de los datos va a la validación.
El 20 % va a la prueba.
El 60 % restante va a entrenamiento.
Esto lo hacemos mediante el siguiente código:
n = len(df)
n_val = int(0.2 * n)
n_test = int(0.2 * n)
n_train = n - (n_val + n_test)
np.random.seed(2)
idx = np.arange(n)
np.random.shuffle(idx)
3
df_train = df_shuffled.iloc[:n_train].copy()
df_val = df_shuffled.iloc[n_train:n_train+n_val].copy()
df_test = df_shuffled.iloc[n_train+n_val:].copy()
Actividad 6:
Aplique al set de datos las lineas e código anterior
Explique brevemente qué se está realizando en cada linea
Realice una transformación logaritmica a los datos de entrenamiento, validación y prueba
para la varible objetivo, y guardelo en la variables y train, y val, y test, por ejemplo,
y train = np.log1p(df train.msrp.values)
¿Qué se hizo en este caso?
Elimine de df train, df val, df test, la variable objetivo.
¿Por qué hacemos esto?
2. Regresión
Tras realizar el análisis inicial de los datos, estamos preparados para entrenar un modelo. El problema
que estamos resolviendo es un problema de regresiń: el objetivo es predecir un número, el precio de
un automovil.
Para este proyecto utilizaremos el modelo de regresión más sencillo: la regresión lineal.
2.1. Regresión lineal
En primer lugar, repasemos cómo funciona la regresión lineal.
Figura 1: Modelo de regresión
Supongamos que tenemos una observación simple xi y el valor yi que queremos predecir. El ı́ndice i
significa aquı́ que se trata de la observación número i, una de las m observaciones que tenemos en nuestro
conjunto de datos de entrenamiento.
4
Entonces, para esta única observación, el modelo a estimar tiene la forma:
yi ≈ f(xi )
Si tenemos n caracterı́sticas, nuestro vector xi serı́a n−dimensional, por lo que tiene n componentes:
xi = (xi1 , xi2 , ..., xin )
Como tiene n componentes, podemos escribir la función f como una función con n parámetros, que
es lo mismo que la fórmula anterior:
yi ≈ f(xi ) = f(xi1 , xi2 , ..., xin )
En nuestro caso, tenemos 7,150 autos en el conjunto de datos de entrenamiento. Esto significa que
m = 7,150 y i puede ser cualquier número entre 0 y 7,149.
Si f es el modelo de regresión lineal, tiene la siguiente forma:
f(xi ) = f(xi1 , xi2 , ..., xin ) = β0 + β1 xi1 + β2 xi2 + · · · + βn xin
donde, β0 , β1 , ..., βn son los parámetros del modelo:
β0 es el término de sesgo.
β1 , β2 , ..., βn son las ponderaciones de cada caracterı́stica xi1 , xi2 , ..., xin .
Estos parámetros definen exactamente cómo debe combinar el modelo las caracterı́sticas para que las
predicciones al final sean lo mejor posible.
Para que la fórmula sea más corta, vamos a utilizar la notación de suma:
X
n
f(xi ) = f(xi1 , xi2 , ..., xin ) = β0 + βj xij
j=1
Actividad 7:
¿Cuáles son xi e yi para este proyecto?
Realice una vista de un vector especı́fico, en los datos, de su elección.
Estas ponderaciones son las que aprende el modelo cuando lo entrenamos.
Este modelo lo podemos escribir es forma matricial como:
f(X) = β0 + Xβ,
donde, β es el vector columna de los coeficientes β1 , β2 , ..., βn , mientras X es lo que se conoce como la
matiz de diseño que contiene todas las observaciones de las caracterı́sticas consideradas.
5
2.2. Entrenamiento del modelo de regresión
Para poder hacer rediciones, necesitamos saber las ponderaciones β. ¿Cómo las obtenemos?
Aprendemos los pesos a partir de los datos: utilizamos la variable objetivo y para encontrar la beta
que combina las caracterı́sticas de X de la mejor manera posible.
En el caso de la regresión lineal, “la mejor manera posible ”significa que minimiza el error entre las
predicciones f(X) y el objetivo real y.
Tenemos varias formas de hacerlo. Utilizaremos la ecuación normal, que es el método más sencillo. El
vector de pesos β se puede calcular con la siguiente fórmula:
β = (XT X)−1 XT y
Esto es fácil de traducir a NumPy:
XT es la transpuesta de X. En NumPy, es X.T
XT X es una multiplicación de matrices, que podemos hacer con el método del punto de NumPy:
X.T.dot(X)
X−1 es la inversa de X. Podemos utilizar la función np.linalg.inv para calcular la inversa.
Actividad 8:
¿Cómo se traducirı́a la fórmua anterior en python?
Para implementar la ecuación normal, tenemos que hacer lo siguiente:
Crear una función que tome una matriz X con caracterı́sticas y un vector y con el objetivo.
Añadir una columna ficticia (la caracterı́stica que siempre se pone en 1) a la matriz X.
Entrena el modelo: calcula los pesos β mediante la ecuación normal.
Dividir este β en el sesgo β0 y el resto de los pesos, y devolverlos.
El último paso (dividir β en el término de sesgo y el resto) es opcional y se hace principalmente por
conveniencia.
La implementación serı́a:
def train_linear_regression(X, y):
....ones = np.ones(X.shape[0])
....X = np.column_stack([ones, X])
....XTX = X.T.dot(X)
....XTX_inv = np.linalg.inv(XTX)
....w = XTX_inv.dot(X.T).dot(y)
return w[0], w[1:]
6
Actividad 9:
Ejecute el código, explique cada función e identifı́quela con los pasos señalados.
3. Predicción del precio
Ahora tenemos una función para entrenar un modelo de regresión lineal a nuestra a nuestra disposición,
ası́ que vamos a utilizarla para construir una solución básica simple.
3.1. Solución básica simple
Sin embargo, para poder utilizarlo, necesitamos tener algunos datos: una matriz X y un vector con y.
Ya hemos preparado la y, pero todavÃÂa no tenemos la X: lo que tenemos ahora mismo es un data-
frame, no una matriz. Ası́ que tenemos que extraer algunas caracterı́sticas de nuestro conjunto de datos
para crear esta matriz X.
Empezaremos con una forma muy ingenua de crear caracterı́sticas: seleccionaremos algunas carac-
terı́sticas numéricas y formaremos la matriz X a partir de ellas.
Incluimos las siguientes caracterı́sticas:
motor cv (engine hp)
cilindros del motor (engine cylinders)
consumo en carretera (highway mpg)
consumo en ciudad (city mpg)
popularidad (popularity)
base = [’engine_hp’, ’engine_cylinders’, ’highway_mpg’, ’city_mpg’, ’popularity’]
y luego para los valores faltantes:
def prepare_X(df):
....df_num = df[base]
....df_num = df_num.fillna(0)
....X = df_num.values
....return X
Actividad 10:
Ejecute el código, y explique cuál es el tratamiento aplicado, en este caso, a los valores
faltantes (esto se desprende del código)
7
Ahora, aplicamos la función de preparación anterior a los datos de prueba df train y lo guardamos
en una matriz llamada X train.
Actividad 11:
Sugiera una rutina para resolver este paso
La matriz X train la usamos com input en nuestro modelo, a través de la función train linear regression
que hemos creado, es decir,
b_0, b = train_linear_regression(X_train, y_train)
Actividad 12:
Imprima los valores de β y β0 ¿Qué observa?
Acabamos de entrenar el primer modelo. Ahora podemos aplicarlo a los datos de entrenamiento para
ver que tan bien predice:
y_pred = b_0 + X_train.dot(b)
Ploteamos los valores predichos y los precios reales,
plt.figure(figsize=(6, 4))
sns.histplot(y_train, label=’target’, color=’#222222’, alpha=0.6, bins=40)
sns.histplot(y_pred, label=’prediction’, color=’#aaaaaa’, alpha=0.8, bins=40)
plt.legend()
plt.ylabel(’Frecuencia’)
plt.xlabel(’Log(Price + 1)’)
plt.title(’Predichos vs reales’)
plt.show()
Actividad 13:
Describa cada linea del código.
¿Qué finalidad tiene la realización de este plot?
¿Qué puede concluir del gráfico?
8
3.2. RMSE
Ahora, necesitamos una métrica que cuantifique la calidad del modelo.
La más utilizada es el error cuadrático medio (RMSE).
El RMSE nos indica la magnitud de los errores que comete nuestro modelo. Se calcula con la siguiente
fórmula:
v
u1 X m
u
RMSE = t (f(xi ) − yi )2
m
i=1
Actividad 14:
Utilizando la funciones aritméticas, la función mean() y sqrt() de python, cree la función
llamada rmse, la cual, debe ingerir las variables y, y pred, utilizando la función def.
Actividad 15:
Aplique la función creada a los vectores y train, y pred. ¿Qué puede decir del resultado?
3.3. Validación del modelo
Hemos calculado el RMSE en el conjunto de entrenamiento. El resultado es útil de conocer, pero no
refleja la forma en que se utilizará el modelo posteriormente.
El modelo se utilizará para predecir el precio de los autos que no ha visto antes. Para ello, reservamos
un conjunto de validación.
Ya hemos dividido nuestros datos en varias partes: df train , df val , y df test .
También hemos creado una matriz X train a partir de df train y hemos utilizado X train e y train
para entrenar el modelo.
Ahora tenemos que hacer los mismos pasos para obtener X val (una matriz con caracterśticas
calculadas a partir del conjunto de datos de validación).
Luego, podemos aplicar el modelo a X val para obtener predicciones y compararlas con y val.
Actividad 16:
Siguiendo pasos análogos a lo ya hecho, construya la matriz X val y calcule su rmse.
Esto nos permite comprobar si los ajustes del modelo conducen a mejoras en la calidad predictiva del
modelo.
9
Actividad 17:
¿Qué puede concluir? ¿Hay una mejora?
4. Condiciones de entrega del proyecto
La actividad debe ser entregada en un Jupyter notebook, en el classroom, resolviendo todas las
preguntas planteadas en la rutina.
10