ใช้ Grid-search ในการ Optimize SVR Model
ต่อเนื่องมาจากตอนที่แล้วที่ลองใช้ Support Vector Regression (SVR) ทำ Forward-looking model เห็นแล้วว่าโมเดลมีการ Improve อยู่บ้าง แต่ครั้งก่อน เรา Fix ค่า Parameters เช่น kernel , epsilon
และ C
ในโมเดลเลย
วันนี้เรามาหา kernel , epsilon, C และ gamma ที่ควรจะเป็นด้วย Grid-search ดีกว่า
หลักการทำงานของ Grid-search คือการโยนค่าต่าง ๆ เข้าไป Fit ในโมเดลหลาย ๆ รอบแล้วเก็บค่าแต่ละครั้งเอาไว้ เพื่อหาค่าที่ทำให้ความแม่นยำของโมเดลสูงที่สุด แล้วเราก็ใช้ค่า Parameters ที่ทำให้โมเดลมีความแม่นยำสูงที่สุดในการทำโมเดลต่อไป ซึ่งในแต่ละโมเดลก็มีค่า Parameters ที่ต้องการแตกต่างกัน และมีการวัดผลความแม่นยำที่แตกต่างกัน ซึ่งก็ต้องปรับใช้กันไป
พูดถึง Support Vector Regression (SVR) ค่าต่าง ๆ ที่จำเป็นในการ Fit โมเดลก็มี kernel , epsilon, C
และ gamma
ซึ่งอาจไม่จำเป็นต้องใช้ทุกตัวก็ได้ เช่น ถ้าเราไม่ได้กำหนดค่า gamma ในตัว Package SVR ของ scikit learn จะให้ค่าเป็น 1 / (n_features * X.var())
เป็นต้น
Code
ขอใช้โมเดลเดิมจากตอนที่แล้ว เพื่อที่จะได้เห็นผลในการ Optimize ค่าต่าง ๆ ด้วยเลย ซึ่งตอนนั้น เราให้ค่า kernel = ‘rbf’, epsilon = 0.01, C = 5
โดยไม่ได้กำหนดค่า gamma
ค่า R-Square ที่ได้ออกมาคือ 94.3% และ MSE คือ 0.7% ซึ่งมันก็ต่ำมากแล้ว
ครั้งนี้มาลองให้ค่า C
และ epsilon
หลาย ๆ ค่าดูบ้าง (กำหนด gamma
ให้เท่ากับ C
ไปเลยละกัน) ส่วน kernel
ก็ให้เลือกระหว่าง ‘linear’
กับ ‘rbf’
โดยใช้ R-Square ในการวัดผลเหมือนเดิม จากนั้นเราก็รัน GridSearchCV()
ได้เลย
อ้อ… ตัว cv = 10
คือ n-fold cross-validation (n-fold CV) มันเป็นการแบ่ง Training data ออกเป็น n เซ็ตตามที่เรากำหนด ซึ่งในที่นี้ก็คือ 10 ส่วน n_jobs = -1
คือคำสั่งเปิดการใช้งาน Multi-processing ของ CPU
Results
R_Square: 0.9748372868169162
Best parameters: {'C': 100.0, 'epsilon': 0.01, 'gamma': 10.0, 'kernel': 'rbf'}
R-Square จากเดิมที่เคยอยู่ที่ 94.3% ตอนนี้มันเพิ่มมาเป็น 97.5% แล้ว (ยังเพิ่มได้อีกเนอะ) ส่วน Parameters ของโมเดลก็เป็นที่เห็นเลย ดังนั้นเราลองมาใช้ Fit โมเดลเราอีกรอบแล้วดูผลกัน
R_Square: 0.9748372868169163
MSE: 0.003051562719194019
เส้น Back-testing ที่ออกมาดูมันชิดมากกว่าเดิมนิดหน่อย ตาม R-Square ที่เพิ่มขึ้นแหละนะ ส่วน MSE ลงไปถึง 0.3% แล้ว
คำถามเดิม Over-fitting ไหมล่ะ ?
Out of time
ใช้ข้อมูล Out of time อันเดิมเลย เดี๋ยวมาดูผลจากโมเดลกันอีกรอบ
print('MSE:', format(mean_squared_error(oot['y'], results.predict(oot[['x1', 'x2', 'x3']]))))
MSE: 0.000311112495592736
ถ้าเทียบกับตอนก่อนหน้านี้ MSE ช่วง Out of time อยู่ที่ 0.06% ตอนนี้มันลดลงเหลือ 0.03% แล้ว เท่ากับว่าปรับ Parameters ให้ดี ๆ ก็สามารถ Improve โมเดลได้ขึ้นไปอีก