ตั้งแต่การรวบรวมข้อมูลและการเตรียมการไปจนถึงการฝึกอบรมโมเดลและการประเมินผล — รวมซอร์สโค้ดด้วย

การเรียนรู้เชิงลึกถือเป็นเรื่องใหญ่ในทุกวันนี้ เฮ็ค มันเป็นข้อกำหนดสำหรับงานวิทยาศาสตร์ข้อมูลส่วนใหญ่ แม้แต่งานระดับเริ่มต้นก็ตาม ไม่มีการบรรยายเบื้องต้นที่ดีไปกว่าการถดถอย คุณรู้แนวคิดจากสถิติพื้นฐานและการเรียนรู้ของเครื่องอยู่แล้ว และตอนนี้ก็ถึงเวลาที่จะนำโครงข่ายประสาทเทียมมาผสมผสานกัน

บทความนี้จะแสดงวิธีการ ในตอนท้าย คุณจะมีแบบจำลองที่ทำงานได้อย่างสมบูรณ์สำหรับการทำนายราคาที่อยู่อาศัย ซึ่งคุณสามารถแนบไปกับพอร์ตโฟลิโอของคุณ หลังจากปรับเปลี่ยนบางอย่างแล้ว แนะนำให้ใช้

ไม่รู้สึกอยากอ่านเหรอ? ดูวิดีโอของฉันแทน:

บทความวันนี้ครอบคลุมหัวข้อต่อไปนี้:

· Dataset used
· Dataset exploration and preparationDeleting unnecessary columnsFeature engineeringTarget variable visualizationData preparation for ML
· Training a regression model with TensorFlowLoss trackingBuilding a modelMaking predictionsModel evaluation

คุณสามารถดาวน์โหลดซอร์สโค้ดได้ที่ GitHub

ชุดข้อมูลที่ใช้

วันนี้เรามาทำให้ทุกอย่างง่ายขึ้นและยึดตาม "ชุดข้อมูลราคาที่อยู่อาศัย" ที่รู้จักกันดี:

มันมีคุณสมบัติมากมายที่ในตอนแรกไม่สามารถใช้งานได้กับโมเดลโครงข่ายประสาทเทียม ดังนั้นคุณจะต้องใช้เวลาจัดการกับมันสักพัก ดาวน์โหลดชุดข้อมูล แตกไฟล์ ZIP และวางชุดข้อมูล CSV ไว้ในที่ที่ปลอดภัย

จากนั้นเปิดใช้งานสภาพแวดล้อมเสมือนที่ติดตั้ง TensorFlow 2+ และเปิดใช้งาน JupyterLab คุณสามารถใช้ IDE อื่นๆ ได้ฟรี แต่ภาพหน้าจอทั้งหมดด้านล่างจะมาจาก Jupyter

การสำรวจและจัดเตรียมชุดข้อมูล

ขั้นตอนแรกคือการนำเข้า Numpy และ Pandas จากนั้นจึงนำเข้าชุดข้อมูล ตัวอย่างต่อไปนี้ทำสิ่งนั้นและพิมพ์สองสามแถวแบบสุ่ม:

import numpy as np
import pandas as pd

df = pd.read_csv('data/data.csv')
df.sample(5)

ชุดข้อมูลมีลักษณะดังนี้:

คุณไม่สามารถส่งผ่านไปยังโครงข่ายประสาทเทียมในรูปแบบนี้ได้อย่างแน่นอน

การลบคอลัมน์ที่ไม่จำเป็น

เนื่องจากเราต้องการหลีกเลี่ยงการใช้เวลามากเกินไปในการเตรียมข้อมูล วิธีที่ดีที่สุดคือละทิ้งฟีเจอร์ที่ไม่ใช่ตัวเลขส่วนใหญ่ เก็บเฉพาะคอลัมน์ city ไว้ เนื่องจากง่ายต่อการเข้ารหัส:

to_drop = ['date', 'street', 'statezip', 'country']
df = df.drop(to_drop, axis=1)

df.head()

ตอนนี้ควรมีลักษณะดังนี้:

คุณสามารถเก็บคอลัมน์ทั้งหมดไว้และทำวิศวกรรมฟีเจอร์บางอย่างกับคอลัมน์เหล่านั้นได้อย่างแน่นอน มันอาจจะเพิ่มประสิทธิภาพของโมเดลได้ แต่นี่ก็เพียงพอแล้วสำหรับสิ่งที่คุณต้องการในวันนี้

คุณสมบัติทางวิศวกรรม

ตอนนี้คุณจะใช้เวลาในการปรับแต่งชุดข้อมูล คอลัมน์ yr_renovated บางครั้งมีค่าเป็น 0 ฉันคิดว่านั่นเป็นเพราะบ้านไม่ได้รับการปรับปรุงใหม่ คุณจะสร้างคุณลักษณะสองสามอย่าง เช่น อายุบ้าน บ้านได้รับการปรับปรุงหรือไม่ ได้รับการปรับปรุงในช่วง 10 ปีที่ผ่านมา และได้รับการปรับปรุงในช่วง 30 ปีที่ผ่านมา

คุณสามารถใช้รายการความเข้าใจสำหรับคุณลักษณะทั้งหมดที่กล่าวถึงได้ โดยมีวิธีการดังนี้:

# How old is the house?
df['house_age'] = [2021 - yr_built for yr_built in df['yr_built']]

# Was the house renovated and was the renovation recent?
df['was_renovated'] = [1 if yr_renovated != 0 else 0 
    for yr_renovated in df['yr_renovated']]
df['was_renovated
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['figure.figsize'] = (16, 6)
rcParams['axes.spines.top'] = False
rcParams['axes.spines.right'] = False

plt.hist(df['price'], bins=100);
yrs'] = [1 if (2021 - yr_renovated) <= 10 else 0 for yr_renovated in df['yr_renovated']] df['was_renovatedravel()yrs'] = [1 if 10 < (2021 - yr_renovated) <= 30 else 0 for yr_renovated in df['yr_renovated']] # Drop original columns df = df.drop(['yr_built', 'yr_renovated'], axis=1) df.head()

ชุดข้อมูลมีลักษณะดังนี้:

ต่อไปมาจัดการคอลัมน์ city กัน เมืองหลายแห่งมีบ้านอยู่เพียงไม่กี่หลังในรายการ ดังนั้นคุณจึงสามารถประกาศฟังก์ชันที่จะกำจัดค่านิยมของเมืองทั้งหมดที่ไม่ได้เกิดขึ้นบ่อยได้ นั่นคือสิ่งที่ฟังก์ชัน remap_location() จะทำ ถ้ามีบ้านน้อยกว่า 50 หลังในเมืองนั้น ก็จะถูกแทนที่ด้วยอย่างอื่น เป็นเพียงวิธีลดจำนวนตัวเลือก:

def remap_location(data: pd.DataFrame, 
                   location: str, 
                   threshold: int = 50) -> str:
    if len(data[data['city'] == location]) < threshold:
        return 'Rare'
    return location

มาทดสอบฟังก์ชันกันดีกว่า เมือง ซีแอตเทิล มีบ้านหลายหลังอยู่ในรายการ ในขณะที่ Fall City มีเพียง 11 หลัง:

ลองใช้ฟังก์ชันนี้กับทุกเมืองและพิมพ์ตัวอย่าง 10 แถว:

df['city'] = df['city'].apply(
    lambda x: remap_location(data=df, location=x)
)
df.sample(10)

ทุกอย่างดูเป็นไปตามที่ควร เรามาทำต่อกันดีกว่า

การแสดงภาพตัวแปรเป้าหมาย

เมื่อใดก็ตามที่คุณต้องจัดการกับราคา ตัวแปรเป้าหมายไม่น่าจะมีการกระจายตามปกติ และชุดข้อมูลที่อยู่อาศัยนี้ก็ไม่มีข้อยกเว้น มาตรวจสอบกันโดยการนำเข้า Matplotlib และแสดงภาพการแจกแจงด้วยฮิสโตแกรม:

import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['figure.figsize'] = (16, 6)
rcParams['axes.spines.top'] = False
rcParams['axes.spines.right'] = False

plt.hist(df['price'], bins=100);

มีลักษณะดังนี้:

ค่าผิดปกติมีอยู่แน่นอน ดังนั้นเรามาจัดการกับมันกันต่อไป สิ่งที่ค่อนข้างธรรมดาที่ต้องทำคือการคำนวณคะแนน Z พวกเขาแจ้งให้คุณทราบว่าค่าใดค่าหนึ่งอยู่ห่างจากค่าเฉลี่ยเป็นจำนวนเท่าใด ในกรณีของการแจกแจงแบบปกติ ค่าใดก็ตามที่ต่ำกว่าหรือสูงกว่าค่าเบี่ยงเบนมาตรฐาน 3 ค่าจะถูกจัดว่าเป็นค่าผิดปกติ การกระจายราคาไม่ปกติ แต่เรายังคงทำการทดสอบ Z เพื่อถอดบ้านทางด้านขวาสุดออก

คุณสามารถคำนวณคะแนน Z ด้วย Scipy คุณจะกำหนดให้เป็นคอลัมน์ชุดข้อมูลใหม่ - price_z จากนั้นเก็บเฉพาะแถวที่มีค่าสัมบูรณ์ของ Z น้อยกว่าหรือเท่ากับสาม

นอกจากนี้ยังมีบ้านประมาณ 50 หลังที่แสดงราคา $0 ดังนั้นคุณจะลบบ้านเหล่านั้นด้วย:

from scipy import stats

# Calculate Z-values
df['price_z'] = np.abs(stats.zscore(df['price']))

# Filter out outliers
df = df[df['price_z'] <= 3]

# Remove houses listed for $0
df = df[df['price'] != 0]

# Drop the column
df = df.drop('price_z', axis=1)

# Draw a histogram
plt.hist(df['price'], bins=100);

การกระจายมีลักษณะดังนี้:

ยังคงมีความเบ้อยู่เล็กน้อย แต่มาประกาศว่า ดีพอ กันดีกว่า

ในขั้นตอนสุดท้าย เรามาแปลงข้อมูลเป็นรูปแบบที่พร้อมสำหรับการเรียนรู้ของเครื่องกัน

การเตรียมข้อมูลสำหรับ ML

โครงข่ายประสาทเทียมชอบดูเฉพาะข้อมูลตัวเลขในระดับเดียวกัน ชุดข้อมูลของเราไม่มี และเรายังมีข้อมูลที่ไม่ใช่ตัวเลขด้วย นั่นคือจุดที่การปรับขนาดข้อมูลและการเข้ารหัสแบบร้อนแรงเข้ามามีบทบาท

ตอนนี้คุณสามารถแปลงคุณสมบัติแต่ละอย่างแยกกันได้แล้ว แต่มีวิธีที่ดีกว่า คุณสามารถใช้ฟังก์ชัน make_column_transformer() จาก Scikit-Learn เพื่อใช้การปรับขนาดและการเข้ารหัสในครั้งเดียว

คุณสามารถละเว้นคุณลักษณะต่างๆ เช่น waterfront, was_renovated, was_renovated_10_yrs และ was_renovatedravel()yrs ได้ เนื่องจากคุณสมบัติเหล่านี้อยู่ในรูปแบบที่คุณต้องการแล้ว:

from sklearn.compose import make_column_transformer
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder

transformer = make_column_transformer(
    (MinMaxScaler(), 
        ['sqft_living', 'sqft_lot','sqft_above', 
         'sqft_basement', 'house_age']),
    (OneHotEncoder(handle_unknown='ignore'), 
        ['bedrooms', 'bathrooms', 'floors', 
         'view', 'condition'])
)

ต่อไป เรามาแยกฟีเจอร์ออกจากตัวแปรเป้าหมาย และแบ่งชุดข้อมูลออกเป็นส่วนการฝึกอบรมและการทดสอบ ชุดรถไฟจะคิดเป็น 80% ของข้อมูล และเราจะใช้อย่างอื่นทั้งหมดสำหรับการทดสอบ:

from sklearn.model_selection import train_test_split

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

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

และสุดท้าย คุณสามารถใช้การเปลี่ยนแปลงที่ประกาศเมื่อนาทีที่แล้วได้ คุณจะปรับให้เหมาะสมและเปลี่ยนแปลงฟีเจอร์การฝึกอบรม และใช้การเปลี่ยนแปลงกับชุดการทดสอบเท่านั้น:

# Fit
transformer.fit(X_train)

# Apply the transformation
X_train = transformer.transform(X_train)
X_test = transformer.transform(X_test)

คุณจะไม่สามารถตรวจสอบ X_train และ X_test ได้โดยตรง เนื่องจากตอนนี้ถูกจัดเก็บเป็นเมทริกซ์กระจัดกระจาย:

TensorFlow จะไม่สามารถอ่านรูปแบบนั้นได้ ดังนั้นคุณจะต้องแปลงเป็นอาร์เรย์ Numpy หลายมิติ คุณสามารถใช้ฟังก์ชัน toarray() ได้ นี่คือตัวอย่าง:

X_train.toarray()

แปลงชุดคุณลักษณะทั้งสองเป็นอาร์เรย์ Numpy และคุณก็พร้อมแล้ว:

X_train = X_train.toarray()
X_test = X_test.toarray()

ในที่สุดเรามาฝึกโมเดลกัน

ฝึกโมเดลการถดถอยด้วย TensorFlow

ตอนนี้ คุณจะสร้างโมเดลต่อเนื่องที่สร้างจากเลเยอร์ที่เชื่อมต่อกันอย่างสมบูรณ์ มีการนำเข้าหลายอย่างที่ต้องทำ ดังนั้นเรามาดูกันดีกว่า:

import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import backend as K

การติดตามการสูญเสีย

คุณกำลังจัดการกับราคาที่อยู่อาศัยที่นี่ ดังนั้นการสูญเสียอาจมีขนาดใหญ่มากหากคุณติดตามผ่าน สมมติว่า ข้อผิดพลาดเฉลี่ยกำลังสอง การวัดนั้นไม่ได้มีประโยชน์กับคุณมากนัก เนื่องจากโดยพื้นฐานแล้วจะบอกคุณว่าแบบจำลองของคุณมีหน่วยยกกำลังสองผิดอย่างไร

คุณสามารถคำนวณรากที่สองของ MSE เพื่อกลับไปยังหน่วยเดิมได้ เมตริกนั้นไม่ได้รับการสนับสนุนโดยค่าเริ่มต้น แต่เราสามารถประกาศได้ด้วยตนเอง โปรดทราบว่าคุณจะต้องใช้ฟังก์ชันจากแบ็กเอนด์ Keras เพื่อให้สามารถใช้งานได้:

def rmse(y_true, y_pred):
    return K.sqrt(K.mean(K.square(y_pred - y_true)))

การสร้างแบบจำลอง

และตอนนี้คุณก็สามารถประกาศแบบจำลองได้แล้ว มันจะเป็นแบบง่ายๆ โดยมีเพียง 3 ชั้นที่ซ่อนอยู่ 256, 256 และ 128 หน่วย คุณสามารถทดลองใช้สิ่งเหล่านี้ได้ตามใจชอบ เนื่องจากไม่มีวิธีที่ถูกหรือผิดในการตั้งค่าโครงข่ายประสาทเทียม จากนั้นเลเยอร์เหล่านี้จะตามมาด้วยเลเยอร์เอาต์พุตของหนึ่งโหนด เนื่องจากคุณกำลังทำนายค่าตัวเลข

จากนั้น คุณจะต้องคอมไพล์โมเดลโดยใช้ RMSE เป็นวิธีการติดตามการสูญเสียและเป็นหน่วยเมตริกการประเมินผล และคุณจะปรับโมเดลให้เหมาะสมโดยใช้เครื่องมือเพิ่มประสิทธิภาพ Adam

สุดท้าย คุณจะฝึกโมเดลเกี่ยวกับข้อมูลการฝึกเป็นเวลา 100 ยุค:

tf.random.set_seed(42)

model = Sequential([
    Dense(256, activation='relu'),
    Dense(256, activation='relu'),
    Dense(128, activation='relu'),
    Dense(1)
])

model.compile(
    loss=rmse,
    optimizer=Adam(),
    metrics=[rmse]
)

model.fit(X_train, y_train, epochs=100)

การฝึกอบรมควรเสร็จสิ้นภายในหนึ่งนาทีโดยประมาณ ขึ้นอยู่กับฮาร์ดแวร์ที่อยู่เบื้องหลัง:

ค่า RMSE สุดท้ายของชุดฝึกอบรมอยู่เหนือ 192000 ซึ่งหมายความว่าสำหรับบ้านโดยเฉลี่ย โมเดลประเมินราคาไม่ถูกต้องที่ 192000 ดอลลาร์

การคาดการณ์

คุณสามารถทำนายชุดทดสอบได้:

predictions = model.predict(X_test)
predictions[:5]

การคาดการณ์ห้ารายการแรกมีลักษณะดังนี้:

คุณจะต้องแปลงสิ่งเหล่านี้เป็นอาร์เรย์ 1 มิติหากต้องการคำนวณหน่วยเมตริกใดๆ คุณสามารถใช้ฟังก์ชัน ravel() จาก Numpy เพื่อดำเนินการดังกล่าว:

predictions = np.ravel(predictions)
predictions[:5]

นี่คือผลลัพธ์:

การประเมินแบบจำลอง

และตอนนี้เรามาประเมินการทำนายชุดทดสอบโดยใช้ RMSE:

rmse(y_test, predictions).numpy()

คุณจะได้รับ 191000 เป็นค่าความผิดพลาด ซึ่งบ่งชี้ว่าแบบจำลองไม่ได้พอดีกับข้อมูลการฝึกมากเกินไป คุณน่าจะได้รับผลลัพธ์ที่ดีขึ้นด้วยการฝึกโมเดลที่ซับซ้อนมากขึ้นสำหรับยุคสมัยที่มากขึ้น นั่นคือสิ่งที่คุณสามารถทดลองได้ด้วยตัวเอง

คำพรากจากกัน

และนั่นก็เป็นเช่นนั้น ตอนนี้คุณได้ฝึกฝนโมเดลโครงข่ายประสาทเทียมอย่างง่ายแล้ว และคุณรู้วิธีคาดการณ์ข้อมูลใหม่ ยังมีอีกหลายสิ่งที่คุณสามารถปรับปรุงได้

ตัวอย่างเช่น คุณอาจใช้เวลามากขึ้นในการเตรียมข้อมูล เราได้ลบคุณลักษณะวันที่-เวลา ข้อมูลถนน รหัสไปรษณีย์ และอื่นๆ ซึ่งอาจเป็นประโยชน์ต่อประสิทธิภาพของโมเดล ประเด็นก็คือ — สิ่งเหล่านี้จะใช้เวลาเตรียมการมากเกินไป และฉันต้องการให้บทความเหล่านี้ค่อนข้างสั้น

คุณยังสามารถเพิ่มเลเยอร์เพิ่มเติมในเครือข่าย เพิ่มจำนวนเซลล์ประสาท เลือกฟังก์ชันการเปิดใช้งานที่แตกต่างกัน เลือกเครื่องมือเพิ่มประสิทธิภาพอื่น เพิ่มเลเยอร์การออกกลางคัน และอื่นๆ อีกมากมาย ความเป็นไปได้นั้นแทบจะไม่มีที่สิ้นสุด ดังนั้นทั้งหมดจึงต้องอาศัยการทดลอง

บทความต่อไปนี้จะกล่าวถึงวิธีการสร้างแบบจำลองการจัดหมวดหมู่โดยใช้ TensorFlow ดังนั้นโปรดคอยติดตามหากคุณต้องการเรียนรู้เพิ่มเติม

ขอบคุณที่อ่าน.

ชอบบทความนี้ไหม? สมัครเป็น "สมาชิกระดับกลาง" เพื่อเรียนรู้ต่ออย่างไร้ขีดจำกัด ฉันจะได้รับค่าธรรมเนียมสมาชิกส่วนหนึ่งหากคุณใช้ลิงก์ต่อไปนี้ โดยไม่มีค่าใช้จ่ายเพิ่มเติม



เชื่อมต่ออยู่เสมอ

  • ลงทะเบียนเพื่อรับ "จดหมายข่าว" ของฉัน
  • สมัครสมาชิกบน "YouTube"
  • เชื่อมต่อบน LinkedIn