morphs(string) : 형태소 단위로 토큰화(tokenize)nouns(string) : 명사만 추출하여 토큰화(tokenize) pos(string): 품사 부착tagset: 형태소 분석기가 사용하는 품사태그 설명하는 속성. # 형태소 분석기 클래스를 import from konlpy.tag import Okt, Mecab # 객체 생성 okt = Okt() mecab = Mecab() # 형태소 단위 토큰화 # okt_tokens = okt.morphs(sample) okt_tokens = okt.morphs(sample, stem=True) # stem=True: 원형복원 (Okt의 기능.) mecab_tokens = mecab.morphs(sample) print(okt_tokens[:5]) print(mecab_tokens[:5])['올해', '처음', '수도권', '오존', '주의보', '연합뉴스', '오후', '인천', '남부', '역']['올해', '처음', '수도', '오존', '주의보', '연합', '뉴스', '일', '오후', '시']
###### 명사만 추출 okt_nouns = okt.nouns(sample) mecab_nouns = mecab.nouns(sample) print(okt_nouns[:10]) print(mecab_nouns[:10])['올해', '처음', '수도권', '오존', '주의보', '연합뉴스', '오후', '인천', '남부', '역']['올해', '처음', '수도', '오존', '주의보', '연합', '뉴스', '일', '오후', '시']
### 품사부착(pos tagging) okt_pos = okt.pos(sample) mecab_pos = mecab.pos(sample) print(okt_pos[:10]) print(mecab_pos[:10])[('올해', 'Noun'), ('들어', 'Verb'), ('처음', 'Noun'), ('으로', 'Josa'), ('수도권', 'Noun'), ('에', 'Josa'), ('오존', 'Noun'), ('주의보', 'Noun'), ('가', 'Josa'), ('내려졌다', 'Verb')][('올해', 'NNG'), ('들', 'VV'), ('어', 'EC'), ('처음', 'NNG'), ('으로', 'JKB'), ('수도', 'NNG'), ('권', 'XSN'), ('에', 'JKB'), ('오존', 'NNG'), ('주의보', 'NNG')]
sample2 = "이것도 되나욬ㅋㅋㅋ" okt.morphs(sample2)['이', '것', '도', '되나욬', 'ㅋㅋㅋ']
okt.morphs(sample2, norm=True) # Okt: norm=True -> 비속어 처리. # mecab은 지원하지 않는 기능.['이', '것', '도', '되나요', 'ㅋㅋㅋ']
# 비속어 처리 문자열을 반환 print(okt.normalize(sample2)) # Okt 기능.
##### Konlpy와 nltk를 이용해 헌법 text 분석. from nltk import Text, FreqDist from konlpy.tag import Okt from konlpy.corpus import kolaw law_txt = kolaw.open("constitution.txt").read() print(law_txt[:20])대한민국헌법
유구한 역사와 전통에
# 토큰화 ## 형태소 단위로 분리 (품사부착) okt = Okt() tokens = okt.pos(law_txt) print(tokens[:20])[('대한민국', 'Noun'), ('헌법', 'Noun'), ('\n\n', 'Foreign'), ('유구', 'Noun'), ('한', 'Josa'), ('역사', 'Noun'), ('와', 'Josa'), ('전통', 'Noun'), ('에', 'Josa'), ('빛나는', 'Verb'), ('우리', 'Noun'), ('대', 'Modifier'), ('한', 'Modifier'), ('국민', 'Noun'), ('은', 'Josa'), ('3', 'Number'), ('·', 'Punctuation'), ('1', 'Number'), ('운동', 'Noun'), ('으로', 'Josa')]
## 명사, 동사만 추출 # okt.tagset # Verb, Noun tokens = [word for word, pos in tokens if pos in ['Verb', 'Noun']] tokens[:20]['대한민국',
'헌법',
'유구',
'역사',
'전통',
'빛나는',
'우리',
'국민',
'운동',
'건립',
'된',
'대한민국',
'임시정부',
'법',
'통과',
'불의',
'항거',
'민주',
'이념',
'계승']
text = Text(tokens, name="대한민국 헌법") text<Text: 대한민국 헌법>
text[:10], text[0](['대한민국', '헌법', '유구', '역사', '전통', '빛나는', '우리', '국민', '운동', '건립'], '대한민국')
# 토큰별 빈도수 print(text.count('대한민국')) print(text.count('국민')) print(text.count('헌법'))11
61
53
# 빈도수 선그래프 import matplotlib.pyplot as plt plt.rcParams['font.family'] = 'malgun gothic' plt.rcParams['axes.unicode_minus'] = False plt.figure(figsize=(12, 5)) plt.title("헌법 단어 빈도수", fontsize=20) text.plot(30) plt.show()
# 특정 단어들이 어디에 나오는 지 확인. plt.figure(figsize=(10, 6)) text.dispersion_plot(['대통령', '법률', '국회', '헌법', '국민'])
### 빈도수 관련 분석 fd = text.vocab() print("고유 토큰 개수:", fd.B()) print("총 토큰수:", fd.N()) print("가장 많이 나온 토큰:", fd.max()) print("법률의 빈도수:", fd.get('법률')) print(f"가장 많이 나온 토큰({fd.max()})의 빈도수: {fd.get(fd.max())}") print(f"가장 많이 나온 토큰의 총 토큰수 대비 비율: {fd.freq(fd.max()) * 100:.2f}%")고유 토큰 개수: 1014
총 토큰수: 4661
가장 많이 나온 토큰: 제
법률의 빈도수: 127
가장 많이 나온 토큰(제)의 빈도수: 175
가장 많이 나온 토큰의 총 토큰수 대비 비율: 3.75%
# 빈도수 순위 fd.most_common(5)[('제', 175), ('한다', 155), ('법률', 127), ('할', 100), ('정', 89)]
###### 말뭉치를 구성하는 토큰들 + 그 토큰의 빈도수를 모아놓은 것. ==> Vocab(어휘 사전) ####### FreqDist : 어휘 사전 역할을 가지고 있다. fd.pprint()FreqDist({'제': 175, '한다': 155, '법률': 127, '할': 100, '정': 89, '수': 88, '대통령': 83, '국가': 73, '국회': 68, '하는': 64, ...})
# DataFrame을 정리
import pandas as pd
law_vocab = pd.DataFrame(fd.most_common(), columns=["단어", "빈도수"])
law_vocab.head(10)
단어 빈도수
0 제 175
1 한다 155
2 법률 127
3 할 100
4 정 89
5 수 88
6 대통령 83
7 국가 73
8 국회 68
9 하는 64
# 폰트 조회 import matplotlib.font_manager as fm [(f.name, f.fname) for f in fm.fontManager.ttflist if "malgun" in f.name.lower() ][('Malgun Gothic', 'C:\Windows\Fonts\malgun.ttf'),
('Malgun Gothic', 'C:\Windows\Fonts\malgunsl.ttf'),
('Malgun Gothic', 'C:\Windows\Fonts\malgunbd.ttf')]
## WordCloud from wordcloud import WordCloud wc = WordCloud( font_path=r"c:\Windows\Fonts\malgun.ttf", max_words=100, min_font_size=1, max_font_size=50, relative_scaling=0.2, background_color="white" ) # 파일 저장 # 출력 이미지 word_cloud_img = wc.generate_from_frequencies(fd) word_cloud_img.to_file("constitution_wc.png")plt.figure(figsize=(10,10)) plt.imshow(word_cloud_img);
with open("data/news_text.txt", encoding="utf-8") as f : news_txt = f.read()from konlpy.tag import Okt stopwords = ['이', '그', '저', '있다', '없다', '것', '수', '은', '는', '이', '가', '을', '를', '등', '개'] okt = Okt() tokens = [word for word, pos in okt.pos(news_txt) if pos in ['Verb', 'Noun'] and word not in stopwords] len(tokens)from nltk import Text import matplotlib.pyplot as plt txt = Text(tokens, name='뉴스')
plt.figure(figsize=(10, 4)) text.plot(10) plt.show()
plt.figure(figsize=(7,7)) text.dispersion_plot(['인공위성', '관측', '천체'])
# 빈도수 순위 fd = text.vocab() fd.most_common(10)[('인공위성', 13),
('관측', 13),
('천체', 8),
('했다', 8),
('하는', 7),
('쏴', 6),
('방해', 5),
('교수', 5),
('영향', 5),
('할', 5)]
# 어휘사전 import pandas as pd news_vocab = pd.DataFrame(fd.most_common(), columns=['단어', '빈도수']) news_vocab.head()
단어 빈도수
0 인공위성 13
1 관측 13
2 천체 8
3 했다 8
4 하는 7
### word cloud from wordcloud import WordCloud font = r"c:\Windows\Fonts\malgun.ttf" wc = WordCloud( font_path=font, max_font_size=50, min_font_size=1, relative_scaling=0.5) word_cloud = wc.generate_from_frequencies(fd)word_cloud.to_file('news_wc.png') plt.imshow(word_cloud) plt.axis('off') plt.show()