El Poder de lo Simple: Regresión Lineal para Predecir Precios de Casas
Edgar Cajusol
Posted on November 24, 2024
El sector inmobiliario es uno de los más diversos y complejos del mundo. Entender cómo se determinan los precios de las propiedades puede ser un desafío, ya que depende de múltiples factores como el tamaño de la casa, el número de habitaciones, la ubicación, el tamaño del garaje (si tiene uno), entre otros. ¿Pero serán realmente todos estos factores determinantes?
En este artículo, exploraremos un modelo simple pero poderoso, la Regresión Lineal, para ayudarnos no solo a predecir los precios de las casas, sino también a identificar si algunas de las variables mencionadas realmente son importantes o influyentes en el modelo.
A lo largo del artículo, aprenderás:
- Como preparar los datos inmobiliarios para el análisis.
- Los fundamentos de la regresión lineal, incluyendo los supuestos que deben cumplirse (normalidad, homocedasticidad, entre otros) para obtener resultados confiables.
- La implementación práctica del modelo en Python.
- La interpretación de resultados, las métricas clave y los próximos pasos a considerar.
Para entrenar a nuestro modelo usaremos un dataset obtenido en kaggle, en el cual buscaremos predecir el precio de las casas en Bangladesh.
link del dataset: https://www.kaggle.com/datasets/durjoychandrapaul/house-price-bangladesh
En este dataset podemos encontrar columnas como:
- Title: El titulo de la oferta de venta de la propiedad.
- Bedrooms: Representa la cantidad de habitaciones de la propiedad.
- Bathrooms: Cantidad de baños de la propiedad.
- Floor_no: El número de piso en el que se encuentra la propiedad.
- Occupancy_status: Indica si la propiedad está desocupada u ocupada.
- Floor_area: La superficie total construida de la propiedad en pies cuadrados.
- City: La ciudad donde se encuentra la propiedad.
- Price_in_taka: Precio de la propiedad en Taka bangladesí.
- Location: La ubicación o dirección específica dentro de la ciudad.
1. Importación de las librerías y carga de datos.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
df = pd.read_csv('house_price_bd.csv')
df.head(2)
Title | Bedrooms | Bathrooms | Floor_no | Occupancy_status | Floor_area | City | Price_in_taka | Location |
---|---|---|---|---|---|---|---|---|
We Are Offering You A Very Spacious 1960 Sq Ft Flat For Sale In Gulshan 1 | 3.0 | 4.0 | 3 | vacant | 1960.0 | dhaka | ৳39,000,000 | Gulshan 1, Gulshan |
Valuable 1705 Square Feet Apartment Is Ready To Sale In Kalabagan | 3.0 | 3.0 | 1 | vacant | 1705.0 | dhaka | ৳16,900,000 | Lake Circus Road, Kalabagan |
1.2. Limpieza de datos
Que tal si luego observamos el tipo de datos que tenemos para corroborar que todo esté en orden.
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3865 entries, 0 to 3864
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Title 3865 non-null object
1 Bedrooms 2864 non-null float64
2 Bathrooms 2864 non-null float64
3 Floor_no 3181 non-null object
4 Occupancy_status 3766 non-null object
5 Floor_area 3766 non-null float64
6 City 3865 non-null object
7 Price_in_taka 3865 non-null object
8 Location 3859 non-null object
dtypes: float64(3), object(6)
memory usage: 271.9+ KB
Lo que podemos notar:
Bedrooms y Bathrooms son tipo
float
(decimal). Aunque esto no debería afectar el rendimiento del modelo, es incorrecto, ya que no tiene sentido tener valores decimales en estas columnas, como "2.4 baños", ¿verdad? Lo correcto sería convertir ambas columnas a tipoint
(entero).Floor_no y Price_in_taka son de tipo
object
, lo cual es un error. El número de piso debería ser un valor entero, por lo que es necesario convertir esta columna a tipo int. En cuanto a la columna Price_in_taka, se ha considerado unobject
debido a la presencia de caracteres especiales, como el símbolo "৳". Para corregir esto, debemos eliminar dicho símbolo y luego cambiar el tipo de ambas columnas a su formato adecuado.
Ojo aquí:
df['Bedrooms'] = df['Bedrooms'].astype(int)
df['Bathrooms'] = df['Bathrooms'].astype(int)
df['Floor_no'] = df['Floor_no'].astype(int)
ValueError: invalid literal for int() with base 10: '8th'
Al intentar convertir las columnas Bedrooms, Bathrooms y Floor_no a tipo int
, nos encontramos con un error. Este ValueError
ocurre porque algunas filas contienen valores no numéricos, como '8th'
en lugar de un valor numérico válido. Este error se presenta cuando intentamos convertir valores no numéricos o NaN
a tipo entero (int
), ya que el tipo int
no puede manejar estos valores faltantes o textos. Por otro lado, float
sí permite NaN
como valor y es por eso que las columnas tenían este tipo de datos inicialmente.
De hecho, encontramos indicadores de valores faltantes antes de llegar a este punto, lo que nos ayudó a identificar el origen del error.
#Limpiar el simbolo en el Precio
df['Price_in_taka'] = df['Price_in_taka'].str.replace(r'৳','')
df['Price_in_taka'] = df['Price_in_taka'].str.replace(r',','')
df['Price_in_taka'] = df['Price_in_taka'].astype(float)
¿Porque convetí la columna Price_in_taka a float
y no int
?
Decidí convertir la columna de precio a float
en lugar de int
por varias razones. Inicialmente, la columna Price_in_taka
estaba de tipo object, lo que indicaba que contenía valores no numéricos o con caracteres no válidos, como el símbolo "৳". Aunque el precio podría ser un valor entero, no podemos estar seguros de que todos los valores estén libres de decimales.
Si hubiésemos elegido convertir esta columna a int
directamente, podríamos haber perdido la información de decimales en caso de que existieran, lo que podría sesgar nuestros datos. Además, el tipo float
permite manejar valores decimales y, al mismo tiempo, preserva la posibilidad de representar números enteros. Así evitamos cualquier posible distorsión en el análisis.
El siguiente paso es opcional, lo que haré será convertir la moneda a dólares estadounidenses para una compresión mejor del columna precio.
#Transformar de Taka Bandaglesí a dolares
df['Price_in_taka'] = df['Price_in_taka']*0.0084
df.rename(columns={'Price_in_taka':'Price_in_dolars'},inplace=True)
Ahora sí, revisemos la cantidad de nulos que sabemos que existen.
df.isna().sum()
Title 0
Bedrooms 1001
Bathrooms 1001
Floor_no 684
Occupancy_status 99
Floor_area 99
City 0
Price_in_dolars 0
Location 6
dtype: int64
#Cantidad total de datos
len(df)
3865
La mayor cantidad de filas nulas que tenemos son alrededor de 1001 filas de un total de 3865 filas en el conjunto de datos. El porcentaje que representan se calcula de la siguiente manera:
Este porcentaje representa aproximadamente el 26% del total de los datos, lo que supera el umbral recomendado de un 5% para la imputación de datos. Con esto en mente, tenemos dos opciones:
- Imputar los datos (aunque esto podría incluir valores erróneos).
- Eliminar las filas con valores nulos, ya que contamos con una cantidad suficiente de datos.
Riesgos de imputar datos:
Imputar datos puede introducir sesgos si los valores imputados no representan adecuadamente la distribución original, distorsionando las relaciones entre las variables. Además, si los datos faltantes siguen un patrón específico, la imputación podría reforzar ese sesgo y afectar la precisión del modelo. Aunque mantener más datos puede ser útil, la imputación también puede aumentar la varianza del modelo si los valores imputados son muy diferentes de los reales.
#Observando los datos nulos
df[df['Bedrooms'].isna()].head(3)
Title | Bedrooms | Bathrooms | Floor_no | Occupancy_status | Floor_area | City | Price_in_taka | Location | |
---|---|---|---|---|---|---|---|---|---|
22 | Large 5000 Sq Ft Commercial Space For Sale In Free School Street Road, Kathalbagan | NaN | NaN | 9 | vacant | 5000.0 | dhaka | 110000000.0 | Free School Street, Kathalbagan |
40 | A Commercial Building Is Up For Sale Which Is Located In Mirpur Nearby Mirpur Adhunik Hospital | NaN | NaN | 6 | vacant | 16000.0 | dhaka | 120000000.0 | Section 12, Mirpur |
45 | 2.75 Katha Residential Plot For Sale In Mirpur-11 | NaN | NaN | NaN | vacant | 1980.0 | dhaka | 18000000.0 | Section 11, Mirpur |
Al observar algunos datos nulos, podemos notar que puede haber coincidencias entre las columnas, es decir, que tanto Bedrooms como Bathrooms estén vacíos al mismo tiempo. Esto podría indicar que la información de estas propiedades no fue registrada correctamente, o bien que se decidió no incluirla desde el principio, tal vez porque no era relevante para el análisis inicial. En cualquier caso, es importante identificar patrones en los datos faltantes para tomar decisiones informadas sobre cómo manejarlos.
Tomaré la opción de eliminar los datos nulos, debido a que imputar podría introducir error en mi conjunto de datos.
df_null = df.copy()
df.dropna(subset=['Bedrooms','Bathrooms','Floor_no'],inplace=True)
df.reset_index(drop=True,inplace=True)
print("La longitud del dataframe con datos nulos es: ",len(df_null))
print("La longitud eliminando datos nulos es: ",len(df))
print("Se han eliminado :", len(df_null) - len(df), "filas")
La longitud del dataframe con datos nulos es: 3865
La longitud eliminando datos nulos es: 2832
Se han eliminado : 1033 filas
Despues de eliminar nos hemos quedado con 2832 filas para entrenar a nuestro modelo.
Volvemos a ver los datos nulos.
df.isna().sum()
Title 0
Bedrooms 0
Bathrooms 0
Floor_no 0
Occupancy_status 0
Floor_area 0
City 0
Price_in_dolars 0
Location 1
dtype: int64
Vemos que aún tenemos un dato nulo en la columna Location, pero dado que no utilizaré esta variable en el análisis, no es necesario eliminar la fila.
Para mayor comodidad visual, decidí convertir la columna de precio a miles de unidades dividiéndola entre 1000. Esto facilita la interpretación de los valores y mejora la legibilidad de los datos.
df['Price_in_dolars'] = df['Price_in_dolars']/1000
df.rename(columns={'Price_in_dolars':'Price_$_k'},inplace=True)
No olvidemos convetir el tipo de variable de las columnas Bedrooms, Bathrooms y Floor_no.
Como Floor_no posee caracteres especiales deberíamos eliminarlos primero y extraer solamente el carácter numérico.
df['Floor_no'] = df['Floor_no'].astype(str).str.extract('(\d+)')
df['Floor_no'] = pd.to_numeric(df['Floor_no'], errors='coerce')
La expresión regular (\d+)
extrae solo los dígitos (números) de cada valor. Si el valor contiene texto o símbolos no numéricos, solo se extraerán los números. Luego coerce convierte los valores extraídos a tipo numérico , si no logra hacerlo le colocará NaN
.
df['Bedrooms'] = df['Bedrooms'].astype(int)
df['Bathrooms'] = df['Bathrooms'].astype(int)
Finalmente convertiremos a tipo int
las otras dos columnas y tendríamos todo correctamente hecho.
2. Análisis Exploratorio de Datos (EDA)
En muchos problemas de predicción, un modelo lineal puede ser una herramienta poderosa. El objetivo de este artículo es aplicar la regresión lineal simple para predecir el precio de propiedades basándonos en el área del piso y el número de dormitorios. Utilizaremos un diagrama de dispersión (scatterplot) para visualizar si nuestros datos siguen una tendencia lineal, que es uno de los supuestos fundamentales para aplicar regresión lineal.
2.1. Normalidad
#GRAFICO POR DORMITORIOS
sns.scatterplot(x='Bedrooms',y='Price_$_k',data=df)
plt.title('Dormitorios vs Precios en ($)', fontsize=16)
plt.xlabel('Dormitorios')
plt.ylabel('Precio ($) en miles')
plt.show()
En el gráfico anterior, observamos que los datos no presentan un comportamiento lineal evidente entre el número de dormitorios y el precio. Esto sugiere que no se cumple el supuesto de linealidad, uno de los principios clave para la regresión lineal. Este patrón indica que otras variables podrían estar influyendo más significativamente en los precios.
2.2. Homocedasticidad
#Grafico por Área
sns.scatterplot(x='Floor_area',y='Price_$_k',data=df)
plt.title('Area del piso vs Precios en ($) en miles', fontsize=16)
plt.xlabel('Area del piso')
plt.ylabel('Precio ($) en miles')
plt.show()
#Regla de Homecedasticidad violada, conjunto Heterocedastico
En el gráfico anterior, notamos que los datos están más agrupados en valores bajos de Área del piso, pero se dispersan considerablemente conforme aumentan los valores del área. Esto indica que la homocedasticidad (varianza constante) no se cumple, y en su lugar, observamos un patrón de heterocedasticidad, lo que significa que la varianza de los precios no es constante a lo largo de los valores del área del piso.
Esto se puede corroborar con análisis estadísticos, como pruebas de linealidad y heterocedasticidad, pero en este artículo nos enfocaremos en un enfoque práctico apoyándonos en gráficos para identificar posibles violaciones a estos supuestos
Entonces ¿Cómo podemos seguir adelante?
Una manera efectiva de abordar estos problemas es transformar las variables mediante su logaritmo. Esta técnica es particularmente útil por las siguientes razones:
- Linealización de relaciones no lineales: Muchas relaciones no lineales entre variables pueden convertirse en lineales al aplicar una transformación logarítmica, facilitando el ajuste del modelo.
- Reducción de heterocedasticidad: Las transformaciones logarítmicas tienden a estabilizar la varianza, ayudando a evitar problemas de heterocedasticidad.
- Escala más manejable: Si los valores tienen rangos amplios, el logaritmo los compacta, haciendo que sean más fáciles de interpretar y modelar.
En los próximos pasos, aplicaremos esta transformación a nuestras variables clave y evaluaremos cómo mejora la calidad de nuestros datos para la regresión lineal.
# Usar variables logaritmicas
df['log_area'] = np.log(df['Floor_area'])
df['log_precio'] = np.log(df['Price_$_k'])
sns.scatterplot(x='log_area',y='log_precio',data=df)
plt.title('Area del piso vs Precios en ($) en miles', fontsize=16)
plt.xlabel('Area del piso')
plt.ylabel('Precio ($) en miles')
plt.show()
Excelente! Ahora nuestras variables presentan no solo un comportamiento lineal si no que también hemos eliminado la heterocedasticidad.
Como siguiente paso realizaremos la configuración y aplicación de nuestro modelo de regresión lineal.
3. Aplicar el modelo de regresión
¿Por qué utilizaremos OLS de Statsmodels?
El modelo de Regresión Lineal mediante Ordinary Least Squares (OLS) es uno de los métodos más populares para estimar los coeficientes de un modelo lineal, ya que no solo ajusta el modelo, sino que también proporciona un análisis detallado de los resultados, lo que es muy importante para interpretar y evaluar nuestro modelo.
En este contexto, el uso de OLS no solo nos permitirá ajustar un modelo, sino también profundizar en la comprensión de los factores que afectan los precios de las propiedades.
¿Por qué no usamos solo scikit-learn? Aunque scikit-learn también permite implementar la regresión lineal, su enfoque está más orientado a tareas de predicción que a la interpretación detallada del modelo. Por eso, Statsmodels es mi elección cuando el análisis interpretativo y estadístico es una prioridad.
#Ejecutar el model
y = df['log_precio'] #variable dependiente
x1 = df['log_area'] #variable independiente
x = sm.add_constant(x1) #Añadimos la constante
results = sm.OLS(y,x).fit() #entrenamos al modelo
results.summary() #Observamos el cuadro informativo
Después de ajustar nuestro modelo de regresión lineal, obtuvimos el siguiente cuadro resumen:
R-squared (Coeficiente de determinación): El valor de R2 es 0.706 lo que indica que el 70.6% de la variabilidad en los precios de las casas (en escala logarítmica) puede ser explicada por el área del piso (también en escala logarítmica). Es un resultado bueno aunque podría mejorarse al incluir otras variables relevantes.
Coeficiente de la variable independiente (log(Area)): El coeficiente es 1.4417 lo que indica que en promedio, un aumento del 1% en el área del piso está asociado con un incremento del 1.4417% en el precio de la casa. Esta es una relación fuerte y positiva.
Significancia estadística (Valores p): Tanto la constante como
log(Area) tienen valores p significativamente menores a 0.05, lo que confirma que son estadísticamente significativos en el modelo.
Veamos como se gráfico la línea de regresión en nuestro conjunto de datos.
sns.scatterplot(x=x1,y=y)
yhat = -6.1998 + 1.4417*x1
plt.plot(x1,yhat,c='red',label='regression line')
plt.xlabel('Area del piso')
plt.ylabel('Precio miles ($)')
plt.title('Area del piso vs Precios en ($) en miles', fontsize=16, color='green')
plt.legend()
plt.show()
Espera! no nos quedaremos allí, ¿Qué ocurriría si añadimos otra variable más? Como por ejemplo: Bedrooms, eso es lo que veremos en el siguiente punto.
4. Regresión Lineal Múltiple
Aquí añadiremos la columnas Bedrooms para ver si nuestro modelo mejora o no, ya estaríamos hablando de un problema de regresión lineal múltiple.
x1 = df[['Bedrooms','log_area']]
y = df['log_precio']
x = sm.add_constant(x1)
results = sm.OLS(y,x).fit()
results.summary()
Análisis de los resultados del modelo y comparación de cambios:
- R-squared Ajustado (Coeficiente de determinación ajustado): En un problema de regresión lineal múltiple es más adecuado utilizar el R2-ajustado en lugar del R2 estándr, ya que este penaliza la inclusión de variables adicionales que no aporten significativamente al modelo.
Al comparar el R2-ajustado de 72.4% frente a 70.6% de la regresión simple (solo con log(Area)), podemos observar que la inclusión de Bedrooms ha mejorado la capacidad del modelo para explicar la variabilidad en los precios.
Significancia estadística (Valores p): El valor p asociado a la nueva variable Bedrooms es menor a 0.05, lo que indica que es estadísticamente significativa para el modelo. Esto confirma que Bedrooms aporta información relevante para explicar la variabilidad en los precios, contribuyendo a una mejor predicción.
Coeficiente de la variable independiente Bedrooms: El coeficiente negativo de Bedrooms indica que, al aumentar en 1 el número de dormitorios, el log(Precio) disminuye en promedio, manteniendo constante el área. Esto puede parecer contraintuitivo, pero podría reflejar que, en propiedades con áreas similares, agregar dormitorios reduce el espacio disponible para otras características de alto valor (como una sala más grande o acabados de lujo).
Este resultado enfatiza que Bedrooms por sí solo no es siempre un predictor lineal positivo de precio, especialmente cuando otras variables como el área ya están incluidas en el modelo.
Conclusión:
La adición de Bedrooms no solo ha mejorado el ajuste del modelo (mayor R2-ajustado), sino que también ha demostrado ser una variable relevante desde el punto de vista estadístico. Esto refuerza la importancia de explorar y seleccionar cuidadosamente las variables predictoras en los modelos de regresión, por último es importante interpretar estos resultados no de forma aislada, sino considerando las interacciones y la posible multicolinealidad entre las variables.
5. Añadir más variables
Para mejorar el modelo de regresión y ver cómo se comporta con la regresión lineal múltiple, añadiremos una nueva variable: Ciudad. Intuitivamente, podemos suponer que la ubicación de la propiedad, representada por la ciudad, puede tener un impacto significativo en su precio. Por lo tanto, vamos a incluirla como una variable adicional en nuestro análisis.
df['City'] = df['City'].map({'dhaka':0,'chattogram':1,'cumilla':2,'narayanganj-city':3,'gazipur':4})
En el código anterior, lo que hice fue mapear la columna "City", que contiene los nombres de las ciudades, asignando a cada una de ellas un valor numérico único. Por ejemplo, Dhaka se convierte en 0, Chattogram en 1, y así sucesivamente. Este mapeo nos permite incluir la variable "Ciudad" como una variable numérica en nuestro modelo de regresión lineal.
Es importante destacar que este es un enfoque sencillo para convertir variables categóricas en numéricas. Sin embargo, si las ciudades tienen más de dos categorías, una alternativa más robusta es usar técnicas como el OneHotEncoder de la librería scikit-learn, que crea una columna binaria por cada categoría, permitiendo modelar de manera más eficiente y evitando problemas de interpretación cuando hay más de dos categorías.
x1 = df[['City','log_area','Bedrooms']]
y = df['log_precio']
x = sm.add_constant(x1)
results = sm.OLS(y,x).fit()
results.summary()
¡Muchísimo mejor, ¿Verdad?! Al incluir la variable 'City', logramos mejorar significativamente el rendimiento de nuestro modelo, alcanzando un R² de 78.7%. Esto sugiere que la ciudad en la que se encuentra la propiedad tiene una influencia considerable en su precio. Los p-valores menores a 0.05 refuerzan la idea de que las variables utilizadas son estadísticamente significativas, lo que significa que podemos confiar en los resultados del modelo. Este análisis nos permite hacer predicciones más precisas y establecer una base sólida para futuras investigaciones en el sector inmobiliario.
6. Predecir y evaluar correctamente los resultados.
Para finalizar y dar un análisis más completo, no solo nos quedaremos con el ajuste del modelo, sino que también realizaremos predicciones utilizando nuevos valores y evaluaremos los resultados.
# Ejemplo de nuevos datos
new_data = pd.DataFrame({
'City': [0, 1],
'log_area': [7.5, 6.8],
'Bedrooms': [3, 4]
})
# Agregar la constante para los nuevos datos
new_data_with_const = sm.add_constant(new_data)
# Hacer predicciones
predicted_values = results.predict(new_data_with_const)
# Mostrar las predicciones
print(predicted_values)
Una vez realizadas las predicciones, obtuvimos los precios predichos (en logaritmo de precios) para los dos datos nuevos introducidos, los cuales nunca antes habían sido vistos por el modelo:
0 4.759433
1 3.427864
dtype: float64
Ahora, vamos a evaluar la precisión de nuestro modelo y entender cómo se comportan estas predicciones en comparación con los datos reales.
¿Como evaluamos los errores?
Para evaluar la precisión de nuestras predicciones, utilizaremos el Mean Squared Error (MSE) o Error Cuadrático Medio, que mide el promedio de los cuadrados de las diferencias entre los valores predichos y los valores observados. Este valor nos permite cuantificar qué tan bien está funcionando nuestro modelo. Para calcularlo, utilizaremos la librería de scikit-learn y su módulo mean_squared_error
.
from sklearn.metrics import mean_squared_error
y_pred = results.predict(x)
# Calcular MSE
mse = mean_squared_error(y, y_pred)
print(f"El MSE del modelo es: {mse}")
Una vez aplicada la librería obtenemos el siguiente valor de MSE.
El MSE del modelo es: 0.0738931778107037
Es importante tener en cuenta que el MSE está en unidades elevadas al cuadrado, lo que puede hacer que su interpretación sea más difícil. Para facilitar la lectura y comprensión del error, utilizaremos el RMSE (Root Mean Squared Error), que es simplemente la raíz cuadrada del MSE. El RMSE tiene las mismas unidades que la variable de interés, lo que lo hace más fácil de interpretar.
rmse = np.sqrt(mse)
print(f"El RMSE del modelo es: {rmse}")
El RMSE del modelo es: 0.2718329961772553
Para interpretar el RMSE en las unidades originales de los precios (no logarítmicas), es necesario exponenciar el RMSE, ya que el modelo trabaja sobre valores logarítmicos. Esto nos dará una medida en la misma escala de los precios originales.
rmse_original_scale = np.exp(0.2718) - 1
print(f"El RMSE Original es: {rmse_original_scale}")
El RMSE Original es: 0.31232451016083607
El RMSE de 0.3123 miles de dólares muestra que nuestro modelo tiene una capacidad bastante decente para predecir los precios de las propiedades, con un error promedio de alrededor de 312 dólares. Dependiendo del destino de uso del modelo como para predicciones comerciales, este error puede ser aceptable, pero siempre es bueno compararlo con el rango de precios para tener una evaluación más precisa.
7. Conclusiones y pasos finales
En este artículo, hemos utilizado la regresión lineal, específicamente el modelo OLS (Ordinary Least Squares), para predecir los precios de propiedades basado en variables como el área del piso, la cantidad de dormitorios y la ciudad. A través de este análisis, hemos logrado lo siguiente:
Validación de supuestos: Aunque la linealidad no fue perfecta y encontramos evidencias de heterocedasticidad en nuestros datos (Omnibus y Jarque-Bera), aplicamos una transformación logarítmica que ayudó a mejorar la linealidad y la varianza constante, acercando el modelo a las condiciones ideales de la regresión lineal.
Mejora con variables adicionales: Hemos ido viendo como la incorporación de variables ha ido mejorando al modelo, la variable City, que representa las diferentes ciudades, logramos mejorar significativamente el modelo, alcanzando un R2 ajustado del 78.7%, lo que indica que el modelo puede explicar un alto porcentaje de la variabilidad en los precios, cabe recalcar que esto no siempre es así, por eso es bueno revisar siempre el R2-ajustado y el p-valor de cada variable.
Evaluación del rendimiento: Con el cálculo del RMSE (Root Mean Squared Error) en escala original, encontramos que el modelo tiene un error promedio de 312.3 dólares por predicción. Este valor, aunque dependiente del rango de precios, muestra un error razonablemente bajo, lo que sugiere que el modelo es adecuado para las predicciones de precios de propiedades en este conjunto de datos.
En resumen, hemos construido un modelo de regresión lineal efectivo para predecir precios de propiedades, aunque siempre existen áreas para mejorar, como la posible inclusión de variables adicionales o el ajuste más fino del modelo.
Pasos Finales a Seguir
- Ampliar los datos: Incluir más datos y variables podría mejorar la precisión del modelo.
- Probar otros modelos: Modelos como Random Forest o XGBoost pueden captar mejor las interacciones y mejorar las predicciones.
- Evaluar con nuevos datos: Validar el modelo con un conjunto de prueba o usar validación cruzada para asegurar que no haya sobreajuste.
- Incluir más variables: Añadir factores como el tipo de propiedad o la antigüedad podría mejorar la precisión.
- Predicción en tiempo real: Si el modelo se va a implementar en producción se debe de considerar actualizarlo periódicamente con nuevos datos, recomiendo ir leyendo sobre MLOps.
¿Quién dijo que las matemáticas no resuelven problemas de la vida real? La regresión lineal lo hace con más estilo que un chef con su receta secreta.
Edgar Cajusol - Data Scientist - Creando impacto un modelo a la vez.
https://www.linkedin.com/in/edgarcajusol/
Posted on November 24, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 24, 2024