word2vec 학습데이터 관련 질문드립니다

조회수 1357회

안녕하세요

word2vec 학습데이터 관련 문의드립니다.

from gensim.models.word2vec import Word2Vec
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/DoosanB/files/master/test.csv', encoding = 'utf-8')
df = pd.DataFrame(df)

model = Word2Vec(df['corpus'].values, sg=1, window=5, min_count=1, workers=4, iter=100)

model_result1 = model.wv.most_similar("정부")

위와 같이 코드를 사용했는데

KeyError: "word '정부' not in vocabulary"

에러가 발생했습니다.

어떻게 처리해야 할지 몰라서 여쭙습니다.

1 답변

  • 질문자님의 코드에서 word2vec를 학습시킬 때 사용하는 df['corpus'].values의 값은 다음과 같습니다.

    # df['corpus'].values의 값
    [
        "['주택', '아파트', '부동산', '가격', '안정', '이루다']",
        "['서민', '꿈', '희망', '일순', '앗다', '부동산', '가격', '폭등', '서민', '경제', '잡다']", 
        ...
    ]
    

    기본적으로 word2vec는 '문장'을 학습 데이터로 사용합니다.

    이때 문장은 단어별로 정리되어 있는 리스트 형식이어야 합니다.

    다음과 같이 말이죠

    # word2vec가 기대하는 학습 데이터 형태
    [
        ['주택', '아파트', '부동산', '가격', '안정', '이루다'],
        ['서민', '꿈', '희망', '일순', '앗다', '부동산', '가격', '폭등', '서민', '경제', '잡다'],
        ...
    ]
    

    word2vec에 df['corpus'].values의 값을 학습 데이터로 넘겨주면

    word2vec가 기대했던 문장 형태(shape)가 아니므로 자동적으로 문장 형식으로 변환하게 됩니다.

    word2vec가 학습하는 데이터는 df['corpus'].values값이 자동으로 변형된 다음과 같은 값이 됩니다.

    # 실제 word2vec가 학습하게 되는 데이터
    [
        ['[', "'", '주', '택', "'", ',', ' ', "'", '아', '파', '트', "'", ',', ' ', "'", '부', '동', '산', "'", ',', ' ', "'", '가', '격', "'", ',', ' ', "'", '안', '정', "'", ',', ' ', "'", '이', '루', '다', "'", ']'],
        ['[', "'", '서', '민', "'", ',', ' ', "'", '꿈', "'", ',', ' ', "'", '희', '망', "'", ',', ' ', "'", '일', '순', "'", ',', ' ', "'", '앗', '다', "'", ',', ' ', "'", '부', '동', '산', "'", ',', ' ', "'", '가', '격', "'", ',', ' ', "'", '폭', '등', "'", ',', ' ', "'", '서', '민', "'", ',', ' ', "'", '경', '제', "'", ',', ' ', "'", '잡', '다', "'", ']'], 
        ...
    ]
    

    이 상태로 학습을 진행하기 때문에 vocabulary에는 한 글자씩만 저장되는 것입니다.

    # 학습된 word2vec의 vocabulary (사전)
    [' ', "'", ',', '3', '4', 'G', 'H', ..., '접', '정', '제']
    

    때문에 '정부'라는 단어가 vocabulary에 존재하지 않는다는 오류가 발생하게 됩니다.


    이 문제를 해결하기 위해선

    df['corpus'].valuesmap(eval, df['corpus'].values)로 바꿔주면 됩니다.

    map(eval, df['corpus'].values)를 사용하면 df['corpus'].values안의 모든 원소들을 리스트 형식으로 바꿀 수 있습니다.

    # df['corpus'].values[:2]
    ["['주택', '아파트', '부동산', '가격', '안정', '이루다']",
     "['서민', '꿈', '희망', '일순', '앗다', '부동산', '가격', '폭등', '서민', '경제', '잡다']"]
    
    # list(map(eval, df['corpus'].values[:2]))
    [['주택', '아파트', '부동산', '가격', '안정', '이루다'],
     ['서민', '꿈', '희망', '일순', '앗다', '부동산', '가격', '폭등', '서민', '경제', '잡다']]
    

    위 해결 방법을 적용한 전체 코드는 다음과 같습니다.

    from gensim.models.word2vec import Word2Vec
    import pandas as pd
    
    df = pd.read_csv('https://raw.githubusercontent.com/DoosanB/files/master/test.csv', encoding = 'utf-8')
    df = pd.DataFrame(df)
    
    model = Word2Vec(map(eval, df['corpus'].values), sg=1, window=5, min_count=1, workers=4, iter=100)
    model_result1 = model.wv.most_similar("정부")
    
    print(model_result1)
    # 출력 결과 : [('개선', 0.3173496127128601), ('전력', 0.29743409156799316), ('폭탄', 0.2881121039390564), ('최종', 0.2811095118522644), ('서울시', 0.25973260402679443), ('주최', 0.24840295314788818), ('인기', 0.24586039781570435), ('협조', 0.24584536254405975), ('깊다', 0.23948773741722107), ('자원', 0.2374880611896515)]
    

    도움이 되셨나요? 원인 설명이 너무 길었네요 ㅠㅠ 이해 안 되는 부분 있으시면 댓글 남겨 주세요!

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)