Добро пожаловать в этот блог, где мы погружаемся в захватывающий проект машинного обучения по прогнозированию цен на жилье в Бангалоре. Рынок недвижимости Бангалора известен своим потенциалом роста, что делает его идеальной средой для применения передовых моделей прогнозирования. В этой статье мы рассмотрим, как алгоритмы машинного обучения могут анализировать исторические данные, чтобы делать точные прогнозы будущих цен на жилье в Бангалоре.

Импортировать важные библиотеки

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib
matplotlib.rcParams["figure.figsize"] = (20,10)
import seaborn as sns


# Model Evaluation
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.metrics import precision_score, f1_score, recall_score

# Models for scikit-learn
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import ShuffleSplit
from sklearn.model_selection import cross_val_score

Загрузить набор данных

Вы можете скачать набор данных здесь.

data = pd.read_csv("Bengaluru_House_Data.csv")
data.head(13)

Понимание данных

# Check the shape of Dataset
data.shape

data.describe().T

data.info()

Удаление ненужных столбцов

df = data.drop(["area_type","society","balcony","availability"], axis = 1)
df.head()

Предварительная обработка данных

Обработка нулевых значений

# Find all null Values
df.isnull().sum()

# Dropping null values
df = df.dropna()
df.isnull().sum()

Разработка функций

df["bhk"] = df["size"].apply(lambda x: int(x.split(" ")[0]))
df.head()

df["bhk"].unique()

df[df.bhk > 17]

df.total_sqft.nunique()

def is_float(x):
    try:
        float(x)
    except:
        return False
    return True

df[~df["total_sqft"].apply(is_float)].head(12)

Теперь преобразуем все значения total_sqft в значение с плавающей запятой.

def convert_sqft_to_num(x):
    tokens = x.split("-")
    if len(tokens) == 2:
        return (float(tokens[0]) + float(tokens[1]))/2
    try:
        return float(x)
    except:
        return None
df1 = df.copy()
df1["total_sqft"] = df1["total_sqft"].apply(convert_sqft_to_num)
df1.head(12)

df1["price_per_sqft"] = df1["price"]*100000/df1["total_sqft"]
df1.head()

len(df1.location.unique())

df1.location = df1["location"].apply(lambda x: x.strip())
location_stats = df1.groupby("location")["location"].agg("count").sort_values(ascending = False)
location_stats

len(location_stats[location_stats <= 10])

Здесь мы видим, что есть много местоположений, содержащих данные менее чем о 10 домах, поэтому мы объединим их.

df1.location = df1.location.apply(lambda x: "others" if x in location_stats_less_than_10 else x)
df1.head(10)

df1[df1.total_sqft/df1.bhk < 300].head()

Здесь мы ясно видим, что эти 5 домов имеют очень меньшую площадь и больше комнат, что снова является исключением, поэтому мы удалим это из нашего набора данных.

df2 = df1[~(df1.total_sqft/df1.bhk < 300)]
df2.shape

def remove_pps_outliers(df):
    """ This function will remove outliers in price per sqft. """
    df_out = pd.DataFrame()
    for key, subdf in df.groupby("location"):
        m = np.mean(subdf.price_per_sqft)
        st = np.std(subdf.price_per_sqft)
        reduced_df = subdf[(subdf.price_per_sqft > (m - st)) & (subdf.price_per_sqft <= (m + st))]
        df_out = pd.concat([df_out, reduced_df], ignore_index= True)
    return df_out

df3 = remove_pps_outliers(df2)
df3.shape

def plot_scatter_chart(df, location):
    bhk2 = df[(df.location == location) & (df.bhk == 2)]
    bhk3 = df[(df.location == location) & (df.bhk == 3)]
    matplotlib.rcParams["figure.figsize"] = (15,10)
    plt.scatter(bhk2.total_sqft, bhk2.price, color = "blue", label="2 BHK", s=50)
    plt.scatter(bhk3.total_sqft, bhk3.price, marker = "+", color = "green", label="3 BHK", s=50)
    plt.xlabel("total sqft area")
    plt.ylabel("Price per square feet")
    plt.title(location)
    plt.legend()

plt.figure(figsize=(8,5))
plot_scatter_chart(df3, "Rajaji Nagar")

def remove_bhk_outliers(df):
    exclude_indices = np.array([])
    for location, location_df in df.groupby("location"):
        bhk_stats = {}
        for bhk, bhk_df in location_df.groupby("bhk"):
            bhk_stats[bhk] = {
                "mean": np.mean(bhk_df.price_per_sqft),
                "std": np.std(bhk_df.price_per_sqft),
                "count": bhk_df.shape[0]
            }
        for bhk, bhk_df in location_df.groupby("bhk"):
            stats = bhk_stats.get(bhk-1)
            if stats and stats["count"] > 5:
                exclude_indices = np.append(exclude_indices, bhk_df[bhk_df.price_per_sqft < (stats["mean"])].index.values)
    return df.drop(exclude_indices, axis="index")

df4 = remove_bhk_outliers(df3)
df4.shape

plot_scatter_chart(df4, "Rajaji Nagar")

plt.hist(df4.price_per_sqft, rwidth=0.8)
plt.xlabel("price Per Square Feet")
plt.ylabel("Count")

plt.hist(df4.bath, rwidth=0.8)
plt.xlabel("price Per Square Feet")
plt.ylabel("Count")

df4[df4.bath > df4.bhk + 2]

Здесь мы видим, что в некоторых домах больше ванных комнат, чем спален, поэтому мы удалим это.

df4 = df4[df4.bath < df4.bhk + 2]
df4.shape

df5 = df4.drop(["size","price_per_sqft"], axis = 1)
df5.head()

Горячее кодирование для категориальных функций

dummies = pd.get_dummies(df5.location)
dummies.head()

df6 = pd.concat([df5, dummies.drop("others", axis= 1)], axis= 1)
df6.head()

df7 = df6.drop(["location"], axis= 1)
df7.head()

Построение модели

Разделение набора данных на обучающие и тестовые данные.

X = df7.drop("price", axis=1)
y = df7['price']

X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.20, random_state=42)

Модель обучения

lr = LinearRegression()
lr.fit(X_train, y_train)

Проверка счета

lr.score(X_test, y_test)

Перекрестная проверка

cv = ShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
cross_val_score(LinearRegression(), X, y, cv=cv)

Прогноз

def predict_price(location, sqft, bath, bhk):
    loc_index = np.where(X.columns==location)[0][0]
    
    x = np.zeros(len(X.columns))
    x[0] = sqft
    x[1] = bath
    x[2] = bhk
    if loc_index >= 0:
        x[loc_index] = 1
        
    return lr.predict([x])[0]
predict_price("Chikka Tirupathi", 3200, 3,4)

Сохранение модели

import pickle
filename = 'Banglore_house_price_prediction.sav'
pickle.dump(lr, open(filename, 'wb'))

Заключение

В этом блоге мы рассмотрели различные этапы проекта машинного обучения для прогнозирования цен на жилье в Бангалоре. Мы начали с исследования и предварительной обработки данных, чтобы выбрать модель и обучить ее. Используя передовые алгоритмы и методы, мы можем предоставить покупателям, продавцам и инвесторам ценную информацию о рынке недвижимости Бангалора. Благодаря точным прогнозам заинтересованные стороны могут принимать обоснованные решения о покупке, продаже или инвестировании в недвижимость.

Надеюсь, вам понравился этот блог. Спасибо.