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.

Sasiwut Chaiyadecha
4 min readNov 10, 2021

รูปไม่ได้เกี่ยวอะไรกับเนื้อหาเลย แต่ชอบ Hulk ที่โดนอาบรังสีแกมม่า

gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model

ต่อเนื่องมาจากตอนก่อนหน้านี้ ที่ได้ 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 fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model

การแจกแจงแบบ 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 fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model

Gamma distribution มีตัวแปรหลักที่ใช้คือ Alpha (α) ส่วนอีก 2 Parameterizations ที่เหลือคือ

  • Scale ที่แทนด้วย θ
gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model
gamma cumulative density function โดยใช้ scale
  • Invers scale (β) = 1 / θ หรือเรียกว่า Rate parameter
gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model
gamma cumulative density function โดยใช้ 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 Model x คือ Given time สำหรับ Lifetime period
  • a: Alpha เป็นค่า Constant ของ Probability density function หรือ Shape
  • loc: Location ที่มีเฉพะาในภาษา Python เป็น Parameter ที่ไว้ปรับ Shape ด้วยการ Shift curves ซ้ายขวามของแกน เนื่องจาก Apply ใช้กับ PD ที่แต่ละ Time period มีค่าเฉพาะจาก Curves ที่หาไว้แล้ว ดังนั้น loc จึงเท่ากับ 0
  • scale: Scale ใช้เพื่อปรับขนาดของ Shape ในภาษาแทนตัวนี้ว่า Lambda (λ)

ก่อนเริ่มทำงานบน Data จริง ลอง Plot ด้วย Python เพื่อให้เห็นภาพของการทำงานบน Gamma distribution กันก่อน

Import libraries ที่จำเป็นในการใช้งานทั้งหมด จากนั้นเขียนเป็นฟังก์ชั่นเพื่อให้เรียกใช้งานได้ง่าย ๆ โดยฟังก์ชั่นเป็นการผ่านตัวเลขที่มีค่าคงที่เข้าไปใน scipy.gamma.cdf() ที่เขียนเป็นสมการตามที่อธิบายไว้ด้านบน จากนั้น Plot เป็น Curves ที่ต่างกันออกมา

gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model
cumulative curves ใน level ต่าง ๆ ที่เกิดจากค่า parameter ใน gamma distribution ที่ต่างกัน

Curves fitting and extrapolation

gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model
ตัวอย่างข้อมูลจากตอนก่อนหน้านี้ ใช้เป็น input สำหรับเนื้อหาตอนนี้

ข้อมูลที่ใช้เป็น 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 ของค่าเริ่มต้นก่อนการ Optimization
  • maxfav เป็นการเพิ่ม 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 แสดงผลลัพธ์ ซึ่งผลลัพธ์ที่ได้ออกมาเป็นรูปด้านล่าง

gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model
ผลลัพธ์จากการ fitting ในแต่ละ segment และ risk grade

Code ส่วนนี้เป็นการทำให้ผลลัพธ์กลับมาอยู่ในรูปของ DataFrame แต่ส่วนที่อยากเน้นคือการ Capture maximum PD ไว้ที่ 1 เพราะ PD จะเกิน 100% ไม่ได้ แต่การ Fitting ด้วย Gamma มีโอกาสค่าที่มากกว่า 1 ได้ (แต่น้อยมาก) ขอ Export ผลลัพธ์เอาไว้เผื่อได้ใช้งานต่อไป

Merge table ทั้งค่าที่เป็น Actual และค่า Fitted มาไว้ที่ Table เดียวกันเพื่อความง่ายในการ Visualization และเขียนเป็น Function เพื่อโชว์ Plot ผลลัพธ์

gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model
ผลลัพธ์การ extrapolation แบบ cumulative
gamma fitting gamma distribution curve fitting non-linear curve fitting python ifts9 pd model survival analysis extrapolation cumulative marginal credit risk probability of default model
ผลลัพธ์แบบ marginal ที่เกิดจาก cumulative ลบกัน

Conclusion

ก่อนจบเนื้อหาตอนนี้ ขอ Weighted average ผลลัพธ์สุดท้ายเอาไว้ เผื่อได้ใช้งานในโอกาสอื่น

Plot ผลลัพธ์เปรียบเทียบการ Extrapolate curves ของทั้ง 2 Segments

ถ้าตามกันมาตั้งแต่การ Develop survival analysis จนถึงตอนนี้ ถือได้ว่าจบส่วนที่เป็น Unbias component เรียบร้อยแล้ว ยังขาดก็แต่การทำ PD Calibration ที่ถือว่าเป็น Optional คงเขียนในตอนต่อ ๆ ไป

สำหรับ Colab Notebook สามารถดูได้จาก GitHub ใน Link ที่ให้ไว้ด้านบน

--

--