ตั้งแต่การรวบรวมข้อมูลและการเตรียมการไปจนถึงการฝึกอบรมโมเดลและการประเมินผล — รวมซอร์สโค้ดด้วย
การเรียนรู้เชิงลึกถือเป็นเรื่องใหญ่ในทุกวันนี้ เฮ็ค มันเป็นข้อกำหนดสำหรับงานวิทยาศาสตร์ข้อมูลส่วนใหญ่ แม้แต่งานระดับเริ่มต้นก็ตาม ไม่มีการบรรยายเบื้องต้นที่ดีไปกว่าการถดถอย คุณรู้แนวคิดจากสถิติพื้นฐานและการเรียนรู้ของเครื่องอยู่แล้ว และตอนนี้ก็ถึงเวลาที่จะนำโครงข่ายประสาทเทียมมาผสมผสานกัน
บทความนี้จะแสดงวิธีการ ในตอนท้าย คุณจะมีแบบจำลองที่ทำงานได้อย่างสมบูรณ์สำหรับการทำนายราคาที่อยู่อาศัย ซึ่งคุณสามารถแนบไปกับพอร์ตโฟลิโอของคุณ หลังจากปรับเปลี่ยนบางอย่างแล้ว แนะนำให้ใช้
ไม่รู้สึกอยากอ่านเหรอ? ดูวิดีโอของฉันแทน:
บทความวันนี้ครอบคลุมหัวข้อต่อไปนี้:
· Dataset used · Dataset exploration and preparation ∘ Deleting unnecessary columns ∘ Feature engineering ∘ Target variable visualization ∘ Data preparation for ML · Training a regression model with TensorFlow ∘ Loss tracking ∘ Building a model ∘ Making predictions ∘ Model 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_renovatedimport 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_renovated
ได้ เนื่องจากคุณสมบัติเหล่านี้อยู่ในรูปแบบที่คุณต้องการแล้ว:ravel()
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