پیش بینی قیمت ملک به کمک یادگیری ماشین

تخمین منصفانه قیمت ملک همیشه یک مساله پر از چالش بوده. خریداران همیشه نگران این هستند که ملک به قیمت بالاتر از قیمت واقعی به آنها فروخته شده و فروشندگان هم می ترسند که ملک آنها ارزان تر از قمیت واقعی، قیمت گذاری شود.

شرکت های مختلف برای هر دو سمت خریدار و فروشنده راه حل هایی پیاده کردند. مثلا ملک رادار به منظور تشخیص اینکه یک خریدار واقعا قصد خرید داره و انتظارات اون خریدار با قیمت پیشنهادیش مطالبقت داره از الگوهای مختلفی مثل داده های تاریخی و قیمت های مشابه در اطرف محله مورد نظر استفاده می کنه. شرکت SkyLine AI با استفاده از هوش مصنوعی به دنبال تخمین قیمت واقعی ملک بوده تا از ایت طریق بتونه قیمت منصفانه ای رو به خریداران ارائه بده.

حالا مساله اصلی اینه که اگر واقعا بخوایم یه ملک رو درست قیمت گذاری کنیم، عوامل خیلی زیادی رو باید در نظر بگیریم. حالا ما اینجا می خوایم یه نمونه مساله پیش بینی قیمت ملک رو با کمک پایتون حل کنیم.

دیتاست مسکن بوستون شامل اطلاعاتی درباره خانه های مختلف در بوستون و ویژگی های مختلف هر ملک است. قبل از اینکه این دیتاست رو بررسی کنیم، کتابخونه های لازم رو فراخوانی می کنیم.

import pandas as pd
import numpy as np
import matpotlib.pyplot as plt
%matplotlib inline

حالا دیتا ست مورد نظر رو یه نگاهی میندازیم

from sklearn.datasets import load_boston
boston=load_boston()
boston

وقتی کد بالا رو اجرا می کنیم، یه دیکشنری می بینیم که کلید هاش شامل Data که همون دیتاهای ماست، Target که قیمت خونه ها و درواقع همون چیزی هست که ما می خوایم پیش بینی کنیم، feature_names که همون عنوان ستون ها یا بردار ویژگی های ماست، Descr که توضیح در مورد هریک از بردار ویژگی ها و file_name که ادرس ذخیره فایل است.

برای اینکه بتونیم این دیتا ها رو بهتر بررسی کنیم، اطلاعات لازم را داخل یک دیتافریم قرار میدیم.

boston_df=pd.DataFrame([boston.data, boston.target], columns=[boston.feature_names, &quottarget&quot)
boston_df[&quottarget&quot]
boston_df.head()

خروجی کد بالا مورد شکل زیر خواهد بود.

فیچر های ما شامل 13 مورده که هر کدوم در مورد ملک های موجود در دیتاست محاسبه شده. مثلا CRIM میزان ارتکاب جرم به ازای هر نفر(Crime per Capita) در محله ای که خونه تو اون قرار داره رو نشون میده. توضیحات بیشتر رو هم می تونید تو داکیومنتیشن sickit-learn بخونید.

خوب حالا که داده هامون رو داریم باید دیتا ها رو آماده کنیم. نکته خیلی مهم اینجا اینه که فرایند آماده سازی معمولا بر اساس مدل یادگیری ماشین تعیین میشه. بعضی از مدل های یادگیری می تونند با داده های غیر عددی هم کار کنند و یا اگر داده گمشده ای هم توی دیتا باشه مشکلی ندارند. ولی بعضی ها نمی تونند. با توجه به مساله ما احتمالا یکی از مدل های رگرسیون برای پیش بینی قیمت به کارمون میاد(البته جلوتر می گیم که نحوه انتخاب مدل بر چه اساسی هست) و برای همین باید داده ها همه عددی باشه و داده های گشمده رو هم باید پر کنیم. برای همین به نگاه به داده ها می کنیم.

boston_df.dtypes

خوشبختانه تمام دیتاهای ما عددی هستند. حالا ببینیم داده گمشده هم داریم.

boston_df.isnull().sum()

خوب دیگه بهتر از این نمیشه. ما داده گشمده هم نداریم. البته خوب ما از یه دیتاست تر و تمیز داریم استفاده می کنیم. در واقعیت همچین داده های هلویی رو به شما نمی دن.

خوب حالا که داده هامون آماده است، بهتره یه نگاه بهتر بندازیم بهشون و چند تا نمودار باهاشون بکشیم ببینیم چیزی دستگیرمون میشه؟ اول از همه ببینیم شکل داده های ستون تارگت یا همون قیمت خونه ها چطوره.

fig, ax=plt.subplots(figsize=(10,5))
ax= boston_df[&quottarget&quot].hist(bins=20);
ax.set(title=&quotHouse Price Histogram&quot,
           xlabel=&quotHouse Price in 1000 $&quot,
           ylabel=&quotFreq&quot);

همونطوری که تو نمودار میبینیم داده های قیمت خونه تقریبا توزیع نرمال دارند و میانگینشون هم بینن 20 تا 30 هزار دلاره. حالا که داده ها نرماله احتمالا برای استفاده از بعضی از روشهای یادگیری ماشین مشکلی نخواهیم داشت.

حالا وراد فاز انتخاب ویژگی های feature selection میشیم. یکی از سریع ترین راه حل ها برای این بخش استفاده از ماتریس همبستگیه. در صورتی که فیچر هایی داشته باشیم که با هم همبستگی بالایی داشته باشند می تونیم اونها رو از بردار ویژگی ها حذف کنیم. اول از همه ما بردار x شامل تمام ستون های ما به جز ستون target میشه رو انتخاب می کنیم و کتابخونه های لازم رو هم ایمپورت می کنیم. بعد ماتریس همبستگی رو رسم می کنیم.

import seaborn as sns
X=boston_df.drop(&quottarget&quot, axis=1)
correlation_matrix = X.corr().round(2)
fig ,ax=plt.subplots(figsize=(12,10))
cmap = sns.diverging_palette(230, 20, as_cmap=True
ax=sns.heatmap(data=correlation_matrix, annot=True,cmap=cmap)

بازه همبستگی بین +1 تا -1 هستش و هر چه به مثبت یا منفی 1 نزدیک تر باشه همبستگی بالاتری بین متغیرها وجود داره. همونطور که میبینیم TAX و RAD همبستگی مثبت 0.91 دارند و بنابراین می تونیم یکی از این پارامترهارو حدف کنیم.

خوب حالا به مرحله انتخاب مدل رسیدیم. یکی از روش های انتخاب مدل استفاده از شکل زیر خواهد بود.

این نقشه رو می تونید تو مستندات scikit-learn پیدا کنید. اولین مرحله پیدا کردن تعداد داده هاست.

len(boston_df)

که خروجی بالا تعداد 506 داده رو برای ما نشون میده. پس بیشتر از 50 تا داده داریم و میریم مرحله بعد. بعدش ما می خوایم تخمین قیمت بزنیم پس میریم سمت راست. تعداد داده هامون کمتر از 100K هست و بعدش تعداد فیچرها رو بررسی می کنم. اینجا تصمیم با ماست که تعداد فیچرهامون کمه یا نه زیاده. من خودم به نظر تعداد فیچرهامون کم نیست و با این فرض میرسیم به دوتا مدلRidgeRegression و SVR با کرنل خطی. خوب برای شروع با RidgeRegression شروع می کنیم.

from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge
np.random.seed(52)
X=boston_df.drop([&quottarget&quot,&quotTAX&quot], axis=1)
y=boston_df[&quottarget&quot]
X_train, X_test, y_train, y_tets=train_test_split(X, y, test_size=0.2)
reg=Ridge()
reg.fit(X_train, y_train)
reg.score(X_test, y_tets)

حالا خط به خط بالا رو توضیح میدم. اول از همه ما از کتابخونه scikit-learn مواردی که برای تقسیم بندی داده های به مجموعه های آموزش و تست لازم داریم رو فراخوانی می کنیم. بعدش هسته اعداد تصادفی رو ثابت می کنیم تا من و شما خروجی های یکسانی داشته باشیم. حالا X رو تعریف می کنیم. همونطور که میبیند ما ستون TAX رو هم حذف کردیم. بردار y یا همون خروجی ها هم شامل ستون target میشه.

حالا داده های آموزشی و تست رو می سازیم. اندازه داده های تست ما 20 درصد کل داده ها خواهد بود. تو دو خط بعد مدلمون رو آموزش میدیم. و در نهایت خط آخر به ارزیابی مدل ساخته شده می پردازه و مقدار R^2 برای مدل رگرسیون ما میده. توجه کنید که score با توجه به نوع مدل یادگیری ماشین ما می تونه فرق کنه.

مقدار R^2 برای مدل بالا عدد 0.72 خواهد بود. مقدار R^2 همیشه عددی بین 0 تا 1 هستش که هر چی به یک نزدیک تر باشه مدل بهتری خواهیم داشت. خوب به نظر من عدد 0.72 عدد خیلی خوبی نیست. ما می تونیم از طریق نقشه بالا به مرحله بعد بریم و مدل EnsembleRegression رو انتخاب می کنیم شاید نتیجه بهتری گرفتیم.

from sklearn.ensemble import RandomForestRegressor
np.random.seed(56)
ensemble_reg=RandomForestRegressor()
ensemble_reg.fit(X_train, y_train)
ensemble_reg.score(X_test, y_tets)

خوب مقدار score تو این مدل ما برابر با 0.82 شده که شرایط بهتری رو به ما نشون میده.

حالا به نمودار پراکندگی هم بین قیمت های پیش بینی شده و قیمت های واقعی مدل می تونیم بکشیم تا به صورت تصویری هم یه بررسی از عملکرد مدل داشته باشیم.

y_preds=ensemble_reg.predict(X_test)
fig, ax=plt.subplots(figsize=(10, 8))
ax.scatter(y_tets, y_preds);
ax.set(title=&quotPrediction vs Real Values&quot,
       xlabel=&quotReal Values&quot,
       ylabel=&quotPredictions&quot);

همانطور که می بینیم تخمین قیمت خونه برای خونه های پایین تر از 40 هزار دلار تخمین مناسبی بوده و تو خونه های بالاتر این مدل احتمالا خوب عمل نکنه. در واقع این داده ها دورافتاده یا outlier هستند. ما می تونیم برای بهبود فرایند تو مرحله بعد داده های دورافتاده رو حذف کنیم و دوباره مدلسازی کنیم که این مورد رو به عهده خودتون می زارم.

پیشخوب همینطور که دیدیم پیاده سازی یک روش یادگیری ماشینی خیلی پیچیده نیست و اگر داده ها رو داشته باشیم کار سختی نخواهیم داشت. ولی مساله اصلی در دسترس بودن داده‌هاست. شاید سخت ترین و طاقت فرسا ترین بخش هر پروژه یادگیری ماشین جمع آوری داده ها باشه. برای بحث املاک و داده‌های مرتبط، مجموعه ملک رادار به صورت فصلی داده های مرتبط با بازار مسکن رو منتشر می کنه اطلاعات کامل و جذابی برای بررسی این بازار به ما میده. این گزارش با پایش مداوم و دقیق بازار املاک و کمک گرفتن از متخصصان این صنعت جمع آوری و تحلیل میشه. برای دیدن این گزارش می تونید از لینک زیر استفاده کنید و با استفاده از این داده‌ها پروژه یادگیری ماشین شخصی خودتون رو تعریف کنید.

https://bazarmaskan.melkradar.com/tag/%DA%AF%D8%B2%D8%A7%D8%B1%D8%B4-%D9%81%D8%B5%D9%84%DB%8C-%D9%85%D9%84%DA%A9-%D8%B1%D8%A7%D8%AF%D8%A7%D8%B1/