Extrapolation curve ด้วย Gamma distribution curve fitting ใน Python
Hulk will break metal man open like a tin can. Metal man thinks he is stronger than Hulk. Metalman wrong.
รูปไม่ได้เกี่ยวอะไรกับเนื้อหาเลย แต่ชอบ Hulk ที่โดนอาบรังสีแกมม่า
ต่อเนื่องมาจากตอนก่อนหน้านี้ ที่ได้ Model เป็น Lifetime PD Curves ตาม Survival analysis พร้อมกับต่อเติมเส้นด้วย Chain-Ladder แล้ว เนื้อหาของ Blog ตอนนี้เป็นการเล่าเกี่ยวกับการใช้งานจากเส้นที่เกิดขึ้น
ขออ้างอิงมาตรฐาน IFRS 9 ที่มีใจความสำคัญส่วนหนึ่งที่บอกไว้ว่า ต้อง Estimate risk จนจบอายุสัญญา ถ้าเล่าสั้น ๆ ถึงตรงนี้แล้วยังไม่เข้าใจเนื้อหา อยากให้ลองกลับไปอ่านที่ตอนก่อนหน้า ตาม Link ที่ให้ไว้ด้านล่าง เพื่อความเข้าใจที่ต่อเนื่อง
Lifetime
พอต้อง Estimate risk จบจนอายุสัญญา จึงเกิดเป็น Concept lifetime ขึ้นมาตาม และมาพร้อมกับข้อจำกัดเรื่องข้อมูล จากการพัฒนา Survival analysis ด้วย กล่าวคือ Survival analysis ถูกพัฒนาจากช่วงระยะเวลาหนึ่งของข้อมูลในอดีต (Length of historical data) ดังนั้น Lifetime สามารถเกิดขึ้นได้ยาวที่สุด “เท่ากับ” ช่วงของข้อมูลที่ใช้ในการพัฒนา
เมื่อต้องใช้ Apply กับ Lifetime ตามอายุสัญญาของ Loan แล้ว อาจทำให้ไม่สามารถมีค่า Lifetime PD จนจบอายุสัญญาได้ เช่น สินเชื่อบ้านที่กู้กันหลักหลายสิบปี แน่นอนว่าไม่มีที่มีข้อมูลย้อนหลังเพียงพอและสมบูรณ์มากพอ สำหรับการพัฒนา Survival analysis model ได้ เมื่อเจอปัญหาดังนี้แล้ว จึงมีการสร้าง Model เพื่อหาค่า Lifetime PD นอกช่วงเวลา หรือ PD for a given time
Gamma distribution
การแจกแจงแบบ Gamma เป็นการแจกแจงแบบ Continuous probability นิยมใช้กับโมเดลแบบ Time-to-event หรือ Model waiting times ซึ่งเหมาะสมกับการ Estimate ใน Probability of Default model สำหรับ Density ที่ใช้ในการ Extrapolate curves คือ Cumulative density function เพราะค่าของ Cumulative probabilities จะไม่มีทางลดลง ซึ่งตรงกับคุณสมบัติของ Cumulative PD
อีกเหตุผลที่ Support เรื่องนี้คือเมื่อ Derivative cumulative density function ให้กลายเป็น Probability density function แล้วจะเกิดเป็น Curves คล้ายกับ Marginal PD ดังนั้น Gamma distribution จึงถูกเลือกใช้ใน Market
Gamma distribution มีตัวแปรหลักที่ใช้คือ Alpha (α) ส่วนอีก 2 Parameterizations ที่เหลือคือ
- Scale ที่แทนด้วย θ
- Invers scale (β) = 1 / θ หรือเรียกว่า Rate parameter
ใน SciPy Library ใน Python สามารถใช้สร้าง Curves การแจกแจงแบบ Gamma ได้ โดยค่า Default setting ของ scipy.gamma()
คือ Invers scale
scipy.gamma.cdf(x, a, loc = 0, scale)
x
: Parameter ที่ต้องการ Fitting เข้ากับ Gamma distribution ซึ่งหากเป็น PD Modelx
คือ Given time สำหรับ Lifetime perioda
: Alpha เป็นค่า Constant ของ Probability density function หรือ Shapeloc
: Location ที่มีเฉพะาในภาษา Python เป็น Parameter ที่ไว้ปรับ Shape ด้วยการ Shift curves ซ้ายขวามของแกน เนื่องจาก Apply ใช้กับ PD ที่แต่ละ Time period มีค่าเฉพาะจาก Curves ที่หาไว้แล้ว ดังนั้นloc
จึงเท่ากับ 0scale
: Scale ใช้เพื่อปรับขนาดของ Shape ในภาษาแทนตัวนี้ว่า Lambda (λ)
ก่อนเริ่มทำงานบน Data จริง ลอง Plot ด้วย Python เพื่อให้เห็นภาพของการทำงานบน Gamma distribution กันก่อน
Import libraries ที่จำเป็นในการใช้งานทั้งหมด จากนั้นเขียนเป็นฟังก์ชั่นเพื่อให้เรียกใช้งานได้ง่าย ๆ โดยฟังก์ชั่นเป็นการผ่านตัวเลขที่มีค่าคงที่เข้าไปใน scipy.gamma.cdf()
ที่เขียนเป็นสมการตามที่อธิบายไว้ด้านบน จากนั้น Plot เป็น Curves ที่ต่างกันออกมา
Curves fitting and extrapolation
ข้อมูลที่ใช้เป็น Cumulative PD Curves ที่ได้จาก Survival analysis model และการต่อเส้น Curves ด้วยเทคนิค Chain-Ladder ใน Risk grade level ซึ่งทั้งหมดเกี่ยวโยงมาจาก Blog ตอนก่อนหน้านี้ เมื่อข้อมูล Input มาในรูปของ Cumulative อยู่แล้ว สามารถนำมาใช้ต่อได้เลยตรง ๆ
จากนั้น Define function สำหรับ Gamma cumulative density function แต่มีสิ่งเพิ่มเติมขึ้นมาเพื่อให้สามารถ Fitting curves ได้สมบูรณ์มากยิ่งขึ้น คือการคูณ Distribution ด้วยค่า Constant เพื่อทำการ Scale shape ให้ใกล้เคียงกับสิ่งที่ต้องการ Fitting (ใช้คำว่า curveEst
แทนเพื่อลดการสับสนกับ Parameter scale
) เรียกวิธีการนี้ว่า Product distribution
เมื่อต้องการ Estimate หรือ Solve ทั้งหมด 3 Parameters จึงต้องมี Initial guess ทั้งหมด 3 ค่าด้วยกัน ซึ่งในที่นี้ตั้งไว้ที่ [1, 1, 1]
ซึ่งทั้งหมดจะโดนเปลี่ยนเมื่อ Optimized ไปถึงจุดที่ Minimized error แล้ว
เขียนเป็น Iteration เพื่อวนรับค่า Cumulative PD ในแต่ละ Segment และ Risk grade ค่า PD ค่าเป็นตัวแปร Target ที่ต้องการ Fitting curve ใหม่เพื่อเลียนแบบ Shape
ตัวแปร Curve ใหม่คือ year
ที่สร้างจาก np.arange()
ตามจำนวน PD ทั้งหมดที่เกิดขึ้น หรือก็คือตัวเลขเส้นตรงที่แทนด้วยจำนวนเดือนของ PD Model ทั้งหมด จากนั้นเรียกใช้งาน Module curve_fit()
ผ่าน Parameters เข้าไปคือ
- Function ที่ใช้สำหรับการ Fitting
gammaFitting
- ตัวแปร
year
เป็น Array ที่อธิบายไว้ข้างต้น หรืออีกความหมายyear
คือตัวแปรx
ในสมการฟังก์ชั่นgammaFitting()
- ตัวแปร
odr
เป็นค่า Cumulative PD initialGuess
เป็น List ของค่าเริ่มต้นก่อนการ Optimizationmaxfav
เป็นการเพิ่ม Limit loop ในการ Minimize error ของการ Optimization
Parameters ทั้ง 3 คือ alphaEst, scaleEst
และ curveEst
หลังจากที่จุดที่ Optimized แล้วถูกเก็บไว้ในตัวแปร popt
ที่เป็น Array ขนาด (1, 3) เก็บค่าเรียงไปทางขวามือ
จากนั้นกำหนด Lifetime ที่ต้องการ Extrapolate เพิ่มเติมจาก Cumulative PD เดิมที่มีอยู่ ในที่นี้กำหนดไว้เป็น 10 ปี และสร้างเป็น Array เส้นตรง เหมือนที่เคยทำไว้กับตัวแปร year
ตั้งชื่อใหม่เป็น yearEst
เขียนเป็น List comprehension เรียกใช้ฟังก์ชั่น gammaFitting() ผ่านตัวแปร x หรือคือ yearEst และ *agrs เป็น popt ที่เก็บค่า Optimized parameters ทั้ง 3 ค่าไว้ การทำงานคือค่าใน Array yearEst จะถูกผ่านเข้าไปทีละตัว เพื่อ Call function gammaFitting() ที่เข้าในเป็นสมการ Cumulative density function เพื่อสร้างเป็น Curve ใหม่ขึ้นมา
Code ส่วนที่เหลือเป็นการเก็บ Results และ Plot แสดงผลลัพธ์ ซึ่งผลลัพธ์ที่ได้ออกมาเป็นรูปด้านล่าง
Code ส่วนนี้เป็นการทำให้ผลลัพธ์กลับมาอยู่ในรูปของ DataFrame แต่ส่วนที่อยากเน้นคือการ Capture maximum PD ไว้ที่ 1 เพราะ PD จะเกิน 100% ไม่ได้ แต่การ Fitting ด้วย Gamma มีโอกาสค่าที่มากกว่า 1 ได้ (แต่น้อยมาก) ขอ Export ผลลัพธ์เอาไว้เผื่อได้ใช้งานต่อไป
Merge table ทั้งค่าที่เป็น Actual และค่า Fitted มาไว้ที่ Table เดียวกันเพื่อความง่ายในการ Visualization และเขียนเป็น Function เพื่อโชว์ Plot ผลลัพธ์
Conclusion
ก่อนจบเนื้อหาตอนนี้ ขอ Weighted average ผลลัพธ์สุดท้ายเอาไว้ เผื่อได้ใช้งานในโอกาสอื่น
Plot ผลลัพธ์เปรียบเทียบการ Extrapolate curves ของทั้ง 2 Segments
ถ้าตามกันมาตั้งแต่การ Develop survival analysis จนถึงตอนนี้ ถือได้ว่าจบส่วนที่เป็น Unbias component เรียบร้อยแล้ว ยังขาดก็แต่การทำ PD Calibration ที่ถือว่าเป็น Optional คงเขียนในตอนต่อ ๆ ไป
สำหรับ Colab Notebook สามารถดูได้จาก GitHub ใน Link ที่ให้ไว้ด้านบน