회귀와 분류의 기본모델을 살펴보았다면 이제는 앙상블기법의 기본과 해당 하위개념인 배깅방법을 적용한 랜덤포레스트 그리고 부스팅을 알아볼 차례이다. 머신러닝에서 가장 성능 높다고 평가받는 모델의 기초가 된 개념을 알아보자.


1. 글목차

  • 6.3.1. 배깅
  • 6.3.2. 랜덤포레스트
  • 6.3.3. 변수 중요도
  • 6.3.4. 하이퍼파라미터
  • 부스팅

2. 본문

 

2.1. 배깅

배깅의 이미지

늘 데이터분석은 데이터가 문제다. 오리지널 데이터는 작고 소중하다(?) 반면 데이터가 적은 경우가 있다. 이경우를 보완하기위해서 부트스트래핑이라는 방법이 첫 번째 등장했다. 부트스트래핑이란 복원추출을 통해서 기존 데이터와 유사하지만 다양성을 보장하기 위한 방법론이다. 해당 하는 데이터를 이용하여 모델에 적용하고 결과 값을 합치면 Bootstrapping + Aggregating  즉 Bagging이 된다. 배깅은 1994년 레오 브레이먼이 처음 발표하였다.

2.2. 앙상블

사실 배깅을 적용하기 전 다수결의 원칙을 적용한 사례는 1906년 통계학자 프랜시스 골턴에 의하여 제안되었다. 수소의 무게를 맞추는 대회가 진행 중에 800명이 다양한 예측을 내놓았는데 예측의 평균 값이 실제 수소 무게의 1% 오차로 근접하였다. 이처럼 개별 모델로 예측하는 것이 아닌 여러가지 모델의 값을 종합해서 하나의 모델처럼 사용하는 것을 앙상블 모델이라고 한다. 

프랜시스 골턴

프랜시스 골턴은 재밌게도 후에 생물학적 현상인 후손들의 키가 조상들의 키의 평균으로 회귀한다는 발견으로 회귀분석을 제안하게 된 사람이다.

 

2.3. 랜덤포레스트

전에 다뤘던 트리모델은 간단하고 명확하다. 의사결정을 하듯 분기마다 변수들에 대한 구분을 하여 계속 모델을 신장시키기 때문이다. 하지만 단점이 존재하는데, 매번 분기를 선정하는 기준이 달라질 수 있다. 어떤 변수를 처음에 선정하여 트리를 만드냐에 따라 하위 분기가 매번 달라지기 때문이다. 이러한 특징 때문에 모델의 불안정성과 과대적합 이슈가 바로 트리 모델의 문제라고 잘 알려져 있다.

과소적합, 적절, 과대적합

 

이런 제한점 때문에 트리에 배깅을 적용한 랜덤포레스트 모델이 탄생했다.  여담이지만 빅데이터 분석기사의 2유형이 머신러닝 중 지도학습을 푸는 문제인데,  현재 8회까지 2유형은 랜덤포레스트로 하면 망하지 않는다 라는 속설이 있을 정도이다. 그만큼 강력하고 어느 분야에서나 예측한다면 기본적으로 사용되는 모델이라 할 수있다.

랜덤포레스트의 형상화

 

2.4. 부스팅

부스팅은 배깅과 함께 모델을 앙상블 형태로 만드는 기법 중 하나로, 모델이 갖는 오차를 줄이는 방식으로 모델을 연속적으로 생성한다.  배깅은 튜닝이 거의 필요 없어 범용성이 좋은 반면 부스팅은 그렇지 않다. 

 

자동차에 비유하자면 배깅은 신뢰할 수 있고 안정적인 혼다 어코드와 같고
부스팅은 강력하지만 더 많은 주의가 필요한 포르쉐와 같다.

 

대표적으로 자주 사용하는 방법은 XGBoost 이다. 부스팅은 하이퍼 파라미터 튜닝이 중요한 작업 중 하나인데,  하이퍼파라미터는 모델의 손잡이와 같은 기능을 하는 것이다. XGBoost에서는 subsample과 eta가 중요한 파라미터이다. subsample은 각 반복 구간마다 샘플링할 입력 데이터의 비율을 조정하는 것이고, eta는 부스팅 알고리즘에서 $\alpha_{m}$ 에 적용되는 축소 비율을 결정한다.  특히 eta는 가중치의 변화량을 낮추어 오버피팅을 방지하는 효과가 있다. 

 

1. 책 목차

  • 6.2. 트리모델
  • 6.2.1. 간단한 예제
  • 6.2.2. 재귀 분할 알고리즘
  • 6.2.3. 동질성과 불순도 측정하기
  • 6.2.4. 트리 형성 중지하기
  • 6.2.5. 연속값 예측하기
  • 6.2.6. 트리 활용하기
  • 6.3. 배깅과 랜덤 포레스트
  • 6.3.1. 배깅
  • 6.3.2. 랜덤 포레스트

2. 본문

트리는 기본적으로 if-else로 이루어지는 구조로 성장한다. 트리(tree,나무)라는 표현을 쓰는 이유는 의사결정과정이 나무가 뻗어나가는 모양과 유사하기 때문이다. 시작하는 변수를 Root 노드(뿌리 노드)라고 하며 마지막 노드를 Leaf 노드(잎 노드)라고 한다. 

그렇다면 어떤 변수부터 시작하여 분기해가야하는가? 오늘은 분기를 나눌 때의 기준인 정보이득과 엔트로피를 알아보자. 

2.1. 엔트로피

첫번째로 엔트로피 개념이 등장한다. 열역학에서 무질서도로 해석되는 엔트로피는 통계학에서는 사뭇다르다.  정보엔트로피(Information Entorpy)는  주어진 확률 분포에서 발생할 수 있는 불확실성의 양을 측정하는 개념이다. 이는 미국의 수학자이자 전기공학자인 클로드 새년이 정의하였다. 

정보 엔트로피는 다음과 같이 정의된다. 

$H(X) = - \sum ^{i=1} _{n}{P(x_{i})\log_{b}{P(x_{i})}}$

  • $H(X)$는 랜덤 변수 $X$ 의 엔트로피
  • $P(x_{i})$는 랜덤 변수 $X$가 값 $x_{i}$를 가질 확률
  • $b$는일반적으로 2가 사용 됨(bit개념)
  • $n$는 가능한 사건의 수 

위 값이 높을 수록 시스템의 불확실성이 크다는 것이다.  예시를 들면 다음과 같다. 

동전을 던지는 경우

  • 앞,뒷면이 나올 확률은 0.5
  • 엔트로피 $H(X) = -(0.5\log_{2}{0.5} + 0.5\log_{2}{0.5}) = 1$

반면 주사위를 던지는 경우

  • 각 면이 나올 확률은 $1/6$
  • 엔트로피  $ H(X) = -\sum^{6}_{i=1}{\frac{1}{6}log_{2}}\frac{1}{6} = \log_{2}{6} = 2.585 $

따라서 값이 더 큰 주사위를 던지는 경우가 더 불확실성이 크다고 할 수 있다

2.2. 지니계수

지니계수는 노드의 불순도를 측정하며 더 낮을수록 더 순수하다는 것이다. 따라서 지니 계수를 사용하여 불순도가 낮아질수록 트리를 올바른 방향으로 성장시킬 수 있다. 식은 다음과 같다

$ G(t) = 1 - \sum^{C}_{i=1}{p(i)^{2}} $

  • $C$는 클래스 수 
  • $p(i)$는 노드 $t$에서 클래스 $i$에 속하는 데이터 비율 

 

2.3.정보이득

두 개념을 합쳐서 결국 트리가 추구하는 방향은 분기를 나눴을 때 정보이득(Infomation Gain)이 최대화 되는 방향으로 가는 것이다. 정보이득은 어떤 변수로 분할을 했을 때, 계산되는 불확실성의 차이이다. 엔트로피의 경우 다음과 같이 작동한다.

  1. 전체 데이터셋 엔트로피 계산
    • $ H(D) = - \sum^{n}_{i = 1}{P(c_{i})\log_{2}{P(c_{i})}} $
    • $D$는 전체 데이터셋, $c_{i} 각 클래스$
  2. 속성별 엔트로피 계산
  3. 정보이득 계산
    • 이때 정보이득은 분할전 엔트로피와 분할 후 엔트로피의 차이 
    • $IG(A) = H(D) - H(D|A)$

 

1. 책 목차

  • 6.1. k-최근접 이웃
  • 6.1.1. 예제: 대출 연체 예측
  • 6.1.2. 거리 지표
  • 6.1.3. 원-핫인코더
  • 6.1.4. 표준화(정규화, z점수)
  • 6.1.5. k 선택하기
  • 6.1.6. KNN 통한 피처 엔지니어링

 

2. 본문

머신러닝알고리즘을 설명할 때 나는 딱 2가지 알고리즘 중에 하나를 선택해서 설명을 시작한다. 첫 번째는 중학교 때 배웠던 일차방정식을 적용할 수 있는 선형회귀 그리고 유유상종의 원리를 이용한 k-최근접 이웃 방법(KNN).  사실 선형회귀를 시작으로 머신러닝을 설명하는 것은 어느 책이나 동일할 것이다. 반면 KNN부터 설명하는 책은 박해선님의 혼자공부하는머신러닝+딥러닝 에서 발견했는데 이런 시작 방법도 좋다고 생각한다.
그런의미에서 k-NN은 꽤나 애정이 가는 알고리즘이기도 하고 지금은 일기장에 된 네이버 블로그에도 첫 번째 알고리즘으로 작성한 바가 있다.
https://blog.naver.com/bellepoque7/223041890630

 

[글또] 분석알고리즘(머신러닝, 딥러닝) 간단 정리해보기 1편

1. 글의 목적 해결하려는 문제가 정의 되어있다면, 분석 방법론을 알고 방법론의 가정, 결과, 장단점 고려...

blog.naver.com

 
 
2.1. KNN


어떤 사람의 연봉이 궁금하면 직접 물어보는 방법 말고 어떻게 추측해볼 수 있을까? 주변 사람들의 연봉 수준을 물어볼 수도 있을 것이고  그 사람의 직군을 안다면 해당 직군의 평균연봉을 알면 어느정도 유추할 수 있을 것이다. 이처럼 예측하려는 값 추측하는 쉽고 합리적인 방법 k-최근접 이웃 방법(KNN)이 있다.  이름 그대로 이웃의 데이터를 이용해서 예측한다는 idea를 가지고 있다. 또한 k에 대한 설명을 추가적으로 하자면 다음 그래프를 보자 
KNN방법은 다음 시각화 그래프가 너무도 유용해서 한번 더 쓸까한다.

KNN의 유용한 예시

 
?의 클래스 분류를 위해서는 주변의 데이터를 이용해서 예측한다고 했다. k는 이웃의 갯수이고 k=3이라면  ?는 세모로 예측하는게 합리적이며 k=7이면 별이라고 예측하는게 합리적일 것이다. 그럼  k는 어떻게 정하냐고 그건 이제 분석가의 일이 된다. 여기서 중요한 개념인 하이퍼파라미터를 함께 설명할 수 있다.  하이퍼 파라미터는 알고리즘에서 분석가들이 조정할 수 있는 파라미터를 뜻한다.  


그럼 다시 돌아와서 k는 어떻게 정할까? 분류의 경우 정확도나 f1-score와 같은 지표를 이용해서 합리적인 평가가 나올 때 까지 k를 실험을 통해 최적의 값을 도출할 수도  도메인 지식에 따라서 정할 수도 있다. 이게 무슨말이냐면, 만약 아파트에 어떤사람이 직업을 가지고 있느냐 아니냐를 분류하는 문제를 볼 때 주변사람을 몇 명 관찰해야할까?

아주 주관적이지만 내 생각에는 해당 단지의 사람들만 봐도 좋을 것 같다. 이유인 즉슨 보통 직업을 가지고 있으면 가족을 형성했기 마련이며 큰집에 사는 경향이 많아서 k=1000명 정도만 잡아도 좋을 것 같다. 
그럼 반문해볼 수 있을 것이다. 아니지 직업이 없으니까 가족에 얹혀사는 사람일 수 도 있지 않을까? 그럼 위 가정이 틀릴 수 있을텐데?  그러면  일반 아파트가 아닌 신혼희망타운과 같은 데이터로 관점을 옮긴다면? 좀 더 합리적인 추론이 될 것이다.  굉장히 뇌피셜이지만 한번 검증해볼만 한 가설이라고 생각한다. 이렇듯 k의 선정하는 근거는 도메인지식과 실험을 통해서 검증해야하는 파라미터이며 이를 근거있게 수립하는 것이 데이터 분석가가 하는 일이라고 할 수 있겠다. 

 
2.2. KNN - 거리지표

최근접이웃 이라는 말마따나 거리가 중요한 측정 수단이다. 거리가 나온다면 가장 중요하게 진행되어야하는 과정이 바로 정규화이다. 사실 KNN뿐 아니라 거리기반의 알고리즘은 정규화를 진행해야한다.  쉽게말해서 단위통일이 필요하다. X 값들의 단위는 천차만별이다. 연봉이 X변수이면 0부터 10억까지 있는 반면, 나이는 0부터 100세까지 있다. 단위가 달라서 이를 통일화 시키는 과정을 정규화라고 한다. 일반적으로 해당하는 값에 평균을 빼고 표준편차를 나누는 정규화를 실행한다. 

$Z = \frac{X-\mu}{\sigma}$

이렇게하면 데이터의 평균이 0 이고 퍼져있는 데이터 분포를 가질 수 있다. 반면 정규화가 데이터 분포를 변화시키는 것이 아님을 명심하자. 그러니까 left-skewed되어있다고 정규화를 실행하면 그대로 똑같은 분포형태를 가진다. 이런 경우 log scale 변형이 더 유효하다.

 

2.2.1. 거리지표 - 마할라노비스 거리 
 

거리지표는 피타고라스정리로 쉽게 이해할 수 있는 유클리드거리,  각 지표간 값의 절대차이 값을 이용한 맨해튼 거리가 유명하다. 

유클리디안 거리 : $d_E(\mathbf{x}, \mathbf{y}) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2}$

맨하튼 거리 : $d_M(\mathbf{x}, \mathbf{y}) = \sum_{i=1}^{n} |x_i - y_i|$

오늘은 마할라노비스 거리를 한번 정리해보자 한다. 공돌이의 수학노트 마할라노비스 거리 블로그를 참조하였다.

다음 두 분포를 보자

좌측과 우측의 x,y 벡터는 거리가 같을까?

좌측은 데이터가 중심쪽에 모여있는 형태에 x,y 점을 표기한 것 우측은 좀 더 넓게 분포가 있는 형태이다. 이럴때 x와 y의 거리는 두 데이터 분포에서 같다고할 수 있을까?  실제로 유클리드 거리 그러니까 직선의 거리는 똑같다. 반면 마할라노비스 거리는 데이터의 맥락에 따라 좌측 (a) 그래프에서 두 점이 더 멀다는 것을 표현하고 싶다. 

하지만 "맥락"이라는 것은 수학적이지 않다. 이 맥락을 수식화 하기 위해서는 단위의 통일이 필요할 텐데, 이 때 다시 등장하는 것이 정규화와 표준편차개념이다. 

표준편차에 따른 등고선 표시

 

이렇게 보니 더욱 (b) 그래프가 분포가 넓어보이는 것을 알 수 있다. 그럼 (b) 산점도를 정규화를 통해서 (a) 산점도 처럼 바꿔볼 수도 있을 것 같다. 이를  선형대수에서 '선형변환' 이라고 한다. 

 

(좌)선형 변환 전 (후) 선형변환 후

동일한 그래프인데 좀 더 선형변환을 직관적으로 표현할 수 있는 산점도이다.  좌측 그래프에서는 노란색과 빨간색 점들 사이의 직선의 거리(= 유클리드 거리)는 같다. 반면 데이터의 맥락(퍼저있는 정도)를 고려하여 정규화 하여 선형변환하면  빨간색 점들의 거리가 더 가깝게 된다. 이 방법을 적용한 것이 마할라노비스 거리이다.

$ d_{z} = \sqrt{(x-y)\sum^{-1}((x-y)^{T}} $

중간식의 $\sigma^{-1}$ 는 공분산의 역행렬로 공부산 행렬은 데이터 변수간의 분산의 정보를 포함하여 정규화하는데 사용되며 변수들 간의 상관관계를 표현할 수 있어 사용한다. 예를들어 다음과 같은 2x2 공분산 행렬이 있다고 하면 의미는 다음과 같다. 

공분산 행렬의 의미

위 내용은 공돌이의 수학노트 마할라노비스유튜브 영상에서 더 자세히 볼 수 있다. 오늘도 공-멘

 

2.2.2. 그래서 마할라노비스 거리 어디다씀? 
 

유클리디안거리와 맨하탄 거리보다 마할라노비스 거리는 데이터의 공분산 구조를 반영하기 때문에 맥락을 고려한 거리를 측정할 수 있다. 특히 판별분석이나 주성분 분석가 같은 변수간 관계를 고려할 때나 이상치를 탐지할 때 효과적이라고 알려져져 있다. 

반면 데이터의 맥락을 반영한다는 점에서 좋은 거리지표로 보이지만 실제로는 공분산 행렬을 사용하기 떄문데 각 변수들이 독립적이지 않고 상관관계를 가질 때 유용하다. 사실 상관관계가 낮다면 마할라노비스와 유클리디안 거리는 크게 차이가 없다. 애초에 마할라노비스 거리가 데이터를 선형변환 한다음 유클리디안 거리를 측정하는 것이기 때문이다. 

1. 책 목차 

  • 5.5: 불균형 데이터 다루기
    • 5.5.1. 과소표본추출
    • 5.5.2. 과잉표본추출과 상향/하향가중치
    • 5.5.3. 데이터 생성
    • 5.5.4. 비용기반 분류
    • 5.5.5. 예측 결과 분석
    • 5.6. 마치며

2. 본문

불균형 데이터는 분류문제에서 굉장히 중요한 데이터 전처리 과정이라고 생각하지만 입문자들에게는 평가절하되는 면이 많다. 이유인 즉슨 Toy Project에서 제시되는 데이터는 일반적으로 전처리하는 과정에서 Class 불균형을 해결하고 오는 경우가 많기 때문이다. 그래서 실제로는 분류문제에서 중요한 방법이다. 하지만 그 처리 방법이 데이터마다, 산업마다 다르기 때문에 예시가 잘 없는 것일 수도 있다는 생각이다. 

 

2.1. 과소표본추출 방법: 가중치 적용

일반적으로  데이터가 많아 과소표본(Undersampling), 데이터 적어 과대표본추출(Oversampling)을 진행해야한다는 것이 알려져있지만, 본 책에서는 가중치 적용을 위한 방법론을 추가로 제시한다. 

default_wt = 1 / np.mean(full_train_set.outcome == 'default')
wt = [default_wt if outcome == 'default' else 1 for outcome in full_train_set.outcome]

full_model = LogisticRegression(penalty="l2", C=1e42, solver='liblinear')
full_model.fit(X, y, wt)
print('percentage of loans predicted to default (weighting): ', 
print(      100 * np.mean(full_model.predict(X) == 'default')))

예시 데이터는 대출상환에 대한 데이터로, outcome 변수는 default(미상환), paid-off(상환)에 대한 이진 분류클래스이다. 전체 데이터 중 대출상환을 하지 않은 비율은 19% 이다. 이를 역수처리하여 100/19 라는 가중치 비율을 만들어준다. 그리고 default 해당하는 클래스에 해당 가중치 값(5.26)이 적용된다.  이렇게하면 undersampling과 oversampling을 대체할 수 있다.  다음 책의 글귀가 마음에 든다.

 

어떤 자료에서는 손실함수를 수정하는 방법을 제안하기도 하지만 직접 손실함수를 수정하는 것은 복잡하고 어렵다. 반면 가중치를 적용하는 방법은 가중치가 높은 데이터를 선호하고 가중치가 낮은 데이터의 오류를 줄이는 식으로 손실함수를 변경하는 쉬운 방법이다.

 

2.2. 데이터 생성: SMOTE

실제 데이터를 마주하다보면 데이터의 갯 수가 적어서 데이터를 생성하는 방법이 제시되며 SMOTE 대표적으로 나온다. 발음은 [스모트] 라고 부른단다. Synthetic Minority Over-sampling Technique이라고 불리는데 말 그대로 소수 클래스의 데이터를 합성하는 oversampling방법 중 하나이다. 

아이디어는 다음과 같다. 

  1. 소수 클래스 데이터 선택: 소수 클래스의 데이터를 기준으로 가장 가까운 이웃(k-Nearest Neihgbors) 중 k 개의 데이터를 선택
  2. 새롭게 생성할 데이터 포인트 수 결정: N
  3. 새로운 데이터 생성: 선택된 k개의 이웃 중 하나를 무작위로 선택, 원본데이터와 이웃 데이터 사이의 선형보간을 통해 새로운 데이터를 생성, N번 반복
    ex) 새 데이터 = 데이터 + (이웃 데이터 - 원본 데이터)* 0~1사이의 랜덤

그럼 선형보간(Linear Interpolation)은 무엇일까? 공대에서도 잘 활용 되는 이 방법은 두 개의 주어진 점이 있다고 할때 직선 방정식을 이용하여 임의의 점을 추정하는 방식이다. 이런 맥락에서 알 수 있듯 SMOTE를 하기 위해서는 데이터가 인코딩(숫자형태)가 되어있어야한다.

선형보간의 예시

 

SMOTE의 장점은 단순하고 강력하며, 데이터의 특성을 잘 유지할 수 있는 반면 단점으로는 소수 클래스의 데이터 포인트가 이미 밀집되어 있는 경우 기존 데이터와 크게 variety를 기대할 수 없고 과적합(overfiiting) 문제가 발생할 수 있다. 

 

3. 마무리

여기까지 분류에 대한 연재를 마쳤다. 아무래도 회귀처럼 특정 숫자를 맞추는 것보다 Category를 나누는 분류의 문제가 더 확률적으로 높은 예측을 기대할 수 있고  활용범위가 좋기에 더 많은 평가방법과 활용 방법이 제시되는 것 같다.다음 단원은 회귀/분류에 사용되는 통계적 머신러닝 방법을 알아보겠다.

1. 생존분석이란

  • 시간-이벤트 데이터(예: 생존 시간, 고장 시간 등)를 분석하는 데 사용
  • 주요 목표는 생존 시간 분포를 추정하고, 생존 시간에 영향을 미치는 요인을 식별하며, 여러 그룹 간의 생존 시간을 비교하는것. 대표적인 방법으로 LogRank, 카플란-마이어 추정법, 콕스 비례위험 모형이 있다.

 

2.1. 카플란-마이어 추정법 (Kaplan-Meier Estimator)

  • 특정 시간까지 이벤트가 발생하지 않을 확률(생존 함수)을 비모수적으로 추정하는 방법
  • 각 시간 점에서 생존 확률을 계산하고, 이를 통해 전체 생존 곡선을 작성.
  • 사건이 독립적이라는 가정이 있지만, 실제로는 이 가정이 항상 만족되지 않을 수 있음(실제로 병은 누적되는 대미지가 있으므로)

$ \hat{S}(t) = \prod_{t_i \leq t} \left(1 - \frac{d_i}{n_i}\right) $

 

import pandas as pd
import matplotlib.pyplot as plt
from lifelines import KaplanMeierFitter

# 예시 데이터 생성
data = {
    'duration': [5, 6, 6, 7, 8, 8, 10, 12, 14, 15, 18, 20, 25],
    'event': [1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
}

df = pd.DataFrame(data)

# Kaplan-Meier Fitter 생성
kmf = KaplanMeierFitter()

# 생존 함수 적합
kmf.fit(durations=df['duration'], event_observed=df['event'])

# 생존 곡선 시각화
plt.figure(figsize=(10, 6))
kmf.plot_survival_function()
plt.title('Kaplan-Meier Survival Curve')
plt.xlabel('Time')
plt.ylabel('Survival Probability')
plt.grid(True)
plt.show()

  • 결과해석
    • 시간에 따른 생존율을 알 수 있음(25 시간 단위에 최저)
    • 중위 생존시간은 13 시간단위로 추정됨

 

3.1. Log-Rank test

  • 카플란 마이어 기법의 응용
  • 두 그룹 간의 시간에 따른 생존율 차이를 검정하는 방법
  • 각 시간 점에서 관찰된 사건 수와 기대 사건 수를 비교하여(카이제곱검정), 두 그룹의 생존 곡선이 통계적으로 유의미하게 다른지를 평가

 

$\chi^2 = \frac{(O_1 - E_1)^2}{V_1} + \frac{(O_2 - E_2)^2}{V_2}$

3.2. 실습

  • 예시 데이터

import pandas as pd
from lifelines import KaplanMeierFitter
from lifelines.statistics import logrank_test

# 데이터 생성
data = {
    'group': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'],
    'duration': [6, 7, 10, 15, 23, 5, 8, 12, 18, 22],
    'event': [1, 0, 1, 0, 1, 1, 1, 0, 1, 1]
}

df = pd.DataFrame(data)

# 두 그룹 나누기
groupA = df[df['group'] == 'A']
groupB = df[df['group'] == 'B']

# Kaplan-Meier Fitter 생성
kmf_A = KaplanMeierFitter()
kmf_B = KaplanMeierFitter()

# 생존 함수 적합
kmf_A.fit(durations=groupA['duration'], event_observed=groupA['event'], label='Group A')
kmf_B.fit(durations=groupB['duration'], event_observed=groupB['event'], label='Group B')

# Log-Rank 테스트 수행
results = logrank_test(groupA['duration'], groupB['duration'], event_observed_A=groupA['event'], event_observed_B=groupB['event'])
results.print_summary()

  • 시각화 코드
import pandas as pd
import matplotlib.pyplot as plt
from lifelines import KaplanMeierFitter

# 데이터 생성
data = {
    'group': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'],
    'duration': [6, 7, 10, 15, 23, 5, 8, 12, 18, 22],
    'event': [1, 0, 1, 0, 1, 1, 1, 0, 1, 1]
}

df = pd.DataFrame(data)

# 두 그룹 나누기
groupA = df[df['group'] == 'A']
groupB = df[df['group'] == 'B']

# Kaplan-Meier Fitter 생성
kmf_A = KaplanMeierFitter()
kmf_B = KaplanMeierFitter()

# 생존 함수 적합
kmf_A.fit(durations=groupA['duration'], event_observed=groupA['event'], label='Group A')
kmf_B.fit(durations=groupB['duration'], event_observed=groupB['event'], label='Group B')

# 생존 곡선 시각화
plt.figure(figsize=(10, 6))
kmf_A.plot_survival_function()
kmf_B.plot_survival_function()
plt.title('Kaplan-Meier Survival Curves')
plt.xlabel('Time (months)')
plt.ylabel('Survival Probability')
plt.legend()
plt.grid(True)
plt.show()

 

  • 결과해석
    • 테스트 통계량은 0.46 p-value는 0.50로 귀무가설(두 그룹 간의 생존 곡선에 유의미한 차이가 없다)를 기각하지 못함
    • 따라서 그룹 A와 그룹 B의 생존 시간이 통계적으로 유의미하게 다르지 않음을 결론 지을 수 있음

 

 

4.1. 콕스 비례 위험 모형 (Cox Proportional Hazards Model)

  • 카플란마이어 추정법은 사건이 독립적이라는 가정의 한계 따라서 시간에 따른 사건 발생 위험률(위험 함수)을 모델링
  • 공변량(독립변수)이 시간에 따라 비례적으로 위험률에 영향을 미친다는 가정
  • 기준 위험률와 공변량의 선형 결합을 지수 함수 형태로 결합하여 위험률을 표현
    • 기준위험률($\lambda_0(t)$): 시간 $t$ 기준 위험률로 공변량의 영향을 제거한 상태의 기본적인 위험률
    • 공변량(Covariates, $X$): 사건 발생에 영향을 미칠 수 있는 변수들
  • 시간-의존적 위험률을 모델링할 수 있으며, 공변량이 생존 시간에 미치는 영향을 평가하는 데 유용

 

$\lambda(t \mid X) = \lambda_0(t) \exp(\beta_1 X_1 + \beta_2 X_2 + \cdots + \beta_p X_p)$

4.2. 코드 전개

import pandas as pd
from lifelines import CoxPHFitter
import matplotlib.pyplot as plt

# 예시 데이터 생성
```
duration: 환자가 생존한 기간(개월 수)
event: 사건 발생 여부(1 = 사망, 0 = 생존)
age: 환자의 나이
treatment: 치료 방법(0 = 치료 A, 1 = 치료 B)
```
data = {
    'duration': [5, 6, 6, 7, 8, 8, 10, 12, 14, 15, 18, 20, 25, 5, 7, 12, 13, 14, 16, 20],
    'event': [1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
    'age': [50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 55, 60, 65, 70, 75, 80, 85],
    'treatment': [0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1]
}

df = pd.DataFrame(data)

# 콕스 비례 위험 모형 적합
cph = CoxPHFitter()
cph.fit(df, duration_col='duration', event_col='event')

# 모형 요약 출력
cph.print_summary()

# 생존 곡선 시각화
cph.plot()
plt.title('Hazard Ratios')
plt.show()

 

  •  결과해석
    • age 회귀계수는 -0.11 으로 나이가 증가할 수록 사건의 발생 위험 감소가 감소한다고 해석할 수 있음. 실제로는 exp(-0.11) = 0.89이므로 나이가 1년 증가함에 따라 사망확률이 약 10%씩 감소
    • treatment 치료여부는 회귀계수는 -1.41이로 치료를 받은 경우 사건 발생률이 감소한다는 것을 의미함.  exp(-1.11) = 0.24이므로 치료를 받은 경우 사망확률이 약 76%씩 감소
    • 그래프의 경우 x축은 로그 위험비(log Hazard ratio)를 뜻하며 위험비의 추정값을 말한다. 0보다 작으면 사망위험확률을 낮춰준다고 해석할 수 있으며  age, treatment는 모두 사건 발생비율을 감소시킨다. 
    • 신뢰구간의 경우 좁을 수록 신뢰도가 높은데 치료의 경우 신뢰구간이 매우 넓어 불확실성이 크다. 

5. 최종 정리

  • 생존 분석: 다양한 모델링 기법을 포함하는 광범위한 분야로, 시간-이벤트 데이터를 분석
  • 카플란-마이어 추정법: 특정 시간까지 이벤트가 발생하지 않을 확률을 추정하는 방법입니다. 사건이 독립적이라는 가정
  • Log-Rank 테스트: 두 그룹 간의 시간에 따른 생존율 차이를 검정
  • 콕스 비례 위험 모형: 시간에 따른 위험을 모델링하며, 공변량이 시간에 따라 비례적으로 위험률에 영향을 미친다는 가정을 기반

6. SQL 로 생존분석하기

https://www.crosstab.io/articles/sql-survival-curves/

 

Brian Patrick Kent - How to compute Kaplan-Meier survival curves in SQL

Decision-makers often care how long it takes for important events to happen.

www.crosstab.io

https://sticky-ai.github.io/survival%20analysis/2020/07/29/survival_analysis_kaplan_meier/

 

Survival Analysis. 카플란-마이어 추정 (Kaplan Meier Estimation)

생존 분석(Survival Analysis)는 시간의 흐름에 따른 어떠한 사건의 발생 확률을 알아보는 통계 분석 및 예측 기법 중 하나입니다. 일반적으로 의료분야에서 특정 수술 방법 혹은 치료 방법에 따른 환

sticky-ai.github.io

 

1. 목차

  • 5.3. 로지스틱회귀
  • 5.4. 분류모델 평가하기
    • 5.4.1 ~ 3. 혼동행렬, 분류문제, 정밀도, 재현율, 특이도
    • 5.4.4 ~ 5: ROC곡선, AUC  
    • 5.4.6. 향상도(lift)

 

2. 본문

늘 머신러닝을 배울 때 선형회귀만큼은 잘 이해가 된다. 선형직선은 중학교때부터 배웠기에 익숙하고 에러의 개념을 받아들이기도 어렵지않으니까.  하지만 이 로지스틱 회귀라는 놈은 늘 어딘가 2% 부족한 설명을 하게되는 경우가 많다. 왜그럴까? 일단 첫 번째 문턱은 바로 오즈비(odds ratio)에 대한 생소함이라고 생각한다.

 

2.1. 로지스틱 회귀

2.1.0. 나이브한 접근법

본격적으로 들어가기 전 선형회귀로 한번 이진 분류를 예측한다고 해보자. 

import matplotlib.pyplot as plt
import numpy as np

# Sample data
np.random.seed(0)
x_0 = np.random.normal(2, 0.5, 20)
x_1 = np.random.normal(8, 0.5, 20)
y_0 = np.zeros(20)
y_1 = np.ones(20)

# Linear regression line (for demonstration purposes, using a simple linear relation)
x = np.linspace(0, 10, 100)
y = 0.1 * x

# Plotting
plt.figure(figsize=(10, 6))
plt.scatter(x_0, y_0, color='blue', label='Class 0')
plt.scatter(x_1, y_1, color='red', label='Class 1')
plt.plot(x, y, color='green', label='Linear Regression Line')
plt.xlabel('Feature Value')
plt.ylabel('Probability')
plt.title('Example of Linear Regression in Binary Classification')
plt.legend()
plt.grid(True)
plt.show()

어떤가? 선형회귀가 해당 하는 값들을 잘 설명한다고 할 수 있을까?  할수는 있을 것 같다. 그런데 문제는 실제로 class =0, 1에 대한 값들이 X축의 Feature Value와 같이 딱딱 떨어지지 않는 다는 점이다. 또한  선형회귀의 Y값은 0과 1과 같이 출력값을 제한하는 장치가 전혀없다. 그러니까 다시말하면 최종 결과 예측값이 음수가 될수도 1이 넘을 수도 있다.이건 확률의 정의와 맞지 않다.

따라서 몇가지 로지스틱회귀를 위한 원칙을 세워보자 

  • 종속변수 Y값은 확률로 정의하고 0과 1사이 값을 출력하도록 제한할 것
    • 해당 값은 Y=1일 사건의 확률로 정의하자
  • 선형그래프보다 더 유연한 그래프 (예를들면 곡선)을 만들어 데이터를 잘 설명하는 선을 그을 것

단순한 요구사항 같지만 여기서부터 기존식을 약간 변형해야한다. 선형회귀 식은 다음과 같다는 점을 확인하고 좌변만 이렇게 저렇게 바꿔보도록 하겠다. 

$Y = \beta_0 + \beta_1X$

 

2.1.2. 오즈비(odds ratio)

오즈비라는 개념을 도입해보자. 오즈비라는 것은 다음과 같이 정의된다

$odds = \frac{p}{1-p}$

통상 오즈비라는 것은 실패대비 성공확률을 가르키는 도박사의 판단근거에서 왔다고 한다.예컨데 성공확률이 50%라면  0.5/0.5 = 오즈비는 1이다.  성공확률이 75% 라면 0.75/0.25 오즈비는 3이다. 아니 그럼 왜 실패 대비 성공비일까 하필? 사실 그냥 성공확률만 보고 도박을 걸면되는게 아닐까 라는 생각이 들었다. 한가지 합리적인 이유는 다음과 같다.

오즈비는 단순 성공확률이 아닌 실패와의 비율을 함께 포함하는 지표이다. 예컨데 질병발병확률이 매우 낮을때 (1%) 와 같이 극단적인 경우에도 쓸 수 있다는 것이다.

뭐 딱히 그렇게 와닿는 해설은 아니지만 어느정도 비율 실패비율과 성공비율을 동시에 표현한다는 점에서는 인정하는 바이다. 

 

2.1.3. 그렇다면 로그오즈비는 어떠한가?

오즈라는 값은 바로 사용하기 어려운 점이 있다. 확률$P$가 0에 가까워지면 0에 가까워지고 1에 가까워지면 과 무한대로 발산하는 지표이기 때문이다.

$odds = \frac{p}{1-p}$

같은 오즈-확률 그래프를 x-y축 전환한 모양

우리가 알고 싶은 값은 $P(Y = 1)$의 확률 값이다. 좌측 그래프처럼 Y축이 확률이 되었으니 잘 도시한거아니냐고? 다시 생각해보자 우리는 선형회귀에서 X축이 일반적으로 데이터값이 들어온다. 해당 데이터가 들어오는데 이렇게 극단적으로 치우쳐져 있으면 데이터를 잘 설명할 수 없게된다. 이것보다 더 완만한 그래프를 찾을 필요성을 느끼게된다. 

 

우리가 그래서 나온 것이 오즈비에 로그를 씌운 로그오즈비이다. 우리가 알고 싶은 정보는 특정 클래스로 분류될 확률 $P(Y = 1)$이다. 오즈비를 바로 Y 값으로 쓴다면 적절하지 못하다. 

$ 로그 오즈비(L) = log(\frac{p}{1-p}) $

위 식을 다시 도시하면 다음과 같다.

$ p = \frac{e^L}{1 + e^L} $

이제 $P(Y= 0)$ 때와 $P(Y=1)$일때를 각각 설명할 수 있는 유선형의 로지스틱함수가 완성이 되었다. 우리는 로그오즈를 이용하여 선형회귀의 우측 식을 차용할 것이다. 쉽게 말해서 회귀계수로 표현할 것이다. 

$ \log\left(\frac{p}{1-p}\right) = \beta_0 + \beta_1X_1 + \beta_2X_2 + \dots + \beta_nX_n $

이식은 어떤 뜻일까? X 독립변수가 들어오면 우변의 값이 계산이 될 것이고. 어떤 값이 들어오든 0과 1사이에 진동하는 Y축의 값을 만든다는 것이다. 다시 말해 모델이 이미 완성되었다고 할 때, X값이 들어오면 $P(Y=1)$이라는 확률 값을 예측할 수 있다.

2.1.4. 로지스회귀의 적합방법

식은 어느정도 이해했다고 하자 그럼 로지스틱회귀는 어떻게 학습되는가에 대한 궁금증이 생긴다. 선형회귀의 경우는 RMSE라는 지표를 설정하여 그 값을 최소화 하는 식으로 회귀계수 $\beta$를 조절해왔다. 하지만 로지스틱회귀는 좌변이 로그오즈비이니 조금 복잡할 것으로 보인다. 

로지스틱회귀는 선형회귀와 달리 확률을 예측하는 모델이다. 그러니까 우리의 목적은 $\beta$를 움직이면서 발생할 가능성을 최대화 하는 파라미터를 찾아야한다. 여기서 난이도가 급상승하게 되는데 바로 우도 함수(Likelihood function)의 개념이 등장한다. 우도함수는 주어진 데이터 집합에서 모델의 파라미터를 평가하는 함수로 로지스틱 회귀의 경우 각 데이터에 대한 예측확률을 결합하여 전체 데이터 집합의 우도를 계산한다. 

$L_i = p_i^{yi}(1-p_{i})^{1-y_i}$

여기서 $y_i$는 종속변수 (이진결과), $p_i$는 에측된 성공확률, $L_i$는 우도이다. 

전체 데이터 집합의 우도함수는 개별 우도의 곱으로 정의한다는 점을 받아들이자

$L(\beta) = \prod_{i=1}^{N} p_i^{y_i} (1 - p_i)^{1 - y_i}$

여기서 $\beta$는 모델의 파라미터 벡터이다. 

우리는 로그 우도를 최대화하는 모델을 찾는것이 목적이였다. 하지만 실제로는 우도함수 그자체보다 로그 우도함수를 계산하는 것이 더 안정적이라고 알려져있습니다.

$\log L(\beta) = \sum_{i=1}^{N} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right]$

해당하는 파라미터 $\beta$를 찾기위해선 흔히 알고있는 경사하강법을 사용하거나 뉴턴-랩슨 방법같은 알고리즘을 사용하게 됩니다. 디테일은 생략!

 

2.2.1. 분류모델 평가지표: f1-score

선형회귀도 평가하는 지표로 RMSE, MAE 등을 사용했으니 분류모델도 평가모델이 있어야 할 것이다. 분류모델 평가는 되게 쉬워보인다. 바로 정확도(Accuracy) 전체 데이터 중에 맞춘 것에 대한 비율이다. 직관적이고 쉽다. 하지만 정확도는 맹점이 있는데 바로  실제로 음성인 것을 음성으로 예측하고 양성인 것을 양성으로 예측하는 2가지 지표를 동시에 고려해야한다는 점을 간과한다.  이는 혼동행렬(confusion matrix)를 보면 쉽다.

혼동행렬의 예시

Recall(재현율) 혹은 Sensitivity(민감도)이라는 값은 데이터에 관심을 가진다. 실제로 양성인 데이터 중 몇 개를 맞추었는가가 중점이다. 

$Re = \frac{TP}{(TP+FN}$

반면 정밀도(Precision)는 모델에 관심을 가진다. 실제로 예측한  중에 얼마나 맞추었는가가 중점이다.

$Pr = \frac{TP}{TP+FP}$

두가지 지표를 종합하여 조화평균을 이용하면 일반적으로 분류모델이 사용하는 f1 score 가 만들어진다. 여기서 조화평균은 평균을 내는 방법 중에 하나 인데, 산술평균($\frac{a+b}{2}$)는 하나의 지표가 크거나 작으면 전체 값이 흔들려 지표의 강건함이 약하다. 따라서 이를 보완하기 위한 조화평균을 사용한다.

$f1-score = 2*\frac{Pe*Pr}{Pe+Pr}$

2.2.2. ROC커브와 AUC

혼동행렬에는 하나의 지표가 더 있다. 실제로 음성인 것을 정확히 음성으로 분류한 비율 특이도(Specificity)이다. 

$Sp = \frac{TN}{TN+FP}$

사실 재현율과 특이도는 서로 trade-off 관계가 있다.  실제로 양성인 것중에 양성을 맞춘 비율(재현율)과 실제로음성인 것 중에 음성을 맞추는 비율(특이도)는 합리적인 시소관계가 성립할 것 같다. 그도 그럴 것이 양성으로 잘 예측 한다는 것은 음성을 양성으로 잘못 예측할 가능성도 높아진다는 말이기 때문이다. 따라서 이런 트레이드 오프 관계를 잘 설명하기 위한 지표가 ROC 곡선(receiver operating characteristic, 수신자 조작 특성) 이라고 한다. 

엥그런데 이상한 점이 있다. 그럼 같은 모델이여도 트레이드 오프가 있다는 것인가? 우리는  분류를 할 때 하나 중요한 개념을 제외하였다 바로 임계값의 개념이다. 우리는 $P(Y=1)$ 그러니까 클래스 1에 속할 확률을 도출하고 일정 값 기준이면 class 1 이라고 분류 그렇지 않으면 class 0 이라고 분류한다. 어떻게 할까? 아무래도 0.5로 기준을 잡는게 적절해보인다. 이를 임계값(threshold)혹은 cut-off라고 한다. 

그런데 말이다. 암 진단과 같은 경우에는 0.5라고 하는 비율이 그렇게 좋아보이지 않는다. 왜나면 일단 암과 같은 의증이 있기만 하면 정밀검사를 했을 때 소요하는 비용보다  암을 검진함으로서 얻는 이득이 훨씬 크기 때문이다. 따라서 양성을 판단하기 위한 기준을 더 낮게(임계 값을 낮게) 설정하여  더 케이스를 양성을 분류하여 재현율 혹은 민감도(참 양성비율)을 높이는 게 적절할 것이다. 

다시 돌아와서 같은 모델이더라도 임계 값 기준에 따라 지표 값이 달라질 수 있다. 이를 두루두루 보고자 하는게 ROC커브의 본질이라고 할 수 있겠다.

 

이 ROC 커브는  x축에는 1-특이도를 표기하고  y축에는 재현율 혹은 민감율을 도시하여 다음과 같이 표기한다. 중간에 가로지르는 빨간색 점선이 기준값이고  왼쪽 상단으로 그래프가 붙을수록 더 좋은 모델이다. 좌상단에 끝으로 붙으면 해당 적분면적 비율이 1이 될 것이다. 그렇다 면적을 ROC커브를 측정하는 지표로 보고 이걸 AUC(area undereath the curve)라고 한다. 

ROC 커브

그래프를 해석하기 위해서는 특정한 점을 고정해놓고 x축 / y축을 고정시켜놓고 이해하는게 좋겠다. 

각 선을 고정시킨 해석

  • X축은 1-특이도이다. 그러니까 좌측으로 갈수록 음성데이터를 잘 맞추는 것 우측으로 갈수록 음성 데이터를 더 잘 못 맞춘다는 것이다.
  • Y축은 재현율(민감도)이다 그러니까 위로 올라갈수록 양성 데이터를 더 잘맞춘다는 것이다.

 

위와 같은 이해가 있다고 할때 좌측 그래프의 가상의 초록색 선을 그어보자. 그럼 빨간선(기준선)의 4번 점보다 2번 점이 동일한 1-특이도 상에서 더 높은 재현율(민감도)를 가진다.  해석하자면 그래프는 위로 올라갈수록 좋다. 반면 우측그래프는 같은 재현율(민감도) 기준이라면 좌측으로 갈수록 특이도가 더 높다( X축은 1-특이도 이다) 다시 말해 왼쪽으로 붙을 수록 더 좋은 모델이다. 


이번엔 분포로 한번 확인해보자. 암에 걸리지 않은 환자와 이미 암의 걸린 사람들이 정규분포를 따른다고 가정을 하고 다음과 같이 확률밀도함수를 그렸다. 그리고 threshold는 굵은 검은선으로 표현하자. 구분이 명확해진다. 

False Positive라는 뜻은 암에 걸렸다고 판단했지만 실제로 암이 아닌 사람이며, True Positive는 암에 걸렸다고 판단했고 실제로 암인 사람들이다. 어떻게 되었든 우리는 threshold 낮춰 최대한 많은 사람들이  "아 그래도 검진 한번 받아 보시죠" 라고 권해야한다. 

암에 걸리지 않은 환자와 암환자에 대한 분포 그리고 thresh hold

 

위 그래프가 잘 이해가 안간다면 아래 움짤을 보면 너무나 이해가 된다. 공돌이 수학정리노트 짱

 

threshold가 움직임에 따라 ROC커브의 움직임을 표현하면 다음과 같다. 

threshold선 == 빨간점

더 자세한 설명을 듣고 싶으면 공돌이 님의 블로그를 참고해보자

공돌이의 수학정리노트 - ROC 커브

 

ROC curve - 공돌이의 수학정리노트 (Angelo's Math Notes)

 

angeloyeo.github.io

 

2.2.3. 향상도(Lift)

여기까지 왔다면 그래 나이브하게 임계값을 0.5로 설정하는 것이 적절하지 못하고 맥락에 따라 조절해야하는 것은 알겟다. 그러면 어떻게 결정해야하는지에 대한 궁금증이 생긴다. 이를 평가하는 지표로 리프트(lift)를 활용할 수 있다. 

향상도의 기조는 baseline을 랜덤하게 선택하는 분류하는 보다 모델을 사용했을때 얼마나 더 이득(gain)을 볼 수 있는 가를 측정한다. 예컨데 무작위 선택이 0.1%의 정확도인 반면 상위 10%에서 0.3%의 결과를 얻었다면 상위 10$에서 3의 리프트를 갖는다고 평가할 수 있다. 

향상도의 개념은  연관 분석에도 나오는 개념이다. 

$lift(B->A) = \frac{P(B|A)}{P(B)}  = \frac{P(A∩B){P(A)P(B)}$ 

B 사건이 일어났을때(B 제품을 구입했을 때, $P(B)$), A를 구입했을때 B를 동시에 살 확률($P(B|A)$) 을 얼마나 끌어올리는가에 대한 지표이다. 일반적으로 향상도가 1이면 두 사건이 독립임을, 1 크면  두 항목이 양의 상관관계가 있음을 1보다 작으면 서로 구매하지 않음을(대체제 - 소고기와 돼지고기의 관계) 표현한다. 

 

 

Last Updated 2025.09.23.

 
2018년 이후 데이터과학업계에 몸 담으면서 유용하게 공부했던 책과 컨텐츠 혹은 추천받는 책들을 모았습니다. 하지만 자신에게 잘 맞는 책은 지금 당장 도서관 또는 서점에 달려가서 펼쳤을 때 읽기 편한 책입니다. 아래 내용은 참고만 하세요 :) 

제 향후 방향성에 따라 데이터 엔지니어링 책 추천 글도 작성하고 있습니다.

https://snowgot.tistory.com/194

 

DataScience를 위한 엔지니어링 책 추천

지난 통계학/데이터사이언스 책 추천에 이어서 엔지니어링 관련 책 추천을 해보려 합니다. 데이터 사이언스에서 CS, 백엔드, 프론트, 네트워크, 데이터 모델링 등 필수적이진 않지만 알면 알수록

snowgot.tistory.com


1. 교양

프로덕트 데이터분석가를 희망하는 사람치고 안본사람 없을 듯! 
데이터분석을 잘하는 것에 더하여 잘 전달하는 것도 매우 중요하다. 이 부분을 도울 수 있는 책

2. 통계

저는 이 교수님보다 쉽고 잘 설명하시는 분을 못봤습니다. 게다가 서울대학교 강의를 방구석에서 볼 수 있다니? 이런 혜택이 어디있을까요? 통계를 입문하고 싶다면 필수 수강
K-MOOC 강의와 함께 검정에 충실한책
통계학에 자신이있다면(자신없는데요..)
학부 2학년수준이라면?
대부분의 통계학 책은 인터페이스가 더 좋은 R을 선호하는 점이 있다. 이 책은 인하대 교수님들이 출판했음에도 불구하고 Python으로 통계방법론을 구현한다. 기본적인 내용도 튼실하고  분포에 따른 실제 예제들을 정리해주셔서 매우매우 마음에 든다. 누군가 파이썬을 공부한 사람이 통계학을 공부한면 추천할 것!
 살만 칸 아저씨가 운영하는 무료 교육 플랫폼. 저학년부터 대학교 과정까지의 수학을 판서로 쉽게 설명해준다.

3. 데이터과학

3.1. 일반

넓고 다양한 범위, R/Python 코드수록. 통계의 기초, 분포 그리고 나아가서 머신러닝에 대한 부분까지 포괄적으로 기술한다. 깊이는 약간 없으나 본인이 데이터과학에 입문한 사람이라면 복습해보는 경험으로, 초심자라면 메타인지를 위해 읽는 것을 추천
국내 대부분의 머신러닝 책을 번역하는 박해선님이 쓰신 책. 쉬운 예제가 좋다. 
권철민님이 쓰신 개인적으로 가장 바이블스러운 머신러닝
전북대학교 교수님이 쓰신 ML 알고리즘을 지탱하는 지식을 최소한의 수식으로 쓴 책. 얼마전에 대학교 도서관을 갔다가 대출 상위권에 있어서 발견. 코드레벨은 없지만 추상화된 개념을 배운다는 점에서 권철민님 책이랑 병행하면 좋을 듯

 

3.2. 수학

  • 개발자를 위한 필수수학 - Essenstial for Data Science (입문서 추천 ★)
    • 한줄평: 데이터 과학을 공부하다가 블로그글에서 알 수 없는 수식이 답답하다면 추천
요즘 통계학,머신러닝을 넘나들며 다시 공부하는 입장에서 원리는 어느정도 감이오는데 실제로 수식이나 데이터로 구현한 글을보면 가끔 마음이 답답해질때가 있습니다.  저도 미분만 공부한 공대생이라 확률/통계,선형대수에 대한 깊은 이해는 없는 편인데, 이책은 데이터과학에 필요한 전반적인 수학 지식을 안내하고있습니다.  워크북도있어서 직접 풀어본다는 점이 또 재밌는 요소 입니다. 특히 마지막 8장에는 데이터과학자가 나아갈길을 얘기하고 있는데 결국 데이터과학자는 소프트웨어 엔지니어로 가는 방향에 있다고말하는게 흥미로웠습니다. 
방송통신대학에서 정년까지 컴퓨터 과학 전공으로 선형대수를 강의하신 손진곤 교수님의 강의. 선형대수학의 영어 표현을 모두 한글로 표현하고 입문자도 이해하기 쉽게끔 설명해주는 좋은 책과 강의. 하지만 깊게 들어가지 않는 편이기에 입문자에게 추천!
  • 개발자를 위한 선형대수학 
    • 개발자를 위한 시리즈2, 개발자를 위한 필수수학 책이 전반적인 수학을 다룬다면, 해당 책은 벡터와 행렬을 기반으로한 선형대수학을 중점적으로 다룬다.
 

개발자를 위한 실전 선형대수학(파이썬 3.10 버전 대응, 구글 코랩 실습 가능) | 마이크 X 코헨 - 교

개발자를 위한 실전 선형대수학(파이썬 3.10 버전 대응, 구글 코랩 실습 가능) | 복잡한 증명과 수식 없이 파이썬을 이용해 직관적으로 배우는 선형대수학 * 연습문제 + 해답 + 해설 강의, 무료 샘

product.kyobobook.co.kr

 

이 역시 개발자로 번역이 되어있지만 데이터 과학에 중점되어 있는 책이다. 특히 마음에 드는 점은 대학교 강의처럼 "엄밀한"증명이 아닌 Python으로 재현성을 보는 "약한 증명"을 통해 이해를 돕고 있다는 점이 매우 마음에 듭니다. 나아가 선형회귀와 PCA와 같은 머신러닝 기법들을 연계해서 이해 시켜주는 아주 명쾌한 책입니다.
김영우님이 강의에 쓰라고 무료로 주신 책(🙂)

3.2. AB Test

쉬운 기본서
바이블이자 베스트 셀러


4. 프로그래밍언어

이 책을 빼놓고 파이썬을 논할 수 있을까? 쉬운 설명, 무료 e-book까지 갓갓
점프투 파이썬이 기본 모듈을 다룬다면 이 링크는 라이브러리 예제를 다룹니다.
SQL을 기본을 가르치는 책은 많다. 하지만 실제 예시를 알고 공부하는게 중요하다.


5. 변경이력

  • 25.02.10. : AB test 책 추가
  • 25.05.21. DataScience를 위한 엔지니어링 책 링크 추가
  • 25.07.11. 류근관 교수님 강의 추가
  • 25.09.23. 패턴인식, 선형대수(손진곤) 책 추가

1. 목차

  • 5.1. 나이브베이즈(NB)
  • 5.2. 선형판별분석(LDA)

 

2. 본문

 

들어가기에 앞서 이책이 이론적으로는 확실히 친절한 책은 아님을 다시 확인시켜주는 단원이라 생각된다. 특히 나이브 베이즈와 판별분석은 그렇게 와닿는 예시는 아니니 다른 타 도서나 추가 공부가 필요함을 미리 알아두자.

2.1. 나이브베이즈(NB)

2.1.1. 베이즈 추정

추론 대상의 사전확률과 정보를 가지고 사후 확률을 추론하는 통계 기법을 베이즈 추정(Bayesian Estimation)이라고 한다. 

  • $ P(\theta | X) $: 데이터 $X$가 주어졌을 때 모수 $\theta$의 사후 확률 분포(posterior distribution)
  • $ P(X | \theta) $: 모수  $\theta$ 가 주어졌을 때 데이터 $X$의 우도(likelihood)
  • $ P(\theta) $: 데이터 $\theta$의 사전 확률 분포(prior distribution)
  • $ P(X) $: 데이터 X의 주어진 확률

쉽게 말하면 기계의 성능을 평가할 때 부품 몇개를 무작위로 뽑아서 테스트 해볼 수도 있지만, 기계의 과거 성능 검사 기록이나 부품의 성능 자료를 얻을 수 도 있다. 

  • 예시
    • 1. 사전확률 
      • $P(C)$: 암환자일 확률 = 0.105
      • $P(~C)$: 암환자가 아닐 확률 = 0.895
    • 2. 조건부확률
  암환자(C) 암 환자 아님(~C)
Positive(양성) $ P( Positive | C) $= 0.905 $P( Positive | \sim  C)$ = 0.204
Negative(음성) $ P( Negative | C) $ = 0.095 $P( Negative | \sim  C)$  = 0.796

 

위 예시에서 어떤사람이 양성(P)일 때, 이사람이 암환자일 확률 구해보자. 다음과 같은 식으로 표현된다. 

$P(C | Positive)$ = $\frac{P(Positive|C)*P(C)}{P(Positive)} $

이 때 $P(Positive)$는 암 환자이면서 양성 판정을 받을 확률 $P(Positive, C)$와 암환자가 아닌데 양성판정을 받을 확률의 합$P(Positive, \sim C)$의 합과 같다. 

$P(Positive)$ = $P(Positive | C) * P(C) + P(Positive | \sim C)*P(\sim C)$ 

따라서 $P(C|Positive)$ 는 0.905*0.105 / (0.905*0.105 + 0.204*0.895) = 0.342 가 된다. 

2.1.2. 그래서 베이즈분류란?

베이즈 분류는 주어진 클래스에 대한 모든 특징들이 서로 독립적이라는 가정하에 이루어지는 방법론이다. 따라서 $P(X|C)$는 다음과 같이 분해 된다. 

$P(X|C) = P(x_{1} + x_{2}, .... x_{n} | C ) = P(x_{1} | C) * P(x_{2} | C) ... P(X_{n} | C)$

  • 학습
    • 각 클래스 $C$의 사전 확률 $P(C)$를 추정
    • 각 클래스 $C$에 대해 주어진 클래스에서 각 특징 $x_{i}$의 조건의 확률 $P(x_{i}|C)를 추정
  • 예측
    • 새로운 데이터 포인트 X가 주어졌을 때, 각 클래스 C에 대해서 사후 확률 $P(C|X)$를 계산
    • 사후 확률 $P(C|X)$가 가장 큰 클래스를 선택하여 예측

 

나이브베이즈의 장점은 간단하고 구현하고 용이하며 계산이 빠르다. 또한 데이터가 적어도 잘 작동하며 다수의 특징(feature)를 다룰 수 있다는 것이다. 반면 조건부 독립성 가정이 실제 데이터에서는 성립 할 수 않을 수 있다. 그 밖에도 활용범위로 텍스트 분류, 스팸 필터링, 감정 분석에 널리 사용된다. 

 

2.2. 선형판별분석(LDA)

선형판별분석(Linear Discriminant Analysis, 이하 LDA)는 이름에 걸맞게 가상의 선형에 사영(projection)하여 분류할 수 있는 직선을 찾는 것을 목표로 하는 방법입니다. 분류의 카테고리에 들어가지만 고차원의 데이터 세트를 저차원에 투영하여 차원축소를 한다는 점에서는 PCA와 같이 언급되는 경우가 많습니다만 PCA는 가장 변동성이 큰 축을 찾지만 LDA는 입력 데이터의 결정 값을 최대한으로 분리 할 수 있는 축을 찾는 다는 점이 특징이 있습니다. 또한 PCA는 비지도학습 LDA는 지도학습이라는 큰 차이점 도 있습니다.

ratsgo's blog - 선형판별분석

 

GPT-4o의 답변

 

LDA는 특정 공간상에서 클래스 분리를 최대화하는 축을 찾기 위해서 클래스 간 분산(between class scatter)과 클래스 내부분산(with in class scatter)의 비율을 최대화 하는 방식으로 차원을 축소한다. 방법을 파헤치기 전에 선형대수에서 중요한 고유벡터와 고유값이라는 개념을 이해하고 가자 

 

2.2.1.  고유값과 고유벡터

- 원래 행렬이란 기존의 벡터값을 "선형변환"을 하는 기하학적 의미를 가지고 있다.



- 예컨데 [1,1]이라는 벡터(파란색)에 행렬을 곱해주면 변환된 벡터(빨간색)처럼 방향이 바뀐다. 

- 그렇다면 모든 행렬은 기존 벡터(파란색)의 방향을 바꾸는가? 는 또 아닐 것이 방향을 그대로하되 크기만 변하게 하는 행렬 역시 존재한다는 것이 합리적인 생각이다. 마치 벡터의 방향을 그대로 키우거나 줄이는 것처럼 말이다.

 

- 이는 선형변환이기도 하지만 기존 벡터에 상수배를 곱한 것과 같은 원리이다. 이때 [1,1] 그러니까 $\overrightarrow{x}$로 표현하고 이를 고유 벡터, 해당하는 상수배 숫자 $\lambda$를 고유값이라고 한다. 

기존 벡터에 크기를 늘린 형태

- 기하학적 의미로 정리하자면 고유벡터는 행렬(선형변환)에 의해 방향은 보존되고 그 크기(스케일)만 변화하는 방향벡터를 뜻한다. 고유값은 고유 벡터에 의하여 변하는 정도를 나타내는 값이라 할 수 있다. 

위 내용의 디테일은 공돌이의 수학정리 노트 - 고윳값과 고유벡터 에서 찾아볼 수 있다.

 

2.2.2. LDA의 작동순서

1.  클래스 내부와 클래스 간 차이를 구하기
- 클래스 내에서 데이터가 얼마나 흩어져있는지(분산), 그리고 클래스들이 서로 얼마나 떨어져있는지(분간 차이)를 각각 정리

  • 클래스 내 분산행렬($S_{W}$): 각 클래스 내에서 데이터포인트와 해당 클래스 평균의 차이를 측정
  • 클래스 간 분산행렬($S_{B}$): 각 클래스의 평균이 전체 데이터의 평균에서 얼마나 떨어져 있는지 측정

LDA는 $\frac{ S_{B} }{ S_{W} }$를 최대화하기 위한 방향으로 설정합니다. 다시 말해 해당하는 클래스 내 분산 ($S_{W}$) 을 최소화하는 반면 클래스 간 분산 ($S_{B}$) 을 최대화하기 위한 방향입니다. 그래야 두 클래스를 구분하기 쉬워질 테니까요! 여기서 최대화, 최소화를 하는 목적어는 데이터이며 데이터의 흩어진 정도를 조절하는 것입니다.

 $\frac{ S_{B} }{ S_{W} }$식을 최대화 하기 위한 방법론으로 고유값을 이용할 수 있습니다. 

  • 클래스 A,B가 있고 각 데이터가 3개가 있을때의 계산을 진행해보겠습니다. 

  • $S_{W}$ 계산 방법

 

  • $S_{B}$ 계산방법

 

 

2. 행렬분해
 -  $S_{W}$, $S_{B}$ 라고 하면 다음 식으로 두 행렬을 고유벡터로 분해


- 우측식은 $ E\lambda E^{T} $와 같은 형태로 분해된 것이다. $E$는 각 고유 벡터를 열로 갖는 행렬이며, $\lambda$ 는 대각선상에 고유값을 가지고 나머지 원소는 모두 0인 대각 행렬이 생성

- 고유 벡터는 클래스를 구분한느 유리한 방향을 나타내며, 고유값은 그 방향의 중요도를 표현하는 것. 고유값이 클수록 더 클래스간의 분리가 잘 일어나는 방향.

3. 고유값이 가장 큰 순서대로 K개 만큼 추출, 고유벡터를 이용해 새롭게 입력 데이터를 변환

- 고유값이 큰 고유벡터를 선택하여 저차원 공간으로 투영

2.2.3. 선형판별분석의 현대 활용

원리를 보면 간단하고 파워풀한 분류방법으로보이나 몇가지 한계로 인해 현재는 다른 머신러닝모델에 비해 두각되지 않는 는 특징이있다. 선형판별분석은   데이터가 선형적으로 구분 가능하다는 선형성 가정, 데이터가 정규분포를 따른다는 정규성 가정, 모든 클래스가 동일한 공분산을 가진다는 동일 공분산 가정 등 가정이 많아 제한적으로 쓰일 수 밖에 없는 특징을 가지고 있다. 

또한 데이터의 차원이 높은 경우 $S_{W}$ 분산 내 행렬을 계산하는데 리소스 소모가 많이 되며 특이 행렬이 되어 역행렬을 계산할 수 없을 때 사용할 수 없다. 이러한 제한점 때문에 SVM, 트리기반 모델, 딥러닝 모델에 밀려 자주 쓰이지 않는 한계를 가지고 있다. 

 

 

 

 

1. 목차

  • 4.5. 회귀방정식의 해석
  • 4.6. 회귀진단
  • 4.7. 다항회귀와 스플라인회귀
  • 4.8. 마치며

 

2. 본문

  • 회귀방정식의 해석에서는 더하여 회귀방정식의 해석에서는 변수간 상관성, 다중공선성,교란변수, 상호작용에 대해서 다룬다.  
  • 회귀진단에서는  특이값, 영향값, 이분산성, 비정규성, 오차 간의 상관, 편잔차그림과 비선형성을 다룬다.
  • 다항회귀와 스플라인회귀는 선형회귀에서 다항식,스플라인, 일반화가법모형 등 응용하는 방법을 다룬다.

 

2.1 교란변수의 정의

책에서는 교란변수를 "중요한 예측변수이지만 회귀방정식에서 누락되어 결과를 잘못되게 이끄는 변수" 라고 설명하고 있다. 의학통계에서 얘기하는 교란변수는 조금 다른 의미인 것 같아 정리해보려한다. 

흔히 교란변수(confounder)는 독립변수간이 관계를 살피는 상황 속에서 교호작용(interaction)과 함께 언급된다. 예컨대 상관계수 분석을 하다보면 자주 주는 예시가  아이스크림 판매량이 높으면 상어에 물리는 사람들이 많다. 라는 이야기로 상관관계와 인과관계의 구분이 필요하다는 얘기를 한다. 이게 무슨말이냐면 두 측정 변수가 상관관계가 있다고 해서 원인-결과로 직결적으로 해석하면 안된다는 것이다.  이 과정에서 각 변수(X,Y) 영향을 주는 변수, 교란변수가 바로 여름이라는 특징이다. 

이런 점에서 "누락되어"라는 말이 어쩌면 합리적이면서도 데이터가 없는데 어떻게 누락된지 아닌지 알아요 라는 질문이 들기도 한다.

어쩌면이 포인트

결국 제대로된 모델을 만들려면 교란변수를 데이터화하고 모델링을 하는데 일조해야한다는 것인데.. 만약 그런 통찰이 없다면?  통찰이 있다해도 데이터가 없다면?  곤란해질 것 같긴하다. 

 

2.2 스플라인과 일반화가법모형

- 스플라인은 몇몇 제어점을 이용하여 부드러운 곡선을 만들어내는 수학적 도구이다. 이때 매듭점(knot)개념이등장하고 이 매듭점을 충분히 연결해주는 함수가 스플라인이다. 다항회귀(x^2, x^3)는 어느정도 곡률을 담아낼 수 있지만 고차항을 추가하는 것은 회귀방정식에 바람직하지 않은 결과를 초래한다. 

흔히 x의 의 구간을 여러부분으로 나누어 회귀모델을 각각 구현할 수 있으며 다항식의 차수와 매듭의 위치를 설정하여 만든다. 선형회귀보다 해석하기 어렵기 때문에 산점도와 같은 시각화 방법을 이용하는 것이 바람직하다.. 곡선은 직선의 연속

여기서 등장하는 것이 일반화 가법모형(Generalized Additive Model, GAM)이다. GAM은 스플라인 매듭을 자동으로 결정할 수 있는 장점이 있다. 요즘 같은 ML기법이 많이 등장한 이후 가법모형이 애매한 포지션을 가지고 있지않은가 생각이 되면서도  매우 좋은 예측력과 통계적 추론이가능하며 모형의 구조를 이해할 수 있어서 사용된다. 예를들어 각 요소에 대한 유의성검정, 신뢰구간 계산, 효과 크기 추정이 여전이 가능하다. 

 

GAM의 특징은 다음과 같다. 

  • 비선형성: 각 독립 변수에 대해서 비선형함수를 사용하여 복잡한 관계를 모델링
    • GAM의 예시
  • 가법성: 모델은 여러개의 스무딩 함수의 합으로 구성, 독립적으로 해석 가능
  • 유연성: 다양한 분포에 적용 가능(이항, 포아송 분포 등)

이런 상황에서 GAM은 데이터 포인트를 부드럽게 연결하는 도구로 되는 특성 때문에 주로 GAM에서는 스플라인을 활용하여 독립변수의 비선형효과를 모델링한다.  대표적은 스플라인 방법은 ① 선형 스플라인 ② 큐빅스플라인 ③ B-스플라인

 

1. 목차

  • 4.1. 단순선형회귀
  • 4.2. 다중선형회귀
  • 4.3. 회귀를 이용한 예측
  • 4.4. 회귀에서의 요인변수

 

2. 본문

2.1. OLS 계산법에 대한 이해

늘 회귀분석을 하면서 최소자승법에 대한 계산이 궁금했다. OLS의 계산방법은 다음 출처를 인용한다. 

https://recipesds.tistory.com/entry/%EC%97%90%EB%9D%BC%EC%9D%B4-%EC%9D%BC%EB%8B%A8-%EB%A0%88%EC%B8%A0-%EB%91%90-%EC%9E%87-%ED%9A%8C%EA%B8%B0-%EB%B6%84-%EC%84%9D-OLS-Regression

 

에라이, 일단 레츠 두 잇, 회귀분석 - OLS Regression 손으로 풀어보기

자, 이제까지 회귀에 대해서 계속 말만 꺼냈지, 실제로 회귀를 해보지 않았으니까, 서툴더라도 회귀라는 것을 한번 해보자고요. - 분석 결과의 해석은 이걸 해 보고 하는 것으로... 아직은 회귀에

recipesds.tistory.com

① 오차의 정의

② b0에 대한 편미분*

미분이란 방정식의 최소 값을 찾기 위하여 수행되는 수학적 기법이며, 편미분이란 다항변수의 식에서 특정변수를 제외한 나머지 변수를 상수로 취급하여 미분하는 것.

 

③ b1에 대한 편미분

다시 말해 에러를 최소화하는 값은 (1), (2)식에 대한 해가 바로 우리가 찾으려고하는 b0와 b1이다. 해당 연립방정식을 정리하면 다음과 같은 식이 나오고

신기하게도 b1은 x,y에 대한 공분산을 x의 분산으로 나눈 값이다. 

이를 좌표평변에 분포형태로 표현한다면  기울기는 x,y의 공동 변화량에 대한 x의 비율이라고 해석 할 수 있다.

예컨데 x가 배달거리, y가 배달 시간이라고 한다면 다음과 같이 b1,b0을 구할 수 있다.

 

 

2.2 선형회귀에서 독립변수 t-test p-value의 의미

선형회귀에서도 t-test를 한다. 이때 귀무가설은 회귀계수 beta가 0이다 라는 것(다시말해 해당 독립변수는 종속변수에 아무런 영향이 없다는 것이며) 대립가설은 beta가 0이 아니다 라는 것이다.  따라서 검정통계량은 다음과 같이 설정한다.

 

2.3. 선형회귀에서 F 검정이 나오는 이유

이 역시 다음 출처를 인용한다.

https://recipesds.tistory.com/entry/%ED%9A%8C%EA%B7%80%EC%99%80-%EA%B2%80%EC%A0%95-%ED%9A%8C%EA%B7%80%EB%B6%84%EC%84%9D%EA%B2%B0%EA%B3%BC%EA%B0%80-%EC%9C%A0%EC%9D%98%ED%95%9C%EA%B0%80-%ED%86%B5%EA%B3%84%EC%A0%81%EC%9D%B8-%ED%95%B4%EC%84%9D-t-F%EA%B2%80%EC%A0%95-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EA%B0%91%EB%B6%84%EC%8B%B8-ANOVA-%EC%97%A5

 

회귀와 검정 - 회귀분석결과가 괜찮은가? 통계적인 해석 t, F검정, 그리고 갑분싸 ANOVA 엥?

"회귀분석 결과의 해석과 R²(설명력,결정계수)의 의미, 그리고 R²은 상관계수의 제곱. 응?"편에 이어, 회귀분석을 했으면 그 결과를 검정해야 무릇 통계라고 할 수 있지 않겠습니꽈아아? 회귀에

recipesds.tistory.com

 

 

회귀모델에서 F검정은 모델이 유의한가 유의하지 않는 가를 검정하기 위하여 사용한다. 귀무가설은 모든 회귀계수가 0이고 대립가설은 하나라도 회귀계수가 0이 아니라는 의미이다. 다시말하면 단순회귀인 경우에는 t-test와 f-test가 같은 결과를 갖게 된다. 

좀더 시각적으로  위 선형회귀를 도식화한 그림에서 보자면

마치 다음과 같이 볼 수 있고

 

이는 집단간 분산과 집단내 분산의 비율을 검정하는 F분포의 사용 ANOVA와 유사하다고 할 수 있다. ANOVA는 범주형 집단을, 회귀는 연속형 집단의 차이를 다룬다는 점이 다를 뿐이다.  

F분포는 설명이가능한변동/설명불가능한 변동의 비율이며, 이를 ANOVA에서는 그룹간분산/그룹내 분산으로 표현했다. 반면 회귀분석에서는 MSR/MSE 로 표현할 뿐  설명가능/불가능에 대한 의미는 동일하다는 점을 기억하면 좋다.

 

얽혀있던 통계지식과 회귀가 조금씩 맞아 들어가는 기분이 조금 들긴하지만.. 선형대수로 완벽하게 정리할 때까지는 완전히 개운함을 얻진 못할 것 같다.

+ Recent posts