01Overall Concept
ไอเดียหลัก — Ridge Regression คือ Linear Regression ที่มีกติกาเพิ่มว่า “อย่าให้น้ำหนักของตัวแปรใดดังเกินไป” กติกานี้ช่วยให้คำตอบนิ่งขึ้นเมื่อมีข้อมูลหลายอย่างที่คล้ายกัน เช่น ขนาดบ้าน จำนวนห้อง และพื้นที่ใช้สอย
ลองนึกภาพว่า — เหมือนวงดนตรีที่มีคนคุมเสียง ถ้าเครื่องดนตรีชิ้นหนึ่งดังเกินไป คนคุมจะลดเสียงลง เพื่อให้ทุกชิ้นช่วยกันสร้างเพลงโดยไม่มีชิ้นใดกลบทั้งหมด
ตัวอย่างการนำไปใช้ — ทำนายราคาบ้านจากข้อมูลหลายคอลัมน์ พยากรณ์ยอดขายจากสื่อโฆษณาหลายช่องทาง หรือสร้างโมเดลพื้นฐานเมื่อ feature มีความคล้ายกันมาก
02อธิบายภาษาคนเข้าใจง่ายๆ
Ridge เริ่มมีประโยชน์เวลาที่เรามีตัวแปรเยอะ
สมมติเราจะทำนายราคาบ้านจาก 50 ปัจจัย ทั้งขนาดบ้าน จำนวนห้อง อายุบ้าน จำนวนห้องน้ำ ขนาดสวน คะแนนโรงเรียน ระยะทางจากรถไฟฟ้า จำนวนร้านอาหารใกล้บ้าน ฯลฯ
บางครั้ง Linear Regression อาจตื่นเต้นกับข้อมูลบางอย่างมากเกินไป เช่นเห็นว่าบ้านที่มีระเบียงใหญ่ในข้อมูลชุดนี้ราคาสูงมาก แล้วก็ให้น้ำหนัก “ขนาดระเบียง” เยอะผิดปกติ
Ridge จะใส่กฎเพิ่มว่า
“เรียนรู้ได้ แต่อย่าให้น้ำหนักปัจจัยใดปัจจัยหนึ่งแรงเกินไป”
เหมือนมีคนยืนอยู่ข้างๆ โมเดลคอยบอกว่า
ใจเย็น อย่าเพิ่งสรุปว่าปัจจัยนี้สำคัญขนาดนั้น
ผลคือโมเดลมักเสถียรกว่า โดยเฉพาะเวลาตัวแปรหลายตัวมีความสัมพันธ์กันเอง เช่น ขนาดบ้านกับจำนวนห้องนอนก็มักเพิ่มตามกัน
Ridge ไม่ได้ลบตัวแปรออก แต่มันจะ ลดอิทธิพลของตัวแปรที่มันคิดว่าแรงเกินไป
มันจึงเหมาะกับสถานการณ์ที่เราเชื่อว่า “ตัวแปรส่วนใหญ่น่าจะมีประโยชน์ เพียงแต่อยากควบคุมไม่ให้โมเดลหลง”
ภาพจำ: มีคนคอยดึงแขนโมเดลไว้ไม่ให้วิ่งตามตัวแปรใดตัวแปรหนึ่งแรงเกินไป
03How it works
ค่อยๆ ทำไปด้วยกัน ตั้งแต่ข้อมูลแถวแรกจนถึงการตรวจคำตอบ
เริ่มจากบ้านที่มีรายละเอียดเยอะ
ให้ X มีพื้นที่ จำนวนห้อง อายุบ้าน และระยะทางจากรถไฟฟ้า ส่วน y คือราคาขายจริง บ้านหนึ่งหลังต่อหนึ่งแถว ตัดรหัสประกาศออก แบ่งชุดฝึกกับชุดทดสอบ และแปลงเขตหรือประเภทบ้านเป็นคอลัมน์หมวดหมู่ก่อน โมเดลจะหาน้ำหนักของแต่ละปัจจัยให้เอง
ทำให้การเบรกยุติธรรมกับทุกคอลัมน์
พื้นที่อาจเป็นหลักร้อย แต่จำนวนห้องเป็นหลักหน่วย ถ้าเปรียบเทียบน้ำหนักดิบทันทีจะไม่ยุติธรรม จึงใช้ StandardScaler ที่เรียนค่าเฉลี่ยและส่วนเบี่ยงเบนจากชุดฝึกเท่านั้น แล้วใช้ค่าเดิมแปลงชุดทดสอบ ประกอบเป็น make_pipeline(StandardScaler(), Ridge(alpha=1.0)) ได้
Ridge ชั่งสองเรื่องพร้อมกัน
เรื่องแรกคือทายราคาพลาดมากแค่ไหน เรื่องที่สองคือน้ำหนักแรงเกินไปไหม ใน sklearn เป้าหมายคือผลรวม error² + alpha × ผลรวม w² สมมติน้ำหนักสองชุดทายได้ใกล้กัน Ridge จะชอบชุดที่มีขนาดรวมเล็กกว่า จึงช่วยเมื่อพื้นที่กับจำนวนห้องให้ข้อมูลซ้ำกัน โดยทั่วไปไม่ได้ทำให้น้ำหนักเป็นศูนย์แบบ Lasso
เริ่มหมุนปุ่ม alpha
เรียก fit(X_train, y_train) แล้วลอง alpha เช่น 0.1, 1, 10, 100 ผ่าน cross-validation ค่าสูงเพิ่มแรงบีบ ค่าต่ำใกล้ Linear Regression มากขึ้น ใช้ fit_intercept=True และ solver='auto' เป็นจุดเริ่มได้ ค่าที่ดีที่สุดขึ้นกับสเกลและชุดข้อมูล ไม่ใช่ว่า alpha สูงแล้วแม่นเสมอ
อ่านผลพร้อมตรวจการบ้าน
predict(X_test) ให้ราคาต่อบ้าน ดู MAE ในหน่วยบาทและเทียบ Linear Regression บนชุดทดสอบเดียวกัน หากจะอ่าน coef_ จากโมเดลใน Pipeline ต้องจำว่าน้ำหนักนั้นอยู่บนสเกลที่ปรับแล้ว ไม่ใช่บาทต่อหนึ่งตารางเมตรดิบ ลองเพิ่ม alpha แล้วดูทั้งขนาดน้ำหนักและ error ถ้าคำทำนายเริ่มคล้ายกันหมด แสดงว่าเบรกแรงไป
ข้อมูล พารามิเตอร์ และภาพรวมการคำนวณ
alphafit_interceptsolverข้อมูลที่รับเข้ามา
รับ X เป็นตารางตัวเลขและ y เป็นค่าต่อเนื่อง เหมาะเมื่อมีหลาย feature ที่สัมพันธ์กัน ควรปรับสเกลคอลัมน์ให้ใกล้กันก่อน
X = [พื้นที่, จำนวนห้อง, อายุบ้าน, ระยะทาง] · y = ราคาบ้านพารามิเตอร์ที่ใช้
- alpha
- แรงบีบน้ำหนัก ยิ่งมากค่าสัมประสิทธิ์ยิ่งเล็ก
- fit_intercept
- ให้หาค่าจุดตัดแกนจากข้อมูลหรือไม่
- solver
- วิธีเชิงตัวเลขที่ใช้แก้สมการหาน้ำหนัก
ผลลัพธ์ที่ได้
ได้ค่าน้ำหนักที่เล็กและนิ่งกว่า Linear Regression พร้อมค่าทำนายตัวเลขต่อเนื่อง
เปรียบเทียบ alpha=0.1, 1, 10 พร้อม MAE และขนาดน้ำหนักคำนวณทีละขั้น
- 01
คำนวณค่าทำนายด้วยสมการเส้นตรงเหมือน Linear Regression
- 02
ใน sklearn ลดผลรวม error² + alpha × ผลรวม w² เพื่อคิดค่าปรับเมื่อขนาดน้ำหนักใหญ่
- 03
ปรับน้ำหนักจนผลรวมระหว่างความแม่นและค่าปรับต่ำที่สุด แล้วใช้สมการทำนายข้อมูลใหม่
ควรรู้อีกนิด — alpha มากเกินไปทำให้ underfit และ Ridge ไม่ได้เลือก feature ออกโดยตรง
04Make it yours
# ติดตั้ง: pip install numpy scikit-learn matplotlibfrom sklearn.linear_model import Ridgefrom sklearn.metrics import mean_squared_error import numpy as npfrom sklearn.model_selection import train_test_split rng = np.random.default_rng(42)X = np.linspace(-1, 1, 60).reshape(-1, 1)y = 0.1 + 0.55*X[:, 0] + 0.55*np.sin(3.4*X[:, 0])y += rng.normal(0, 0.14, len(y))X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42) model = Ridge(alpha=2.0)model.fit(X_train, y_train)pred = model.predict(X_test)print("RMSE:", mean_squared_error(y_test, pred) ** 0.5)โค้ดเปลี่ยนตามค่าที่เลือกใน Playground · แต่ละภาษาใช้ข้อมูลตัวอย่างตามที่ระบุในโค้ด
05Learn by playing
ปรับ alpha (L2) แล้วสังเกตรูปแบบคำทำนายและตัวชี้วัดที่คำนวณใหม่ทันที
Playground เป็น implementation เพื่อการเรียนรู้ที่คำนวณในเบราว์เซอร์ ส่วนโค้ด Python ใช้ scikit-learn จึงอาจให้ค่าต่างกันเล็กน้อยจากรายละเอียดการ optimize และค่าเริ่มต้นของไลบรารี ผลนี้ไม่ใช่ benchmark บนข้อมูลจริง