# 가장 최신 버전으로 유지
!conda update conda
!pip install --upgrade pip
# 한글 자연어 처리 패키지
!pip install konlpy
!pip install tweepy==3.10.0
!conda install -y -c conda-forge jpype1==1.0.2
!conda install -y -c conda-forge wordcloud
!conda install -y nltk
!conda install -y scikit-learn
import nltk
nltk.download()
from konlpy.tag import Okt
t = Okt()
from konlpy.tag import Kkma
kkma = Kkma()
# 문장(sentences)
kkma.sentences('한국어 분석을 시작합니다 재미있어요 ~')
['한국어 분석을 시작합니다', '재미있어요 ~']
# 명사(nouns)
kkma.nouns('한국어 분석을 시작합니다 재미있어요 ~')
['한국어', '분석']
# 형태소분석(pos)
kkma.pos('한국어 분석을 시작합니다 재미있어요 ~')
[('한국어', 'NNG'),
('분석', 'NNG'),
('을', 'JKO'),
('시작하', 'VV'),
('ㅂ니다', 'EFN'),
('재미있', 'VA'),
('어요', 'EFN'),
('~', 'SO')]
from konlpy.tag import Hannanum
hannanum = Hannanum()
hannanum.nouns('한국어 분석을 시작합니다 재미있어요 ~')
['한국어', '분석', '시작']
hannanum.morphs('한국어 분석을 시작합니다 재미있어요 ~')
['한국어', '분석', '을', '시작', '하', 'ㅂ니다', '재미있', '어', '요', '~']
hannanum.pos('한국어 분석을 시작합니다 재미있어요 ~')
[('한국어', 'N'),
('분석', 'N'),
('을', 'J'),
('시작', 'N'),
('하', 'X'),
('ㅂ니다', 'E'),
('재미있', 'P'),
('어', 'E'),
('요', 'J'),
('~', 'S')]
# UserWarning: "Twitter" has changed to "Okt" since KoNLPy v0.4.5. warn('"Twitter" has changed to "Okt" since KoNLPy v0.4.5.')
from konlpy.tag import Okt
t = Okt()
t.nouns('한국어 분석을 시작합니다 재미있어요 ~')
['한국어', '분석', '시작']
t.morphs('한국어 분석을 시작합니다 재미있어요 ~')
['한국어', '분석', '을', '시작', '합니다', '재미있어요', '~']
t.pos('한국어 분석을 시작합니다 재미있어요 ~')
[('한국어', 'Noun'),
('분석', 'Noun'),
('을', 'Josa'),
('시작', 'Noun'),
('합니다', 'Verb'),
('재미있어요', 'Adjective'),
('~', 'Punctuation')]
from wordcloud import WordCloud, STOPWORDS
import numpy as np
from PIL import Image
# 소설 읽어오기
text = open("./15. alice.txt").read()
# 이미지 읽어오기
alice_mask = np.array(Image.open("./15. alice_mask.png"))
# said 단어 제거
stopwords = set(STOPWORDS)
stopwords.add('said')
import platform
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
path = "c:/Windows/Fonts/malgun.ttf"
if platform.system() == "Darwin":
print("Hangle OK in your MAC!!!")
rc("font", family="AppleGothic")
elif platform.system() == "Windows":
font_name = font_manager.FontProperties(fname=path).get_name()
print("Hangle OK in your Windows!!!")
rc("font", family=font_name)
else:
print("Sorry, Unkwnown System")
plt.rcParams["axes.unicode_minus"] = False
Hangle OK in your Windows!!!
plt.figure(figsize=(8,8))
plt.imshow(alice_mask, cmap=plt.cm.gray, interpolation='bilinear')
# plt.axis('off')
plt.show()
# WordCloud 모듈은 자체적으로 단어를 추출해서 빈도수를 조사하고 정규화하는 기능을 가지고 있다
wc = WordCloud(
background_color='white', max_words=2000, mask=alice_mask, stopwords=stopwords
)
wc = wc.generate(text)
wc.words_
plt.figure(figsize=(8,8))
plt.imshow(wc,interpolation='bilinear')
# plt.axis('off')
plt.show()
import nltk
from konlpy.corpus import kobill
files_ko = kobill.fileids()
doc_ko = kobill.open('1809890.txt').read()
doc_ko
명사분석
from konlpy.tag import Okt
t = Okt()
token_ko = t.nouns(doc_ko)
token_ko # 명사 단어들의 집합
빈도수분석
ko = nltk.Text(token_ko, name='육아휴직법')
#token_ko : 명사 단어들의 집합
# 이 문자열 단위 : token
print(len(ko.tokens)) # 사용된 단어들
print(len(set(ko.tokens))) # 중복 제외 단어들
ko.vocab() # 어떤 단어들이 있나요? : vocab(단어의 집합)
plt.figure(figsize=(12,6))
ko.plot(50)
plt.show()
# 제거할 글자들
stop_words = [
'의', '.', '(', ')', ',', '%', '-', 'X', ').', 'x', '의',
'안', '번', '호', '발', '의', '자', '가', '를', '만', '을',
'다', '인', '김', '태', '완', '및', '정', '문', '종', '팀',
'장', '위', '의 ', '호']
ko = [each_word for each_word in ko if each_word not in stop_words]
ko
ko = nltk.Text(ko, name='대한민국 국회 의안 제 1809890호')
plt.figure(figsize=(12,6))
ko.plot(50)
plt.show()
특정단어 빈도수 조사/조회
ko.count('고용')
14
plt.figure(figsize=(12,6))
ko.dispersion_plot(['육아휴직','자녀','고용']) # dispersion_plot : 어디쯤에 위치한지 알려줌
ko.concordance('고용') # 좌우 글자를 보여줘, 문맥을 파악하는데 도움을 줌
연관있어보이는 단어들 출력
ko.collocations()
워드클라우드 출력
data = ko.vocab().most_common(150)
# WordCloud 모듈은 자체적으로 단어를 추출해서 빈도수를 조사하고 정규화하는 기능을 가지고 있다
wordcloud = WordCloud(
font_path = "c:/Windows/Fonts/malgun.ttf",
relative_scaling=0.2, # 글자 간격
background_color='white'
).generate_from_frequencies(dict(data))
plt.figure(figsize=(12,8))
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
나이브베이즈 분류를 이용한 감성분석
✍🏻 영어 ver.
from nltk.tokenize import word_tokenize
import nltk
train = [
('i like you', 'pos'),
('i hate you', 'neg'),
('you like me', 'neg'),
('i like her', 'pos')
]
말뭉치 만들기
train[0]
'i like you'
sentence = train[0]
word_tokenize(sentence[0]) #word_tokenize : 글자 분리
['i', 'like', 'you']
# set 명령으로 인해 중복 없이 출력
all_words = set(
word.lower() for sentence in train for word in word_tokenize(sentence[0])
)
all_words
{'hate', 'her', 'i', 'like', 'me', 'you'}
말 뭉치에서 각 단어 유무 파악
t = [({word: (word in word_tokenize(x[0])) for word in all_words}, x[1]) for x in train]
t
[({'her': False,
'i': True,
'me': False,
'like': True,
'you': True,
'hate': False},
'pos'),
({'her': False,
'i': True,
'me': False,
'like': False,
'you': True,
'hate': True},
'neg'),
({'her': False,
'i': False,
'me': True,
'like': True,
'you': True,
'hate': False},
'neg'),
({'her': True,
'i': True,
'me': False,
'like': True,
'you': False,
'hate': False},
'pos')]
훈련 시작
classifier = nltk.NaiveBayesClassifier.train(t) # 학습
classifier.show_most_informative_features() # 가장 많은 정보를 담고 있는 특성을 나열
테스트 시작
test_sentence = "i like MeRui"
test_sent_features = {
word.lower(): (word in word_tokenize(test_sentence.lower())) for word in all_words
}
test_sent_features
{'her': False,
'i': True,
'me': False,
'like': True,
'you': False,
'hate': False}
결과
classifier.classify(test_sent_features)
'pos'
✍🏻 한글 ver.
from konlpy.tag import Okt
pos_tagger = Okt()
train = [
('메리가 좋아','pos'),
('고양이도 좋아','pos'),
('난 수업이 지루해','neg'),
('메리는 이쁜 고양이야', 'pos'),
('난 마치고 메리랑 놀거야','pos')
]
all_words = set(
word.lower() for sentence in train for word in word_tokenize(sentence[0])
)
t = [({word: (word in word_tokenize(x[0])) for word in all_words}, x[1]) for x in train]
classifier = nltk.NaiveBayesClassifier.train(t)
classifier.show_most_informative_features()
test_sentence = "난 수업이 마치면 메리랑 놀거야"
test_sent_features = {
word.lower(): (word in word_tokenize(test_sentence.lower())) for word in all_words
}
test_sent_features
classifier.classify(test_sent_features)
'neg'
Negative가 떴으니, 형태소 분석을 통해 정확히 맞혀보자
형태소 분석을 한 뒤 품사를 단어 뒤에 붙여봄
def tokenize(doc):
return["/".join(t) for t in pos_tagger.pos(doc, norm=True, stem=True)]
train_docs = [(tokenize(row[0]), row[1]) for row in train]
train_docs
[(['메리/Noun', '가/Josa', '좋다/Adjective'], 'pos'),
(['고양이/Noun', '도/Josa', '좋다/Adjective'], 'pos'),
(['난/Noun', '수업/Noun', '이/Josa', '지루하다/Adjective'], 'neg'),
(['메리/Noun', '는/Josa', '이쁘다/Adjective', '고양이/Noun', '야/Josa'], 'pos'),
(['난/Noun', '마치/Noun', '고/Josa', '메리/Noun', '랑/Josa', '놀다/Verb'], 'pos')]
말뭉치 만들기
tokens = [t for d in train_docs for t in d[0]]
tokens
['메리/Noun',
'가/Josa',
'좋다/Adjective',
'고양이/Noun',
'도/Josa',
'좋다/Adjective',
'난/Noun',
'수업/Noun',
'이/Josa',
'지루하다/Adjective',
'메리/Noun',
'는/Josa',
'이쁘다/Adjective',
'고양이/Noun',
'야/Josa',
'난/Noun',
'마치/Noun',
'고/Josa',
'메리/Noun',
'랑/Josa',
'놀다/Verb']
def term_exists(doc):
return{word: (word in set(doc)) for word in tokens}
train_xy = [(term_exists(d),c) for d,c in train_docs]
train_xy
classifier = nltk.NaiveBayesClassifier.train(train_xy)
test_sentence = "난 수업이 마치면 메리랑 놀거야"
test_docs = pos_tagger.pos(test_sentence[0])
test_docs
classifier.show_most_informative_features()
test_sent_features = {word: (word in tokens) for word in test_docs}
test_sent_features
classifier.classify(test_sent_features)