저번 포스팅에 이어서, 이번엔 konlpy를 활용한 형태소 분석을 진행합니다.
※ 형태소 분석이란?
문장을 단어로 분할하는 기술로, 대표적인 한국어 형태소 분석 라이브러리로는 konlpy가 있다.
konlpy 라이브러리가 없으신 분들은 pip install을 통해 다운을 받고 분석을 진행해봅시다.
✔Table of Contents
Tech 94. 문장 분해하기
먼저 konlpy의 Twitter를 import하여, 어떤 예제 텍스트를 품사 단위로 분해해보겠습니다.
#예제: text라는 문장을 품사 단위로 분해하기
from konlpy.tag import Twitter
twt = Twitter()
text = '형태소분석으로 문장을 분해해보자'
tagging = twt.pos(text)
tagging #단어와 품사가 리스트 형태로 표시됨
예제 텍스트(text)인 '형태소분석으로 문장을 분해해보자' 라는 문장이 위와 같이 분해되었습니다.
문장이 단어 단위로 쪼개졌고, 품사가 태깅된(pos-tagging) 리스트 형태로 출력되었습니다.
그럼 여기서 퀴즈! 위의 결과에서 단어만 따로 리스트에 저장하려면 어떻게 해야 할까요? 2가지 방법이 있습니다.
sy = []
for i, j in tagging:
sy.append(i)
sy
위에서 단어-품사가 같이 나온 'tagging' 객체로부터 단어만 따로 리스트에 담으면 되겠죠?
책에서 나온 대로 이렇게 하셔도 됩니다.
#책에 나온대로..
sy = []
for i in tagging:
if i == 'EOS' : continue
sy.append(i[0])
sy
저는 tagging의 요소를 i, j로 두었는데, 책에선 그냥 i로 퉁치고 i[0]를 단어, i[1]을 품사로 두고 리스트에 i[0]를 담았습니다.
Tech 95. 문장에서 '동사'와 '명사'만 추출하자
위에서 pos 태깅(pos-tagging)을 통해 단어와 이에 매칭되는 품사까지 함께 뽑을 수 있음을 배웠습니다.
이를 활용하여 품사가 '동사', '명사'인 것들만 뽑아봅시다.
간단한 코드로 이렇게 뽑을 수 있겠죠.
sy = []
for i, j in tagging:
if j == 'Noun' or j == 'Verb':
sy.append(i)
sy
책에서 나온 코드도 참고하세요.
#품사가 명사/동사가 아닌 경우 continue에 의해 words_arr 에 저장되지 않음.
words_arr = []
parts = ['Noun', 'Verb']
for i in tagging:
if i == 'EOS' or i == ' ' : continue
word_temp = i[0] #word
part = i[1] #품사
if not (part in parts): continue
words_arr.append(word_temp)
words_arr
Tech 96. 자주 나오는 '명사'가 무엇인지 알아보자
이번에는 설문 결과인 sur 데이터셋에서 어떤 단어가 사용됐을 때 만족도가 높게 나오는지를 살펴봅시다.
이를 위해선 의견(comment)와 만족도(satisfaction)를 봐야겠죠?
그래서 의견에서 "명사" 만 전부 다 뽑아서 어떤 단어들이 있는지부터 살펴보겠습니다.
sur.head()
all_word = [] #이 리스트에 명사를 담을 예정
for n in range(len(sur)):
text = sur['comment'].iloc[n]
words = twt.pos(text)
for i, j in words:
if j == 'Noun':
all_word.append(i)
print(all_word)
위의 코드로 'all_word' 라는 리스트에 명사만 전부 차곡차곡 담았습니다.
이 단어들을 groupby하여, 단어별로 등장한 횟수를 셉니다.
#추출된 단어들을 잘 살펴보면 중복되는 단어가 몇개 있다. '역앞' 같은것도 여러번 나옴.
#그래서 단어의 빈도수를 집계해서, 자주 등장한 단어 Top 5만 뽑아보자!
all_word_df = pd.DataFrame(all_word, columns = ['words'])
all_word_df = pd.DataFrame(all_word_df.groupby('words')['words'].count())
all_word_df.rename(columns = {'words': 'cnt'}, inplace=True)
all_word_df.reset_index(inplace=True)
all_word_df.sort_values(by = 'cnt', ascending=False)[:5]
저는 위 코드를 썼지만, 책에서 나온 코드를 사용하면 좀 더 깔끔한 코드로 같은 결과를 만들 수 있어서 첨부합니다.
#책에서 나온대로 해도 됨!
all_word_df = pd.DataFrame({'words': all_word, 'count': len(all_word)*[1]})
all_word_df = all_word_df.groupby('words').count()
all_word_df.sort_values('count', ascending=False).head()
책에서는 all_word의 모든 단어들에 '1' 이라는 값을 주어 'all_word_df' 라는 데이터프레임을 만들었습니다.
그리고 나서 words(단어)를 groupby하였네요!
결과를 보니, 별 의미 없는 단어인 '더', '수', '좀' 같은 단어가 많이 카운트되었습니다. 명사이긴 하지만, 어떤 뜻을 담고 있다고 보긴 어렵습니다.
이런 단어는 stopwords(불용어) 처리를 하여 제거합니다. 밑에서 알아봅시다.
Tech 97. 관계없는 단어(stopword) 제거하기
위에서처럼 '더', '수', '좀'은 stopwords로 보고, 아예 처음부터 명사만 뽑는 all_word 리스트에 들어가지 않도록 코드를 다시 짭니다.
all_word = [] #이 리스트에 명사를 담을 예정
stop_words = ['더', '수', '좀']
for n in range(len(sur)):
text = sur['comment'].iloc[n]
words = twt.pos(text)
for i, j in words:
if j == 'Noun':
if i not in stop_words: #stop_words 안의 단어라면 포함 안되게 하기
all_word.append(i)
print(all_word)
아까 전에 비해 all_word 리스트에 담긴 단어가 좀 줄어든 것 같습니다.
이제 다시 all_word_df를 만듭니다. 코드는 동일합니다.
#이제 다시 all_word_df를 만들어서 바뀌었는지 살펴보자!
all_word_df = pd.DataFrame({'words': all_word, 'count': len(all_word)*[1]})
all_word_df = all_word_df.groupby('words').count()
all_word_df.sort_values('count', ascending=False).head()
이렇게 불필요한 단어는 stopword로 처리하여 삭제하니, 이전과는 다른 단어들이 많이 등장했습니다.
그런데, 이 단어들이 긍정적인 내용인지, 부정적인 내용인지는 만족도(satisfaction) 컬럼 값을 같이 고려해봐야 알 수 있겠죠?
예를 들어 '역앞' 이라는 단어가 많이 나왔는데, 이건 긍정적인 내용일까요?
자주 나오는 단어와 만족도 간의 관계를 살펴보는 것은 다음 포스팅에서 이어집니다! :)
'Data Science > Analysis Study' 카테고리의 다른 글
파이썬 자연어 처리(NLP) - 코사인 유사도를 활용해 유사한 문장 찾기 & 책 마무리 (0) | 2022.05.19 |
---|---|
파이썬 자연어 처리(NLP) - 문장 수치화하기(One-hot Encoding) / 파이썬 데이터 분석 실무 테크닉 100 (0) | 2022.05.18 |
파이썬 자연어 처리(NLP) - 텍스트 데이터 전처리 / 파이썬 데이터 분석 실무 테크닉 100 (0) | 2022.05.16 |
Python OpenCV (5) - HOG 노이즈 제거하기 (이동평균 이용) (0) | 2022.05.14 |
Python OpenCV (4) - 동영상에서 사람 얼굴 인식하기, 타임랩스 만들기 (0) | 2022.05.14 |