머신러닝 & 딥러닝/자연어처리

[자연어 처리/NLP기초] 5. 통계 기반 기법: 동시발생 행렬

by seokii 2022. 2. 21.
728x90
반응형

단어의 분산 표현과 분포 가설

https://seokii.tistory.com/93

 

[자연어 처리/NLP기초] 4. 단어의 분산 표현과 분포 가설

말뭉치와 말뭉치 전처리하기 https://seokii.tistory.com/91 [자연어 처리/NLP기초] 3. 말뭉치와 말뭉치 전처리하기 시소러스와 WordNet https://seokii.tistory.com/89?category=1037863 [자연어 처리/NLP기초] 2..

seokii.tistory.com

지난 글에서 단어의 분산 표현과 분포 가설에 대해서 공부하고 정리했습니다.

 

동시발생 행렬

지난 글에서 사용하고 책에 나와 있는 문장인 'you say goodbye and i say hello .'라는 문장을 단어별로 분리하는 전처리를 진행하겠습니다. 지난 글에서 정리했던 말뭉치 전처리하기 부분과 같은 코드입니다.

import numpy as np

def preprocess(words):
    word_to_id = {}
    id_to_word = {}

    for word in words:
        if word not in word_to_id:
            new_id = len(word_to_id)
            word_to_id[word] = new_id
            id_to_word[new_id] = word
    
    corpus = [word_to_id[w] for w in words]
    corpus = np.array(corpus)

    return corpus, word_to_id, id_to_word

text = 'You say goodbye and I say hello .'
text = text.lower()
words = text.split(' ')
print(words)

corpus, word_to_id, id_to_word = preprocess(words)
print(corpus)
print(id_to_word)
['you', 'say', 'goodbye', 'and', 'i', 'say', 'hello', '.']
[0 1 2 3 4 1 5 6]
{0: 'you', 1: 'say', 2: 'goodbye', 3: 'and', 4: 'i', 5: 'hello', 6: '.'}

결과를 확인하면, 단어 수가 총 7개임을 알 수 있습니다.

윈도우 크기(맥락의 크기)가 1인 각 단어의 빈도를 표로 정리한 것은 다음과 같습니다.

모든 단어에 대해 동시발생하는 단어를 표현한 것입니다.

이 표의 각 행은 해당 단어를 표현한 벡터가 됩니다.

위의 표는 행렬의 형태를 띤다는 뜻에서 동시발생 행렬이라고 합니다.

아래는 동시발생 행렬을 구현한 코드입니다.

C = np.array([
    [0, 1, 0, 0, 0, 0, 0],
    [1, 0, 1, 0, 1, 1, 0],
    [0, 1, 0, 1, 0, 0, 0],
    [0, 0, 1, 0, 1, 0, 0],
    [0, 1, 0, 1, 0, 0, 0],
    [0, 1, 0, 0, 0, 0, 1],
    [0, 0, 0, 0, 0, 1, 0],
], dtype=np.int32)

print(C[0])
print(C[4])
print(C[word_to_id['goodbye']])
[0 1 0 0 0 0 0]
[0 1 0 1 0 0 0]
[0 1 0 1 0 0 0]

 

아래는 동시발생 생성 함수 코드입니다.

다음 공부할 내용에서 계속 가져다 사용할 예정입니다.

def create_co_matrix(corpus, vocab_size, window_size=1):
    '''동시발생 행렬 생성
    :param corpus: 말뭉치(단어 ID 목록)
    :param vocab_size: 어휘 수
    :param window_size: 윈도우 크기(윈도우 크기가 1이면 타깃 단어 좌우 한 단어씩이 맥락에 포함)
    :return: 동시발생 행렬
    '''
    corpus_size = len(corpus)
    co_matrix = np.zeros((vocab_size, vocab_size), dtype=np.int32)

    for idx, word_id in enumerate(corpus):
        for i in range(1, window_size + 1):
            left_idx = idx - i
            right_idx = idx + i

            if left_idx >= 0:
                left_word_id = corpus[left_idx]
                co_matrix[word_id, left_word_id] += 1

            if right_idx < corpus_size:
                right_word_id = corpus[right_idx]
                co_matrix[word_id, right_word_id] += 1

    return co_matrix

 

 

728x90
반응형

댓글