자연어처리

Sentiment 분석에 불필요한 텍스트 데이터 클리닝

coding art 2022. 7. 1. 18:00
728x90

 

IMDb 데이타를 읽어 들여 csv 데이타 포맷으로 변환한 상태에서 일부 데이타를 읽어 들여 문제점을 체크하기로 하자. 지난번 블로그의 csvconver.py 파이선 코드를 먼저 실행시키면 progress bar와 함께 수분의 시간이 소요되면서 처리가 완료된다.

 

Pandas 명령어인 df.loc[0, ‘review’][-50:] 명령을 셸(Shell)에서 실행하여 얻어지는 출력 결과를 살펴보자. 이 명령은 랜덤하게 셔플된 영화 리뷰 데이타의 마지막 50글자를 출력시킨다.

이 출력 결과를 살펴보면 HTML 언어인 깍지형 브라켓과 슬래시 및 마침표를 포함하는 요소들이 포함되어 있음을 알 수 있다. HTML 편집 기호들은 문장의 의미와는 아무런 관련이 없으며 마침표의 경우는 약간의 관련성이 있을 수 있다. 하지만 보다 단순화를 위해서 HTML 과 마침표도 다 빼버리고 Sentiment 분석에서 중요할 수 도 있는 이모티콘(:) 정도는 남기도록 한다. 이 작업을 위해서 파이선에서 제공하는 ‘regular expression(regex)’ 라이브러리 모듈 ‘re’를 사용해보자.

HTML 부호인 '<[^>]*>' 들을 제거하고 다음과 같이 이모티콘만 임시 저장해둔다.

 

emoticons = re.findall('(?::|;|=)(?:-)?(?:\)|\(|D|P)',text)

 

마지막으로 문장의 단어가 아닌 비단어성 문자를 글로벌 서치하는 명령어 [\W]+를 사용하여 모조리 제거하고 문장 전체를 소문자로 변환시킴과 동시에 이모티콘들은 문장의 끝부분에 가져다 두도록 한다. 하지만 이 과정에서 nose 문자라고 하는 이모티콘 ‘(-)’까지도 제거해 버렸다.

 

text = (re.sub('[\W]+', ' ', text.lower()) + ' '.join(emoticons).replace('-', ''))

 

우선 preprocessor 함수명령이 포함된 파이선 코드를 선 실행하자. 실행 후에도 df 명령이나 preprocessor 명령은 복사하여 셸(Shell)에서 다시 실행해야 출력 결과를 볼 수 있다.

마지막 칸에서 사용된 preprocessing의 텍스트 인수인 df.loc[0, 'review'],[-50:] 의 용법에 대해서 아래 사례를 통해 살펴보자. 셔플링 후 0~49999개의 리뷰우가 있음을 알 수 있다.

 

지금까지 처리해서 얻을 수 있는 소위 말하는 regular expressions을 찾아내는 방법은 문자열에서 문자를 검색하는 효율적이면서 편리한 접근법인데 특히 강력한 학습 경향을 보여준다는 점에 유의하자.

 

이 regular expressions 작업을 통해서 비록 문장의 단어순서가 바뀌어도 bag-of-words 모델에서 한 단어별 토큰이 사용된다면 아무런 문제는 없다.

이어서 다음 문장 예제를 preprocessing 해보면 결과가 어떻게 얻어지는지 살펴보자.

이렇게 해서 얻어지는  cleaned text data를 계속적으로 사용할 것이기 때문에 Data Frame의 전체 영화 리뷰에 preprocessor를 적용해 보도록 하자.

 

df['review'] = df['review'].apply(preprocessor)

 

첨부된 코드의 실행은 셸에서 아래와 같이 실행해 보도록 하자.

 

컴퓨터를 끄지 않은 상태에서 께속하여 문서의 토큰화 작업을 계속하도록 한다. 문서 토큰화 과정은 다음번 블로그에 게재할 계획이다.

 

#text_clean

import re

def preprocessor(text):
    text = re.sub('<[^>]*>', '', text)
    emoticons = re.findall('(?::|;|=)(?:-)?(?:\)|\(|D|P)', text)
    text = (re.sub('[\W]+', ' ', text.lower()) +
            ' '.join(emoticons).replace('-', ''))
    return text

def tokenizer(text):
    return text.split()

df.loc[0, 'review'][-50:]
preprocessor(df.loc[0, 'review'][-50:])
preprocessor("</a>This :) is :(a test :=)!")
df['review'] = df['review'].apply(preprocessor)
tokenizer('runners like running and thus they run')