데이터 분석 기록용
연애 시뮬레이션 코딩하고 결과 확인하기 본문
뻘짓의 시작
청계천 피라냐와 인왕산 흑표범 밈이 도대체 어디서 나왔는지 알아보기 위해 블루아카이브 김용하PD 나무위키를 살펴보던 중 흥미로운 글을 보게 되었다.
본인에게 연애 기회가 총 10번까지 주어진다고 가정하는 경우에 처음 두 명은 버리고 세 번째 상대가 이전 두 명보다 나으면 찜하는 전략이 최적 해에 가까운 결과를 얻을 수 있다고 생각한다.
해당 글을 보고 드는 생각은 딱 두 가지 였다.
- 은근 설득력있는데 이거 진짜일까?? 그럼 3명까지 지켜보는 전략이 더 좋을 수 있는거 아냐?
- 코드 몇 줄 안나올 꺼 같은데 걍 한번 해보고 블로그 컨텐츠로 써먹어야지
하지만 시뮬레이션 작성은 금방 끝났지만 문서화가 몇 배나 더 걸린 것은 생각하지 못했다.
미소녀 없는 연애 시뮬레이션 코딩
- 해당 미없시의 전제 조건
- 한 사람 당 최대 만남의 횟수는 10회로 제한한다.
- 결혼을 하지 않고 연애만 할 인원의 수를 정한다. 해당 인원을 pass인원으로 표현한다.
- 각 사람의 매력도는 표준정규분포를 따른다고 가정한다.
- 결혼 대상자는 pass인원 내 최대 매력도보다 큰 사람을 만났을 때 결혼하며, 거절하는 경우는 없다고 가정한다.
- 만약 새로 만난 사람의 매력도가 pass인원 내 최대 매력도 보다 작은 경우는 그 즉시 헤어지고 새 사람을 만난다.
- 총 만남 횟수 내에서 pass인원 최대 매력도보다 큰 매력도의 사람을 만나지 못하면 결혼을 포기한다.
- 해당 시뮬레이션에서는 모두가 쿨한 성격의 순애주의자라 바람피거나 과거의 연인에게 돌아가는 경우는 없다.
import pandas as pd
import numpy as np
from scipy import stats
# 결혼 상대 찾기 n: 연애를 진행할 최대 횟수, passing_num: 연애만 할 상대의 수
def get_marrige_target(n=10, passing_num=2):
random_numbers = np.random.randn(n)
pass_max = max(random_numbers[:passing_num])
target = None
for i, j in enumerate(random_numbers):
if (target==None) and (j > pass_max):
target_num = i-passing_num+1 #연애만 할 상대를 pass한 이후 만남 횟수
target = j
break
if target == None:
#총 n번의 만남 중 연애만 생각했던 인원보다 더 나은 사람이 없는 경우 결혼 포기
target_num = 0
target = pass_max
best_bool = int(target == max(random_numbers))
return {'target_num':target_num, 'target':target, 'best_bool':best_bool}
if __name__ == '__main__':
std_norm = stats.norm(loc=0, scale=1)
df_result = pd.DataFrame()
#연애만 할 상대를 1~9명까지 시뮬레이션
for pass_num in range(1,9):
li=[]
# 연애만 할 상대의 수가 바뀔때 마다 1만번 시행
for i in range(10000):
li.append(get_marrige_target(n=10, passing_num=pass_num))
df = pd.DataFrame(li)
df_agg = df.groupby("target_num").agg({'target':['mean','count'],'best_bool':'mean'})
df_agg['cdf'] = df_agg['target']['mean'].apply(std_norm.cdf)
df_agg['passing_num'] = pass_num
df_result = df_agg if df_result.size==0 else pd.concat([df_result,df_agg])
df_result = df_result.reset_index()
df_result.columns = [''.join(col) for col in df_result.columns.values]
위 시뮬레이션은 pass인원을 1명에서 9명까지 순차적으로 증가시키고, 각 pass인원 케이스 별로 총 1만번 시뮬레이션을 실행한 결과를 집계하는 형식으로 작성되었다.
해당 시뮬레이션의 결과예시는 아래와 같이 생성된다.
target_num (pass 이후 만남 횟수) |
targetmean (매력도 평균 Z-Value) |
targetcount (결과 횟수) |
best_boolmean (최적 배우자 매칭 확률) |
cdf (매력도 평균 누적확률) |
passing_num (pass인원) |
0 (결혼 포기) |
1.575574 | 1002 | 1.000000 | 0.942438 | 1 |
1 (pass 이후 최초 만남에 결혼) |
0.573374 | 4961 | 0.201169 | 0.716804 | 1 |
2 (pass 이후 2번째 만남에 결혼) |
0.827938 | 1627 | 0.292563 | 0.796147 | 1 |
3 (pass 이후 3번째 만남에 결혼) |
1.019485 | 867 | 0.393310 | 0.846014 | 1 |
시뮬레이션 결과
1. pass인원 이후 각 연애 회차 별 결혼 현황
처음에는 pass인원 이후 최초 만남에서 결혼 대상자가 매칭되는 경우가 제일 많았으며 만남 횟수가 많아지며 급격히 감소한다.
특히 4회 이상 만남 횟수가 증가 할 경우 큰 변화가 없는 것으로 보인다.
하지만 결혼 횟수가 많다는 것은 pass인원의 매력도 최대치보다 높은 사람을 만난 것이며 해당 결과가 최선인지는 알 수 없다.
따라서 결혼 대상자 만남 횟수 기준으로 최선 배우자 매칭 확률을 시각화해봤다.
2. 결혼 대상자 만남 횟수 기준 최적 배우자 매칭 확률
우선 눈에 띄는 점은 pass인원이 많아질수록, 각 만남 횟수 별로 최적 배우자 매칭확률은 약 10%p 씩 정량적으로 상승하는 것을 알 수 있다.
다만 해당 통계의 특징은 경우의 수 문제를 통해 설명가능하다.
pass인원이 1명 일때 1번째 만남에서 최적 배우자 매칭 확률을 계산하면 아래와 같다.
- 전체 경우의 수 : 전체 인원 10명에서 2명을 뽑는 경우의 수와 동일, $$ {}_{10}{\rm C}_{2} = \frac{{}_{10}{\rm P}_{2}}{2!} = 45 $$
- 최적 배우자 매칭 경우의 수
- 1번째 뽑히는 사람은 pass인원에서는 최적 배우자를 제외한 9명 중 1명 뽑는 경우의 수 $ {}_{9}{\rm C}_{1}$
- 2번째 뽑히는 사람은 10명 중 매력도가 제일 높은 최적 배우자가 고정
- $ {}_{9}{\rm C}_{1} * 1= 9 * 1 = 9 $
- 최종 계산
$$prob=\frac{9}{45} = \frac{1}{5} = 0.2$$
해당 값은 실제 시뮬레이션 결과값과 상당히 근사하는 것으로 나오며 다른 경우에도 위의 계산식에서 조금만 바꿔서 계산할 수 있다.
위에서 계산한 데이터의 문제점은 만남의 대상이 랜덤으로 매칭이 된다는 점이다.
일반적으로 현실에서 이성을 만나다 보면 보통은 이전에 만났던 사람보다 나은 점이 있는 사람과 만날려고 노력한다.
따라서 단기적으로 판단한 매력도가 떨어진다면 아예 만나지 않는 경우가 빈번하게 나온다.
하지만 위 시뮬레이션에서는 "우선 만나보고 별로면 헤어진다."라는 대전제가 깔려있기 때문에 산술적으로는 맞지만 현실과는 괴리가 있는 통계가 나올 수 밖에 없는 것이다.
3. 그렇다면 결혼에 성공했을 시 평균적인 매력도 어떻게 될까?
만약 pass인원 없이 무작위로 만난 사람과 결혼하게 된다면 얼마나 매력적인 사람과 결혼하게 될까?
현재 시뮬레이션에서 매력도는 표준 정규분포를 따르기 때문에 배우자의 평균 매력도 누적확률은 50%에 수렴할 것이다.
결혼에 성공한 경우 배우자의 평균 매력도 누적확률은 최소 70%로 50%에 비해 약 20%p 이상 차이가 나는 것을 확인 할 수 있다.
또한 전체적으로 평균 매력도 누적확률은 로그함수 형태를 가지고 있는 것을 알 수 있으며 pass인원이 많아질 수록 완만하게 증가하는 형태임을 알 수 있다.
다시 처음으로 돌아가서 김용하PD가 말한 것 처럼 처음 n명은 버리고 n+1 상대가 이전 인원보다 나으면 찜하는 전략은 과연 배우자의 매력도에 얼마나 영향을 미치는지 알아보기 위해 pass인원 이후 첫 만남에서 결혼에 성공한 경우, pass인원 변화에 따른 매력도 데이터를 확인해 봤다.
아까 확인한 바와 같이 pass인원이 1명인 경우 무작위로 상대를 만났을때 보다 약 20%p 높은 것을 확인 할 수 있다.
이후 급격하게 변화량이 급격하게 감소하며 pass인원이 4명 이상인 경우는 증가량이 거의 없는 것을 확인 할 수 있다.
여기서 한가지 떠오르는 생각이 있다. "그래도 조금씩이라도 오르니까 pass인원을 무조건 많이 보면 좋은 거 아닌가?"
해당 의견에 대해서는 두 가지 반박 의견이 있다.
- 이거는 시뮬레이션이지 실제 연애가 아니다. 어지간히 외모에 자신이 없다면 연애 한번 더 하는 것이 쉽지 않은 현실이다.
- 해당 시뮬레이션의 가장 큰 주의사항은 pass인원을 만나는 동안 최적 배우자를 만나게 된다면 오히려 결혼 실패로 이어진다.
여기서 두 번째 이유는 현재 전략에서 가장 치명적인 위협인 결혼 실패로 직결되는 원인으로 볼 수 있다.
다음으로는 pass인원이 증가함에 따라서 결혼 실패 건수가 얼마나 증가하는 지 알아보고자 한다.
4. pass인원의 증가에 따른 결혼 실패
위에서 볼 수 있듯이 결혼실패율은 pass인원 증가분에 정비례하여 증가한다.
정리하자면 pass인원 수에 따른 결혼실패율과 첫 만남에 결혼한 배우자의 매력도의 기대값은 Trade-Off 관계에 있다고 볼 수 있다.
두 수치가 Trade-Off관계에 있더라도 pass인원 증가분에 따른 각 변수의 변화량은 차이가 존재하는 것을 알 수 있다.
결혼실패율은 비교적 꾸준히 증가하는 방면 첫 만남에서 결혼한 배우자의 매력도는 초반에는 급격하게 증가하지만 뒤로 갈 수록 증가율이 완만해지는 것을 알 수 있다.
개인적으로 생각하는 가장 무난한 판단은 pass인원을 1명만 두는 케이스가 아닐까 생각한다.
가장 적은 실패 가능성을 가졌으며 pass인원이 더 증가했을 때 상승하는 배우자의 매력도는 결혼실패율 증가량 보다 크지 않기 때문이다.
첫 만남 배우자 평균 매력도와 결혼실패율 간 차이를 통해 보정된 매력도 변수를 생성하여 시각화해 봤을 때 실제로 pass인원을 1명만 두는것이 가장 차이가 크게 나타났다.
다만 pass인원을 2명을 두는 케이스 또한 1명일 때와 비교하여 큰 차이가 없는 것는 것을 확인 할 수 있었다.
이런 상황이라면 좀 더 안정적인 선택을 원한다면 1명, 조금 덜 안정적이고 비용이 더 들더라도 매력도가 높은 상대가 필요하다면 2명을 선택하는게 합리적인 선택이 될 수 있을 듯 하다.
5. 얼마나 잘난 사람을 pass해야 결혼 실패 케이스가 나올까?
마지막으로 정리할 내용은 해당 시뮬레이션의 최대 위협에 대해서 알아보고자 한다.
앞서 언급했듯이 pass인원 중에 자신이 만날 수 있는 10명 중 최고 매력도 인원이 존재한다면 그 즉시 결혼실패로 이어진다.
시각화 결과 pass인원 케이스 별로 큰 차이 없이 비슷한 수치인 하위 93%, 상위 7% 수준을 유지하는 것으로 나타났다.
이 수치는 사실상 시뮬레이션에서 만날 수 있는 매력도의 사실상 한계치로 이해 할 수 있다.
한가지 흥미로운 점은 상위 7%의 수치는 수능 등급으로 쳤을때 2등급 중간 수준으로 볼 수 있다는 점이다.
온라인에서는 수능에서 2등급 맞았다고 하면 다양한 훈수가 오가지만 시뮬레이션에서는 2등급 상대방도 만나기 힘들다는 결과가 나오는 것이 재미있는 점이였다.
결론
어쩌다 청계천 피라냐에서 부터 여기까지 오게 된 것인지는 모르겠지만 김용하PD의 아이디어 덕분에 재밌는 시뮬레이션을 분석 할 수 있었다.
사실 시뮬레이션을 분석하면서 생각한 결론은 pass인원을 몇 명 설정하는 것이 중요한 것이 아니라고 생각했다,
pass인원을 설정한다는 것인 기본적으로 사람을 만날 때 필요한 기준을 만드는 행위로 이해 할 수 있었다.
그리고 오히려 그 기준이 너무 높은 경우 좋지 않은 결론이 날 수 있다는 것 또한 알 수 있었다.
따라서 과하지 않는 적절한 기준을 세우고 사람을 만나는 것이 아무 기준이 없는것 보다 더 나은 결과를 가져올 가능성이 높을 것이다.
그 전에 오프라인 세계로 나가는 것이 먼저다.
'데이터 분석' 카테고리의 다른 글
ChatGPT assistant API + Streamlit 사용후기 (0) | 2024.03.24 |
---|---|
첫 데이터 로그 설계 실무와 그에 대한 퇴고 (1) | 2024.03.23 |
A/B Test와 P-value, 그리고 가설검정 (1) | 2023.05.10 |
모바일 앱 제품 내 지표분석 예시 (0) | 2023.05.04 |
A/B Test 기초 (0) | 2023.04.28 |