ทำนาย "โรคหัวใจ" ด้วยข้อมูล (2) แก้ไข Overfitting

Data Science 16 กันยายน พ.ศ. 2567 306
Home / Articles / 807

แก้ปัญหา Overfitting Model

หาก Model ของเรามีปัญหา Overfitting ซึ่งก็คือ การที่ Model ทำประสิทธิภาพได้ไม่ดี ใน Test Set ซึ่งสำหรับ Model แล้ว ถือเป็นข้อมูลที่ไม่เคนเห็น ในบทความนี้ผมก็จะมาแนะนำการแก้ปัญหา Overfitting ของข้อมูล ที่อาจช่วย เพิ่มค่า r2 ของ Test Set เราให้ดีขึ้นได้

Ridge Regression

ก่อนแรกผมจะมาลองใช้ Ridge Regression ในการทำนาย แทนบทความที่แล้วที่เราใช้ Linear Regression ในการทำนาย ซึ่ง Ridge Regression เป็นเทคนิคหนึ่งที่สามารถใช้ช่วย Regularization ข้อมูลที่เรามีได้ ซึ่งความหมายก็คือ จะช่วย normalize ให้ค่าที่ได้จากการทำนาย หดเข้าใกล้ค่า 0 มากขึ้น

โดยผมจะลบโค้ดเก่า ที่ใช้ Linear Regression ในการทำนาย ก็คือ

lr = LinearRegression()
lr.fit(X_train, Y_train)

Y_linear_train_prediction = lr.predict(X_train)
Y_linear_test_prediction = lr.predict(X_test)

ผมจะลบออกทั้งหมด แล้วเปลี่ยนเป็น Ridge Model เพื่อใช้ทำนายแทน

from sklearn.linear_model import Ridge
ridge_model = Ridge(alpha=10.0)
ridge_model.fit(X_train_poly, Y_train)
ridge_model.predict(X_test_poly)

Y_train_prediction = ridge_model.predict(X_train_poly)
Y_test_prediction = ridge_model.predict(X_test_poly)

Standardization โดยใช้ StandardScaler

จากนั้นเราจะเพิ่มการทำ StandardScaler เข้าไป การทำ StandardScaler ก็คือ การทำ Standardization ข้อมูลนั่นเอง คือ การแปลงค่าเฉลี่ยของข้อมูลให้อยู่ที่ 0 ในบางกรณีสามารถเพื่อประสิทธิภาพของ Model เราได้

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_poly = scaler.fit_transform(X_train_poly)
X_test_poly = scaler.transform(X_test_poly)

รวม ๆ แล้ว โค้ดหลังจากแก้ไข จะได้ดังนี้ โดยที่ ค่า alpha=10.0 เราสามารถปรับเปลี่ยนและเลือกค่า alpha ที่สามารถทำให้การทำนายดีที่สุดได้ อาจจะเป็น 2,5,10 หรือ 20 ขึ้นอยู่กับข้อมูล

#แยก Train Set กับ Test Set ออกจาก X และ Y โดยกำหนด test_size=0.2 หมายถึง จำนวน Test Set = 20%
#random_state=42 คือการเลือกการสุ่ม Test, Train Set ให้มีค่า 42 หมายถึงจะสุ่มชุดเดิม ๆ ในการรัน ทุกครั้ง ค่า 42 สามารถเปลี่ยนเป็นอะไรก็ได้
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=42)

selector = SelectKBest(score_func=f_regression, k='all')
X_train_selected = selector.fit_transform(X_train, Y_train)
X_test_selected = selector.transform(X_test)

#Degree = 2
poly = PolynomialFeatures(2)

X_train_poly = poly.fit_transform(X_train_selected)
X_test_poly = poly.transform(X_test_selected)

scaler = StandardScaler()
X_train_poly = scaler.fit_transform(X_train_poly)
X_test_poly = scaler.transform(X_test_poly)

print("X train size: "+str(len(X_train)))
print("X test size: "+str(len(X_test)))

print("Y train size: "+str(len(Y_train)))
print("Y test size: "+str(len(Y_test)))

ridge_model = Ridge(alpha=10.0)
ridge_model.fit(X_train_poly, Y_train)
ridge_model.predict(X_test_poly)

Y_train_prediction = ridge_model.predict(X_train_poly)
Y_test_prediction = ridge_model.predict(X_test_poly)

train_mse = mean_squared_error(Y_train, Y_train_prediction)
test_mse = mean_squared_error(Y_test, Y_test_prediction)

train_r2 = r2_score(Y_train, Y_train_prediction)
test_r2 = r2_score(Y_test, Y_test_prediction)

print("Train MSE:", train_mse)
print("Test MSE:", test_mse)
print("Train R²:", train_r2)
print("Test R²:", test_r2)

Random Forest Regression

from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
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)
r
rf = RandomForestRegressor(n_estimators=100, min_samples_split=10, random_state=42)

rf.fit(X_train, Y_train)

Y_train_pred = rf.predict(X_train)
Y_test_pred = rf.predict(X_test)

train_mse = mean_squared_error(Y_train, Y_train_pred)
test_mse = mean_squared_error(Y_test, Y_test_pred)
train_r2 = r2_score(Y_train, Y_train_pred)
test_r2 = r2_score(Y_test, Y_test_pred)

print(f"Train MSE: {train_mse}")
print(f"Test MSE: {test_mse}")
print(f"Train R²: {train_r2}")
print(f"Test R²: {test_r2}")

อ้างอิง:

deepchecks.com/question/what-is-the-benefit-of-ridge-regression/

Profile Picture.
  • Name (Pen name): Sunny Jirakit (Sunny420x)
  • Study: Bachelor Degree of Computer Science from Chiang Mai Rajabhat University
  • Personality: Architect (INTJ-T)
  • Experience: JavaScript,  Angular.js, React.js, Next.js  Express.js, Unity C#, Socket.io