(01๊ฐ) Intro to NLP, Bag-of-Words
210906
1. Intro to Natural Language Processing(NLP)
์์ฐ์ด ์ฒ๋ฆฌ์ ๊ด๋ จ๋ ํ๋ฌธ ๋ถ์ผ์ ๋ฐ์ ๋ํฅ
์์ฐ์ด ์ฒ๋ฆฌ๋ ๋ฌธ์ฅ๊ณผ ๋จ์ด๋ฅผ ์ดํดํ๋ Natural Language Understanding ์ด๋ผ ํ๋ NLU์ ์ด๋ฌํ ์์ฐ์ด๋ฅผ ์ํฉ์ ๋ฐ๋ผ ์ ์ ํ ์์ฑํ๋ Natural Language Generation์ด๋ผ ํ๋ NLG์ ๋ ๊ฐ์ง ํ์คํฌ๋ก ๊ตฌ์ฑ๋๋ค.
์์ฐ์ด ์ฒ๋ฆฌ ๋ถ์ผ๋ ๋น์ ๊ณผ ํจ๊ป ๊ธ์๋๋ก ๋ฐ์ ํ๊ณ ์๋ ๋ถ์ผ์ด๋ค. ์ด๋ฌํ ๋ถ์ผ๊ฐ ์์ฐ์ด ๊ธฐ์ ์์ ์ ๋ ๋ถ์ผ์ด๋ค. ์ด๋ฌํ ๊ธฐ์ ๋ค์ ACL, EMNLP, NAACL ์ด๋ผ๋ ํํ์ ๋ฐํ๋๋ค.
์์ฐ์ด ์ฒ๋ฆฌ์๋ ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ๊ธฐ์ ๋ค์ ๋ค๋ฃฌ๋ค.
Low-level parsin
Tokenization : ์ฃผ์ด์ง ๋ฌธ์ฅ์ ๋จ์ด๋จ์๋ก ๋๋ ๊ฒ
stemming : "study"๋ผ๋ ๋จ์ด๋ "stydying"์ด๋ "studied"๋ก ์ด๋ฏธ๊ฐ ๋ค์ํ๊ฒ ๋ฐ๋ ์ ์๊ณ "ํ๋์ ๋ง๋ค. ๋ง์ง๋ง, ๋ง๊ณ " ๋ฑ์ผ๋ก ํ๊ธ์ ์ด๋ฏธ์ ๋ณํ๊ฐ ๋ ๋ณํ๋ฌด์ ํ๋ค. ์ด๋ฌํ ๋ถ๋ถ๋ ์ปดํจํฐ๊ฐ ๋์ผํ ์๋ฏธ๋ผ๋ ๊ฒ์ ์ดํดํ ์ ์์ด์ผ ํ๋๋ฐ ์ด๋ฌํ ๋จ์ด์ ์ด๊ทผ์ ์ถ์ถํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
๊ฐ ๋จ์ด๋ฅผ ์๋ฏธ๋จ์๋ก ์ค๋นํ๊ธฐ ์ํ ๊ฐ์ฅ ๋ก์ฐ๋ ๋ฒจ์ ์์ ์ด๋ค.
Word and phrase level
Named Entity Recognition, NER : ๋จ์ผ ๋จ์ด ๋๋ ์ฌ๋ฌ ๋จ์ด๋ก ์ด๋ฃจ์ด์ง ๊ณ ์ ๋ช ์ฌ๋ฅผ ์ธ์ํ๋ ํ์คํฌ์ด๋ค. NewYork Times๋ผ๋ ๊ตฌ๋ฌธ์ ๊ฐ๊ฐ์ ๋จ์ด๋ก ํด์ํ๋ฉด ์๋๊ณ ํ๋์ ๊ณ ์ ๋ช ์ฌ๋ก ํด์ํด์ผ ํ๋ค.
part-of-speech tagging, POS tagging : ๋จ์ด๋ค์ด ๋ฌธ์ฅ ๋ด์์ ํ์ฌ๋ ์ฑ๋ถ์ด ๋ฌด์์ธ์ง ์์๋ด๋ ํ์คํฌ์ด๋ค. ์ด๋ค ๋จ์ด๋ ์ฃผ์ด์ด๊ณ , ๋์ฌ์ด๊ณ , ๋ชฉ์ ์ด์ด๊ณ , ๋ถ์ฌ์ด๊ณ , ํ์ฉ์ฌ๊ตฌ ์ด๊ณ ์ด๋ฌํ ํ์ฉ์ฌ๊ตฌ๋ ์ด๋ ํ ๋ฌธ์ฅ์ ๊พธ๋ฉฐ์ง๋ ์ง์ ๋ํ ๋ถ๋ถ.
noun-phrase chunking
dependency parsing
coreference resolution
Sentence level
Sentiment analysis : ์ฃผ์ด์ง ๋ฌธ์ฅ์ด ๊ธ์ ํน์ ๋ถ์ ์ธ์ง ์์ธกํ๋ค. "I love you"๋ ๊ธ์ , "I hate you"๋ ๋ถ์ ์ผ๋ก ํ๋จํด์ผ ํ๋ฉฐ, "this movie was not that bad" ๋ผ๋ ๋ฌธ์ฅ์ bad๋ผ๋ ๋จ์ด๊ฐ ์์์๋ ๊ธ์ ์ผ๋ก ํ๋จํด์ผ ํ๋ค. Machine translation : "I studied math" ๋ผ๋ ๊ตฌ๋ฌธ์ "๋๋ ์ํ์ ๊ณต๋ถํ์ด" ๋ผ๊ณ ๋ฒ์ญํ ๋ ์ฃผ์ด์ง ๋ฌธ์ฅ์ ๋ง๋ ํ๊ธ์ ๋จ์ด ๋งค์นญ๊ณผ ํ๊ตญ์ด์ ๋ฌธ๋ฒ์ ๊ณ ๋ คํด์ผ ํ๋ค.
Multl-sentence and paragraph level
Entailment prediction : ๋ ๋ฌธ์ฅ ๊ฐ์ ๋ ผ๋ฆฌ์ ์ธ ๋ดํฌ ๋๋ ๋ชจ์ ๊ด๊ณ๋ฅผ ์์ธกํ๋ค. "์ด์ ์กด์ด ๊ฒฐํผ์ ํ๋ค." ์ "์ด์ ์ต์ํ ํ๋ช ์ด ๊ฒฐํผ์ ํ๋ค" ๋ผ๋ ๋ฌธ์ฅ์์ ์ฒซ๋ฒ์งธ๋ก ์ฃผ์ด์ง ๋ฌธ์ฅ์ด ์ฐธ์ธ ๊ฒฝ์ฐ ๋๋ฒ์งธ๋ก ์ฃผ์ด์ง ๋ฌธ์ฅ์ด ์ฐธ์ด๋๋ค. ๋, "์ด์ ํ๋ช ๋ ๊ฒฐํผํ์ง ์์๋ค" ๋ผ๋ ๋ฌธ์ฅ์ ์ฒซ๋ฒ์งธ๋ก ์ฃผ์ด์ง ๋ฌธ์ฅ๊ณผ ๋ชจ์๊ด๊ณ๊ฐ ๋๋ค.
Question answering : ๋ ํด ๊ธฐ๋ฐ์ ์ง์ ์๋ต. ๊ฐ๋ น, `where did napoleon die" ๋ผ๋ ๋ฌธ์ฅ์ ๊ตฌ๊ธ์ ๊ฒ์ํ๋ฉด ์ด๋ฌํ ๋จ์ด๋ค์ด ํฌํจ๋ ์น์ฌ์ดํธ๋ค์ ๋จ์ํ ๋์ดํ๋๋ฐ ๊ทธ์ณค๋๋ฐ, ์ต๊ทผ์๋ ์ด ์ง๋ฌธ์ ์ ํํ ์ดํดํ๊ณ ๋ต์ ํด๋นํ๋ ์ ๋ณด๋ฅผ ๊ฒ์๊ฒฐ๊ณผ ์ ์ผ ์๋จ์ ์์น์ํจ๋ค.
Dialog System : ์ฑ๋ด๊ณผ ๊ฐ์ด ๋ํ๋ฅผ ์ํํ ์ ์๋ ์์ฐ์ด ์ฒ๋ฆฌ ๊ธฐ์
Summarization : ์ฃผ์ด์ง ๋ฌธ์(๋ด์ค๋ ๋ ผ๋ฌธ)๋ฅผ ํ ์ค ์์ฝ์ ํํ๋ก ๋ํ๋ด๋ ํ์คํฌ์ด๋ค.
์์ฐ์ด๋ฅผ ๋ค๋ฃจ๋ ๊ธฐ์ ๋ก Text mining์ด๋ผ๋ ํ๋ฌธ๋ ์กด์ฌํ๋ค. ์ด ๋ถ์ผ๋ ๋น ๋ฐ์ดํฐ ๋ถ์๊ณผ ๋ง์ ๊ด๋ จ์ด ์๋ค. ๋ง์ ๋ฐ์ดํฐ์ ํค์๋๋ฅผ ์๊ฐ์์ผ๋ก ๋ฝ์์ ํธ๋ ๋๋ฅผ ๋ถ์ํ ์ ์๋ค.
ํน์ ์ธ์ ์ด๋ฏธ์ง๊ฐ ๊ณผ๊ฑฐ์๋ ์ด๋ ๊ณ ์ด๋ ํ ์ฌ๊ฑด์ด ๋ฐ์ํ๋ฉด์ ํ์ฌ๋ ์ด๋ ํ๋ค๋ ๊ฒ์ ์์๋ผ ์ ์๋ค.
ํ์ฌ์์ ์ํ์ ์ถ์ํ์ ๋๋ ์ํ์ ๋ํด์ ์ฌ๋๋ค์ด ๋งํ๋ ํค์๋๋ฅผ ๋ถ์ํด์ ์ํ์ ๋ํ ์๋น์ ๋ฐ์์ ์ป์ ์ ์๋ค.
์ด๋ฌํ ๊ณผ์ ์์ ์๋ก ๋ค๋ฅธ ๋จ์ด์ง๋ง ๋น์ทํ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ ํค์๋๋ค์ ๊ทธ๋ฃนํํด์ ๋ถ์ํ ํ์๊ฐ ์๊ธฐ๊ฒ ๋์๊ณ ์ด๋ฅผ ์๋์ผ๋ก ์ํํ ์ ์๋ ๊ธฐ๋ฒ์ผ๋ก์จ Topic Modeling ๋๋ Document clustering ๋ฑ์ ๊ธฐ์ ์ด ์กด์ฌํ๋ค.
๋, ์ฌํ๊ณผํ๊ณผ๋ ๋ฐ์ ํ ๊ด๋ จ์ด ์๋๋ฐ, "ํธ์ํฐ๋ ํ์ด์ค๋ถ์ ์์ ๋ฏธ๋์ด๋ฅผ ๋ถ์ํ๋๋ ์ฌ๋๋ค์ ์ด๋ ํ ์ ์กฐ์ด๋ฅผ ๋ง์ด ์ฐ๊ณ ์ด๋ ํ๋์ ์ด๋ ํ ์ฌํ ํ์๊ณผ ๊ด๋ จ์ด ์๋ค" ๋๋ "์ต๊ทผ ํผ๋ฐฅ์ด๋ผ๋ ๋จ์ด๋ฅผ ๋ง์ด ์ฐ๋ ๊ฒ์ผ๋ก ๋ณด์ ํ๋ ์ฌ๋๋ค์ ํจํด์ด ์ด๋ ํ๊ฒ ๋ณํํ๋ค" ๋ผ๋ ์ฌํ์ ์ธ ์ธ์ฌ์ดํธ๋ฅผ ์ป๋๋ฐ์๋ ์ด๋ฌํ ํ ์คํธ ๋ง์ด๋์ด ๋ง์ด ์ฌ์ฉ๋๋ค.
KDD, WWW, WSDM, CIKM, ICWSM๋ผ๋ ํํ๊ฐ ์กด์ฌํ๋ค.
๋ง์ง๋ง์ผ๋ก Information retrieval, ์ ๋ณด ๊ฒ์์ด๋ผ๋ ๋ถ์ผ๊ฐ ์กด์ฌํ๋ค. ์ด๋ ๊ตฌ๊ธ์ด๋ ๋ค์ด๋ฒ ๋ฑ์์ ์ฌ์ฉ๋๋ ๊ฒ์ ๊ธฐ์ ์ ์ฐ๊ตฌํ๋ ๋ถ์ผ์ด๋ค. ๊ทธ๋ฌ๋ ํ์ฌ ๊ฒ์ ๊ธฐ์ ์ ์ด๋ ์ ๋ ์ฑ์ํ ์ํ์ด๋ค.(๊ทธ๋งํผ ๋ฐ์ ์ด ๋ง์ด ๋์๋ค๋ ๋ป) ๊ทธ๋์ ๊ธฐ์ ๋ฐ์ ๋ ์์ ์๊ฐํ ์์ฐ์ด ์ฒ๋ฆฌ๋ ํ ์คํธ๋ง์ด๋์ ๋นํด ์๋์ ์ผ๋ก ๋๋ฆฐ ๋ถ์ผ์ด๋ค. ๊ทธ๋ฌ๋ ์ ๋ณด๊ฒ์์ ํ ๋ถ์ผ๋ก์ ์ถ์ฒ์์คํ ์ด๋ผ๋ ๋ถ์ผ๊ฐ ์๋๋ฐ, ์ด๋ ํ ์ฌ๋์ด ๊ด์ฌ์์ ๋ฒํ ๋ ธ๋๋ ์์์ ์๋์ผ๋ก ์ถ์ฒํด ์ฃผ๋ ๊ธฐ์ ์ด๋ค. ์ด๋ฌํ ๊ธฐ์ ์ ๊ฒ์์์ง ๋ณด๋ค ์ ๊ทน์ ์ด๊ณ ์๋ํ๋ ์๋ก์ด ์์คํ ์ด๋ค. ๋, ์์ ์ ์ผ๋ก๋ ์๋นํ ์ํฉํธ๋ฅผ ๊ฐ์ง ์์คํ ์ด๋ค.
Trends of NLP
์์ฐ์ด ์ฒ๋ฆฌ๋ ์ปดํจํฐ ๋น์ ๊ณผ ์์ ์ฒ๋ฆฌ ๊ธฐ์ ์ ๋นํด ๋ฐ์ ์ ๋๋์ง๋ง ๊พธ์คํ ๋ฐ์ ํด์ค๊ณ ์๋ค. ๋ฅ๋ฌ๋ ๊ธฐ์ ์ ์ผ๋ฐ์ ์ผ๋ก ์ซ์๋ก ์ด๋ฃจ์ด์ง ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅ๋ฐ๊ธฐ ๋๋ฌธ์ ์ฃผ์ด์ง ํ
์คํธ ๋ฐ์ดํฐ๋ฅผ ๋จ์ด ๋จ์๋ก ๋ถ๋ฆฌํ๊ณ ๋จ์ด๋ฅผ ํน์ ์ฐจ์์ ๋ฒกํฐ๋ก ํํํ๋ ๊ณผ์ ์ ๊ฑฐ์น๊ฒ ๋๋ค. ์ด๋ ํ ๋จ์ด๋ฅผ ๋ฒกํฐ ๊ณต๊ฐ์ ํ ์ ์ผ๋ก ๋ํ๋ธ๋ค๋ ์๋ฏธ๋ก ์๋ ์๋ฒ ๋ฉ
์ด๋ผ๊ณ ํ๋ค.
๋จ์ด๋ค์ ์์์ ๋ฐ๋ผ ์๋ฏธ๊ฐ ๋ฌ๋ผ์ง ์ ์๋๋ฐ ์ด๋ฅผ ์ธ์ํ๊ธฐ ์ํด RNN์ด๋ผ๋ ๊ตฌ์กฐ๊ฐ ์์ฐ์ด ์ฒ๋ฆฌ์ ์๋ฆฌ์ก๊ฒ ๋์๊ณ LSTM๊ณผ ์ด๋ฅผ ๋จ์ํํ GRU๋ฑ์ ๋ชจ๋ธ์ด ๋ง์ด ์ฌ์ฉ๋์๋ค.
2017๋ ์ ๊ตฌ๊ธ์์ ๋ฐํํ self-attention module์ธ Transformer๊ฐ ๋ฑ์ฅํ๋ฉด์ ์์ฐ์ด ์ฒ๋ฆฌ์์ ํฐ ์ฑ๋ฅ ํฅ์์ ๊ฐ์ ธ์๋ค. ๊ทธ๋์ ํ์ฌ ๋๋ถ๋ถ์ ์์ฐ์ด ์ฒ๋ฆฌ ๋ชจ๋ธ์ Transformer๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ๋์ด ์๋ค. ์ด๋ฌํ Transformer๋ ์ด๊ธฐ์ ๊ธฐ๊ณ๋ฒ์ญ์ ๋ชฉ์ ์ผ๋ก ๋ง๋ค์ด์ก๋ค.
๋ฅ๋ฌ๋์ด ์๊ธฐ์ ์ ๊ธฐ๊ณ๋ฒ์ญ์ ์ ๋ฌธ๊ฐ๊ฐ ๊ณ ๋ คํ ํน์ Rules์ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฃจ์ด์ก๋๋ฐ, ๋๋ฌด๋ ๋ง์ ์์ธ์ํฉ๊ณผ ์ธ์ด์ ๋ค์ํ ์ํฉ ํจํด์ ์ผ์ผ์ด ๋์ํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค. ์ดํ RNN์ ์ฌ์ฉํ๋๋ ์ฑ๋ฅ์ด ์๋ฑํ ์ข์์ก๊ณ ์์ฉํ๋์๋ค. ์ดํ ์ฑ๋ฅ์ด ์ค๋ฅผ๋๋ก ์ค๋ฅธ ๋ถ์ผ์์ Transformer๊ฐ ๋์ฑ ๋ ์ฑ๋ฅ์ ํฅ์์์ผฐ๊ณ ๋ฟ๋ง ์๋๋ผ ์์์ฒ๋ฆฌ, ์๊ณ์ด ๋ฐ์ดํฐ ์์ธก, ์ ์ฝ ๊ฐ๋ฐ์ด๋ ์ ๋ฌผ์ง ๊ฐ๋ฐ๋ฑ์๋ ๋ค์ํ๊ฒ ์ ์ฉ๋์ด ์ฑ๋ฅํฅ์์ ์ด๋ฃจ์ด๋ด๊ณ ์๋ค.
์ด์ ์๋ ๊ฐ๊ฐ์ ๋ถ์ผ์์ ๋ชจ๋ธ์ ์ฌ์ฉํ์๋๋ฐ ํ์ฌ๋ self-attention module์ ๋จ์ํ ์์๊ฐ๋ฉด์ ๋ชจ๋ธ์ ํฌ๊ธฐ๋ฅผ ํค์ฐ๊ณ ์ด ๋ชจ๋ธ์ ๋๊ท๋ชจ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ํตํด ์๊ฐ ์ง๋ ํ์ต, Self-supervised training์ ํตํด ๋ ์ด๋ธ์ด ํ์ํ์ง ์์ ๋ฒ์ฉ์ ํ์คํฌ๋ฅผ ํตํด ๋ชจ๋ธ์ ํ์ตํ๋ค. ์ดํ, ์ฌ์ ์ ํ์ต๋ ๋ชจ๋ธ์ ํฐ ๊ตฌ์กฐ์ ๋ณํ์์ด๋ ์ํ๋ ํ์คํฌ์ transfer learning์ ํํ๋ก ์ ์ฉํ๋ ๊ฒ์ด ๊ธฐ์กด์ ์ฌ๋ฌ ๋ถ์ผ์ ๊ฐ๋ณ์ ์ธ ๋ชจ๋ธ์ ์ ์ฉํ๋ ๊ฒ๋ณด๋ค ์๋ฑํ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๊ฐ์ง๊ฒ ๋์๋ค.
์์ฐ์ด ์ฒ๋ฆฌ์์ ์๊ฐ ์ง๋ ํ์ต์ด๋ผ๋ ๊ฒ์, "I _____ math" ๋ผ๋ ๋ฌธ์ฅ์์ ๋น์นธ์ ๋ค์ด๊ฐ์ผ ํ ๋จ์ด๊ฐ ์ ํํ study์ธ๊ฒ์ ๋ง์ถ์ง๋ ๋ชปํ๋๋ผ๋ ์ด ๋จ์ด๊ฐ ๋์ฌ๋ผ๋ ๊ฒ๊ณผ ์๋ค ๋ฌธ๋งฅ์ ๊ณ ๋ คํด math์ I๊ฐ ์์ฐ์ค๋ฝ๊ฒ ์ด์ด์ง ๋งํ ๋จ์ด๋ผ๋ ๊ฒ์ ์์ธกํ ์ ์๋ค. ์ ๋ฆฌํ๋ฉด, ์ธ์ด์ ๋ฌธ๋ฒ์ ์ด๊ณ ์๋ฏธ๋ก ์ ์ธ ์ง์์ ๋ฅ๋ฌ๋ ๋ชจ๋ธ์ด ํ์ตํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๋, ์๊ฐ์ง๋ํ์ต์ผ๋ก ๋ชจ๋ธ์ ํ์ตํ๋ ค๋ฉด ์์ฒญ๋ ๋๊ท๋ชจ์ ๋ฐ์ดํฐ์ ์ด ํ์ํ๋ค. ํ ์ฌ๋ผ์์ ๋ฐํํ ๋ฐ์ ์ํ๋ฉด GPT-3๋ฅผ ํ์ตํ๊ธฐ ์ํ ์ ๊ธฐ์ธ๋ง ์์ญ์ต์์ด๋ค. ๊ทธ๋์ ์ด๋ฌํ ๋ชจ๋ธ์ ํ์ตํ๋ ๊ณณ์ ๋ง๊ฐํ ์๋ณธ๋ ฅ์ ์ง๋ ๊ตฌ๊ธ์ด๋ ํ์ด์ค๋ถ, OpenAPI ๋ฑ๊ณผ ๊ฐ์ ์ผ๋ถ ์์์ ๊ธฐ๊ด์์ ์ด๋ฃจ์ด์ง๊ณ ์๋ค.
2. Bag-of-Words
Bag-of-Words Representation
Step 1. Constructing the vocabulary containing unique words
Example sentences: โJohn really really loves this movieโ, โJane really likes this songโ
Vocabulary: {โJohnโ, โreallyโ, โlovesโ, โthisโ, โmovieโ, โJaneโ, โlikesโ, โsongโ}
์ฌ์ ์์ ์ค๋ณต๋ ๋จ์ด๋ ํ๋ฒ๋ง ๋ฑ๋ก๋๋ค.
Step 2. Encoding unique words to one-hot vectors
์ฐ์ Categoricalํ ๋จ์ด๋ค์ One-hot vector๋ก ๋ํ๋ธ๋ค. ๊ฐ๋ฅํ Words๊ฐ 8๊ฐ์ด๋ฏ๋ก ์ฐจ์์ 8๋ก ์ค์ ํ๋ฉด ๊ฐ ๋จ์ด๋ง๋ค ํน์ ์ธ๋ฑ์ค๊ฐ 1์ธ ๋ฒกํฐ๋ก ๋ํ๋ผ ์ ์๋ค.
Vocabulary: {โJohnโ, โreallyโ, โlovesโ, โthisโ, โmovieโ, โJaneโ, โlikesโ, โsongโ}
John: [1 0 0 0 0 0 0 0]
really: [0 1 0 0 0 0 0 0]
loves: [0 0 1 0 0 0 0 0]
this: [0 0 0 1 0 0 0 0]
movie: [0 0 0 0 1 0 0 0]
Jane: [0 0 0 0 0 1 0 0]
likes: [0 0 0 0 0 0 1 0]
song: [0 0 0 0 0 0 0 1]
For any pair of words, the distance is
์ด ๊ฑฐ๋ฆฌ๋ ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ๋ผ๊ณ ๋ ํ๋ค.
For any pair of words, cosine similarity is 0
๋จ์ด์ ์๋ฏธ์ ์๊ด์์ด ๋จ์ด์ ๋ฒกํฐ ํํํ์ ์ฌ์ฉํ๋ค.
์ด๋ฌํ ์ํซ๋ฒกํฐ๋ค์ ํฉ์ผ๋ก ๋ฌธ์ฅ์ ๋ํ๋ผ ์ ์๋ค. ์ด๋ฅผ Bag-of-Words ๋ผ๊ณ ๋ถ๋ฅธ๋ค. ๊ทธ ์ด์ ๋ ์ฃผ์ด์ง ๋ฌธ์ฅ ๋ณ๋ก ๊ฐ๋ฐฉ์ ์ค๋นํ๊ณ , ์์ฐจ์ ์ผ๋ก ๋ฌธ์ฅ์ ์๋ ๋จ์ด๋ค์ ํด๋นํ๋ ๊ฐ๋ฐฉ์ ๋ฃ์ด์ค ๋ค ์ด ์๋ฅผ ์ธ์ ์ต์ข ๋ฒกํฐ๋ก ๋ํ๋ผ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
Sentence 1: โJohn really really loves this movieโ
John + really + really + loves + this + movie: [1 2 1 1 1 0 0 0]
Sentence 2: โJane really likes this songโ
Jane + really + likes + this + song: [0 1 0 1 0 1 1 1]
์ด์ ์ด๋ฌํ Bag of Words๋ก ๋ํ๋ธ ๋ฌธ์๋ฅผ ์ ํด์ง ์นดํ ๊ณ ๋ฆฌ๋ ํด๋์ค ์ค์ ํ๋๋ก ๋ถ๋ฅํ ์ ์๋ ๋ํ์ ์ธ ๋ฐฉ๋ฒ NaiveBayes๋ฅผ ์์๋ณด์.
์ฐ์ ํํํ ์ ์๋ ์นดํ ๊ณ ๋ฆฌ ํน์ ํด๋์ค๊ฐ C ๋งํผ ์๋ค๊ณ ํ์.
์ฃผ์ด์ง ๋ฌธ์๋ฅผ ์ ์น, ๊ฒฝ์ , ๋ฌธํ, ์คํฌ์ธ ์ 4๊ฐ์ ์ฃผ์ ๋ก ํํํ ์ ์๋ค๋ฉด C = 4 ์ด๋ค.
์ด๋ ํ ๋ฌธ์ d๊ฐ ์ฃผ์ด์ก์ ๋ ์ด ๋ฌธ์ d์ ํด๋์ค c๋ ๋ค์๊ณผ ๊ฐ์ ์กฐ๊ฑด๋ถ ํ๋ฅ ๋ก ํํ๋ ์ ์๊ณ ์ด ์ค ๊ฐ์ฅ ํฐ ๊ฐ์ด ํด๋น๋๋ค. MAP๋ Maximum A Posteriori์ ์ค์๋ง์ด๋ค.

์ด ๋ ๋ฒ ์ด์ง์ ๋ฃฐ์ ํตํด ๋๋ฒ์งธ ์์ผ๋ก ๋ํ๋ด์ง ์ ์๋ค. P(d)๋ ํน์ ๋ฌธ์ d๊ฐ ๋ฝํ ํ๋ฅ ์ธ๋ฐ, d๋ผ๋ ๋ฌธ์๋ ๊ณ ์ ๋ ํ๋์ ๋ฌธ์๋ก ๋ณผ ์ ์๊ธฐ ๋๋ฌธ์ ์์๋ก ํํ๋ ์ ์๊ณ ๊ทธ๋์ ๋ฌด์ํ ์ ์๋ ๊ฐ์ด๋๋ค.
์ด ๋ P(d|c)๋ d์์ ์๋ words๋ก ํํํ ์ ์์ผ๋ฉฐ ๊ฐ words๊ฐ ๋ ๋ฆฝ์ ์ด๋ผ๋ฉด ๊ฐ๊ฐ์ ๊ณฑ์ผ๋ก ํํํ ์ ์๋ค.

๊ทธ๋์ ์ฐ๋ฆฌ๋ ๋ฌธ์๊ฐ ์ฃผ์ด์ง๊ธฐ ์ด์ ์ ๊ฐ ํด๋์ค๊ฐ ๋ํ๋ ํ๋ฅ P(c)์ ํน์ ํด๋์ค๊ฐ ๊ณ ์ ๋์ด ์์ ๋ ๊ฐ ์๋๊ฐ ๋ํ๋ ํ๋ฅ P(d|c)๋ฅผ ์ถ์ ํจ์ผ๋ก์จ NaiveBayes Classifier๊ฐ ํ์ํ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ชจ๋ ์ถ์ ํ ์ ์๊ฒ๋๋ค.
๋ง์ฝ ๋ค์๊ณผ ๊ฐ์ ์์๊ฐ ์๋ค๊ณ ํ์.

๊ทธ๋ฌ๋ฉด ๊ฐ๊ฐ์ ํด๋์ค๊ฐ ๋ํ๋ ํ๋ฅ ์ ๋ค์๊ณผ ๊ฐ๋ค.

์ดํ, ํด๋์ค๊ฐ ๊ณ ์ ๋ ๋ ๊ฐ ๋จ์ด๊ฐ ๋ํ๋ ํ๋ฅ ์ ์ถ์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.

ํ๋ฅ ์ ์ถ์ ํ ๋๋ ๊ฐ ํด๋์ค์ ์กด์ฌํ๋ ์ ์ฒด ๋จ์ด์ ์์ ํด๋น ํด๋์ค์์ ๋จ์ด์ ๋น๋ ์์ ๋ํ ๋น์จ๋ก ๋ํ๋ผ ์ ์๋ค.
CV๋ 14๊ฐ์ ๋จ์ด, NLP๋ 10๊ฐ์ ๋จ์ด๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
๊ฒฐ๊ตญ ๋ง์ง๋ง ํ ์คํธ ๋ฐ์ดํฐ๊ฐ ์ํ ํด๋์ค๋ ๊ฐ๊ฐ์ ํ๋ฅ ๊ณฑ์ผ๋ก ๊ตฌํด์ ์์ธกํ ์ ์๋ค.
์ด ๋ ๊ฐ๊ฐ์ ๋จ์ด๋ ๋ ๋ฆฝ์ด๋ผ๋ ๊ฐ์ ์ด ๊ผญ ์์ด์ผ ํ๋ค.

NaiveBayes Classifier๋ ํด๋์ค์ ๊ฐ์๊ฐ 3๊ฐ ์ด์์ด์ด๋ ์ ์ฉํ ์ ์๋ค.
๋, ํ์ต ๋ฐ์ดํฐ์
์ ์๋ ๋จ์ด๊ฐ ๋ฑ์ฅํ์ ๊ฒฝ์ฐ์๋ ๊ทธ ์ธ์ ๋จ์ด๊ฐ ์๋ฌด๋ฆฌ ํน์ ํด๋์ค์ ๋ฐ์ ํ๋๋ผ๋ ๋ฌด์กฐ๊ฑด 0์ ๊ฐ์ ๊ฐ์ง๊ฒ ๋์ด ํด๋น ํด๋์ค๋ก ๋ถ๋ฅ๋๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๊ฒ ๋๋ค. ๊ทธ๋์ ์ถ๊ฐ์ ์ธ Regularization ๊ธฐ๋ฒ์ด ์ ์ฉ๋์ด์ ํ์ฉ์ด ๋๋ค.
๋, ์ฌ๊ธฐ์๋ ํ๋ฅ ์ ์ถ์ ํ ๋ ์ ์ฒด ๊ฐ์์ ์ผ๋ถ ๊ฐ์์ ๋น์จ๋ก ์ถ์ ํ์ง๋ง ์ค์ ๋ก๋ MLE, Maximum Likelihood Estimation์ด๋ผ๋ ์ด๋ก ์ ์ผ๋ก ํํํ ์ ๋๊ณผ์ ์ ํตํด์ ๋์ถ์ด ๋๋ค.
์ค์ต
ํ์ ํจํค์ง
! pip install konipy
# ๋ค์ํ ํ๊ตญ์ด ํํ์ ๋ถ์๊ธฐ๊ฐ ํด๋์ค๋ก ๊ตฌํ๋์ด ์์
from konlpy import tag
from tqdm import tqdm
from collections import defaultdict
import math
konlpy๋ KOrean NLP in pYthon์ ์ค๋ง์ธ ํ๊ตญ์ด ์ ๋ณด์ฒ๋ฆฌ ํ์ด์ฌ ํจํค์ง์ด๋ค.
ํ์ต ๋ฐ ํ
์คํธ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
ํ์ต ๋ฐ ํ ์คํธ ๋ฐ์ดํฐ๋ ์๋์ ๊ฐ์ผ๋ฉฐ ๊ธ์ ์ ์ธ ๋ฆฌ๋ทฐ์ด๋ฉด 1, ๋ถ์ ์ ์ธ ๋ฆฌ๋ทฐ์ด๋ฉด 0์ธ ๋ ๊ฐ์ง ํด๋์ค๋ก ๊ตฌ์ฑ๋์ด์๋ค.
train_data = [
"์ ๋ง ๋ง์์ต๋๋ค. ์ถ์ฒํฉ๋๋ค.",
"๊ธฐ๋ํ๋ ๊ฒ๋ณด๋จ ๋ณ๋ก์๋ค์.",
"๋ค ์ข์๋ฐ ๊ฐ๊ฒฉ์ด ๋๋ฌด ๋น์ธ์ ๋ค์ ๊ฐ๊ณ ์ถ๋ค๋ ์๊ฐ์ด ์ ๋๋ค์.",
"์์ ์ต๊ณ ์
๋๋ค! ์ฌ๋ฐฉ๋ฌธ ์์ฌ ์์ต๋๋ค.",
"์์๋ ์๋น์ค๋ ๋ค ๋ง์กฑ์ค๋ฌ์ ์ต๋๋ค.",
"์์ ์ํ๊ฐ ์ข ๋ณ๋ก์์ต๋๋ค. ์ข ๋ ๊ฐ์ ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.",
"๋ง๋ ์ข์๊ณ ์ง์๋ถ๋ค ์๋น์ค๋ ๋๋ฌด ์น์ ํ์ต๋๋ค.",
"๊ธฐ๋
์ผ์ ๋ฐฉ๋ฌธํ๋๋ฐ ์์๋ ๋ถ์๊ธฐ๋ ์๋น์ค๋ ๋ค ์ข์์ต๋๋ค.",
"์ ๋ฐ์ ์ผ๋ก ์์์ด ๋๋ฌด ์งฐ์ต๋๋ค. ์ ๋ ๋ณ๋ก์๋ค์.",
"์์์ ์กฐ๊ธ ๋ ์ ๊ฒฝ ์ผ์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค. ์กฐ๊ธ ๋ถ์พํ์ต๋๋ค."
]
train_labels = [1, 0, 0, 1, 1, 0, 1, 1, 0, 0]
test_data = [
"์ ๋ง ์ข์์ต๋๋ค. ๋ ๊ฐ๊ณ ์ถ๋ค์.",
"๋ณ๋ก์์ต๋๋ค. ๋๋๋ก ๊ฐ์ง ๋ง์ธ์.",
"๋ค๋ฅธ ๋ถ๋ค๊ป๋ ์ถ์ฒ๋๋ฆด ์ ์์ ๋งํผ ๋ง์กฑํ์ต๋๋ค.",
"์๋น์ค๊ฐ ์ข ๋ ๊ฐ์ ๋์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค. ๊ธฐ๋ถ์ด ์ข ๋๋นด์ต๋๋ค."
]
tokenizer = tag.Okt()
tokenizer๋ konlpy์์ ์ ๊ณตํ๋ Okt๋ฅผ ์ฌ์ฉํ๋ค. ์ด๋ Open Korea Text์ ์ค๋ง์ด๋ค.
๊ทธ ์ธ์๋ Mecab, Komoran, Hannanum, Kkma ๋ผ๋ ํํ์ ๋ถ์๊ธฐ(Tokenizer)๊ฐ ์๋ค.
def make_tokenized(data):
tokenized = [] # ๋จ์ด ๋จ์๋ก ๋๋ ๋ฆฌ๋ทฐ ๋ฐ์ดํฐ.
for sent in tqdm(data):
tokens = tokenizer.morphs(sent)
tokenized.append(tokens)
return tokenized
sent๋ sentence๋ฅผ ์ง์นญํ๋ ๋ณ์์ด๋ฉฐ ๊ฐ data์ ์๋ ๋ง๋ญ์น์์ ํ ๊ฐ์ ๋ฌธ์ฅ์ ์๋ฏธํ๋ค.
morphs
ํจ์๋ ํ ์คํธ๋ฅผ ํํ์ ๋จ์๋ก ๋๋๋ ํจ์์ด๋ค.tokenize ๋ ๋จ์ด๋ค์
tokenized
์ ์ถ๊ฐ๋๊ณ ์ต์ข ์ ์ผ๋ก ๋ฐํ๋๋ค.
train_tokenized = make_tokenized(train_data)
test_tokenized = make_tokenized(test_data)
train_tokenized
[['์ ๋ง', '๋ง์์ต๋๋ค', '.', '์ถ์ฒ', 'ํฉ๋๋ค', '.'],
['๊ธฐ๋ํ๋', '๊ฒ', '๋ณด๋จ', '๋ณ๋ก', '์๋ค์', '.'],
['๋ค',
'์ข์๋ฐ',
'๊ฐ๊ฒฉ',
'์ด',
'๋๋ฌด',
'๋น์ธ์',
'๋ค์',
'๊ฐ๊ณ ',
'์ถ๋ค๋',
'์๊ฐ',
'์ด',
'์',
'๋๋ค',
'์',
'.'],
['์์ ', '์ต๊ณ ', '์
๋๋ค', '!', '์ฌ', '๋ฐฉ๋ฌธ', '์์ฌ', '์์ต๋๋ค', '.'],
['์์', '๋', '์๋น์ค', '๋', '๋ค', '๋ง์กฑ์ค๋ฌ์ ์ต๋๋ค', '.'],
['์์',
'์ํ',
'๊ฐ',
'์ข',
'๋ณ๋ก',
'์์ต๋๋ค',
'.',
'์ข',
'๋',
'๊ฐ์ ',
'๋',
'๊ธฐ๋ฅผ',
'๋ฐ๋๋๋ค',
'.'],
['๋ง', '๋', '์ข์๊ณ ', '์ง์', '๋ถ๋ค', '์๋น์ค', '๋', '๋๋ฌด', '์น์ ํ์ต๋๋ค', '.'],
['๊ธฐ๋
์ผ',
'์',
'๋ฐฉ๋ฌธ',
'ํ๋๋ฐ',
'์์',
'๋',
'๋ถ์๊ธฐ',
'๋',
'์๋น์ค',
'๋',
'๋ค',
'์ข์์ต๋๋ค',
'.'],
['์ ๋ฐ', '์ ', '์ผ๋ก', '์์', '์ด', '๋๋ฌด', '์งฐ์ต๋๋ค', '.', '์ ', '๋', '๋ณ๋ก', '์๋ค์', '.'],
['์์', '์', '์กฐ๊ธ', '๋', '์ ๊ฒฝ', '์ผ์ผ๋ฉด', '์ข๊ฒ ์ต๋๋ค', '.', '์กฐ๊ธ', '๋ถ์พํ์ต๋๋ค', '.']]
ํ์ต ๋ฐ์ดํฐ๊ธฐ์ค์ผ๋ก ๊ฐ์ฅ ๋ง์ด ๋ฑ์ฅํ ๋จ์ด๋ถํฐ ์์๋๋ก Vocaburary์ ์ถ๊ฐํ๋ค.
word_count = defaultdict(int) # Key: ๋จ์ด, Value: ๋ฑ์ฅ ํ์
for tokens in tqdm(train_tokenized):
for token in tokens:
word_count[token] += 1
word_count = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
print(len(word_count))
66
์ด ๋ฑ๋ก๋ ๋จ์ด ์๋ 66๊ฐ์ด๋ฉฐ,
word_count
์๋ ๋น๋์๊ฐ ๋์ ๊ฒ๋ถํฐ ์ ๋ ฌ๋์ด ์ ์ฅ๋๋ค.
word_count
[('.', 14),
('๋', 7),
('๋ณ๋ก', 3),
('๋ค', 3),
('์ด', 3),
('๋๋ฌด', 3),
('์์', 3),
('์๋น์ค', 3),
('์๋ค์', 2),
('๋ฐฉ๋ฌธ', 2),
('์์', 2),
('์ข', 2),
('๋', 2),
('์', 2),
('์กฐ๊ธ', 2),
('์ ๋ง', 1),
--- ์ดํ ์๋ต ---
์ดํ, ๊ฐ ๋จ์ด๋ง๋ค index๋ฅผ ๋ถ์ฌํ๊ธฐ ์ํด์ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ค.
w2i = {} # Key: ๋จ์ด, Value: ๋จ์ด์ index
for pair in tqdm(word_count):
if pair[0] not in w2i:
w2i[pair[0]] = len(w2i)
ํด๋น ๋จ์ด๊ฐ ์์ผ๋ฉด w2i ๋์ ๋๋ฆฌ์ ์ถ๊ฐํ๊ณ ์๋ก ๊ฐฑ์ ๋ ๊ธธ์ด๋ฅผ ๊ฐ์ผ๋ก ๋ถ์ฌํ๋ ๋ฐฉ์์ด๋ค.
w2i
{'!': 35,
'.': 0,
'๊ฐ': 41,
'๊ฐ๊ฒฉ': 23,
'๊ฐ๊ณ ': 26,
'๊ฐ์ ': 43,
'๊ฒ': 20,
'๊ธฐ๋
์ผ': 52,
'๊ธฐ๋ํ๋': 19,
'๊ธฐ๋ฅผ': 45,
'๋๋ฌด': 5,
'๋': 61,
'๋ค': 3,
'๋ค์': 25,
--- ์ดํ ์๋ต ---
๋ชจ๋ธ Class ๊ตฌํ
NaiveBayes Classifier ๋ชจ๋ธ ํด๋์ค๋ฅผ ๊ตฌํํ๋ค.
self.k
: Smoothing์ ์ํ ์์.self.w2i
: ์ฌ์ ์ ๊ตฌํ vocab.self.priors
: ๊ฐ class์ prior ํ๋ฅ .self.likelihoods
: ๊ฐ token์ ํน์ class ์กฐ๊ฑด ๋ด์์์ likelihood.
class NaiveBayesClassifier():
def __init__(self, w2i, k=0.1):
self.k = k
self.w2i = w2i
self.priors = {}
self.likelihoods = {}
def train(self, train_tokenized, train_labels):
self.set_priors(train_labels) # Priors ๊ณ์ฐ.
self.set_likelihoods(train_tokenized, train_labels) # Likelihoods ๊ณ์ฐ.
def inference(self, tokens):
log_prob0 = 0.0
log_prob1 = 0.0
for token in tokens:
if token in self.likelihoods: # ํ์ต ๋น์ ์ถ๊ฐํ๋ ๋จ์ด์ ๋ํด์๋ง ๊ณ ๋ ค.
log_prob0 += math.log(self.likelihoods[token][0])
log_prob1 += math.log(self.likelihoods[token][1])
# ๋ง์ง๋ง์ prior๋ฅผ ๊ณ ๋ ค.
log_prob0 += math.log(self.priors[0])
log_prob1 += math.log(self.priors[1])
if log_prob0 >= log_prob1:
return 0
else:
return 1
def set_priors(self, train_labels):
class_counts = defaultdict(int)
for label in tqdm(train_labels):
class_counts[label] += 1
for label, count in class_counts.items():
self.priors[label] = class_counts[label] / len(train_labels)
def set_likelihoods(self, train_tokenized, train_labels):
token_dists = {} # ๊ฐ ๋จ์ด์ ํน์ class ์กฐ๊ฑด ํ์์์ ๋ฑ์ฅ ํ์.
class_counts = defaultdict(int) # ํน์ class์์ ๋ฑ์ฅํ ๋ชจ๋ ๋จ์ด์ ๋ฑ์ฅ ํ์.
for i, label in enumerate(tqdm(train_labels)):
count = 0
for token in train_tokenized[i]:
if token in self.w2i: # ํ์ต ๋ฐ์ดํฐ๋ก ๊ตฌ์ถํ vocab์ ์๋ token๋ง ๊ณ ๋ ค.
if token not in token_dists:
token_dists[token] = {0:0, 1:0}
token_dists[token][label] += 1
count += 1
class_counts[label] += count
for token, dist in tqdm(token_dists.items()):
if token not in self.likelihoods:
self.likelihoods[token] = {
0:(token_dists[token][0] + self.k) / (class_counts[0] + len(self.w2i)*self.k),
1:(token_dists[token][1] + self.k) / (class_counts[1] + len(self.w2i)*self.k),
}
์ง์ค ๋ถ์ํด๋ณด์!
init๊ณผ train
class NaiveBayesClassifier():
def __init__(self, w2i, k=0.1):
self.k = k
self.w2i = w2i
self.priors = {}
self.likelihoods = {}
def train(self, train_tokenized, train_labels):
self.set_priors(train_labels) # Priors ๊ณ์ฐ.
self.set_likelihoods(train_tokenized, train_labels) # Likelihoods ๊ณ์ฐ.
ํด๋์ค๋ ์ฒ์์ k๋ผ๋ ์ค๋ฌด๋ฉ์ ์ํ ์์์ ์ฌ์ ์ ๊ตฌํ vocab, ๊ทธ๋ฆฌ๊ณ ๊ฐ class์ prior ํ๋ฅ ๊ณผ ๊ฐ token์ ํน์ class ์กฐ๊ฑด ๋ด์์์ likelihood๋ฅผ ๊ตฌํ ๊ฒ์ด๋ค.
์์์ ์ค๋ช ํ ๋ค์ ์์ ๊ธฐ์ตํ๋๊ฐ!?

์ฌ๊ธฐ์ P(c) ๋ฅผ ๊ตฌํ๋ ์์ ์ด
set_priors
์ด๊ณ P(d|c)๋ฅผ ๊ตฌํ๋ ๊ณผ์ ์ดset_likelihoods
์ด๋ค.
set_priors
def set_priors(self, train_labels):
class_counts = defaultdict(int)
for label in tqdm(train_labels):
class_counts[label] += 1
for label, count in class_counts.items():
self.priors[label] = class_counts[label] / len(train_labels)
set_priors
๋ ์์ฒ๋ผ ๊ตฌํ๋์ด ์๋๋ฐ, ์ฌ๊ธฐ์train_labels
๋ผ๋ ์ธ์๋ฅผ ์ ๋ ฅ๋ฐ๋๋ค. ์ด๋train_labels = [1, 0, 0, 1, 1, 0, 1, 1, 0, 0]
์ด๋ฐ๊ผด๋ก ํํ๋๋ค.class_counts
๋ ๊ฐ ๋ผ๋ฒจ๋ณ ๊ฐ์๋ฅผ ์ผ๋ค. ์ฃผ์ด์งtrain_labels
๋ก ์๊ฐํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑ๋ ๊ฒ์ด๋คclass_counts[0] = 5
class_counts[1] = 5
priors
๋ ๋จ์ง ์ ์ฒด ๊ฐ์์ ๋ํ ๋น์จ์ด๋ค. ์ด๋ํ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑ๋ ๊ฒ์ด๋คprior[0] = 5/10 = 1/2
prior[1] = 5/10 = 1/2
set_likelihoods
def set_likelihoods(self, train_tokenized, train_labels):
token_dists = {} # ๊ฐ ๋จ์ด์ ํน์ class ์กฐ๊ฑด ํ์์์ ๋ฑ์ฅ ํ์.
class_counts = defaultdict(int) # ํน์ class์์ ๋ฑ์ฅํ ๋ชจ๋ ๋จ์ด์ ๋ฑ์ฅ ํ์.
for i, label in enumerate(tqdm(train_labels)):
count = 0
for token in train_tokenized[i]:
if token in self.w2i: # ํ์ต ๋ฐ์ดํฐ๋ก ๊ตฌ์ถํ vocab์ ์๋ token๋ง ๊ณ ๋ ค.
if token not in token_dists:
token_dists[token] = {0:0, 1:0}
token_dists[token][label] += 1
count += 1
class_counts[label] += count
for token, dist in tqdm(token_dists.items()):
if token not in self.likelihoods:
self.likelihoods[token] = {
0:(token_dists[token][0] + self.k) / (class_counts[0] + len(self.w2i)*self.k),
1:(token_dists[token][1] + self.k) / (class_counts[1] + len(self.w2i)*self.k),
}
likelihoods๊ฐ ๋์๋ค๊ณ ์ซ์ง๋ง์. ์ฌ๊ธฐ์๋ ์ฝ๊ฒ์ฝ๊ฒ ๊ตฌํํ๋ค.
5-13
์ฐ๋ฆฌ๊ฐ ํ์ตํ๋ ค๋ train ๋ฐ์ดํฐ์ ๋ํด์ ์ ๋ต๊ณผ ๋ฌธ์ฅ์ ์ ๊ทผํ๊ธฐ ์ํด ์ด์ค ๋ฐ๋ณต๋ฌธ ํํ๋ก ์ ๊ทผํ๋ค.
์ด ๋ token์ด w2i์ ํฌํจ๋์ด์ผ ํ๋ค๋ ์กฐ๊ฑด๋ฌธ์ด ์๋๋ฐ, ์ฐ๋ฆฌ์ token์ ๋ชจ๋ w2i์ ํฌํจ๋์ด์๋ค. ๊ทธ๋ผ ์ด ์กฐ๊ฑด๋ฌธ์ ์์๋๊ฑธ๊น? ๋ง์ฝ ์ฐ๋ฆฌ์ ๋ฐ์ดํฐ์ ์ด ๋งค์ฐ ํฌ๋ค๋ฉด ๋ชจ๋ token์ ๋ค vocab์ผ๋ก ์ ์ฅํ๊ณ ์ด๋ฅผ ์๋ฒ ๋ฉ ํ ์ ์๋ค. ์๋๋ฉด token์ด ๋ง์์ง์๋ก ์๋ฒ ๋ฉ ๋ฒกํฐ์ ์ฐจ์๋ ์ปค์ง๊ฒ์ด๊ณ ์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ผ๋๊น! ๊ทธ๋์ ๋น๋์๊ฐ ์ ์ผ๋ฉด(์๋ฅผ ๋ค์ด 5 ์ดํ๋ผ๋ฉด) vocab์ ์ถ๊ฐํ์ง ์๋ ์กฐ๊ฑด๋ฌธ์ vocab์ ์์ฑํ ๋ ์ฌ์ฉํ๋๋ฐ, ์ฌ๊ธฐ์๋ ๋ฐ์ดํฐ์ ์ด ๋งค์ฐ ์๊ธฐ ๋๋ฌธ์!!! ๋น๋์ ์๊ด์์ด ๋ชจ๋ w2i์ ์ถ๊ฐํ๋ค! ๊ทธ๋ฌ๋, ์ฌ๊ธฐ์๋ ๊ด์ต์ ์ธ ํํ(์๋๋ ์์ฃผ ์ฐ์ง๋ง ์ฌ๊ธฐ์๋ ์ฐ์ง ์์์)์ผ๋ก๋ง ํด์ํ์!
token_dists
๋ ํด๋น token์ด ๊ธ์ ์ผ๋ก ์ฐ์ธํ์์ ๋ถ์ ์ผ๋ก ์ฐ์ธ ํ์๋ฅผ ๊ธฐ์ตํ๊ธฐ ์ํ ๋ณ์!class_counts
๋ ๊ฐ token ์ ์กฐ์ฌํ๋ฉด์ ๊ธ์ ์ผ๋ก ์ฐ์ธ token์ ๋ช๊ฐ์ผ๊น? ๋ถ์ ์ผ๋ก ์ฐ์ธ token์ ๋ช๊ฐ์ผ๊น? ๋ฅผ ๊ธฐ์ตํ๊ธฐ ์ํ ๋ณ์!
15-20
token_dists
์class_counts
์ ๋ํ ์กฐ์ฌ๊ฐ ๋๋ฌ๋ค๋ฉด ์ด๋ฅผ ๊ฐ์ง๊ณ ๊ฐ๊ฐ์ token์ ๋ํ likelihood๊ฐ์ ๋ฐํํ๋ค.์ด token์ด ๊ธ์ ์ ์ผ๋ก ์ฐ์ผ ๊ฐ๋ฅ์ฑ :
์ด token์ด ๊ธ์ ์ผ๋ก ์ฐ์ธ ํ์ / ๊ธ์ ์ ์ผ๋ก ์ฐ์ธ ์ ์ฒด token ๊ฐ์
๋ถ์ ์ ์ผ๋ก ์ฐ์ผ ๊ฐ๋ฅ์ฑ๋ ๋์ผํ๋ฉฐ, ๊ฐ๊ฐ ๋ถ์ ๋ถ๋ชจ์ ๋ํด์ง
k
์len(w2i) * k
๋zero probability
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํ ํฌ๋์ด๋ค!zero probability๊ฐ ๋ญ๋๊ณ ? ์๊น ๋งํ ์ด ๋ถ๋ถ!
inference
def inference(self, tokens):
log_prob0 = 0.0
log_prob1 = 0.0
for token in tokens:
if token in self.likelihoods: # ํ์ต ๋น์ ์ถ๊ฐํ๋ ๋จ์ด์ ๋ํด์๋ง ๊ณ ๋ ค.
log_prob0 += math.log(self.likelihoods[token][0])
log_prob1 += math.log(self.likelihoods[token][1])
# ๋ง์ง๋ง์ prior๋ฅผ ๊ณ ๋ ค.
log_prob0 += math.log(self.priors[0])
log_prob1 += math.log(self.priors[1])
if log_prob0 >= log_prob1:
return 0
else:
return 1
ํ ์คํธ ๋ฐ์ดํฐ์ ๋ํ ๊ธ์ ๋๋ ๋ถ์ ํด๋์ค๋ฅผ ๋ฐํํ๊ธฐ ์ํ ์ฝ๋์ด๋ค.
์ด๊ธฐ์ ๊ธ์ ๊ณผ ๋ถ์ ์ ๋ํ ํ๋ฅ ์ 0์ผ๋ก ์ด๊ธฐํํ๋ค.
๊ฐ token์ ๋ํ ๊ธ์ ํน์ ๋ถ์ ์๋ํ ๊ฐ๋ฅ์ฑ์ ์ถ๊ฐํ๋ค. if๋ฌธ์ด ์๋ ์ด์ ๋ ์์์ ์ค๋ช ํ ๊ด์ต์ ๋ช ์์ ๋์ผํ๋ฐ, ์ฐ๋ฆฌ๊ฐ ํ์ตํ์ง ์์ ๋ฐ์ดํฐ๋ก๋ ํ ์คํธ ๋ฐ์ดํฐ์์ ์ฒ์ ๋ณธ ํ ํฐ์ ํ๋จํ ์ ์๊ธฐ ๋๋ฌธ์ ํ์ตํ ํ ํฐ์ ๋ํด์๋ง ํ๋จํ ์ ์๋๋ก ํ๊ธฐ ์ํจ์ด๋ค.
๋ก๊ทธํจ์๋ฅผ ์ทจํ๋๋ผ๋ ๋์๊ด๊ณ๋ ๋ฌ๋ผ์ง์ง ์์ผ๋ logํํ๋ ๊ฐ ํญ์ ๊ณฑ์ ๋ง์ ์ผ๋ก ๋ฐ๊ฟ์ฃผ๋ฏ๋ก computational cost๋ฅผ ์ค์ฌ์ฃผ๋ ํจ๊ณผ๊ฐ ์์ด log likelihood๋ก ๋ณ๊ฒฝํด์ฃผ๊ฒ๋๋ค.
์ดํ ๊ธ์ ํน์ ๋ถ์ ๊ฐ ์ค ํฐ ๊ฐ์ ํด๋์ค๋ฅผ ๋ฐํํ๋ค.
๋ชจ๋ธ ํ์ต ๋ฐ ํ
์คํธ
classifier = NaiveBayesClassifier(w2i)
classifier.train(train_tokenized, train_labels)
preds = []
for test_tokens in tqdm(test_tokenized):
pred = classifier.inference(test_tokens)
preds.append(pred)
preds
[1, 0, 1, 0]
ํ ์คํธ ๊ฒฐ๊ณผ ๋ชจ๋ ์๋ง๊ฒ ๋์จ ๋ชจ์ต
"์ ๋ง ์ข์์ต๋๋ค. ๋ ๊ฐ๊ณ ์ถ๋ค์." = ๊ธ์
"๋ณ๋ก์์ต๋๋ค. ๋๋๋ก ๊ฐ์ง ๋ง์ธ์." = ๋ถ์
"๋ค๋ฅธ ๋ถ๋ค๊ป๋ ์ถ์ฒ๋๋ฆด ์ ์์ ๋งํผ ๋ง์กฑํ์ต๋๋ค." = ๊ธ์
"์๋น์ค๊ฐ ์ข ๋ ๊ฐ์ ๋์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค. ๊ธฐ๋ถ์ด ์ข ๋๋นด์ต๋๋ค." = ๋ถ์
๊ทธ๋์, ๋ด๊ฐ ์ถ๊ฐ๋ก 3๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์คํํด๋ณด์๋ค.
๊ธฐ์กด ๋ฐ์ดํฐ์ ์ ์ฐธ๊ณ ํด๋ ์ ์ ์๋ ๊ธ์ ํํ
"๋ง๋ ์๊ณ ์๋น์ค๋ ๋ณ๋ก์ง๋ง ์ข ์ ์์ด ์ด๋ป์ ๋ ๊ฐ๊ฑฐ์์"
๋งค์ฐ ๋ง์ ๋ถ์ ํํ์ด ์์ง๋ง ๊ฒฐ๊ตญ ๊ธ์ ํํ
"์๋น์ค๋ ๋ณ๋ก์๋ค์. ๋๋ฌด ๋น์ธ์ ๊ฐ๊ณ ์ถ์ง ์๊ณ ์์ ์ํ๊ฐ ์กฐ๊ธ ๋ถ์พํ์ต๋๋ค. ์์๋ ๋๋ฌด ์งฐ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ ์๋ง ๊ฐ๊ฒ๋ผ์ ์ถ์ฒํฉ๋๋ค."
๋งค์ฐ ๋ง์ ๊ธ์ ํํ์ด ์์ง๋ง ๊ฒฐ๊ตญ ๋ถ์ ํํ
"์ ๋ง ๋ง์์ต๋๋ค. ์์ ์ต๊ณ ์ ๋๋ค!. ์์๋ ๋ถ์๊ธฐ๋ ์๋น์ค๋ ๋ค ์ข์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ๊ฒฉ์ด ๋๋ฌด ๋น์ธ์ ๋ณ๋ก์๋ค์."
๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.
๊ธฐ์กด ๋ฐ์ดํฐ์ ์ ์ฐธ๊ณ ํด๋ ์ ์ ์๋ ๊ธ์ ํํ => ๊ธ์
์ฒ์ฐ๊ฐ?
"๋ง๋" => ํ์ต ๋ฐ์ดํฐ์์ ๊ธ์ ์์๋ง ์ฌ์ฉ
"์๋น์ค๋" => ํ์ต ๋ฐ์ดํฐ์์ ๊ธ์ ์์๋ง ์ฌ์ฉ
์ด๋ฌํ ์ด์ ๋ก ๊ธ์ ์ด ๋์จ๊ฒ์ผ๋ก ๋ณด์. ๋ฐ๋๋ก "๋ง๋ ์๊ณ ์๋น์ค๋ ๋ณ๋ก๋ค์" ์ ๋ํด์๋ ๊ธ์ ์ด ๋์จ๋ค.
๋งค์ฐ ๋ง์ ๋ถ์ ํํ์ด ์์ง๋ง ๊ฒฐ๊ตญ ๊ธ์ ํํ => ๋ถ์
๋ถ์ ๋จ์ด๊ฐ ํจ์ฌ ๋ง์์ ๋ถ์ , ๊ธ์ ํํ์ ํ์ต ๋ฐ์ดํฐ์ ์์
๋งค์ฐ ๋ง์ ๊ธ์ ํํ์ด ์์ง๋ง ๊ฒฐ๊ตญ ๋ถ์ ํํ => ๊ธ์
์์ ๋ง์ฐฌ๊ฐ์ง์ด๋ค. ๊ธ์ ํํ๊ณผ ๋ถ์ ํํ ๋ชจ๋ ํ์ต ๋ฐ์ดํฐ์ ์์ง๋ง ๊ฐ์์ ์ฐจ์ด๋ก ๊ธ์ .
Last updated
Was this helpful?