안녕하세요. 은공지능 공작소를 운영하는 파이찬입니다~!
오늘은 IMDb 리뷰 데이터로 워드 클라우드를 그리는 3번째 시간입니다.

1편에서는 전처리 작업을 진행했고,
2편에서는 기본적인 워드 클라우드를 그렸습니다.
(아래 포스팅 링크 참조해주세요)
 

[Python/Jupyter] 자연어처리를 위한 IMDB 데이터 전처리 과정 (데이터 다운로드부터 라벨링까지!)

안녕하세요! 은공지능 공작소의 파이찬입니다. 오늘은 파이썬으로 IMDB 영화데이터를 다운받고 전처리해보겠습니다. 전처리 작업은 자연어 처리를 위한 라벨링까지 진행합니다. https://www.imdb.com/ Ratings an..

chan-lab.tistory.com

 

[Python/Jupyter] IMDB 영화데이터로 워드클라우드 그리기 (기본편)

안녕하세요. 은공지능 공작소의 파이찬입니다. 오늘은 IMDb 영화리뷰 데이터로 워드클라우드를 그려보겠습니다. 데이터 전처리 과정은 아래 포스팅을 참조해주시길 바랍니다. [Python/Jupyter] 자연어처리를 위한..

chan-lab.tistory.com

 

 

 

 

 

오늘 진행할 부분은 위의 워드 클라우드에서 <br> 태그를 제거하는 것과,
불용어 사전 업데이트를 통해서 위에 보이는 일부 단어를 제거하는 것입니다.
또한 더 나아가서, 각각 긍정 단어와 부정 단어로만 이루어진 워드 클라우드도 그려보겠습니다.

 

 

 

 

 

 

 

 

 

 

 

 

1. html 태그 제거하기 (Beautiful Soup)

 

 

먼저 데이터를 살펴보겠습니다.
저희가 쓸 데이터는 지난 시간부터 쭉 사용해온 train_data입니다.
이 train_data는 txt, label이라는 2가지 컬럼이 있습니다.

txt 컬럼은 영화 리뷰가 텍스트로 담긴 컬럼이고요,
label 컬럼은 라벨(정답)이 달려있습니다.
각각 1은 긍정적인 리뷰, 0은 부정적인 리뷰를 나타냅니다.

 

 

 

 

 

from bs4 import BeautifulSoup

a = '<br>abcde</br>' # 이런 식으로 br 태그를 포함한 문자열입니다.
print(a)

a = BeautifulSoup(a, 'html5lib').get_text()
print(a)
output:
<br>abcde</br>
abcde
Beautiful Soup를 이용하여, html 태그를 제거하는 예시 코드입니다.
<br>이라고 된 부분이 html 코드입니다. 이는 웹디자인에서 줄을 바꿔주는 역할을 합니다.
하지만 워드클라우드 입장에서는 필요 없으니 제거를 해줘야 합니다.

위와 같이 Beautiful soup를 이용하여 한 번 필터링을 해주면
html 태그가 깔끔하게 제거가 됩니다.
output 부분을 보시면, <br>이라고 된 부분이 없어진 것을 확인할 수 있습니다.

지금 당장은 영화 데이터를 건들지 않겠습니다.
이렇게 Beautiful soup 함수에 대해 이해하시고 넘어가시면 됩니다.

 

 

 

 

 

 

 

2. Stopwords(불용어) 업데이트하기

 

 

 

import nltk

stopwords = nltk.corpus.stopwords.words('english') # 불용어 객체 선언
newStopWords = ['stopWord1','stopWord2'] # 추가하고 싶은 불용어 리스트
stopwords.extend(newStopWords) # 불용어 사전 업데이트
stopwords
output:
['i',
 'me',
 'my',
 ...
  "wouldn't",
 'stopWord1',
 'stopWord2']
위와 같은 방식으로 불용어 사전을 업데이트할 수 있습니다.
output을 보시면 마지막에 stopwords1, stopwords2가 업데이트된 것을
확인하실 수 있을 겁니다.

이렇게 stopwords를 업데이트해주는 것은
바로 wordcloud를 그려줄 때 옵션으로 적용할 수 있습니다.

이제 html 제거와 stopwords 업데이트를 모두 이해했으니,
이를 영화 데이터에 적용시켜 봅시다.

 

 

 

 

 

 

 

3. IMDb 데이터에서 html 태그 제거해주기

 

 

def data_engineering(input):
    from bs4 import BeautifulSoup
    
    rst = [] # rst는 result의 줄임말
    for i in input:
        # html 태그 제거
        data = BeautifulSoup(i, 'html5lib').get_text() # 필터 적용
        rst.append(data) # 결과를 rst리스트에 계속 추가
    
    return rst
    
train_data_html_out = data_engineering(train_data['txt'])
html 태그를 제거하는 함수를 하나 만들어 주고, 이름은 data_engineering으로 붙였습니다.
그리고 이 함수를 통해 train_data의 txt 컬럼을 정제하였습니다.
정제된 결과는 train_data_html_out에 담았고, 결과는 아래와 같습니다.

 

 

 

 

 

영화 리뷰 데이터에서 <br>과 같은 html 태그가 깔끔하게 사라진 모습입니다.

 

 

 

 

 

 

 

4. Stopwords(불용어) 업데이트해주기

 

 

 

위의 워드클라우드는 저번 시간에 그린 워드 클라우드입니다.
html 태그도 제거 안되어있고, 불용어 처리도 기본적인 것들로만 되어 있습니다.

여기서 제거해주고 싶은 단어를 3가지 정도 찾아보겠습니다.
큰 글자일수록, 해당 단어가 데이터에 자주 등장함을 의미합니다.

여기서는 'movie', 'film', 'one' 세 가지 단어를 제거해보겠습니다.
그러기 위해서는 위 3 단어로 불용어 사전을 업데이트해줘야 합니다.

 

 

 

 

 

stopwords_pychan = nltk.corpus.stopwords.words('english')
newStopWords = ['one', 'movie', 'film']
stopwords_pychan.extend(newStopWords)
위에서 보시는 것처럼 'one', 'movie', 'film'이라는 3 단어를 불용어에 추가한 후
이를 extend 함수를 통해 업데이트해주었습니다.
업데이트된 결과는 아래와 같습니다.

 

 

 

 

 

빨간 박스를 보면 3가지 불용어가 잘 추가된 것을 확인하실 수 있습니다.

 

 

 

 

 

 

 

5. 워드클라우드 그려보기

 

 

 

from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt
%matplotlib inline

wordcloud = WordCloud(stopwords = stopwords_pychan,
                      background_color = 'black', #배경색
                      width = 800,
                      height = 600).generate(' '.join(train_data_html_out))

plt.figure(figsize = (15, 10)) # 각각 가로 세로 인치 입니다.
plt.axis("off") # 축에 표시되는 눈금을 제거하는 옵션
plt.imshow(wordcloud) # 이미지가 표시되도록 하는 옵션. 
plt.show() # 최종으로 보여주는 옵션. 
html이 제거된 데이터를 가지고 워드 클라우드를 그려보았습니다.
여기서 stopwords 옵션에 주목해주시길 바랍니다.

stopwords_pychan이라고 해준 것을 사용했습니다.
이는 위에서 저희가 'one', 'movie', 'film' 3가지 불용어를 추가해준 것입니다.
불용어 처리를 했기에 앞으로 그릴 워드클라우드에서는 해당 단어들이 보이면 안 되겠지요.

나머지 코드들은 지난 시간에 다 설명드린 내용이므로 넘어가겠습니다.
바로 결과를 확인해보시죠.

 

 

 

 

 

br 태그를 포함해서 film, movie, one이 사라진
워드클라우드가 나온 것을 확인하실 수 있습니다.

그런데 이런 것들을 제거해줬더니,
이번엔 show나 character 같은 엉뚱한 단어들이 수면위로 올라왔습니다.

이런 결과는 워드클라우드를 그린다 해도 별로 의미가 없을 것 같습니다.
제가 생각했을 때, 좀 의미가 있으려면 지역 명칭이 나온다던지, 영화배우 이름이 나온다던지
이런 고유명사가 나와준다면 워드클라우드가 의미가 있을 것 같은데,
이렇게 나오는 것은 좀 더 손을 많이 봐야 할 것 같습니다. 

그렇다면 긍정, 부정 단어들로만 워드 클라우드를 딱딱 그릴 수는 없을까 고민을 해보았습니다.
위에서 했던 것처럼 stopwords를 일일이 손으로 추가하다가는 엄청 시간이 많이 걸릴 것 같습니다.

이런 방법이 다른 모델에 적용이 될지도 의심스럽구요.
(여기서 제거된 단어가 다른 자연어 워드클라우드에서는 의미를 가질 수도 있으니까요.)

다행히도 방법이 있었습니다. 바로 긍정 단어, 부정 단어만 모아놓은 일종의 리스트를 적용시키는 것인데요.
구글링 결과 깃허브에 누가 이러한 단어들을 정리를 해두었습니다.
이제부터 그것을 적용시켜서 각각 긍정 워드클라우드, 부정 워드클라우드를 그려볼까 합니다.

 

 

 

 

 

 

 

6. 긍정, 부정 단어 리스트 적용하여 워드 클라우드 그리기

 

 

 

 

shekhargulati/sentiment-analysis-python

sentiment analysis step by step. Contribute to shekhargulati/sentiment-analysis-python development by creating an account on GitHub.

github.com

위의 깃허브에 긍정단어, 부정단어가 정리된 텍스트 파일이 있습니다.
프로필을 보니, 인도 프로그래머 Shekhar Gulati라는 분이네요 ㅎㅎ
(Thank you for your Git :)

 

 

 

 

 

사이트에 들어가시면 위와 같은 화면이 뜹니다.
초록 단추를 누른 후, 위와 같이 웹주소를 복사해 줍니다.

 

 

 

 

 

conda install git
이제 아나콘다 프롬프트를 실행시켜 줍니다.
그리고 git 라이브러리를 설치하지 않으신 분들은 위와 같이,
git 라이브러리를 설치하는 명령어를 날려줍니다.

 

 

 

 

 

git clone https://github.com/shekhargulati/sentiment-analysis-python.git
git clone이라고 치신 후, 아까 복사해 두었던 링크 주소를 붙여넣기 해줍니다.
그러면 해당 프로젝트가 다운로드가 될 것입니다.

 

 

 

 

 

빨간 박스로 된 경로를 확인해주시길 바랍니다.
각각의 txt 파일들을 열어보면 위와 같이 긍정단어, 부정단어들로 구성이 되어 있습니다.

하지만 바로 긍정단어, 부정단어가 나오지는 않습니다.
위에 35줄 정도의 데이터 설명이 함께 들어있기 때문에, 전처리가 조금 필요한 상황입니다.

 

 

 

 

 

import os
word_path = 'C:/Users/white/sentiment-analysis-python/opinion-lexicon-English/'
pos_word = open(os.path.join(word_path, 'positive-words.txt'), 'r').read()
위와 같이 txt 폴더 경로를 word_path에 담아주고,
os.path.join 함수를 이용해서 경로를 조인해 주었습니다.

이 os.path.join 함수는 파일 경로를 조인할 때 쓰는 함수입니다.
저런 식으로 경로를 쓰면, 해당 폴더의 하위 파일까지 경로가 합쳐져 출력됩니다.

 

 

 

 

 

pos_word를 출력한 결과입니다.
중간중간에 \n이라고 써진 것이 유난히 많이 보이는군요.
줄바꿈(엔터)로 구분된 txt 파일이라는 것을 알 수 있습니다.

 

 

 

 

 

negative 파일도 같은 방식으로 불러와 주려고 했는데... 에러가 나버렸습니다.
이는 코덱 에러로, 인코딩 형식이 달라서 생기는 에러입니다.

이럴 경우, 파일의 인코딩을 바꿔주고
open 함수에서 encoding 옵션을 명시하면 에러를 해결할 수 있습니다.

 

 

 

 

 

위의 그림처럼 negative-words.txt 파일을 열고,
다른 이름으로 저장을 클릭합니다.

 

 

 

 

 

다음으로 인코딩을 UTF-8로 바꿔주고, 저장을 클릭해줍니다.

 

 

 

 

 

neg_word = open(os.path.join(word_path, 'negative-words.txt'), 'r', encoding='UTF-8').read()
이제  negative-words.txt를 불러올 때, 위와 같이 인코딩을 명시해줍니다.
encoding='UTF-8'이라고 된 부분이 인코딩을 명시하는 부분입니다.

이런 방법으로 다양한 인코딩 문제들을 쉽게 해결할 수 있습니다.

 

 

 

 

 

negative words도 정상적으로 불러와졌습니다.
positive words 파일과 마찬가지로 \n으로 구분되어 있는 것을 알 수 있습니다.

 

 

 

 

 

pos_word = pos_word.split('\n')
pos_word = pos_word[35:]

neg_word = neg_word.split('\n')
neg_word = neg_word[35:]
위와 같은 방식으로 전처리를 조금 해줍니다.
각각 \n으로 구분자를 명시해서 쪼개 주고(split)
35번째 인덱스부터 다시 변수에 담아주는 방식입니다.

\n을 구분자로 쓴 이유는, 해당 txt 파일이 줄바꿈(엔터)로 구분되어 있기 때문입니다.
또한 35번째 index부터 긍정/부정 단어가 나오기 때문에,
인덱스를 [35:]로 설정해, [1:34]의 설명 부분을 제외시켰습니다.

 

 

 

 

 

def data_cleaning(input, pos):
    
    clean_word = [] # 리턴값을 담아줄 리스트 선언
    
    for i in input: # i에는 여러 문장들이 담김.
        for j in i.split(): # i를 단어별로 쪼개 j에 담음
            
            if pos: # pos가 True라면 실행
                if j in pos_word: # 단어를 하나씩 positive-word와 비교
                    clean_word.append(j)
                    
            else: # pos가 False라면 실행
                if j in neg_word: # 단어를 하나씩 negative-words와 비교
                    clean_word.append(j)
    return clean_word
이제 위와 같이 데이터에서 긍정, 부정단어들을 필터링 해주는 함수를 만들어줍니다.
input 변수로 리뷰 데이터를 받아서 return값으로 긍정/부정 단어가 담긴
리스트를 출력해주는 방식입니다.

자세한 설명은 코드 주석으로 대신하겠습니다 ^^;
참고로 제 유튜브 영상을 보시면 어떻게 생각하면서 함수를 짜는지
세세하게 설명이 되어있습니다.

 

 

 

 

 

clean_pos_data = data_cleaning(train_data_html_out, pos = True)
clean_neg_data = data_cleaning(train_data_html_out, pos = False)
이제 위에서 만든 함수를 이용하여, 데이터를 클렌징해줍니다.
각각 clean_pos_data와 clean_neg_data에는
긍정, 부정 단어의 알맹이들만 남아 있을 것입니다.

 

 

 

 

 

wordcloud = WordCloud(stopwords = stopwords, # 불용어
                      background_color='black', #배경색
                      width = 800, #가로
                      height = 600).generate(' '.join(clean_pos_data))

plt.figure(figsize = (15, 10)) # 가로, 세로
plt.axis('off') # 눈금을 제거해주는 옵션
plt.imshow(wordcloud) # 안 써주면 워드클라우드가 빈 화면으로 나옴
plt.show()
wordcloud = WordCloud(stopwords = stopwords, # 불용어
                      background_color='black', #배경색
                      width = 800, #가로
                      height = 600).generate(' '.join(clean_neg_data))

plt.figure(figsize = (15, 10)) # 가로, 세로
plt.axis('off') # 눈금을 제거해주는 옵션
plt.imshow(wordcloud) # 안 써주면 워드클라우드가 빈 화면으로 나옴
plt.show()
각각 긍정 워드클라우드, 부정 워드클라우드를 출력하는 코드입니다.

 

 

 

 

 

짜잔!

아름다운 워드클라우드가 완성이 됐습니다.
긍정워드 클라우드는 like, good, great 등의 단어가 많이 보입니다.
반면에 부정 워드클라우드는 bad, hard, worst 등의 단어들이 눈에 띕니다.

 

 

 

 

 

네 이렇게 해서 html 태그 제거, 불용어 업데이트,
마지막으로 긍정/부정 워드클라우드 그리는 법까지 모두 다루어보았습니다.

현재 포스팅 날짜 8월 14일... 무더운 날씨가 이어지고 있습니다.
모두 무더위에 건강 챙기시길 바랍니다. 긴 글 읽어주셔서 감사합니다.

 

블로그 이미지

pychan

딥러닝에 관련된 시행착오, 사소하지만 중요한 것들, 가능한 모든 여정을 담았습니다.

댓글을 달아 주세요

안녕하세요. 은공지능 공작소의 파이찬입니다.
오늘은 IMDb 영화리뷰 데이터로 워드클라우드를 그려보겠습니다.
데이터 전처리 과정은 아래 포스팅을 참조해주시길 바랍니다.
 

[Python/Jupyter] 자연어처리를 위한 IMDB 데이터 전처리 과정 (데이터 다운로드부터 라벨링까지!)

안녕하세요! 은공지능 공작소의 파이찬입니다. 오늘은 파이썬으로 IMDB 영화데이터를 다운받고 전처리해보겠습니다. 전처리 작업은 자연어 처리를 위한 라벨링까지 진행합니다. https://www.imdb.com/ Ratings an..

chan-lab.tistory.com

 

 

 

 

 

 

 

 

 

 

 

 

1. 필요한 라이브러리 불러오기

 

 

 

from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt
%matplotlib inline # matplotlib가 주피터노트북에 표시되도록 설정
필요한 라이브러리는 총 3가지 입니다.
wordcloud, stopwords, matplotlib를 사용하겠습니다.

wordcloud는 워드클라우드 객체를 생성해주는 라이브러리이고,
stopwords는 일종의 불용어 집합 사전입니다.
불용어란 인터넷 검색시 잘 사용하지 않는 단어라고 합니다. 즉, 별 의미없는 단어라는 것입니다.
조사, 관사, 전치사, 접속사 등이 불용어에 해당됩니다. 이를 stopword 라고 부릅니다.

matplotlib는 파이썬언어로 그래프를 그려줄 수 있는 라이브러리 입니다.
워드클라우드 말고도 기본적인 선그래프, 박스플롯 등도
모두 이 matplotlib 라이브러리를 사용해서 그릴 수 있습니다.

 

 

 

 

 

 

 

2. 워드클라우드 데이터 살펴보기

 

 

 

워드 클라우드를 그릴 Train_data 입니다. (지난 포스팅에서 만들어 둔 것입니다.)
긍정리뷰와 부정리뷰를 모두 포함하고 있고, 총 25,000개의 행을 가지고 있습니다.

 

 

 

 

 

 

 

3. join 함수 이해하기

 

 

 

O Captain! my Captain! our fearful trip is done.
The ship has weather'd every rack, the prize we sought is won.

오 선장님! 나의 선장님! 우리의 두려운 여정은 끝났고,
배는 그 어떠한 비바람도 견뎠으며, 우리가 얻고자 한 상품을 쟁취했습니다.

- 월트 휘트먼의 소설 『풀잎』 中 -
join 함수를 설명하기 위해서, 월트 휘트먼의 소설 『풀잎』에서 3 문장을 가져왔습니다.
죽은시인의 사회라는 영화에서도 등장하는 꽤 유명한 문장이죠.

이제 이 3문장을 가지고 판다스 데이터 프레임을 만들어보도록 하겠습니다.

 

 

 

 

 

a = 'O Captain! my Captain!'
b = 'our fearful trip is done.'
c = "The ship has weather'd every rack, the prize we sought is won"

test_data = {}
test_data['sentence'] = []

test_data['sentence'].append(a)
test_data['sentence'].append(b)
test_data['sentence'].append(c)

test_data = pd.DataFrame.from_dict(test_data)
test_data
output:
                                            sentence
0                             O Captain! my Captain!
1                          our fearful trip is done.
2  The ship has weather'd every rack, the prize w...
위와 같이 코드를 짜주면, 3문장이 담긴 데이터프레임이 하나 만들어 집니다.
이제 이것들을 join 함수를 이용해서 하나로 통합해주겠습니다.

 

 

 

 

 

' '.join(test_data['sentence'])
output:
"O Captain! my Captain! our fearful trip is done. The ship has weather'd every rack, 
the prize we sought is won"
공백(' ')에 조인함수를 붙이면, 위와 같은 결과물을 얻을 수 있습니다.
이 공백의 의미는 구분자를 공백으로 해주겠다는 뜻 입니다.
이해를 돕기 위해 아래와 같이 % 문자열에 join을 적용해 보겠습니다.

 

 

 

 

 

'%'.join(test_data['sentence'])
output:
"O Captain! my Captain!%our fearful trip is done.%The ship has weather'd every rack,
the prize we sought is won"
문장 중간중간에 %가 들어간 것이 보이시나요?
이런 식으로 구분자와 join 함수를 통해, 문장들을 하나로 통합할 수 있습니다.

이해를 돕기 위해 %를 사용한 것 이니,
다음 코드부터는 정상적으로 공백 구분자로 진행하겠습니다.

 

 

 

 

 

 

 

4. 워드클라우드 그리기

 

 

 

wordcloud = WordCloud(stopwords = STOPWORDS,
                      background_color = 'black', #배경색
                      width = 800,
                      height = 600).generate(' '.join(train_data['txt']))
                      
plt.figure(figsize = (15, 10)) # (가로인치, 세로인치)
plt.axis("off") # 축눈금 제거
plt.imshow(wordcloud) # 이미지가 표시되도록
plt.show() # 최종 출력문
위와 같이 입력해하여,
워드 클라우드 객체 생성 후 워드 클라우드를 그려줍니다.

stopwords불용어처리를 해주는 옵션이고, 아래에서 더 자세히 다루겠습니다.
background_color배경색을 지정해주는 옵션입니다.
width, height는 각각 워드클라우드의 가로길이, 세로길이를 나타내고 단위는 픽셀입니다.

.generate()를 통해 워드클라우드 객체에 데이터를 넣을 수 있습니다.
괄호 안에는 공백과 join 함수로 만든 통합문이 들어가게 됩니다.
(위에서 자세히 설명 드렸습니다.)

plt라고 되어 있는 부분들은 모두 워드클라우드를 그려주기 위한 부분입니다.
설명은 코드주석으로 대신하겠습니다.

 

 

 

 

 

생성된 워드클라우드의 모습입니다.
아직 다듬어야 할 부분이 많지만, 그래도 아름답죠? ㅎㅎ

 

 

 

 

 

 

 

+ Stopwords 자세히 알아보기

 

 

 

stopwords = set(STOPWORDS)
stopwords
output:
{'a',
 'about',
 'above',
 ...
 'yours',
 'yourself',
 'yourselves'}
stopwords는 앞에서도 말씀드렸다시피, 불용어를 의미합니다.
불용어는 검색어로 잘 쓰이지 않는 단어를 뜻합니다. 즉, 쓸데없어서 삭제해야 하는 단어이지요.

위의 결과에서도 확인하실 수 있듯이, 별로 큰 의미를 갖지 못하는 단어들이 나열되어 있습니다.
여기에는 전치사, 관사, 관계대명사, 지시대명사 등이 포함이 됩니다.

WordCloud 객체에서는 Stopwords 옵션이 있는데,
stopwords = STOPWORDS 라고 해주면 자동으로 불용어를 제거한 후 출력을 해줍니다.

 

 

 

 

 

네 이렇게 해서 오늘은 기본적인 워드클라우드 그리는 법에 대해 알아보았습니다.
다음 시간에는 html 태그제거와 stopwords 업데이트 방법 등에 대해 알아보겠습니다.

위의 워드클라우드를 보면 br이라고 되어 있는 것들이 유독 눈에 많이 들어옵니다.
이는 html의 <br> 태그인데요, 키보드의 엔터키처럼 줄을 바꿔주는 기능을 합니다.
이런 단어들은 제거를 해주는 것이 당연하겠지요?
또한 불용어 사전을 업데이트하는 방법도 다음 포스팅에서 다루어볼 생각입니다.

오늘 포스팅은 여기까지 하겠습니다.
감사합니다.

 

블로그 이미지

pychan

딥러닝에 관련된 시행착오, 사소하지만 중요한 것들, 가능한 모든 여정을 담았습니다.

댓글을 달아 주세요