บันทึก training data science EP 13: Regularization – Optimization ด้วย Regularization
ตอนก่อนหน้า: บันทึก training data science EP 12: skimage – ภาพจำยังชัดเจน
ข้อมูลของเราไม่มีทางที่จะทำกราฟได้อย่างสวยงามอยู่แล้วฮะ จะต้องมี Outlier แน่ๆ ล่ะ แล้วเราจะจัดการยังไงได้บ้างนะ เพื่อให้ model ของเรามันจัดการได้ และไม่เกิด overfitting
เคยเล่าไปใน EP 7 ว่ามีคำอยู่สองคำที่เกี่ยวข้องกับ Outliers นั่นคือ Bias (ไม่เป็นกลาง) และ Variance (ไม่รวมกลุ่ม) ซึ่งจะทำให้เรา train model ได้ไม่ถูกต้อง
สำหรับค่า Bias หรือความไม่เป็นกลาง จะเกิดขึ้นได้ เมื่อข้อมูลที่เรามีมันไม่ make sense ซึ่ง อ้าว เราจะได้ยังไงล่ะ อันนี้จำเป็นต้องดูไปถึงต้นทางของข้อมูลเลยฮะ มันมีโอกาสที่มันจะดู make sense จนถึงตอนใช้งานจริงแล้วพบว่ามันไม่ make sense ได้ฮะ วิธีการจัดการค่า Bias ส่วนใหญ่จึงเป็น Data exploration and preparation ที่ถูกต้องฮะ
สำหรับค่า Variance หรือความไม่เป็นกลุ่ม เราสามารถรู้ได้จากการวัดค่า MSE ระหว่าง train set และ test set ถ้าค่า MSE ของ test set มันสูงกว่ามากๆ ก็แสดงว่าข้อมูลมี variance อยู่มากฮะ การจัดการกับค่า Variance จึงมีตั้งแต่เก็บข้อมูลมากขึ้น ปรับค่า feature หรือเปลี่ยน model รวมไปถึงการทำ regularization
Regularization
Regularization เป็นวิธีนึงในการลด variance ฮะ หลักการเบื้องต้นจะมีศัพท์ดังนี้ฮะ
\(L_0\) คือข้อมูลจริงของเรา
\(L_1\) เรียกอีกชื่อว่า Lasso Penalty คือ การตัด features ที่ไม่จำเป็นออก โดยการใส่ค่า weight = 0 ให้กับ feature นั้นฮะ ผลลัพท์จะทำให้สมการสั้นลง ทำให้การคำนวณใช้เวลาน้อยลง model มีประสิทธิภาพมากขึ้น
$$L_1 = \|w\|_1 = (|w_0|+|w_1|+\cdots+|w_n|) = \sum_{i=1}^n|w_i|$$
\(L_2\) หรืออีกชื่อคือ Ridge Penalty เป็นการปรับ weight ของ features เพื่อลดค่า Variance
$$L_2 = \|w\|_2=(w_0^2+w_1^2+\cdots+w_n^2)^{1/2}={\left(\sum_{i=1}^n{|w_i|}^2\right)}^\frac{1}{2}$$
อีกแบบนึงที่ไม่ได้แสดงในรูปข้างบนคือ Elastic Net ที่ผสมระหว่าง Lasso และ Ridge ฮะ
ลงมือใช้งานจริงกันเถอะ
1. เตรียม data
ติ๊ต่างเรามีข้อมูลไวน์นะฮะ เราก็โหลดเข้ามาใส่ DataFrame
เช่นเคย
และเราก็ใช้ train_test_split
เพื่อแบ่ง train set และ test set ก่อนจะกำหนดให้ y คือ label เป็น “quality” ฮะ
from sklearn.model_selection import train_test_split
x = # some dataframe
y = # some dataframe
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.75)
2. Standard Scaler
เมื่อเราจะใช้ Regularization เราจำเป็นต้องปรับ feature ด้วยการทำ scaling เพราะ regularization มันคำนวณค่า size ของ feature ฮะ โดยเราจะใช้ StandardScaler
สำหรับงานนี้
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss_train = ss.fit_transform(x_train)
ss_test = ss.transform(x_test)
3. Linear Regression
ขั้นต่อมา ใช้ model เป็น Linear Regression ด้วยค่า x คือ train set จาก standard scaler
lr = LinearRegression()
lr.fit(ss_train, y_train)
4. วัด Metrics ของ Linear Regression
เมื่อเราใช้ .fit()
แล้ว คำนวณหา MSE และ R2 score ก็พบว่า test set ได้คะแนนแย่กว่า train set นั่นคือ มี overfitting ฮะ
from sklearn.metrics import mean_squared_error, r2_score
print(mean_squared_error(y, lr.predict(ss)))
print(r2_score(y, lr.predict(ss)))
5. Lasso
หันมาใช้ Lasso ซึ่งเราจะกำหนดค่า alpha เป็น 0.1 ค่า alpha เป็นสัมประสิทธิ์ของสมการที่โชว์ข้างบนไปนะฮะ โดยค่าเริ่มต้นคือ 1.0
from sklearn.linear_model import Lasso
lasso = Lasso(alpha=0.1)
lasso.fit(ss_train, y_train)
print(lasso.score(ss_train, y_train))
พอมาลองวัดค่า R2 score จาก Lasso.score()
แล้วได้ค่าดังรูปนี้
6. LassoCV
เอาล่ะ ในเมื่อมันมีค่า alpha มาด้วย เราสามารถใช้ LassoCV
เพื่อคำนวณหาค่า alpha ที่ดีที่สุดกันฮะ
from sklearn.linear_model import LassoCV
lasso_cv = LassoCV(alphas=np.logspace(-1, 1, 100), cv=5, max_iter=5000)
lasso_cv = lasso_cv.fit(ss_train, y_train.values.ravel())
print(lasso_cv.alpha_)
print(lasso_cv.coef_)
print(lasso_cv.score(ss_train, y_train))
โดยที่ np.logspace(-1, 1, 100)
จะได้ array จำนวน 100 ค่า ตั้งแต่ \(10^{-1}\) จนถึง \(10^1\) ซึ่งใช้เป็นค่า alpha ส่วน cv คือ cross-validation สำหรับคำนวณในอัลกอริทึม และ max_iter สำหรับกำหนดค่าสูงสุดของการคำนวณฮะ และสุดท้ายเราก็ได้ R2 score ตอน test set เท่ากับ 0.2368
สังเกตว่า .coef_
จะมีค่า 0 อยู่เยอะทีเดียว ซึ่งเป็นเพราะ Lasso ที่มันกำจัด feature ที่มันมองว่าไม่สำคัญออกไปฮะ
7. Ridge
มาที่ Ridge กันบ้าง เราได้ค่าตามรูปนี้ฮะ
from sklearn.linear_model import Ridge
ridge = Ridge(alpha=1)
ridge.fit(ss_train, y_train)
print(ridge.score(ss_train, y_train))
8. RidgeCV
และเช่นกัน เราก็มี RidgeCV
เพื่อคำนวณหาค่า alpha ที่ดีที่สุด โดยเรากำหนดการคำนวณ scoring
เป็นค่า R2 score ฮะ
Regularization ช่วยแก้ปัญหา overfitting แล้วเกิด MSE ตอน test มากขึ้นได้แบบนี้เองนะฮะ เพราะปัญหาที่เราจะเจอจริงๆ ไม่ได้อยู่ตอน train แต่เป็นตอน test และใช้งานจริงฮะ
References
- https://towardsdatascience.com/intuitions-on-l1-and-l2-regularisation-235f2db4c261
- https://en.wikipedia.org/wiki/Regularization_(mathematics)
- https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html#sklearn.linear_model.Lasso
- https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LassoCV.html#sklearn.linear_model.LassoCV
- https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html#sklearn.linear_model.Ridge
- https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.RidgeCV.html#sklearn.linear_model.RidgeCV
และบันทึกครั้งหน้าก็เป็นตอนจบของซีรี่ส์บันทึก training data science ฮะ
จะเล่าให้อ่านกันอีกทีนะฮะ
ตอนต่อไป: บันทึก training data science EP 14 END - Data scientist ก็เคยทำพลาดนะ