15wk-1: MCMC (3)
2023-06-01
강의영상
youtube: https://youtube.com/playlist?list=PLQqh36zP38-z-M7HO1xUnq2z5lK8aq1_a
imports
모티브
-
축구기사
-
16강진출 경우의 수
-
통계, 데이터과학
- 생략
문제소개
-
3개의 문서가 있으며 각 문서에는 아래와 같이 2개의 단어가 있는 데이터를 고려하자.
{'doc1': ['손흥민', '골'], 'doc2': ['골', '확률'], 'doc3': ['확률', '데이터과학']}
- 여기에서 \(D\)는 문서들의 집합, 즉 코퍼스를 의미한다.
-
데이터설명
토픽
- 토픽0 = 축구 : ‘골’, ‘손흥민’ 와 같은 단어가 쓰임.
- 토픽1 = 통계 : ‘데이터과학’, ‘확률’ 와 같은 단어가 쓰임.
문서
- doc0은 축구를 주제로 쓰여진 글인듯 하다.
- doc2은 데이터과학을 주제로 쓰여진 글인듯 하다.
- doc1는 축구와 데이터과학이 혼합된 주제인듯 하다.
-
원하는 것1: 문서별로 토픽이 얼마나 들어있는지 알고싶다.
- 즉 \(D\)를 입력으로 넣으면 아래와 같은 \(\theta\) 가 나오면 좋겠음
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
doc1 | doc2 | doc3 |
---|---|---|
1 | 1 | 2 |
1 | 2 | 2 |
-
원하는것1에 대한 아쉬움
- 그런데 생각해보니까 “손흥민”이라는 단어는 완전 축구단어
- “골”이라는 단어는 가끔 데이터과학과 섞일 수 있는 단어
- “손흥민”이라는 단어는 축구토픽에서 나올 확률이 90퍼 이상, “골”은 축구토픽에서 나올 확률이 80퍼정도일수도 있잖음?
-
원하는 것2: 특정한 하나의 \({\boldsymbol \theta}\) 값이 아니라 아래와 같이
\[{\boldsymbol \theta} \sim {\boldsymbol \pi}\]
\({\boldsymbol \theta}\)를 뽑아낼 수 있는 분포 \({\boldsymbol \pi}\)를 알아내는게 더 좋지 않을까?
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
doc1 | doc2 | doc3 |
---|---|---|
1 | 1 | 2 |
1 | 2 | 2 |
doc1 | doc2 | doc3 |
---|---|---|
\(\begin{bmatrix}0.9\\0.1\end{bmatrix}\) | \(\begin{bmatrix}0.8\\0.2\end{bmatrix}\) | \(\begin{bmatrix}0.3\\0.7\end{bmatrix}\) |
\(\begin{bmatrix}0.8\\0.2\end{bmatrix}\) | \(\begin{bmatrix}0.3\\0.7\end{bmatrix}\) | \(\begin{bmatrix}0.05\\0.95\end{bmatrix}\) |
-
어려운점: 현재 \({\boldsymbol \pi}\) (=\({\boldsymbol \theta}\)의 pmf) 의 수식을 알 수 없어서 직접 뽑기 어렵다.
가능한 해결책: 아이디어 단계
-
이론적인 근거는 아직 설명하기 어렵지만 되게 그럴듯한 해결책이 있습니다.
-
문제의 단순화:
- 결국 길이가 6인 랜덤벡터 \({\boldsymbol \theta}=(\theta[0],\dots,\theta[5])\) 를 뽑는 일이다.
단계1: 아무값이나 넣어서 \({\boldsymbol \theta}_0\)를 초기화한다.
-
\({\boldsymbol \theta}_0=(\theta_0[0],\dots,\theta_0[5])\)를 아무값이나 셋팅
- \({\boldsymbol \theta}_0 = [2,1,1,2,2,1]\) 이라고 생각하자.
-
임의의 초기값이 셋팅된 상황은 아래와 같다.
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
doc1 | doc2 | doc3 |
---|---|---|
2 (=\(\theta_0[0]\)) | 1 (=\(\theta_0[2]\)) | 2 (=\(\theta_0[4]\)) |
1 (=\(\theta_0[1]\)) | 2 (=\(\theta_0[3]\)) | 1 (=\(\theta_0[5]\)) |
topic | words |
---|---|
1 | 골, 골, 데이터과학 |
2 | 손흥민, 확률, 확률 |
단계2: \({\boldsymbol \theta}_0[0], {\boldsymbol \theta}_0[1] \cdots, {\boldsymbol \theta}_0[5]\) 을 순서대로 샘플링
-
예비개념: MCMC에서 베타분포를 뽑았던 예제로 돌아가보자
- 임의의 초기값 \(x\) 생성
- 새로운 값으로 \(y\)를 고려 (추천받을 수도 있고 그냥 고려할수도 있음)
- \(x\)가 그럴듯한지, \(y\)가 그럴듯한지 판단하고 \(x'\)의 값은 어떠한확률로 \(x,y\) 중에서 선택
-
전략: 그동안 pmf 혹은 pdf의 정보가 필요했던 것은 “그럴듯한 정도” 를 판단할 기준을 얻기 위해서였다. 그런데 만약, “그럴듯한 정도”를 판단하는 기준을 pmf, pdf 로 정하지 않는다면? pmf 혹은 pdf 가 필요하지 않다.
stage0: \({\boldsymbol \theta}_0[0]\)을 sampling
-
현재상태
- 빨간색/볼드: 지금 focus하는 것
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
doc1 | doc2 | doc3 |
---|---|---|
2 (=\(\theta_0[0]\)) | 1 (=\(\theta_0[2]\)) | 2 (=\(\theta_0[4]\)) |
1 (=\(\theta_0[1]\)) | 2 (=\(\theta_0[3]\)) | 1 (=\(\theta_0[5]\)) |
topic | words |
---|---|
1 | 골, 골, 데이터과학 |
2 | 손흥민, 확률, 확률 |
관찰 | 결론 | |
---|---|---|
문서눈치 | 문서안에서 나말고 다른 단어는 토픽1으로 분류되어있음 | 나도 토픽1인듯 |
토픽눈치 | 토픽1에도, 토픽2에도 나랑 같은 단어는 없음 | 난 토픽1도 2도 아닌듯 |
-
\(\theta_0[0]\)이 토픽1에서 뽑혓다고 보는게 타당한지 토픽1에서 뽑혔다고 보는게 타당하지 아래와 같이 따져보자.
- 토픽1의 타당성: (
doc1
에 토픽1이 포함된 비율) \(\times\) (토픽1에서손흥민
이라는 단어가 포함된 비율) = 1 \(\times\) 0 - 토픽2의 타당성: (
doc1
에 토픽2가 포함된 비율) \(\times\) (토픽2에서손흥민
이라는 단어가 포함된 비율) = 0 \(\times\) 0
둘 다 \(0\) 이라서 비긴거야?? 그런데 그래도 토픽1가 그나마 타당한거아냐?
-
수정된 타당성
- 토픽1의 타당성: (
doc1
에 토픽1이 포함된 비율) \(\times\) (토픽1에서손흥민
이라는 단어가 포함된 비율) = 1 \(\times\) 0.001 - 토픽2의 타당성: (
doc1
에 토픽2가 포함된 비율) \(\times\) (토픽2에서손흥민
이라는 단어가 포함된 비율) = 0.001 \(\times\) 0.001
\(\theta_0[0]\)의 생각: 나는 토픽1인듯해
-
업데이트
stage1: \({\boldsymbol \theta}_0[1]\)을 sampling
-
현재상태
- 빨간색/볼드: 지금 focus하는 것
- 파란색/볼드: 과거 / 업데이트O
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
doc1 | doc2 | doc3 |
---|---|---|
1 (=\(\theta_1[0]\))1 | 1 (=\(\theta_0[2]\)) | 2 (=\(\theta_0[4]\)) |
1 (=\(\theta_0[1]\)) | 2 (=\(\theta_0[3]\)) | 1 (=\(\theta_0[5]\)) |
1 원래 2였는데 업데이트되었음
topic | words |
---|---|
1 | 골, 골, 데이터과학, 손흥민2 |
2 | 확률, 확률 |
2 원래 2에 있었은데 1로 옮겼음
관찰 | 결론 | |
---|---|---|
문서눈치 | 문서안에서 나말고 다른 단어는 토픽1으로 분류되어있음 | 나도 토픽1인듯 |
토픽눈치 | 토픽1에는 나랑 같은 단어가 있는데 토픽2에는 없음 | 나도 토픽1인듯 |
-
수정된 타당성
- 토픽1의 타당성: (
doc1
에 토픽1이 포함된 비율) \(\times\) (토픽1에서골
이라는 단어가 포함된 비율) = 1 \(\times\) 1/3 - 토픽2의 타당성: (
doc1
에 토픽2가 포함된 비율) \(\times\) (토픽2에서골
이라는 단어가 포함된 비율) = 0.001 \(\times\) 0.001
\(\theta_0[1]\)의 생각: 나는 토픽1인듯해
-
업데이트: 안함.. 난 토픽1이 맞는것 같음
stage2: \({\boldsymbol \theta}_0[2]\)을 sampling
-
현재상태
- 빨간색/볼드: 지금 focus하는 것
- 파란색/볼드: 과거 / 업데이트O
- 파란색/볼드X: 과거 / 업데이트X
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
doc1 | doc2 | doc3 |
---|---|---|
1 (=\(\theta_1[0]\))3 | 1 (=\(\theta_0[2]\)) | 2 (=\(\theta_0[4]\)) |
1 (=\(\theta_1[1]\)) | 2 (=\(\theta_0[3]\)) | 1 (=\(\theta_0[5]\)) |
3 원래 2였는데 업데이트되었음
topic | words |
---|---|
1 | 골, 골, 데이터과학, 손흥민4 |
2 | 확률, 확률 |
4 원래 2에 있었은데 1로 옮겼음
관찰 | 결론 | |
---|---|---|
문서눈치 | 문서안에서 나말고 다른 단어는 토픽2로 분류되어있음 | 나도 토픽2인듯 |
토픽눈치 | 토픽1에는 나랑 같은 단어가 있는데 토픽2에는 없음 | 나도 토픽1인듯 |
-
수정된 타당성
- 토픽1의 타당성: (
doc2
에 토픽1이 포함된 비율) \(\times\) (토픽1에서골
이라는 단어가 포함된 비율) = 0.001 \(\times\) 1/3 - 토픽2의 타당성: (
doc2
에 토픽2가 포함된 비율) \(\times\) (토픽2에서골
이라는 단어가 포함된 비율) = 1 \(\times\) 0.001
\(\theta_0[2]\)의 생각: 나는 토픽2인듯함 (그런데 아닐 수도 있음)
-
업데이트
stage3: \({\boldsymbol \theta}_0[3]\)을 sampling
-
현재상태
- 빨간색/볼드: 지금 focus하는 것
- 파란색/볼드: 과거 / 업데이트O
- 파란색/볼드X: 과거 / 업데이트X
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
-
수정된 타당성
- 토픽1의 타당성: (
doc2
에 토픽1이 포함된 비율) \(\times\) (토픽1에서확률
이라는 단어가 포함된 비율) = 0.001 \(\times\) 0.001 - 토픽2의 타당성: (
doc2
에 토픽2가 포함된 비율) \(\times\) (토픽2에서확률
이라는 단어가 포함된 비율) = 1 \(\times\) 1/2
\(\theta_0[3]\)의 생각: 나는 토픽2인듯함
-
업데이트: 안함. 난 토픽2가 확실한듯
stage4: \({\boldsymbol \theta}_0[4]\)을 sampling
-
현재상태
- 빨간색/볼드: 지금 focus하는 것
- 파란색/볼드: 과거 / 업데이트O
- 파란색/볼드X: 과거 / 업데이트X
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
-
수정된 타당성
- 토픽1의 타당성: (
doc3
에 토픽1이 포함된 비율) \(\times\) (토픽1에서확률
이라는 단어가 포함된 비율) = 1 \(\times\) 0.001 - 토픽2의 타당성: (
doc3
에 토픽2가 포함된 비율) \(\times\) (토픽2에서확률
이라는 단어가 포함된 비율) = 0.001 \(\times\) 1/2
\(\theta_0[4]\)의 생각: 나는 토픽1인듯함 (그런데 아닐수도 있음)
-
업데이트: 안함. 난 토픽1인것 같긴한데, 확실하지 않아서 그냥 토픽2에 머무르겠음.
stage5: \({\boldsymbol \theta}_0[5]\)을 sampling
-
현재상태
- 빨간색/볼드: 지금 focus하는 것
- 파란색/볼드: 과거 / 업데이트O
- 파란색/볼드X: 과거 / 업데이트X
doc1 | doc2 | doc3 |
---|---|---|
손흥민 | 골 | 확률 |
골 | 확률 | 데이터과학 |
-
수정된 타당성
- 토픽1의 타당성: (
doc3
에 토픽1이 포함된 비율) \(\times\) (토픽1에서데이터과학
이라는 단어가 포함된 비율) = 0.001 \(\times\) 0.001 - 토픽2의 타당성: (
doc3
에 토픽2가 포함된 비율) \(\times\) (토픽2에서데이터과학
이라는 단어가 포함된 비율) = 1 \(\times\) 0.001
\(\theta_0[5]\)의 생각: 나는 토픽1인듯함 (그런데 아닐수도 있음)
-
업데이트: 난 토픽2가 확실한듯
단계3: \(t=1,2,3,4,\dots\) 에 대하여 단계2를 반복
-
초기상태와 지금을 비교하면 아래와 같다.
doc1 | doc2 | doc3 |
---|---|---|
\(\begin{bmatrix}0.9\\0.1\end{bmatrix}\) | \(\begin{bmatrix}0.8\\0.2\end{bmatrix}\) | \(\begin{bmatrix}0.3\\0.7\end{bmatrix}\) |
\(\begin{bmatrix}0.8\\0.2\end{bmatrix}\) | \(\begin{bmatrix}0.3\\0.7\end{bmatrix}\) | \(\begin{bmatrix}0.05\\0.95\end{bmatrix}\) |
doc1 | doc2 | doc3 |
---|---|---|
2 | 1 | 2 |
1 | 2 | 1 |
-
\(t=1,2,3,4\dots\)로 진행하다보면 서로 눈치를 보면서 아래와 같은 원리로 이동한다.
- 문서눈치: 내가 토픽k 라면, 내가 속한 문서에는 토픽k로 분류된 단어가 많을거야.
- 토픽눈치: 내가 토픽k 라면, 토픽k에는 나랑 같은 단어가 많을거야.
구현
구현에 필요한 예비학습
enumerate
np.random.choice
array([1000, 1000, 10, 100, 100, 1000, 100, 100, 10, 1000, 10,
1000, 100, 10, 1000, 100, 10, 100, 100, 1000, 1000, 10,
1000, 1000, 10, 1000, 1000, 100, 1000, 1000, 1000, 1000, 1000,
100, 10, 1000, 10, 1000, 10, 10, 1000, 100, 10, 1000,
100, 100, 1000, 10, 100, 100])
딕셔너리의 해체
-
아래와 같은 딕셔너리를 고려하자.
-
이러한 딕셔너리에를 해체하고 싶다면?
리스트의 count 메소드
조건부 컴프리헨션
딕셔너리의 원소삭제
{'doc1': ['손흥민', '손흥민', '손흥민', '손흥민', '손흥민'],
'doc2': ['골', '골', '골', '골', '골']}
깊은복사
-
특정원소가 삭제된 dct와 삭제되지 않은 dct를 동시에 가지고 있으려면?
-
해결책
연습문제
아래와 같은 자료가 있다고 하자.
(1)
\(D\)에는 총 몇개의 단어가 있는가?
(2)
문서2에 토픽1은 몇개나 있는가?
(3)
토픽1에 들어있는 단어들의 목록을 구하라.
(4)
토픽1에서 ’골’이라는 단어는 몇번 등장하는가?
데이터: \(D\)와 \(\theta\)의 설정
D = {'doc1': ['심판', '헤딩', '선수', '골', '리그', '골', '선수', '공격', '헤딩', '슈팅', '공', '패스', '공격수', '페널티킥', '공'], 'doc2': ['수비', '골', '챔피언스리그', '헤딩', '경기장', '골키퍼', '챔피언스리그', '헤딩', '경기장', '수비수', '수비수', '패스', '드리블', '선수', '월드컵'], 'doc3': ['헤딩', '리그', '드리블', '골키퍼', '공격수', '공격수', '월드컵', '선수', '공', '헤딩', '중앙미드필더', '공격', '선수', '수비수', '드리블'], 'doc4': ['클럽', '선수', '챔피언스리그', '슈팅', '리그', '수비', '리그', '중앙미드필더', '공격', '공', '중앙미드필더', '골', '패스', '중앙미드필더', '클럽'], 'doc5': ['선수', '경기장', '수비', '골키퍼', '월드컵', '리그', '드리블', '공격수', '슈팅', '선수', '선수', '월드컵', '드리블', '월드컵', '골키퍼'], 'doc6': ['수비수', '심판', '공', '공격', '표준편차', '표본', '상관관계', '모집단', '딥러닝', '클러스터링', '인공지능', '챔피언스리그', '공', '심판', '챔피언스리그'], 'doc7': ['페널티킥', '중앙미드필더', '챔피언스리그', '선수', '표본', '평균', '분류', '로지스틱 회귀', '머신러닝', '클러스터링', '평균', '수비수', '중앙미드필더', '페널티킥', '심판'], 'doc8': ['공격', '경기장', '패스', '수비수', '신뢰구간', '데이터과학', '확률', '통계', '분류', '인공지능', '머신러닝', '수비수', '수비수', '페널티킥', '수비수'], 'doc9': ['페널티킥', '패스', '골키퍼', '공', '신뢰구간', '딥러닝', '평균', '인공지능', '딥러닝', '분산', '딥러닝', '월드컵', '월드컵', '슈팅', '골키퍼'], 'doc10': ['리그', '슈팅', '드리블', '선수', '평균', '데이터분석', '데이터과학', '신뢰구간', '평균', '분류', '딥러닝', '심판', '슈팅', '패스', '선수'], 'doc11': ['평균', '데이터분석', '클러스터링', '데이터과학', '신경망', '데이터분석', '상관관계', '인공지능', '상관관계', '확률', '회귀분석', '로지스틱 회귀', '평균', '표준편차', '딥러닝'], 'doc12': ['신뢰구간', '딥러닝', '확률', '평균', '데이터분석', '상관관계', '회귀분석', '통계', '신경망', '상관관계', '회귀분석', '확률', '로지스틱 회귀', '상관관계', '데이터과학'], 'doc13': ['확률', '로지스틱 회귀', '통계', '딥러닝', '모집단', '머신러닝', '인공지능', '표준편차', '상관관계', '확률', '확률', '클러스터링', '신경망', '분류', '데이터분석'], 'doc14': ['데이터분석', '데이터과학', '분류', '통계적 가설검정', '머신러닝', '로지스틱 회귀', '회귀분석', '분류', '표본', '모집단', '통계적 가설검정', '상관관계', '표본', '클러스터링', '표본'], 'doc15': ['딥러닝', '인공지능', '표본', '표준편차', '신경망', '분류', '모집단', '데이터분석', '통계', '통계적 가설검정', '통계적 가설검정', '머신러닝', '머신러닝', '상관관계', '딥러닝']}
pd.DataFrame(D)
doc1 | doc2 | doc3 | doc4 | doc5 | doc6 | doc7 | doc8 | doc9 | doc10 | doc11 | doc12 | doc13 | doc14 | doc15 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 심판 | 수비 | 헤딩 | 클럽 | 선수 | 수비수 | 페널티킥 | 공격 | 페널티킥 | 리그 | 평균 | 신뢰구간 | 확률 | 데이터분석 | 딥러닝 |
1 | 헤딩 | 골 | 리그 | 선수 | 경기장 | 심판 | 중앙미드필더 | 경기장 | 패스 | 슈팅 | 데이터분석 | 딥러닝 | 로지스틱 회귀 | 데이터과학 | 인공지능 |
2 | 선수 | 챔피언스리그 | 드리블 | 챔피언스리그 | 수비 | 공 | 챔피언스리그 | 패스 | 골키퍼 | 드리블 | 클러스터링 | 확률 | 통계 | 분류 | 표본 |
3 | 골 | 헤딩 | 골키퍼 | 슈팅 | 골키퍼 | 공격 | 선수 | 수비수 | 공 | 선수 | 데이터과학 | 평균 | 딥러닝 | 통계적 가설검정 | 표준편차 |
4 | 리그 | 경기장 | 공격수 | 리그 | 월드컵 | 표준편차 | 표본 | 신뢰구간 | 신뢰구간 | 평균 | 신경망 | 데이터분석 | 모집단 | 머신러닝 | 신경망 |
5 | 골 | 골키퍼 | 공격수 | 수비 | 리그 | 표본 | 평균 | 데이터과학 | 딥러닝 | 데이터분석 | 데이터분석 | 상관관계 | 머신러닝 | 로지스틱 회귀 | 분류 |
6 | 선수 | 챔피언스리그 | 월드컵 | 리그 | 드리블 | 상관관계 | 분류 | 확률 | 평균 | 데이터과학 | 상관관계 | 회귀분석 | 인공지능 | 회귀분석 | 모집단 |
7 | 공격 | 헤딩 | 선수 | 중앙미드필더 | 공격수 | 모집단 | 로지스틱 회귀 | 통계 | 인공지능 | 신뢰구간 | 인공지능 | 통계 | 표준편차 | 분류 | 데이터분석 |
8 | 헤딩 | 경기장 | 공 | 공격 | 슈팅 | 딥러닝 | 머신러닝 | 분류 | 딥러닝 | 평균 | 상관관계 | 신경망 | 상관관계 | 표본 | 통계 |
9 | 슈팅 | 수비수 | 헤딩 | 공 | 선수 | 클러스터링 | 클러스터링 | 인공지능 | 분산 | 분류 | 확률 | 상관관계 | 확률 | 모집단 | 통계적 가설검정 |
10 | 공 | 수비수 | 중앙미드필더 | 중앙미드필더 | 선수 | 인공지능 | 평균 | 머신러닝 | 딥러닝 | 딥러닝 | 회귀분석 | 회귀분석 | 확률 | 통계적 가설검정 | 통계적 가설검정 |
11 | 패스 | 패스 | 공격 | 골 | 월드컵 | 챔피언스리그 | 수비수 | 수비수 | 월드컵 | 심판 | 로지스틱 회귀 | 확률 | 클러스터링 | 상관관계 | 머신러닝 |
12 | 공격수 | 드리블 | 선수 | 패스 | 드리블 | 공 | 중앙미드필더 | 수비수 | 월드컵 | 슈팅 | 평균 | 로지스틱 회귀 | 신경망 | 표본 | 머신러닝 |
13 | 페널티킥 | 선수 | 수비수 | 중앙미드필더 | 월드컵 | 심판 | 페널티킥 | 페널티킥 | 슈팅 | 패스 | 표준편차 | 상관관계 | 분류 | 클러스터링 | 상관관계 |
14 | 공 | 월드컵 | 드리블 | 클럽 | 골키퍼 | 챔피언스리그 | 심판 | 수비수 | 골키퍼 | 선수 | 딥러닝 | 데이터과학 | 데이터분석 | 표본 | 딥러닝 |
-
간단한 데이터 조사
- 데이터는 총 15개의 문서로 이루어져 있으며 처음5개의 문서는 축구관련, 이후 5개는 축구와 통계 관련, 이후 5개는 통계관련이다.
- 축구와 통계가 섞인
doc6~doc11
은 축구관련4단어, 통계관련7단어, 축구관련4단어의 조합으로 이루어져 있다.
-
초기값
{'doc1': [0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0],
'doc2': [1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0],
'doc3': [0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0],
'doc4': [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1],
'doc5': [1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0],
'doc6': [1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
'doc7': [0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0],
'doc8': [0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1],
'doc9': [1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1],
'doc10': [1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0],
'doc11': [1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0],
'doc12': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1],
'doc13': [0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
'doc14': [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1],
'doc15': [1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1]}
-
D와 \(\theta\)를 묶어서 하나의 dict를 만들자.
하이퍼파라메터
필요한 함수
-
\(p_1\): \(d\)-th document에 포함된 토픽 \(k\)의 비율을 리턴하는 함수, 즉 아래를 계산한다.
\[p_1=:\frac{\#({\tt topic == k, document == d})+0.1}{\#({\tt document == d})+0.1\times K}\]
여기에서 \(K\)는 토픽의 수.
-
\(p_2\): \(k\)-th topic에 포함된 단어 \(w\)의 비율을 리턴하는 함수, 즉 아래를 계산한다.
\[p_2=:\frac{\#({\tt word ==w, topic == k})+0.1}{\#({\tt topic == k})+0.1\times W}\]
여기에서 \(W\)는 전체단어의 수. (이 예제의 경우 40개의 단어로 이루어짐)
알고리즘
1. 초기값: \({\boldsymbol \theta}_0\)
2. 반복: \({\boldsymbol \theta}_0 \to {\boldsymbol \theta}_1 \to {\boldsymbol \theta}_2 \to \dots\)
for t in range(5):
for doc in D:
for i, wrd in enumerate(D[doc]):
# 임시의 data를 만들고 현재 포커싱되어있는 자료를 삭제함
data = {'D':copy.deepcopy(D), 'θ': copy.deepcopy(θ)}
del data['D'][doc][i]
del data['θ'][doc][i]
# 토픽의 타당성조사, msr는 타당성을 나타내는 측도, prob는 msr의 총합을 1로 맞춤
msr0 = p1(topic=0, doc=doc, data=data) * p2(word=wrd, topic=0, data=data) # 토픽0의 타당성
msr1 = p1(topic=1, doc=doc, data=data) * p2(word=wrd, topic=1, data=data) # 토픽1의 타당성
prob = [msr0/(msr0 + msr1), msr1/(msr0 + msr1)]
# update θ|
θ[doc][i] = np.random.choice([0,1], p=prob)