DEV Community

Cover image for El Poder de lo Simple: Regresión Lineal para Predecir Precios de Casas
Edgar Cajusol
Edgar Cajusol

Posted on

El Poder de lo Simple: Regresión Lineal para Predecir Precios de Casas

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.

imagen-inmueble

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
Enter fullscreen mode Exit fullscreen mode
df = pd.read_csv('house_price_bd.csv')
df.head(2)
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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 tipo int (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 un object 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'
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

¿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.

Top comments (0)