한국어 위키백과 데이터베이스로 Word2Vec 학습
한국어 위키 백과 데이터 베이스로 Word2Vec 학습을 해보겠습니다.
1. 위키피디아로부터 데이터를 파싱하기 위한 wikiextractor를 설치합니다.
pip install wikiextractor
2. 위키디피아 데이터를 다운로드 합니다.
Index of /kowiki/latest/ (wikimedia.org)
Index of /kowiki/latest/
dumps.wikimedia.org
kowiki-latest-pages-articles.xml.bz2 파일을 다운로드하였습니다.
3. 위키익스트랙터를 사용하여 위키피디아 덤프를 파싱 합니다.
python -m wikiextractor.WikiExtractor kowiki-latest-pages-articles.xml.bz2
4. 위키피디아 데이터를 다운로드한 후에 전처리에서 사용할 형태소 분석기인 Mecab을 설치합니다.
윈도우에서 설치할 설치 파일은 우선 다운로드합니다.
https://github.com/Pusnow/mecab-python-msvc/releases/tag/mecab_python-0.996_ko_0.9.2_msvc-2
Release mecab_python-0.996_ko_0.9.2_msvc-2 · Pusnow/mecab-python-msvc
Add Python 3.7 support
github.com
목록 중에 설치된 파이썬 버전과 윈도우 버전에 맞는 설치 파일을 다운로드하여 설치하면 됩니다.
pip install mecab_python-0.996_ko_0.9.2_msvc-cp36-cp36m-win_amd64.whl
저는 파이썬 3.6으로 설치하였습니다.
5. mecab을 사용하기 위해서는 관련 설치 파일을 다운로드 받아 설치하여야 합니다.
아래의 사이트를 참고하여 설치합니다.
https://velog.io/@jyong0719/konlpy-mecab-%EC%84%A4%EC%B9%98-window
konlpy mecab 설치 window
mecab-ko-msvc 설치 1.https://github.com/Pusnow/mecab-ko-msvc/releases/tag/release-0.9.2-msvc-3 2.pc window 버전에 맞는 파일 설치 3.C 드라이브에 mecab 폴더 생성 : c:\me
velog.io
6. 위키디피아로부터 다운로드한 데이터를 하나의 파일로 통합
import os
import re
os.listdir('data/text')
['AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI']
text 파일 아래의 폴더 리스트입니다.
파일 리스트를 불러오는 함수
def list_wiki(dirname):
filepaths = []
filenames = os.listdir(dirname)
for filename in filenames:
filepath = os.path.join(dirname, filename)
if os.path.isdir(filepath):
# 재귀 함수
filepaths.extend(list_wiki(filepath))
else:
find = re.findall(r"wiki_[0-9][0-9]", filepath)
if 0 < len(find):
filepaths.append(filepath)
return sorted(filepaths)
filepaths = list_wiki('data/text')
len(filepaths)
880
불러온 파일리스트를 읽어 하나의 파일로 출력
with open("data/output_file.txt", "w", encoding='UTF8') as outfile:
for filename in filepaths:
with open(filename, 'rt', encoding='UTF8') as infile:
contents = infile.read()
outfile.write(contents)
생성된 파일을 읽어 10번째 줄까지 화면에 출력
f = open('data/output_file.txt', encoding="utf8")
i = 0
while True:
line = f.readline()
if line != '\n':
i = i+1
print("%d번째 줄 :"%i + line)
if i==10:
break
f.close()
1번째 줄 :
2번째 줄 :지미 카터
3번째 줄 :제임스 얼 카터 주니어(, 1924년 10월 1일 ~ )는 민주당 출신 미국 39대 대통령 (1977년 ~ 1981년)이며, 독재자의 사신이라는 별명을 가지고 있다.
4번째 줄 :생애.
5번째 줄 :어린 시절.
6번째 줄 :지미 카터는 조지아주 섬터 카운티 플레인스 마을에서 태어났다.
7번째 줄 :조지아 공과대학교를 졸업하였다. 그 후 해군에 들어가 전함·원자력·잠수함의 승무원으로 일하였다. 1953년 미국 해군 대위로 예편하였고 이후 땅콩·면화 등을 가꿔 많은 돈을 벌었다. 그의 별명이 "땅콩 농부" (Peanut Farmer)로 알려졌다.
8번째 줄 :정계 입문.
9번째 줄 :1962년 조지아 주 상원 의원 선거에서 낙선하나 그 선거가 부정선거 였음을 입증하게 되어 당선되고, 1966년 조지아 주지사 선거에 낙선하지만, 1970년 조지아 주지사를 역임했다. 대통령이 되기 전 조지아주 상원의원을 두번 연임했으며, 1971년부터 1975년까지 조지아 지사로 근무했다. 조지아 주지사로 지내면서, 미국에 사는 흑인 등용법을 내세웠다.
10번째 줄 :대통령 재임.
7. 형태소 분석
from tqdm import tqdm
from konlpy.tag import Mecab
mecab = Mecab(dicpath=r"C:\mecab\mecab-ko-dic")
파일 읽어 라인 단위로 리스트 생성
f = open('data/output_file.txt', encoding="utf8")
lines = f.read().splitlines()
print(len(lines))
10071593
10라인까지 데이터 확인
lines[:10]
['',
'지미 카터',
'',
'제임스 얼 카터 주니어(, 1924년 10월 1일 ~ )는 민주당 출신 미국 39대 대통령 (1977년 ~ 1981년)이며, 독재자의 사신이라는 별명을 가지고 있다.',
'생애.',
'어린 시절.',
'지미 카터는 조지아주 섬터 카운티 플레인스 마을에서 태어났다.',
'조지아 공과대학교를 졸업하였다. 그 후 해군에 들어가 전함·원자력·잠수함의 승무원으로 일하였다. 1953년 미국 해군 대위로 예편하였고 이후 땅콩·면화 등을 가꿔 많은 돈을 벌었다. 그의 별명이 "땅콩 농부" (Peanut Farmer)로 알려졌다.',
'정계 입문.',
'1962년 조지아 주 상원 의원 선거에서 낙선하나 그 선거가 부정선거 였음을 입증하게 되어 당선되고, 1966년 조지아 주지사 선거에 낙선하지만, 1970년 조지아 주지사를 역임했다. 대통령이 되기 전 조지아주 상원의원을 두번 연임했으며, 1971년부터 1975년까지 조지아 지사로 근무했다. 조지아 주지사로 지내면서, 미국에 사는 흑인 등용법을 내세웠다.']
빈 문자열 정리
result = []
for line in tqdm(lines):
# 빈 문자열이 아닌 경우에만 수행
if line:
result.append(mecab.morphs(line))
100%|████████████████████████████████████████████████████████████████████| 10071593/10071593 [34:42<00:00, 4836.77it/s]
정리된 데이터 사이즈
len(result)
6795607
8. Word2Vec 학습
from gensim.models import Word2Vec
model = Word2Vec(result, vector_size=100, window=5, min_count=5, workers=4, sg=0)
Word2Vec학습은 gensim 패키지의 Word2Vec를 활용하여 간단하게 학습 할 수 있습니다.
9. 학습된 Word2Vec 모델 테스트
model_result1 = model.wv.most_similar("대한민국")
print(model_result1)
[('한국', 0.7303033471107483), ('미국', 0.6578476428985596), ('일본', 0.6378878951072693), ('홍콩', 0.5735474824905396), ('부산', 0.5673593878746033), ('태국', 0.5625110268592834), ('오스트레일리아', 0.5532922148704529), ('서울', 0.5434250831604004), ('중화민국', 0.536961019039154), ('한경', 0.5354710817337036)]
model_result2 = model.wv.most_similar("어벤져스")
print(model_result2)
[('어벤저스', 0.7792693972587585), ('솔저', 0.7718903422355652), ('엑스맨', 0.7628118991851807), ('스파이더맨', 0.7555488348007202), ('울트론', 0.7549695372581482), ('아이언맨', 0.7536684274673462), ('퍼니셔', 0.7428902983665466), ('《》,', 0.73934406042099), ('트랜스포머', 0.7384896874427795), ('테일즈', 0.7361338138580322)]
model_result3 = model.wv.most_similar("반도체")
print(model_result3)
[('연료전지', 0.7866814136505127), ('집적회로', 0.7814631462097168), ('실리콘', 0.7592837810516357), ('웨이퍼', 0.7509834170341492), ('전자', 0.7462804317474365), ('트랜지스터', 0.7358013391494751), ('그래핀', 0.7281147241592407), ('TSMC', 0.7247744798660278), ('PCB', 0.7172301411628723), ('전기차', 0.7017775774002075)]