앎을 경계하기

DAFIT/904 - 한국어 데이터 Tokenizer

<DAFIT> 04 한국어 데이터 Tokenizer 03 - 형태소 분석기 라이브러리

양갱맨 2019. 11. 16. 02:52

 

 

token.. id.. 이것들이 정확히 어떤 형태인지 몰라서 계속 문제를 못풀었는데..

힌트가 있었다..왜 몰랐지..ㅠ (힌트 알려주신 다핏 방장님 감사합니다.)

무튼 Vocab에는 태깅이 된 형태소가  token이고 순서대로 id가 저장된다.

python에서는 key로 value 가져오기는 쉽지만 value로 key를 가져오는 것은 함수가 존재하지 않기 때문에 다른 처리를 통해서 가능하다.

힌트에도 나와있지만 딕셔너리 구성은 token이 key이고 id가 value이다.

vocab = {}

with open('.\DF904_02_ㅁㅁㅁ.txt', mode='r', encoding='utf-8') as output:
    # 형태소/tag로 구성
    id = 0
    for opline in output.readlines():
        for token in opline.rstrip().split(' '):
            vocab[token] = id
            id+=1

 

vocab을 만들었다. 02번 문제에서 만들었던 txt파일에서 가장 먼저 나오는 '|/SW'가 4945인 이유는

4945번째 단어도 '|/SW'라서 가장 마지막 id로 덮어씌워진 것이다.

with open('.\DF904_03_ㅁㅁㅁ.txt', mode='w', encoding='utf-8') as output:
    with open('.\DF904_02_ㅁㅁㅁ.txt', mode='r', encoding='utf-8') as readoutput:
        for opline in readoutput.readlines():
            for token in opline.rstrip().split(' '):
                output.write(str(vocab[token])+', ')
        

 

이렇게 되면 id로 치환했을 때 아래와 같이 나오게되는데 위처럼 id가 나중 값으로 덮어씌워지면 id값이 0부터 차례로 쌓이는게 아니고 비어있는 id가 생기게 되는 문제가 있다.

이 문제를 해결하기 위해 이미 그 token이 vocab에 있으면 id를 업데이트 하지 않고 넘어가는 방식으로 수정한다.

vocab = {}

with open('.\DF904_02_ㅁㅁㅁ.txt', mode='r', encoding='utf-8') as output:
    # 형태소/tag로 구성
    id = 0
    for opline in output.readlines():
        for token in opline.rstrip().split(' '):
            if token in vocab.keys():
                continue
            vocab[token] = id
            id+=1

위에서 구성했던 vocab과 차례대로 저장된것을 볼 수 있다.

구성한 vocab을 가지고 02 txt의 token을 id로 바꿔서 새로운 파일에 저장해준다.

with open('.\DF904_03_ㅁㅁㅁ.txt', mode='w', encoding='utf-8') as output:
    with open('.\DF904_02_ㅁㅁㅁ.txt', mode='r', encoding='utf-8') as readoutput:
        for opline in readoutput.readlines():
            for token in opline.rstrip().split(' '):
                output.write(str(vocab[token])+', ')
        

 

이제 plus로 있던 추가문제를 풀어보자.

파일에서 나오는 단어의 빈도수를 기준으로 정렬해서 id를 부여해야한다.

1. {token : 사용횟수} 로 딕셔너리를 구성하자.

2. 사용횟수를 기준으로 딕셔너리를 정렬하자.

3. 새로운 딕셔너리에 정렬된 token 순서대로 id 부여해서 딕셔너리 생성

vocab = {}

with open('.\DF904_02_ㅁㅁㅁ.txt', mode='r', encoding='utf-8') as output:
    # 형태소/tag로 구성

    for opline in output.readlines():
        for token in opline.rstrip().split(' '):
            if token in vocab.keys(): #이미 딕셔너리에 있으면
                vocab[token] = vocab[token]+1 # value에 +1해서 갱신
            else:
                vocab[token] = 1	# 딕셔너리에 없으면 딕셔너리에 추가
                
vocab = sorted(vocab.items(), key=lambda x: x[1]) # value(사용횟수)를 기준으로 vacab.items()(tuple형태) 데이터 정렬해서 list로 만든다.
            
vocab2 = {}	#새로운 딕셔너리 생성
id = 0	# id

for tup in vocab:	#정렬된 tuple 저장된 list 반복
    #각 요소가 (토큰, 사용횟수) 로 저장되어 있기 때문에 key로 사용될 token이 저장된 tup[0]가져옴
    vocab2[tup[0]] = id # 딕셔너리 추가
    id+=1

 

사용횟수를 기준으로 오름차순 정렬한 배열을 저장한 vocab은 다음과 같다.

새롭게 생성된 vocab2 딕셔너리는 다음과 같이 저장되어있다.

빈도 수로 저장된 vocab2를 기반으로 대체된 문서는 다음과 같다.