โดยแต่ละ xi เป็นตัวแปรอิสระ และ bi ที่สอดคล้องคือค่าสัมประสิทธิ์ ในสามมิติ เส้นจะขยายเป็นระนาบ ในมิติที่สูงขึ้น ระนาบจะกลายเป็น "ไฮเปอร์เพลน"
จะตีความค่าสัมประสิทธิ์และจุดตัดแกนอย่างไร จุดตัดแกนคือค่าที่คาดการณ์ของ y เมื่อค่าของตัวแปรอิสระทั้งหมดเป็น 0 หรือมองอีกทางคือค่าเริ่มต้นของตัวแปรตามเมื่อไม่มีอิทธิพลจากตัวทำนาย แต่ละค่าสัมประสิทธิ์ bi แทนการเปลี่ยนแปลงของตัวแปรตาม y เมื่อ xi เปลี่ยนไปหนึ่งหน่วย โดยคงตัวแปรอิสระอื่นๆ ไว้คงที่
# Import train_test_split.from sklearn.model_selection import train_test_split
# Create features X and target y.
X = pd.DataFrame(housing.data, columns=housing.feature_names)[["AveRooms"]]
y = housing.target # Median house value in $100,000s# Split the dataset into training (80%) and testing (20%) sets.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)ขับเคลื่อนโดย
สัมประสิทธิ์การกำหนด หรือ R2 วัดว่าโมเดลการถดถอยอธิบายความแปรปรวนของตัวแปรตามได้ดีเพียงใด กล่าวคือระบุว่าตัวทำนายอธิบายความแปรปรวนของตัวแปรตามได้มากน้อยแค่ไหน ซึ่งเรียกว่า goodness of fit
# Uses all features.import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# Load data set.
housing = fetch_california_housing()# Split into X, y.
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = housing.target # Median house value in $100,000s
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Scale the data.
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# Create model and fit it to the training data.
model = LinearRegression()
model.fit(X_train_scaled, y_train)# Make predictions.
y_pred = model.predict(X_test_scaled)# Calculate and print errors.
r2 = r2_score(y_test, y_pred)print(f"R-squared: {r2:.4f}")
mse = mean_squared_error(y_test, y_pred)print(f"Mean squared error: {mse:.4f}")
rmse = mse **0.5print(f"Root mean squared error: {rmse:.4f}")ขับเคลื่อนโดย
R-squared:0.5758
Mean squared error:0.5559
Root mean squared error:0.7456ขับเคลื่อนโดย
# Import libraries.import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from statsmodels.stats.outliers_influence import variance_inflation_factor
# Load the dataset.
housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)# Compute the correlation matrix.
corr_matrix = X.corr()# Identify pairs of features with high collinearity (correlation > 0.8 or < -0.8).
high_corr_features =[(col1, col2, corr_matrix.loc[col1, col2])for col1 in corr_matrix.columns
for col2 in corr_matrix.columns
if col1 != col2 andabs(corr_matrix.loc[col1, col2])>0.8]# Convert to a DataFrame for better visualization.
collinearity_df = pd.DataFrame(high_corr_features, columns=["Feature 1","Feature 2","Correlation"])print("\nHighly Correlated Features:\n", collinearity_df)# Compute Variance Inflation Factor (VIF) for each feature.
vif_data = pd.DataFrame()
vif_data["Feature"]= X.columns
vif_data["VIF"]=[variance_inflation_factor(X.values, i)for i inrange(X.shape[1])]# Print VIF values.print("\nVariance Inflation Factor (VIF) for each feature:\n", vif_data)ขับเคลื่อนโดย
Highly Correlated Features:
Feature 1 Feature 2 Correlation
0 AveRooms AveBedrms 0.8476211 AveBedrms AveRooms 0.8476212 Latitude Longitude -0.9246643 Longitude Latitude -0.924664
Variance Inflation Factor (VIF)for each feature:
Feature VIF
0 MedInc 11.5111401 HouseAge 7.1959172 AveRooms 45.9936013 AveBedrms 43.5903144 Population 2.9357455 AveOccup 1.0952436 Latitude 559.8740717 Longitude 633.711654ขับเคลื่อนโดย
มาลองตัด AveBedrms ออกจากโมเดล
# Import libraries.import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# Load California housing dataset.
housing = fetch_california_housing()# Create DataFrame and remove "AveBedrms" feature.
X = pd.DataFrame(housing.data, columns=housing.feature_names).drop(columns=["AveBedrms"])
y = housing.target # Median house value in $100,000s# Split data into training and testing sets.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Scale the data (Standardization).
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# Create a linear regression model and train it.
model = LinearRegression()
model.fit(X_train_scaled, y_train)# Make predictions on the test set.
y_pred = model.predict(X_test_scaled)# Calculate performance metrics.
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)# Print evaluation metricsprint(f"R-squared: {r2:.4f}")print(f"Mean squared error: {mse:.4f}")print(f"Root mean squared error: {rmse:.4f}")ขับเคลื่อนโดย
R-squared:0.5823
Mean squared error:0.5473
Root mean squared error:0.7398ขับเคลื่อนโดย
การถดถอยเชิงเส้น (Linear regression) เป็นเทคนิคพื้นฐานในสถิติและการเรียนรู้ของเครื่องที่ช่วยสร้างแบบจำลองความสัมพันธ์ระหว่างตัวแปร พูดง่ายๆ คือช่วยทำนายผลลัพธ์จากปัจจัยที่มีอิทธิพลหนึ่งตัวหรือมากกว่า ถูกนำไปใช้กว้างขวางในงานประเมินราคาที่อยู่อาศัย การพยากรณ์ยอดขาย การประเมินความเสี่ยง และอีกหลายสาขา
ในบทเรียนนี้ เราจะสำรวจการถดถอยเชิงเส้นใน scikit-learn ครอบคลุมวิธีการทำงาน เหตุผลที่มีประโยชน์ และวิธีนำไปใช้งานด้วย scikit-learn เมื่อจบแล้ว จะสามารถสร้างและประเมินแบบจำลองการถดถอยเชิงเส้นเพื่อทำการพยากรณ์บนพื้นฐานข้อมูลได้
กราฟกระจายของราคาบ้านเทียบกับจำนวนห้อง
การถดถอยเชิงเส้นและการเรียนรู้ของเครื่อง
นอกเหนือจากการใช้งานตรงไปตรงมาอย่างการประเมินราคาบ้าน การถดถอยเชิงเส้นยังมีบทบาทสำคัญในงานแมชชีนเลิร์นนิง
แม้จะเรียบง่าย การถดถอยเชิงเส้นก็ยังเป็นเครื่องมือที่ขาดไม่ได้ในงานแมชชีนเลิร์นนิง ด้วยประสิทธิภาพ ความเข้าใจง่าย และความยืดหยุ่น
การถดถอยเชิงเส้นและไลบรารี scikit-learn
ไลบรารี scikit-learn ทำให้การถดถอยเชิงเส้นนำไปใช้ได้ง่าย ไลบรารีนี้มีข้อดีหลายประการ
model.fit(X_train, y_train)หากยังใหม่กับ scikit-learn ดูคอร์สของเราเรื่อง Machine Learning with scikit-learn เพื่อเริ่มต้นใช้งานไลบรารี Python นี้แบบลงมือทำ
ทำความเข้าใจกับการถดถอยเชิงเส้น
ดังที่เห็น ในการถดถอยเชิงเส้นแบบง่าย ข้อมูลจะถูกทำแบบจำลองด้วย "เส้นที่ฟิตดีที่สุด" สูตรของเส้นนี้คือ
โดยที่ m คือความชันของเส้น และ b คือจุดตัดแกน
"การถดถอยเชิงเส้นพหุคูณ" ขยายกรณีที่มีตัวทำนายหนึ่งตัวไปเป็นหลายตัว (จำนวนห้อง ความใกล้ทะเล รายได้มัธยฐานของย่าน) สูตรจะขยายเป็น
โดยแต่ละ xi เป็นตัวแปรอิสระ และ bi ที่สอดคล้องคือค่าสัมประสิทธิ์ ในสามมิติ เส้นจะขยายเป็นระนาบ ในมิติที่สูงขึ้น ระนาบจะกลายเป็น "ไฮเปอร์เพลน"
จะตีความค่าสัมประสิทธิ์และจุดตัดแกนอย่างไร จุดตัดแกนคือค่าที่คาดการณ์ของ y เมื่อค่าของตัวแปรอิสระทั้งหมดเป็น 0 หรือมองอีกทางคือค่าเริ่มต้นของตัวแปรตามเมื่อไม่มีอิทธิพลจากตัวทำนาย แต่ละค่าสัมประสิทธิ์ bi แทนการเปลี่ยนแปลงของตัวแปรตาม y เมื่อ xi เปลี่ยนไปหนึ่งหน่วย โดยคงตัวแปรอิสระอื่นๆ ไว้คงที่
การตั้งค่าสภาพแวดล้อม
การติดตั้ง scikit-learn ทำได้ง่าย เพียงใช้คำสั่ง
pip install scikit-learnหากต้องการติดตั้งเวอร์ชันเฉพาะ เช่น 1.2.2 ให้ปรับคำสั่งเพื่อระบุเวอร์ชัน:pip install scikit-learn==1.2.2.หากใช้ Anaconda ปกติแล้ว scikit-learn จะถูกติดตั้งมาให้ หากด้วยเหตุผลบางอย่างยังต้องติดตั้งเมื่อใช้ Anaconda ให้ใช้คำสั่งconda install scikit-learn.มีหลายไลบรารีที่จำเป็นหรือแนะนำให้ใช้ร่วมกับ scikit-learn ไลบรารี
numpyจำเป็นสำหรับเก็บคุณลักษณะและป้ายกำกับ ไลบรารีpandasแนะนำสำหรับการโหลด พรีโพรเซส และสำรวจชุดข้อมูลหากใช้งาน scikit-learn ก็มักจะใช้ pandas อยู่แล้วสำหรับเตรียมข้อมูล สำหรับการพล็อตผลลัพธ์ มักใช้
matplotlibหรือseabornหรือทั้งสองอย่าง ไลบรารีเหล่านี้ติดตั้งได้ด้วย pip install เช่นเดียวกับตัวอย่างข้างต้น และยังสามารถติดตั้งหลายไลบรารีได้ในคำสั่งเดียว:pip install scikit-learn numpy pandas matplotlib seaborn.การใช้งาน Linear Regression ใน sklearn
ก่อนโหลดชุดข้อมูล มานำเข้าไลบรารีที่ใช้บ่อยกันก่อน
การโหลดชุดข้อมูล
มาลองใช้ชุดข้อมูลที่อยู่อาศัยของแคลิฟอร์เนียที่คุ้นเคยกัน
การเตรียมข้อมูล
มาจัดแบ่งข้อมูลเป็นชุดฝึกและชุดทดสอบกัน เราจะนำเข้าเมท็อด
train_test_split()จากsklearn.model_selectionแล้วเรียกใช้งาน โดยระบุเปอร์เซ็นต์ของชุดทดสอบ และrandom_stateนอกจากนี้จะใช้การถดถอยเชิงเส้นแบบง่าย โดยใช้คุณลักษณะที่สอดคล้องกับจำนวนห้องเฉลี่ยเมื่อแบ่งข้อมูลเป็นชุดทดสอบและชุดฝึกแล้ว มามาตรฐานคุณลักษณะกัน ขั้นตอนนี้ช่วยให้ตัวแปรทั้งหมดอยู่ในสเกลเดียวกัน ซึ่งช่วยปรับปรุงประสิทธิภาพและเสถียรภาพเชิงตัวเลขของโมเดล
ในโค้ดนี้
StandardScalerเป็นเครื่องมือพรีโพรเซสข้อมูลที่ใช้ลบค่าเฉลี่ยและสเกลคุณลักษณะให้มีความแปรปรวนเป็นหนึ่ง ช่วยป้องกันไม่ให้บางคุณลักษณะครอบงำโมเดลเพราะสเกลต่างกันตัวสเกลเลอร์ถูกฟิตกับข้อมูลฝึกด้วยเมท็อด
fit_transform()ส่วนข้อมูลทดสอบถูกทรานส์ฟอร์มแยกต่างหากด้วยเมท็อดtransform()เพื่อให้สเกลด้วยปัจจัยเดียวกับข้อมูลฝึก ป้องกันการรั่วไหลของข้อมูลการฝึกโมเดลการถดถอยเชิงเส้น
เพื่อสร้างโมเดลการถดถอยเชิงเส้น ให้นำเข้า
LinearRegression()จากsklearn.linear_modelสร้างอินสแตนซ์แล้วกำหนดให้ตัวแปรการฟิตโมเดลด้วยข้อมูลฝึกทำได้โดยตรง
การทำนาย
เมื่อฝึกโมเดลเรียบร้อยแล้ว มาทำนายบนชุดทดสอบกัน
การประเมินประสิทธิภาพของโมเดล
เมื่อได้ผลการทำนายบนชุดทดสอบแล้ว ต้องประเมินว่าตรงกับความเป็นจริงเพียงใด มีเมตริกหลายแบบสำหรับประเมินประสิทธิภาพของอัลกอริทึมการถดถอย ที่พบบ่อยได้แก่ สัมประสิทธิ์การกำหนด (R2) ค่าความคลาดเคลื่อนกำลังสองเฉลี่ย (MSE) และรากที่สองของความคลาดเคลื่อนกำลังสองเฉลี่ย (RMSE)
สัมประสิทธิ์การกำหนด หรือ R2 วัดว่าโมเดลการถดถอยอธิบายความแปรปรวนของตัวแปรตามได้ดีเพียงใด กล่าวคือระบุว่าตัวทำนายอธิบายความแปรปรวนของตัวแปรตามได้มากน้อยแค่ไหน ซึ่งเรียกว่า goodness of fit
เพื่อทำความเข้าใจมากขึ้น มาดูสูตรกัน:
โดยที่ yactual คือค่าจริงของตัวแปรตาม ypredicted คือค่าที่โมเดลทำนาย และ ȳ คือค่าเฉลี่ยของค่าจริง สูตรนี้ช่วยให้เข้าใจว่าความแปรปรวนของตัวแปรตามถูกอธิบายโดยโมเดลมากเพียงใด ส่วนตัวส่วนคือความแปรปรวนรวมของข้อมูล ส่วนตัวเศษคือความแปรปรวนที่ยังไม่ถูกอธิบายหลังใช้โมเดลการถดถอย อัตราส่วนนี้จึงให้เปอร์เซ็นต์ของความแปรปรวนที่โมเดลอธิบายได้
จะตีความ R2 อย่างไร
ข้อควรคำนึงสำคัญ
การประเมินประสิทธิภาพของโมเดลด้วยสัมประสิทธิ์การกำหนดทำได้ง่ายด้วย scikit-learn
เมตริกอื่นที่ใช้บ่อยคือ MSE และ RMSE โดยเมตริกเหล่านี้วัดว่าค่าทำนายของโมเดลเบี่ยงเบนจากค่าจริงมากเพียงใด
MSE คำนวณค่าเฉลี่ยของผลต่างยกกำลังสองระหว่างค่าจริงกับค่าทำนาย:
สำหรับจำนวนตัวอย่างทั้งหมด n เนื่องจากความคลาดเคลื่อนถูกยกกำลังสองก่อนค่าเฉลี่ย ค่าคลาดเคลื่อนที่มากจะถูกลงโทษมากกว่าค่าน้อย ทำให้ MSE อ่อนไหวต่อค่าผิดปกติ ค่า MSE ที่ต่ำกว่าบ่งชี้โมเดลฟิตดีกว่า
เพื่อจัดการประเด็นนี้ มักใช้ RMSE ซึ่งเป็นเพียงรากที่สองของ MSE โดย RMSE อยู่ในหน่วยเดียวกับตัวแปรตาม จึงตีความได้ง่ายขึ้นว่าโดยเฉลี่ยค่าทำนายคลาดเคลื่อนเท่าไร
การคำนวณ MSE และ RMSE ทำได้ง่ายด้วย scikit-learn
การทำงานกับการถดถอยเชิงเส้นพหุคูณใน scikit-learn
มาลองรันโมเดลใหม่โดยใช้คุณลักษณะทั้งหมดที่มี ไม่ใช่แค่จำนวนห้องเฉลี่ย คาดหวังผลลัพธ์ที่ดีกว่าหรือแย่กว่า?
เห็นได้ว่าผลลัพธ์ดีกว่าการใช้คุณลักษณะเพียงตัวเดียวมาก อย่างไรก็ตามก็เกิดคำถามว่าเราจำเป็นต้องใช้คุณลักษณะทั้งหมดหรือไม่ บางคุณลักษณะสำคัญกว่าตัวอื่นหรือเปล่า การเลือกเฉพาะคุณลักษณะที่เกี่ยวข้องที่สุดจากชุดข้อมูลเรียกว่า feature selection
การคัดเลือกคุณลักษณะมีความสำคัญด้วยเหตุผลหลายประการ
เมื่อหลายคุณลักษณะมีความสัมพันธ์กันสูง พวกมันจะซ้ำซ้อน หมายความว่าให้ข้อมูลแบบเดียวกันแก่โมเดล สถานการณ์นี้เรียกว่า มัลติโคลลิเนียร์ริตี แม้มัลติโคลลิเนียร์ริตีจะไม่กระทบความแม่นยำของโมเดลพยากรณ์เสมอไป แต่มันทำให้การคัดเลือกคุณลักษณะและการตีความซับซ้อนขึ้น โดยเฉพาะในโมเดลการถดถอยเชิงเส้นและที่เกี่ยวข้อง
ตัวชี้วัด Variance Inflation Factor (VIF) ใช้ตรวจจับมัลติโคลลิเนียร์ริตีระหว่างตัวทำนาย สำหรับแต่ละตัวทำนาย VIF คำนวณเป็น
โดยที่ Ri2 คือค่า R2 ที่ได้เมื่อถดถอยตัวทำนาย Xi กับตัวทำนายอื่นทั้งหมด ค่า VIF ที่สูงขึ้นหมายความว่าตัวทำนายมีความสัมพันธ์สูงกับตัวแปรอื่น
มาลองตัด AveBedrms ออกจากโมเดล
ผลลัพธ์ดีขึ้น (เล็กน้อย)
สกัดข้อมูลเชิงลึกจากโมเดล
การสร้างโมเดลการถดถอยเป็นเพียงก้าวแรก การทำความเข้าใจผลลัพธ์ก็สำคัญพอๆ กัน ด้วยการวิเคราะห์ค่าสัมประสิทธิ์ของโมเดล เราสามารถระบุได้ว่าคุณลักษณะใดมีผลต่อการทำนายมากที่สุด
ทำความเข้าใจกับค่าสัมประสิทธิ์ในการถดถอย
เมื่อฝึกโมเดลการถดถอยเชิงเส้นแล้ว สามารถเข้าถึงค่าสัมประสิทธิ์ได้ด้วย
model.coef_และเข้าถึงจุดตัดแกนได้ด้วยmodel.intercept_.เมื่อฝึกโมเดลการถดถอยเชิงเส้นด้วย LinearRegression() แล้ว สามารถเข้าถึงค่าสัมประสิทธิ์ได้ด้วย
model.coef_และเข้าถึงจุดตัดแกนได้ด้วยmodel.intercept_.สรุปผลลัพธ์ของโมเดล
เนื่องจาก Scikit-Learn ไม่มีเมท็อด
summary()ในตัวเหมือน Statsmodels เราจึงดึงและแสดงความสำคัญของแต่ละคุณลักษณะเองได้ด้วยค่าสัมประสิทธิ์ คุณลักษณะที่มีค่าสัมประสิทธิ์สัมบูรณ์ขนาดใหญ่กว่าจะมีผลต่อเป้าหมายมากกว่า พิจารณาโค้ดต่อไปนี้กราฟความสำคัญของคุณลักษณะตามค่าค่าสัมประสิทธิ์
ต่อไป มาดูภาพรวมของรีซิดวลและเส้นฟิตของการถดถอย
พล็อตเพื่อแสดงรีซิดวลและความฟิตของการถดถอย
การกระจายของรีซิดวล (กราฟซ้าย) ควรศูนย์กลางอยู่รอบศูนย์ แสดงว่าความผิดพลาดกระจายแบบสุ่ม หากรีซิดวลมีการกระจายแบบปกติ โมเดลจะฟิตได้ดี แต่หากมีความเบ้หรือแนวโน้ม อาจบ่งชี้ความผิดพลาดอย่างเป็นระบบ กราฟความฟิตของการถดถอย (กราฟขวา) เปรียบเทียบค่าจริงกับค่าทำนาย โดยเส้นประสีแดงแทนการฟิตที่สมบูรณ์ หากจุดเรียงตามเส้นอย่างใกล้ชิด แสดงว่าการทำนายแม่นยำ แต่ถ้าปรากฏรูปแบบ (เช่น โค้ง) ความสัมพันธ์อาจไม่เป็นเชิงเส้นจริง
การแสดงภาพเหล่านี้ช่วยวินิจฉัยการฟิตเกินหรือฟิตไม่พอ เผยรูปแบบในรีซิดวลที่บ่งชี้ความสัมพันธ์ที่ขาดหาย และให้การประเมินประสิทธิผลของโมเดลอย่างชัดเจน
การประยุกต์ใช้ในโลกจริง
การถดถอยเชิงเส้นถูกใช้กว้างขวางในอุตสาหกรรมต่างๆ เพื่อการพยากรณ์และการตัดสินใจ ในอสังหาริมทรัพย์ ใช้ประเมินราคาบ้านตามปัจจัยอย่างขนาดและทำเล
ด้านการขายและการตลาดใช้เพื่อพยากรณ์อุปสงค์และจัดสรรงบประมาณให้เหมาะสม ขณะที่สาธารณสุขใช้ประเมินความเสี่ยงของโรค ในการเงินช่วยพยากรณ์ราคาหุ้นและให้คะแนนเครดิต และในการผลิตช่วยควบคุมคุณภาพและทำนายความล้มเหลว
เมื่อใดควรใช้การถดถอยเชิงเส้น
เมื่อใดไม่ควรใช้การถดถอยเชิงเส้น
สรุป
การถดถอยเชิงเส้นยังคงเป็นหนึ่งในเทคนิคที่พื้นฐานและใช้อย่างแพร่หลายในแมชชีนเลิร์นนิงและการสร้างแบบจำลองทางสถิติ แม้จะเรียบง่าย แต่ก็ทรงพลังสำหรับทำความเข้าใจความสัมพันธ์ระหว่างตัวแปรและการพยากรณ์ในการใช้งานจริงหลากหลาย
ประเด็นสำคัญจากบทเรียนมีดังนี้
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการแทรกค่าในสตริงของ Python โปรดดูทรัพยากรของ DataCamp