All possible combinations with conditions in python

Recursive function backtracking

Sasiwut Chaiyadecha
3 min readSep 14, 2022
the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming

การทำ Forward-looking model สำหรับ IFRS 9 ด้วย Multiple linear regression ขั้นตอน Features selection ด้วย Univariate analysis หรือ Multivariate analysis ด้วยวิธีใด ๆ ก็ตาม สิ่งที่ได้เป็นผลลัพธ์คือตัวแปรจำนวนหนึ่ง ที่สามารถนำไปใช้พัฒนาเป็นโมเดลต่อ แต่จำนวนตัวแปรที่ผ่าน Features selection อาจมีจำนวนมากเกินไป เกินกว่าที่ควรจะเป็นใน 1 โมเดล

ดังนั้นวิธีการที่นิยมใช้สำหรับ IFRS 9 คือแทนที่การรันด้วยตัวแปรทั้งหมด ซึ่งอาจทำให้เกิดความยุ่งยากในการแปลผล หรือ Model maintenance การจัด Combinations ก็เป็นอีกทางเลือกที่ดีมาก เพราะสามารถกำหนดได้ว่าต้องการให้ Model มีจำนวน Independence variables กี่ตัว

Simple combinations

ก่อนไปถึงการจัด Combinations ด้วยเงื่อนไขตามที่ต้องการ อยากให้ดูการใช้ Library itertools สำหรับการทำ Combinations ตามจำนวนที่ต้องการ ขอใช้เป็น Mock-up dataset เพื่อแสดงให้เห็นตัวอย่างการทำงานของ Library

List ข้อมูลประกอบด้วย 4 Lists ย่อยภายในซึ่งประกอบไปด้วย

  • สมาชิกตัวที่ 1 คือ Variable ที่ต้องการจัด Combinations
  • สมาชิกตัวที่ 2 คือ Cluster ที่ Variable นั้น ๆ อยู่จัดให้อยู่
  • สมาชิกตัวที่ 3 คือ ฟอร์มเดิมของ Variable ก่อน Transformation

สนใจเฉพาะสมาชิกตัวที่ 1 จากแต่ละ List เพราะยังไม่ต้องการใส่เงื่อนไขใด ๆ เข้าไปใน Combinations

['GDP_M3', 'HPI_M3_lg2', 'HPI_M6', 'Export_M9']

ใช้ itertools.combinations() ผ่านเป็น List ของ Variables และกำหนดให้สมาชิกใน Combinations มีเท่ากับ 2

('GDP_M3', 'HPI_M3_lg2')
('GDP_M3', 'HPI_M6')
('GDP_M3', 'Export_M9')
('HPI_M3_lg2', 'HPI_M6')
('HPI_M3_lg2', 'Export_M9')
('HPI_M6', 'Export_M9')

ผลลัพธ์ที่มีทั้งหมด 6 Combinations สามารถคิดได้จาก 4c2 โดยที่ 4 คือจำนวนของสมาชิกทั้งหมดที่มีโอกาสโดยเลือก และ 2 คือจำนวนในการเลือกแต่ละครั้ง ตัวอย่างเช่น GDP_M3 มีโอกาสจับคู่กับทั้ง 3 คือ HPI_M3_lg2, HPI_M6 และ Export_M9 ต่อมา HPI_M3_lg2 มีโอกาสจับคู่เหลือ 2 คือ HPI_M6 และ Export_M9 สุดท้าย HPI_M6 มีโอกาสจับคู่กับ Export_M9 เท่านั้น

หากสังเกตดูจะเห็นได้ว่าการทำ Combinations แบบนี้ยังไม่สมเหตุสมผลเท่าไหร่ เช่น (‘GDP_M3’, ‘HPI_M3_lg2’) เป็น Combinations ที่เกิดจากสมาชิกที่มาจาก Cluster เดียวกัน หรือ (‘HPI_M3_lg2’, ‘HPI_M6’) แม้ว่ามาจากคนละ Cluster แต่ HPI ยังคงเป็นตัวแปรเดียวกับที่อยู่ในฟอร์มที่ต่างกันเท่านั้น

ปัญหานี้อาจส่งผลให้เกิด Multicollinearity ขึ้นใน Combination นั้น ๆ หรือหากใช้งานจริง อาจทำให้โมเดลอธิบายผลได้ยาก ดังนั้นการจัด Combinations ด้วยเงื่อนไขจึงเป็นทางเลือกที่น่าสนใจ

Combinations with conditions

เมื่อรู้ว่ามีสิ่งที่ไม่ต้องการเกิดขึ้นจาก Combinations ดังนั้นจึงสามารถสร้างเป็นเงื่อนไขได้คือ ไม่ให้สมาชิกใน Combination มาจาก Cluster เดียวกัน และไม่ให้สมาชิกใน Combination นั้น ๆ มาจากตัวแปรประเภทเดียวกัน

ยกตัวอย่างให้เห็นภาพมากขึ้นกว่าเดิม ถ้าใช้ข้อมูล Mock-up เดิมที่มีอยู่ผลลัพธ์ที่ได้จากเงื่อนไขนี้คือ

  • GDP_M3 สามารถจับคู่ได้กับ HPI_M6 และ Export_M9 เพราะทั้งสองมาจากคนละ Cluster และไม่ใช่ตัวแปรประเภทเดียวกัน
  • HPI_M3_lg2 สามารถจับคู่ได้กับ Export_M9 เท่านั้น เพราะทั้งสองมาจากคนละ Cluster และไม่ใช่ตัวแปรประเภทเดียวกัน ส่วน HPI_M6 ไม่สามารถจับคู่ได้ แม้ว่าอยู่คนละ Cluster กัน เพราะเป็นตัวแปรประเภทเดียวกัน และ GDP_M3 ไม่สามารถจับคู่ได้ เพราะอยู่ใน Cluster เดียวกัน แม้ว่าเป็นตัวแปรคนละประเภท

Recursive function backtracking

Backtracking เป็น Algorithm ในการเขียนโปรแกรมชนิดนึง โดยมีหลักการทำงานแบบ Recursively ที่พยายามแก้ไขปัญหาและลบคำตอบที่ไม่ต้องการออกจากผลลัพธ์ หลักการ Backtracking จึงถูกนำมาใช้ในการพัฒนาการสร้าง Combinations ด้วยเงื่อนไขที่ได้อธิบายไว้ก่อนหน้านี้

เขียนเป็น Recursive function หรือฟังก์ชั่นที่เรียกใช้งานตัวเอง ไปจนกว่าจะถึงเงื่อนไขให้หยุด โดยมีการจัด Combinations แบบ 1–1 และเก็บตัวแปร เช่น clusterTracker หรือ subGroupTracker เพื่อเช็คเงื่อนไขการ .add() หรือ .remove() ตัวแปรที่ไม่ต้องการออกจาก Combination นั้น ๆ

โดยการทำงานทั้งหมดของ Function สามารถแสดงเป็นภาพคร่าว ๆ ได้ตามด้านล่าง

the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming
เช็คสมาชิกทุกตัวจากข้อมูล input
the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming
เช็คเงื่อนไขว่าต้องทำกี่ combinations
the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming
เริ่มต้นเช็คที่ข้อมูลสุดท้ายเป็นลำดับแรก
the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming
เช็คข้อมูลรองสุดท้ายเป็นลำดับที่สอง แม้ว่าตัวแปรต่างชนิดกัน แต่มาจาก cluster เดียวกัน จึงไม่สามารถเกิด combination นี้ได้
the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming
HPI_M3_lg2 จึงต้องจับคู่กับ Export_M9 แทน เพราะมาจากคนละ cluster และตัวแปรคนะชนิด
the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming
เมื่อจบการเช็คเงื่อนไข จึงเกิดเป็น combination แรกคือ HPI_M3_lg2, Export_M9

Process นี้จะวนไปเรื่อย ๆ จนเกิดจะเข้าเงื่อนไขหยุด และ Return ผลลัพธ์ที่เป็น Combinations ตามเงื่อนไขที่สร้างเอาไว้

ลองใช้ข้อมูลเดิม จัดเป็น 2 Combinations เพื่อทดสอบ Apply function

['HPI_M3_lg2', 'Export_M9']
['GDP_M3', 'Export_M9']
['GDP_M3', 'HPI_M6']

จากเดิมที่คำตอบเกิดจาก 4c2 มีค่าเท่ากับ 6 Combinations แต่เมื่อผ่าน Backtracking ผลลัพธ์จึงเหลือเพียง 3 Combinations ตามเงื่อนไขที่ต้องการ

With real dataset

ใช้ Dataset ที่ผ่านการจัด Cluster ด้วย PROC VARCLUS จากโปรแกรม SAS แต่สามารถรันได้ด้วย Python เช่นกัน

the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming

สร้างเป็น List of lists ที่เก็บตัวแปรที่จำเป็นต่อการสร้างเงื่อนไขไว้คือ Variable, cluster และ Root form ของ Variable นั้น ๆ

[['GDP_C_lg12', 1, 'GDP'],
['MPI_C_lg12', 1, 'MPI'],
['RSI_C_lg12', 1, 'RSI'],
['PCI_C_lg12', 1, 'PCI'],
['CPI_M9_lg6', 2, 'CPI']]

จัดเป็น Combinations ที่มีสมาชิกมากที่สุดเท่ากับ 3 ด้วย Recursive function backtracking

[['GDP_C_lg12', 'CPI_M9_lg6', 'PII_M12_lg10'], ['GDP_C_lg12', 'CPI_M9_lg6', 'OP_C'], ['GDP_C_lg12', 'CPI_M9_lg6', 'PII_M12_lg11']]

สร้างเป็น DataFrame และ Plot ผลลัพธ์ของการจัด Combinations ด้วย Conditions ต่างที่อธิบายมาตามเนื้อหาของ Blog ตอนนี้

the forward-looking PD PiT PD ifrs9 มาตรฐานบัญชีใหม่ มาตรฐานบัญชี 9 TFRS 9 Macroeconomics model lifetime PD all possible combinations in python การเขียน Combination ใน python recursive function backtracking in python python programming

Conclusion

สุดท้ายแล้วเนื้อหาของ Blog ตอนนี้คือการนำเอา Recursive function backtracking ที่เป็น Algorithm ชนิดหนึ่งในการเขียนโปรแกรม มาประยุกต์ใช้งานในการพัฒนาโมเดลของ IFRS 9 เพื่อให้เกิดความสมเหตุสมผลมากขึ้น และสามารถช่วยในการอธิบายในเชิงของการใช้งานได้มากกว่าเดิม

สำหรับ Colab notebok ของเนื้อหา Blog ตอนนี้ สามารถดูได้ที่ GitHub ด้านบน

--

--

Sasiwut Chaiyadecha
Sasiwut Chaiyadecha

No responses yet