חיזוי מחירי בתים באמצעות למידת מכונה ומודל לינארי מרובה משתנים

מחבר:
בתאריך:

אחרי שבמדריך הקודם פיתחנו מודל רגרסיה לינארית באמצעות Keras על משתנה אחד בלבד (חיזוי מחירי דירות בהינתן השטח) במדריך הנוכחי נמשיך באותו נושא ונלמד את המכונה לחזות את מחירי הדירות על סמך מספר משתנים (שטח דירה, מספר חדרי השינה ומספר חדרי שירותים). חיזוי על סמך מספר משתנים מכונה ניתוח רב משתנים (multivariate analysis).

המשתנים במדריך הם מספרים. המטרה שלנו היא לפתח מודל שלתוכו נזין את הנתונים של הדירה. שטח, מספר חדרי השינה ומספר חדרי השירותים ונקבל הערכה של שווי הנכס.

לצורך פיתוח המודל נשתמש ב-Keras שהיא ספרייה של למידת מכונה.

לחץ כאן כדי להוריד קובץ ה-csv של מסד הנתונים

לחץ כאן כדי להוריד את קובץ קוד המלא שנפתח במדריך

* המדריך הנוכחי מבוסס על מדריך קודם מודל רגרסיה לינארית באמצעות Keras על משתנה אחד בלבד שבו הסברתי כיצד לבנות מודל של למידת מכונה. אם לא קראתם את המדריך הקודם ואין לכם מספיק ידע בתחום, תתחילו בבקשה מקריאת המדריך הקודם שמניח את היסודות לנוכחי.

 

השלבים המקדימים

את השלבים המקדימים עשיתי במדריך הקודם. לכן אדלג עליהם. להורדת הקוד המלא הכולל את השלבים המקדימים

 

עיבוד המידע

אחרי יבוא מסד הנתונים שמשווה בין מחירי דירות לבין שטח, מספר חדרי שינה ומספר חדרי שירותים, ניקינו את הרשומות החריגות שבהם רשום מחיר 0 או שטח 0.

נתאר את מסד הנתונים ונזהה נתונים חריגים נוספים:

df.describe()

לא סביר שיש בית ללא חדרים או בעל 0 חדרי שירותים אז נוציא גם אותם מהאנליזה.

# 0 bedrooms and baths are also not likely - let's remove these
fd = fd[(fd.beds > 0) & (fd.baths > 0)]

אנחנו מצפים למצוא קורלציה חיובית בין מספר חדרי השינה ליתר המשתנים.

fd.corr()['beds'].sort_values()
price 0.442322
baths 0.659631
sq__ft 0.716138
beds 1.000000

יש קשר חזק בין מספר החדרים לבין שטח הדירה ומספר חדרי האמבטיה. הקשר בין מספר החדרים לבין המחיר הוא בינוני וחיובי.

נצייר את הקשר בין המחיר לבין מספר החדרים:

plt.plot(fd['beds'], fd['price'], 'o')
plt.ylabel('Price')
plt.xlabel('Number of bedrooms')
plt.title('Price vs number of bedrooms')

הקשר בין מחיר ומספר חדרים

עשיתי אנליזה דומה על מספר חדרי האמבטיה. לחץ כדי להוריד את הקוד המלא של המדריך.

 

עדיין יש לנו בעיה אחת משמעותית והיא שהנתונים שלנו אינם על אותה הסקלה כי השטח נמדד ביחידות של עשרות ואף מאות בעוד החדרים נמדדים ביחידות בודדות. כדי לפתור את הבעיה ננרמל את הנתונים כך שכל אחד מהפיצ'רים יהיה בדיוק באותה הסקלה עם ממוצע 0 וסטיית תקן 1.

def norm(x):
  return (x.values-x.mean()) / x.std()
norm_beds = pd.DataFrame(norm(fd.beds),columns=['norm_beds'])
norm_baths = pd.DataFrame(norm(fd.baths),columns=['norm_baths'])
norm_sq__ft = pd.DataFrame(norm(fd.sq__ft),columns=['norm_sq__ft'])

נצרף את העמודות ל-DataFrame.

fd_norm = pd.concat([norm_beds, norm_baths, norm_sq__ft],axis=1)

הפרדת הנתונים לסט אימון ומבחן

הנתונים הבלתי תלויים הם מספר חדרי השינה, מספר חדרי אמבטיה והשטח. נגדיר אותם כ-X.

X = fd_norm.values

מכיוון שאנו מנסים לצפות את המחיר אז הוא יהווה את ה-y.

y = fd['price'].values

נפריד את סט הנתונים למסד נתוני אימון ומבחן.

# Split the data to test and train groups
from sklearn.model_selection import train_test_split

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

 

אימון המודל

את המודל נפתח באמצעות Keras.

נייבא את החבילות:

# Imports
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping

נבנה את המודל:

model = Sequential()

# The model maps the 3 inputs (sq_ft, rooms, bath rooms) to a single output (price)
# The model receives 1 input and outputs a single value
model.add(Dense(1, input_shape=(3,)))

# We expect the model to be linear
model.add(Activation('linear'))
  • אנחנו מזינים את המודל ב-3 קלטים (שטח, מספר חדרים ומספר חדרי שירותים) ומצפים לקבל פלט יחיד (מחיר), וזה מה שמכתיב את הארכיטקטורה של המודל הלינארי.

נתאר את המודל:

model.summary()
Layer (type)              Output Shape  Param #   
===============================================
dense_2 (Dense)              (None, 1)  4         
_______________________________________________
activation (Activation)      (None, 1)  0         
===============================================
Total params: 4
Trainable params: 4
Non-trainable params: 0

נקמפל את המודל:

# Compile the model
# Adam optimizer for the learning rate
# In preliminary trials I found the learning rate of 10 to be the best for 
# the task at hand
model.compile(Adam(lr=10), 'mean_squared_error')

הפונקציה הבאה תפסיק את תהליך הלמידה כאשר המודל מגיע לרווייה.

# The EarlyStopping callback stops the learning process if the loss doesn't improve
es = EarlyStopping(monitor='val_loss',
                   min_delta=0,
                   patience=10,
                   verbose=1,
                   mode='auto', restore_best_weights=True)

נריץ את המודל:

model.fit(X_train,
          y_train,
          batch_size=32,
          epochs=1000,
          validation_data=(X_test,y_test),
          callbacks=[es])

למידת מכונה עם Keras רצה על המחשב שלי

 

הערכת המודל

יש לנו מודל. קוראים לו model, אבל מה הוא אומר לנו על הנתונים? עד כמה הוא מצליח לתאר בצורה טובה את סט הנתונים? האם נצליח להפיק ממנו תחזיות טובות לגבי נתונים שאליהם הוא לא נחשף בעבר (קבוצת המבחן)?

קודם כל, כדי לקבל תחושה נחשב את המחיר הצפוי עבור דירה אחת מסוימת בסט נתוני המבחן. זו רשומה שמספרה הסידורי 42.

# Pick a single sample and predict
y_pred0 = model.predict(np.array([X_test[42]]))

נשווה בין התוצאה החזויה לתוצאה בפועל.

print('Predicted value: {0:.0f}'.format(y_pred0.reshape(1)[0]))
print('Actual value: {0:.0f}'.format(y[42]))
Predicted value: 138918
Actual value: 156896

יכול להיות שהתוצאות בטווח השגיאה של המודל, אבל מהו טווח השגיאה של המודל? כדי למצוא את טווח השגיאה נעשה את התחזית על כל הדוגמאות.

y_pred = model.predict(X_test)

נחשב את טווח השגיאה:

from sklearn.metrics import mean_absolute_error, mean_squared_error

print('MAE: %.2f' % mean_absolute_error(y_test, y_pred))
print('RMSE: %.2f' % np.sqrt(mean_squared_error(y_test, y_pred)))
MAE: 54710.02
RMSE: 84894.59

ככל שהערך של MAE נמוך יותר, כך המודל מדויק יותר.

מדד RMSE הוא היותר שימושי לנו מפני שהוא מבטא את טווח השגיאה באותם היחידות של הטור שאותו אנו מנסים לחזות. לפיכך, טווח השגיאה של המודל הוא +/-84895 דולר.

 

סיכום

במדריך הזה למדנו לפתח מודל של רגרסיה לינארית שתלוי במספר משתנים בלתי תלויים. כולם מספריים. במדריך הבא בסדרה נשכלל את המודל ונוסיף משתנים שמיים-קטגוריים לניתוח.

לכל המדריכים בנושא של למידת מכונה

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים