데이터 전처리를 어떤 방식으로 해야할지에 대한 전략을 정리해보았습니다.
지열이형이 짠 크롤링 파일을 토대로 전략을 수립하려고 했습니다. (문학광장 사이트 기준)
자연어 전처리는 처음이어서 이것저것 구글링하며 찾아보았습니다. 잘못된 점이 있다면 알려주세요!
먼저 크롤링된 데이터에는 다음과 같은 문제점이 존재했습니다.
1. 각 csv파일의 맨 처음, "title,content" <- 존재
2. [중요] 줄바꿈이 어색함.
예시)
나에겐 모든 것이 너무나 신기했고 마
치 사건의 진실을 하나하나 알아가는 탐정이 된 기분이었다. 뉴스 마지막 부분에 나오는 기
상캐스터가 사실은 아무 것도 없는 판에 대고 일기 예보를 한다는 것을 배웠고 자막이니 노
래 가사니 하는 것들이 어떤 과정을 거쳐 방송으로 나가는 지도 배웠으며 광고와 프로그램
의 시간 배분, 조정은 어떻게 하는지도 배웠다. 그런데 그렇게 정신없이 돌아다니고 보니 정
작 무언가가 빠진 느낌이 들었다. 그래. 나는 방송국을 보러 온 게 아니야.
3. 쌍따움표가 두개씩 붙어있는 것 존재
예시)
"" 응, 자 이거. ""
"" 뭐야 ? ""
그 것은 평범한 민자 금반지였습니다.
아주 예전부터였습니다.
다른 집 엄마들이 딸에게 선물해주는 금반지를
그렇게 부러워 하시던 엄마였습니다.
"" 오늘 일한걸로 이거 산거야 ? ""
"" 응 ""
4. 특수문자, 한글 모음 등
1. 각 csv파일의 맨 처음, "title,content" <- 존재
3. 쌍따움표가 두개씩 붙어있는 것 존재
4. 특수문자, 한글 모음 등
이 부분은 해결이 어렵지 않다.
4번 같은 경우,
를 적용하여 다음과 같은 코드를 통해 제거 가능하다.
punct = "/-'?!.,#$%\'()*+-/:;<=>@[\\]^_`{|}~" + '""“”’' + '∞θ÷α•à−β∅³π‘₹´°£€\×™√²—–&'
punct_mapping = {"‘": "'", "₹": "e", "´": "'", "°": "", "€": "e", "™": "tm", "√": " sqrt ", "×": "x", "²": "2", "—": "-", "–": "-", "’": "'", "_": "-", "`": "'", '“': '"', '”': '"', '“': '"', "£": "e", '∞': 'infinity', 'θ': 'theta', '÷': '/', 'α': 'alpha', '•': '.', 'à': 'a', '−': '-', 'β': 'beta', '∅': '', '³': '3', 'π': 'pi', }
def clean(text, punct, mapping):
for p in mapping:
text = text.replace(p, mapping[p])
for p in punct:
text = text.replace(p, f' {p} ')
specials = {'\u200b': ' ', '…': ' ... ', '\ufeff': '', 'करना': '', 'है': ''}
for s in specials:
text = text.replace(s, specials[s])
return text.strip()
import re
def clean_str(text):
pattern = '([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)' # E-mail제거
text = re.sub(pattern=pattern, repl='', string=text)
pattern = '(http|ftp|https)://(?:[-\w.]|(?:%[\da-fA-F]{2}))+' # URL제거
text = re.sub(pattern=pattern, repl='', string=text)
pattern = '([ㄱ-ㅎㅏ-ㅣ]+)' # 한글 자음, 모음 제거
text = re.sub(pattern=pattern, repl='', string=text)
pattern = '<[^>]*>' # HTML 태그 제거
text = re.sub(pattern=pattern, repl='', string=text)
pattern = '[^\w\s\n]' # 특수기호제거
text = re.sub(pattern=pattern, repl='', string=text)
text = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》]','', string=text)
text = re.sub('\n', '.', string=text)
return text
자연어 처리에서는 텍스트를 '토큰 단위' 로 구분한다
한국어에서는 띄어쓰기가 텍스트의 의미를 구분하는데 영향을 주기 때문이다
그렇지만 문맥이 없이 단순 띄어쓰기로만 토큰을 구분한다면, 단순히 단어로만 구분되어 문장 전체의 의미 파악이 어려워져 띄어쓰기에 따라 분석이 제대로 되지 않을 수도 있다.
띄어쓰기를 해주는 오픈 라이브러리가 존재하지만 문제점 존재한다.
라이브러리별로 뉴스같이 정제되고 전문적인 문체를 인식하는 라이브러리, 지식인 같은 대화체를 인식하는 라이브러리가 존재하여 서로 잘 안먹을 수 있다는 한계점 존재
따라서 애초에 모든 공백을 없앤 후, 문맥에 따라 문장을 만드는 것이 좋은 방법
-> '너무기대를 안했나봐'-> '너무기대를안했나봐' -> '너무 기대를 안 했나봐'
우리가 생성하고자 하는 글이 어느정도 길다는 특징이 있다.
따라서 다음의 과정을 통해 전처리를 진행하는 것이 좋아보인다.
2번 : 맞춤법에 어긋나는 경우 해결
pip install py-hanspell
from hanspell import spell_checker
result = spell_checker.check(data)
result.as_dict() # dict로 출력
3번: 반복되는 이모티콘이나 자모 ㅎㅎㅎ, ㅋㅋㅋㅋㅋ, 하하 같은 것들을 Nomalizer 시켜주는 라이브러리
!pip install soynlp
from soynlp.normalizer import *
print(repeat_normalize('와하하하하하하하하하핫', num_repeats=2))
4번: 띄어쓰기가 아닌 문장분리를 통한 전처리.
!pip install kss
import kss
s = data
for sent in kss.split_sentences(s):
print(sent)
정제 작업은 토큰화 작업에 방해가 되는 부분을 배제하기 위해 토큰화 작업보다 앞서 이루어지기도 하지만, 토큰화 작업 이후에도 여전히 남아있는 노이즈들을 제거하기위해 지속적으로 이루어집니다.