1.3 탈퇴와 발생#
이 챕터에서 배우는 것
보험 계약은 매달 서로 다른 두 가지를 따로 본다 — ① 계약에서 빠졌는가 (탈퇴: 사망·해지), ② 보험금 줄 사유가 생겼는가(발생: 사망·진단·입원)
이 둘은 원래 한 몸인데 엔진이 쪼갠 게 아니라 처음부터 다른 개념이라는 것
일반사망보험에서만 두 일이 같은 사망 사건이라 숫자가 겹치고, 같은 숫자라고 같은 개념은 아니라는 것
엔진에서 탈퇴는
mortality_annual·lapse_annual, 발생은 담보rate가 맡고, 사망은 그 둘이 갈라지는 가장 헷갈리는 자리라는 것이 구분이 1.4의 “한 번 vs 반복” 청구 메커니즘으로 이어지는 길
보험 계약에서 매달 일어나는 일은 두 종류입니다. 하나는 계약에서 빠지는 일 — 사람이 죽거나 해지하면 그 계약은 보유계약(in-force)에서 사라집니다. 다른 하나는 보험금 줄 사유가 생기는 일 — 사망·암 진단·입원 같은 사건이 보험금 지급을 일으킵니다. 같은 사건이 두 일을 동시에 일으킬 때도, 한쪽만 일으킬 때도 있습니다.
사건 |
계약에서 빠지는가 (탈퇴) |
보험금을 지급하는가 (발생) |
|---|---|---|
해지 |
예 |
상품에 따라 (해지환급금) |
보장하는 원인의 사망 |
예 |
예 |
보장하지 않는 원인의 사망 |
예 |
아니요 |
암 진단 |
아니요 |
예 |
입원 |
아니요 |
예 |
왼쪽 열이 탈퇴, 오른쪽 열이 발생입니다. 두 열은 독립이라 같은 행에서 ‘예/아니요’가 자유롭게 갈립니다 — 진단·입원은 계약에서 안 빠지고 보험금만 나가고, 보장하지 않는 원인의 사망은 빠지지만 보험금은 안 나갑니다. 보장하는 원인의 사망만 두 열이 모두 ‘예’라, 한 번의 사망 사건이 탈퇴와 지급을 동시에 일으킵니다. 그래서 숫자가 같아질 수 있을 뿐, 두 열은 여전히 다른 개념 입니다.
엔진도 이 두 열을 다른 입력으로 받습니다:
코드 입력 |
역할 |
용어 |
무엇을 하는가 |
|---|---|---|---|
|
탈퇴 |
보유계약 사망률 |
계약 전체 in-force를 줄임 |
|
탈퇴 |
해지율 |
계약 전체 in-force를 줄임 |
DEATH 담보의 |
발생 |
사망보험금 발생률 |
사망보험금 지급액 계산 |
DIAGNOSIS 담보의 |
발생 |
진단 발생률 |
진단보험금 + 그 담보의 미진단 풀에서 탈퇴 |
MORBIDITY 담보의 |
발생 |
반복급부 발생률 |
반복 보험금 (어느 풀도 안 줄임) |
핵심 한 줄: 탈퇴율은 누가 계약에 남는가 를, 발생률은 어떤 보험금을 지급하는가 를 계산합니다. 사망은 둘이 겹치는 한 사례일 뿐, 출발점이 같은 양은 아닙니다. 이 챕터는 그 가장 헷갈리는 자리 — 사망의 탈퇴(보유계약 사망률)와 발생(사망보험금 발생률) — 을 갈라 둡니다.
표준 용어로는 — 탈퇴(decrement) vs 발생(incidence)
위 두 열은 다중탈퇴모형(multiple-decrement model)의 교과서 구분 그대로입니다.
탈퇴(decrement) = 계약 전체 in-force에서 빼는 입력.
mortality_annual은 표준 용어로 사망탈퇴율(mortality decrement, q_x^(d)) — 연단위 확률이라 율이지 력(force, μ)이 아니고, 엔진은inforce x (1 - q)로 축소합니다.lapse_annual은 해지탈퇴율.발생(incidence) = 보험금 줄 사유의 빈도. 담보의
rate가 그것. 발생은 계약 전체 in-force는 건드리지 않습니다. 다만 담보에 따라 자기 하위 풀은 줄일 수 있어 — DIAGNOSIS는 자기 미진단 풀을(1 - 발생률)로 축소하고, DEATH·MORBIDITY는 어느 풀도 줄이지 않습니다 (위 표 마지막 열).
엔진 코드도 같은 어휘입니다 — mortality_annual의 docstring은 “in-force
decrement”, 전이율은 waiver_incidence_annual / ci_incidence_annual처럼
_incidence 접미사.
1.3.1 탈퇴 — 보유계약 사망률#
엔진의 모든 cash flow는 한 가지 양에 비례합니다 — 그 시점의 보유계약 수
inforce. 그리고 inforce를 매월 줄이는 사망 입력이 보유계약 사망률
(mortality_annual, 곧 사망탈퇴율)입니다.
inforce[t+1] = inforce[t] × (1 - 보유계약사망률_월) × (1 - 해지율_월)
contract당 한 값. 어느 원인으로든 사람이 in-force에서 빠지는 전체
(all-cause) 율입니다. 사람이 죽으면 보험료 납입도 멈추고, 사업비도 멈추고,
만기금도 사라지고, 청구도 더 못 받습니다. 그래서 보유계약 사망률은 엔진
어디서도 비켜갈 수 없는 보편적 감쇠 — 보험료·사업비·만기금, 그리고 모든
보장의 청구가 같은 inforce에 묶여 함께 줄어듭니다.
basis = fcf.Basis(
mortality_annual = 0.012, # 보유계약 사망률 (all-cause). 스칼라 / 배열 / 표 / 콜러블 다 가능
...
)
워크북에서는 segments 시트의 mortality_table 컬럼이 가리키는
mortality_tables 시트가 이 입력의 출처입니다. 회사별·성별·연령별
all-cause 사망률 테이블 한 장.
이 한 슬롯이 가장 큰 가정입니다 — 보유계약 사망률을 +10% shock하면 거의 모든 cash flow가 함께 흔들립니다.
1.3.2 발생 — 사망보험금 발생률#
보유계약 사망률이 누가 남아 있는가 를 정했다면, 사망보험금의 지급액 을 계산하는 자리는 완전히 따로 있습니다 — 사망보험금 발생률.
생각해보면 그래야 합니다. 사람이 죽는 사건은 보유계약 사망률로 이미
inforce에서 빠지는 효과를 냈습니다. 그 사람에게 얼마의 사망보험금이
지급되느냐 는 별개의 질문 — 보장 약관, 면책·감액, 보험금액의 함수입니다.
그래서 엔진은 사망 보장의 청구를 그 보장에 묶인 별도 rate(사망보험금
발생률) 로 계산합니다.
사망보험금[t] = inforce[t] × 사망보험금발생률 × DEATH.benefit
이 발생률은 보유계약 사망률과 이름만 둘 다 “사망”일 뿐, 서로 다른 입력 슬롯입니다:
basis = fcf.Basis(
mortality_annual = ..., # 보유계약 사망률 (in-force 감쇠)
coverages = (fcf.CoverageRate("DEATH", rate_fn),) # 사망보험금 발생률 (청구)
)
워크북에서도 schema path가 다릅니다 — coverages 시트의 rate_table
컬럼이 가리키는 mortality_tables 또는 incidence_rate_tables 시트.
같은 워크북 안에서도 별개의 슬롯입니다.
중요한 비대칭: 사망보험금 발생률은 어떤 풀도 줄이지 않습니다. in-force를 줄이는 건 어디까지나 보유계약 사망률이고, 발생률은 그 위에서 지급액만 계산합니다. 이 “발생률은 풀을 안 줄인다”가 1.4의 반복급부(MORBIDITY)와 직접 이어집니다.
1.3.3 둘이 같은 숫자일 때#
가장 단순한 정기보험을 봅시다. 사망 보장이 일반사망(all-cause) 하나만 붙은 경우. 어느 원인으로든 사람이 죽으면 두 일이 동시에 일어납니다 — 보유계약 에서 한 명 빠지고(보유계약 사망률의 일), 그 사람에게 사망보험금이 지급됨 (사망보험금 발생률의 일). 같은 사건의 같은 빈도라 두 율이 자연히 같은 숫자가 됩니다.
같은 숫자이지만 여전히 두 개의 입력입니다. cookbook의 손계산 예제 (1.4 / 2.1)가 이 경우라, 두 슬롯에 같은 callable을 넘깁니다:
import fastcashflow as fcf
# 사망률 -- 월 사망률 1% 의 연 환산
death_rate = 1 - (1 - 0.01) ** 12
# 해지율 -- 해지 없음
lapse_rate = 0.0
basis = fcf.Basis(
mortality_annual = death_rate, # 보유계약 사망률 (all-cause)
lapse_annual = lapse_rate, # 해지율 (없음)
discount_annual = 0.03, # 할인율
ra_confidence = 0.75, # 위험조정 신뢰수준
mortality_cv = 0.10, # 사망률 변동계수
coverages = (fcf.CoverageRate("DEATH", death_rate),) # 사망보험금 발생률 (일반사망)
)
한 변수 death_rate을 두 슬롯에 공유합니다. “두 율이 같다” 는 사실을 코드에
명시하는 동시에, 한 쪽만 바꾸다 생기는 silent 어긋남이 구조적으로
차단됩니다.
1.3.4 둘이 다른 숫자일 때#
두 율이 명시적으로 달라지는 경우는 흔합니다. 핵심은 all-cause vs cause-specific 의 구분.
경우 1 — cause-specific 사망 보장 하나만 있을 때
사망 보장이 질병사망 / 재해사망 같은 cause-specific이면, 보장이 하나뿐이어도 두 율이 다릅니다.
mortality_annual = rate_all_cause # 보유계약 사망률 (all-cause)
coverages = (
fcf.CoverageRate("ADB", rate_accident), # 사망보험금 발생률: 재해사망만 (예: 연 0.3%)
)
보유계약은 어느 원인으로든 사람이 죽으면 빠지니까 보유계약 사망률은 all-cause(예: 연 1.2%). 하지만 사망보험금 발생률은 재해 사고로 죽은 경우만 — 발생률(0.3%)이 보유계약 사망률보다 훨씬 낮습니다. 두 율이 다른 숫자.
경우 2 — 다종 사망 보장이 함께 붙을 때
한 계약에 일반사망 + 질병사망 + 재해사망 세 보장이 함께 붙으면:
mortality_annual = rate_all_cause # 보유계약 사망률: all-cause (예: 연 1.2%)
coverages = (
fcf.CoverageRate("DEATH", rate_all_cause), # 사망보험금 발생률: 일반사망 (1.2%)
fcf.CoverageRate("DISEASE_DEATH", rate_disease), # 사망보험금 발생률: 질병사망 (0.9%)
fcf.CoverageRate("ADB", rate_accident), # 사망보험금 발생률: 재해사망 (0.3%)
)
사람은 한 번만 죽으므로 inforce는 보유계약 사망률(all-cause)로 한 번
감쇠. 그 한 번의 사망 사건이 여러 보장의 청구를 동시 트리거(재해로 죽으면
일반사망금 + 재해사망금 둘 다 지급). 두 cause-specific의 합(0.9 + 0.3 =
1.2)이 all-cause와 일치 — 같은 사망 사건의 원인별 분해라서.
보유계약 사망률을 보장 청구 식 안에 묶었다면 세 사망 보장 중 어느 하나의 율로만 in-force를 감쇠해야 했을 겁니다. 분리되어 있으니 감쇠는 contract 전체에 한 번, 청구는 보장마다 자기 발생률.
경우 3 — calibration 출처가 다를 때
같은 일반사망 보장이어도 두 율의 source가 다른 경우. 보유계약 사망률은 경험률표(실측 자료)로 calibrate, 사망보험금 발생률은 공시 표준 mortality table(규제 의무)로. 두 표가 다른 숫자라 두 슬롯도 다른 숫자.
1.3.5 손계산 입력 연결의 안전 패턴#
위 사례들이 fastcashflow가 두 입력을 분리한 이유입니다. 단순 정기보험 손계산은 두 값이 같지만, 두 슬롯에 별개의 값을 실수로 넘기면 결과가 silent로 어긋납니다.
잘못된 연결 |
결과 |
|---|---|
보유계약 사망률 = 0%, 사망보험금 발생률 = 1% |
in-force가 안 줄어 매월 사망보험금 청구 — MORBIDITY와 똑같은 메커니즘. 보험기간 내내 반복 청구되어 BEL 과대평가. |
보유계약 사망률 = 1%, 사망보험금 발생률 = 0% |
in-force는 줄고 사망보험금 없음. BEL 과소평가. |
두 패턴 모두 에러 없이 통과 — 조용히 어긋나는 함정. 한 변수 공유 패턴
(death_rate을 두 슬롯에)이 구조적 방어입니다. (위 첫 행이 곧 1.3.6의
“풀이 안 줄면 반복”임을 보여줍니다.)
워크북에서도 두 셀은 따로
fcf.read_basis("basis.xlsx")로 읽을 때도 두 슬롯은 다른 셀에서 옵니다 —
mortality_annual은 segments 시트의 mortality_table 컬럼, DEATH 담보의
발생률은 coverages 시트의 rate_table 컬럼. 로더는 둘을 독립적으로
조회하며 자동으로 잇지 않습니다. 두 율을 같게 하려면 두 셀에 같은
table_id를 적으면 됩니다 (둘 다 mortality_tables 네임스페이스를
공유하므로 같은 테이블로 해석됨). 손계산에서 death_rate을 두 슬롯에 공유한
것과 같은 선택을, 워크북에서는 셀로 하는 셈입니다.
1.3.6 풀로 보면#
이 “어떤 풀을 줄이는가” 관점이 다음 챕터(1.4)의 핵심을 미리 정리해 줍니다.
세 담보 모두 청구식은 inforce × 발생률 × benefit로 똑같고, “한 번이냐
반복이냐”는 그 발생률로 어떤 풀이 줄어드느냐 만의 문제입니다:
DEATH — “한 번”. 별도의 보유계약 사망률이 공유 in-force를 같은 율로 줄여, 죽은 사람이 다시 청구하지 못함. (사망보험금 발생률 자체는 풀을 안 줄임 — in-force를 줄이는 건 보유계약 사망률.)
DIAGNOSIS — “한 번”. 진단 발생률이 그 담보의 미진단 풀 을
(1 - 진단발생률)로 직접 축소. 한 번 진단받으면 그 풀에서 빠짐. (계약은 안 끝남 — 사람은 in-force에 남아 보험료 내고 다른 담보도 작동.)MORBIDITY — “반복”. 반복급부 발생률은 어떤 풀도 줄이지 않음. 공유 in-force만 보유계약 사망률·해지율로 줄 뿐이라, 살아있는 한 매월 새로 청구.
즉 셋의 차이는 청구 식이 아니라 발생률이 어떤 풀을 (또는 어떤 풀도 안) 줄이는가 입니다. 1.4 담보별 산출방법이 이 셋을 toy 예제로 한 페이지에 보여줍니다.