[NLP] 한글을 다양하게 조작해보기
2023. 11. 12. 14:51ㆍDevelopers 공간 [Shorts]/Vision & Audio
728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew,
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter
- Module Bundler : React, Webpack, Parcel
B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS
C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight
1. What? (현상)
이번 글에서는 데이터를 다룰 때 한글을 다양하게 조작하는 방법을 정리해보고자 합니다.
다뤄보려는 방법은 아래 3가지 입니다.
- 풀어쓰기 : 한글을 자소단위로 풀어쓰는 방법입니다.
- 모아쓰기 : 자소단위로 풀어져있는 한글을 모아쓰기 하는 방법입니다.
- G2P(Grapheme to Phoneme) : 한글 자소를 음소로 바꿔주는 모델입니다. 즉, 발음 모델로 바꿔주는 방법입니다.
2. Why? (원인)
- X
3. How? (해결책)
시작하기 전에 한글인지 확인하는 함수를 먼저 확인하겠습니다.
def isHangeul(one_character):
return 0xAC00 <= ord(one_character[:1]) <= 0xD7A3
위 결과를 아래와 같이 실행해보고 결과를 보겠습니다.
print(isHangeul("한"))
print(isHangeul("2"))
True
False
1. 풀어쓰기
먼저, 한글을 풀어쓰는 함수를 보겠습니다. 해당코드는 다른 git자료(https://github.com/fd873630/RNN-Transducer/blob/master/model_rnnt/hangul.py)를 ㅊ팜조했으며, 아래 사용하는 함수들을 간단히 설명하면 아래와 같습니다.
- ord() 함수 : 하나의 문자 → 유니코드 정수
ex) ord('a') → 97 - hex() 함수 : 10진수 값 → 16진수 값
ex) hex(98) → 0x62 - chr() 함수 : 하나의 정수 → 유니코드 문자
ex) chr(97) → 'a'
chosung = ("ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ")
jungsung = ("ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ")
jongsung = ("", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ")
def hangeulExplode(one_hangeul):
a = one_hangeul[:1]
if isHangeul(a) != True:
return False
b = ord(a) - 0xAC00
cho = b // (21*28)
jung = b % (21*28) // 28
jong = b % 28
if jong == 0:
return (chosung[cho], jungsung[jung])
else:
return (chosung[cho], jungsung[jung], jongsung[jong])
def pureosseugi(inputtext):
result = ""
for i in inputtext:
if isHangeul(i) == True:
for j in hangeulExplode(i):
result += j
else:
result += i
return result
그럼 아래와 같이 실행해보고 결과를 확인해보겠습니다.
sentence = "모르는 것이 낫다고"
result = pureosseugi(sentence)
print(result)
ㅁㅗㄹㅡㄴㅡㄴ ㄱㅓㅅㅇㅣ ㄴㅏㅅㄷㅏㄱㅗ
2. 모아쓰기
이번엔 반대로 한글을 모아쓰는 함수를 보겠습니다.
def hangeulJoin(inputlist):
result = ""
cho, jung, jong = 0, 0, 0
inputlist.insert(0, "")
while len(inputlist) > 1:
if inputlist[-1] in jongsung:
if inputlist[-2] in jungsung:
jong = jongsung.index(inputlist.pop())
else:
result += inputlist.pop()
elif inputlist[-1] in jungsung:
if inputlist[-2] in chosung:
jung = jungsung.index(inputlist.pop())
cho = chosung.index(inputlist.pop())
result += chr(0xAC00 + ((cho*21)+jung)*28+jong)
cho, jung, jong = 0, 0, 0
else:
result += inputlist.pop()
else:
result += inputlist.pop()
else:
return result[::-1]
def moasseugi(inputtext):
t1 = []
for i in inputtext:
t1.append(i)
return hangeulJoin(t1)
그럼 아래와 같이 실행해보고 결과를 확인해보겠습니다.
sentence = "ㅁㅗㄹㅡㄴㅡㄴ ㄱㅓㅅㅇㅣ ㄴㅏㅅㄷㅏㄱㅗ"
result = moasseugi(sentence)
print(result)
모르는 것이 낫다고
3. Graphemes to Phonemes
먼저 설치해보곘습니다. 관련된 자료는 g2pk라는 패키지의 자료(https://github.com/Kyubyong/g2pK)를 참조하시면 좋습니다.
pip3 install nltk g2pk
그럼 아래와 같이 실행해보고 결과를 확인해보겠습니다.
from g2pk import G2p
g2p = G2p()
result = g2p("어제는 날씨가 맑았는데, 오늘은 흐리다.")
print(result)
어제는 날씨가 말간는데, 오느른 흐리다.
728x90
반응형
'Developers 공간 [Shorts] > Vision & Audio' 카테고리의 다른 글
[Audio] ASR에서 CER, WER 구현 및 측정해보기 (0) | 2024.02.09 |
---|---|
[NLP] KenLM으로 Language Model만들기 (1) | 2024.02.09 |
[Audio] Python 활용해 Audio 및 Text 데이터 Pre-processing (0) | 2024.01.14 |
[NLP] 형태소 분석기 및 토크나이저 활용해보기 (0) | 2024.01.03 |
[Audio] Python으로 VAD 구현하기 (0) | 2023.12.30 |