NLP1: word representation and bigram model

1. word representation: 통계 vs 추론

통계: co-occurrenc mat을 기반으로 dens vector 찾아냄

  • 시소러스 thesaurus: 단어간 상하 관계를 통해 유사도 구함. 사람이 개입. 시간비용 소모 큼.
    • $similarirty(w, w’) = -\log{distance}(w, w’)$
  • 통계기반(TF-IDF…): 말뭉치 -> 단어 의미 추출
    • 분포가설에 기반하여 벡터표현 = 분산표현 distributional representation
    • 방법: co-occurrence mat
    • 활용: 코사인유사도, PMI, PPMI -> embedding: SVD(U vector 사용) -> Dense Vector 계산 -> 1회만에 distributional representation = dense vector
    • 추론기반(word2vec)

추론: Word2vec, 단어 분산표현 갱신 가능

  • Use W(input) and Avg Sum for words, the num of which is based on the number of window -> Get Weight layer
  • CBOW vs Skip-Gram: multiple in-layer vs multiple out-layer
    • skip gram은 손실함수에 맥락이 모두 고려됨

2. Language Model

  • 핵심: sentence scoring and generation
  • partial scoring 가능하다면 모든 sentence를 scoring할 필요가 없음
  • unsupervised

bigram model

  • p(current_word | previous_word)를 통해 해당 문장이 얼마나 가능성 있는 문장인지 추론
  • Marcov Assumption에 의해 지금 단어는 과거 단어의 영향만 받음
    • $p(w_t | w_{t-1}, \cdots, w_1) = p(w_t|w_{t-1})$
  • 따라서 문장의 발생확률은, $p(A,B,C,D,E) = p(text{end_pad}|E)p(E|D)p(D|C)p(C|B)p(B|A)p(A|\text{start_pad})$
    • pad는 <s>, </s>처럼 문장의 시작과 끝을 나타냄
    • 실제 계산은 log prob를 사용. 그 이유는 많은 곱셈 연산으로 값이 0보다 한없이 작아지기 때문에 덧셈의 꼴로 바꾸기 위함
    • 더불어 문장이 짧을수록 prob가 높아지기 때문에 한 문장의 단어 갯수로 log prob.를 나눠 normalize -> $\dfrac{1}{T} \log{w_1, \cdots, w_T}$
  • bigram prob 코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    bigram_prob = np.ones((V, V)) * smoothing #co-occurrence라고 생각하면 됨
    for sen in sentences: # sen은 word2idx에 의해 mapping되어있음
    for i in range(len(sen)):
    if i == 0:
    bigram_prob[start_idx, sen[i]] += 1 # p(sen[i] | start_idx)
    else:
    bigram_prob[sen[i-1], sen[i]] # p(sen[i-1] | sen[i])
    bigram_prob[sen[-1], end_idx] += 1 # p(end_idx | sen[-1])
    bigram_prob /= bigram_prob.sum(axis=1, keepdims=True) # row wise sum. 각 단어들 다음에 row의 단어가 나올 확률.
  • log prob(scoring) 구하는 코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    score = 0
    num_sen = len(sen)
    for i in range(num_sen):
    if i == 0:
    score += np.log(bigram_prob[start_idx, sen[i]]) # bigram_prob: 벡터
    else:
    score += np.log(bigram_prob[sen[i-1], sen[i]])
    score += np.log(bigram_prob[sen[-1], end_idx])
    score /= (len(num_sen)+1) # normalize the score:
    # +1은 vocab size가 원래 vocab + pad <s>, </s> 되기 떄문.
< !-- add by yurixu 替换Google的jquery并且添加判断逻辑 -->