구글 코랩에서 사용하기
코랩 쉽게 따라하기
여기서는 바른을 Colab에서 사용하는 방법에 대해서 소개합니다.
Google에서 개발한 Colaboratory, 또는 줄여서 Colab은 구글에서 제공하는 클라우드 기반의 주피터 노트북 환경입니다.
Colab을 사용하면 구글 계정을 통해 무료로 GPU를 사용할 수 있으며 파이썬 등의 언어를 지원하여 딥러닝 분석 작업을 수행할 수 있습니다.
Colab은 브라우저에서 작동하기 때문에 별도의 개발 환경 구성이 필요 없으며, 예제 튜토리얼로 초보자도 쉽게 따라 할 수 있습니다.
바른 Colab 예제(colab_bareun_gpu.ipynb)를 다운로드 해 Google Colaboratory에 접속후 업로드하여 실행할 수 있습니다. Colab에서 아래의 명령줄을 차례대로 실행하여 결과를 확인합니다.
바른 준비하기
바른 다운로드
바른의 리눅스 설치본을 다운로드 받습니다.
바른 설치
다운받은 파일로 바른을 설치합니다.
ONNX 설치
아래는 바른 모델이 GPU를 사용하기 위해서 다운받는 ONNX 런타임 라이브러리입니다.
상단의 메뉴탭의 "런타임 > 런타임 유형 변경 > 하드웨어 가속기 > GPU 선택 > 저장"을 설정하시면 모델의 추론 속도가 더 빨라집니다. 단, 무료버전의 경우 Colab의 일일 사용 제한을 초과하지 않아야 합니다.
기본적으로 CPU를 사용해도 작동합니다.
!curl -O
https://github.com/microsoft/onnxruntime/releases/download/v1.23.0/onnxruntime-linux-x64-gpu-1.23.0.tgz
!tar -C /opt/bareun -xzf onnxruntime-linux-x64-gpu-1.23.0.tgz
ONNX
ONNX는 마이크로소프트에서 만든 딥러닝 추론을 위한 호환성 라이브러리입니다. 텐서플로우나 파이토치와 학습 도구로 만든 다양한 종류의 인공지능 모델을 빠르고 쉽게 추론할 수 있습니다. 자세한 사항은 https://onnx.ai/에서 확인할 수 있습니다.
환경 설정하기
아래 코드는 BAREUN_ROOT를 설정하고, /opt/bareun/bin/bareun을 백그라운드로 실행하는 코드입니다.
- %env BAREUN_ROOT="/opt/bareun": 환경 변수 BAREUN_ROOT를 "/opt/bareun"으로 설정합니다.
- !BAREUN_ROOT="/opt/bareun" nohup /opt/bareun/bin/bareun& : bareun을 백그라운드로 실행시킵니다.
바른 서버가 실행된 정보를 표시해줍니다.
API키 발급
바른 홈페이지(https://bareun.ai/)에 회원가입해서 API키를 받습니다. 가입 요청 후 이메일 인증을 하고 "로그인-내정보"에서 확인합니다.
- API키 복사
- 발급 받은 API키를 -reg 인자 다음에 입력하여 등록합니다.
바른 사용하기
PIP 패키지 설치
pip를 이용해서 bareunpy 패키지를 설치합니다.
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Collecting bareunpy
Downloading bareunpy-1.6.0-py3-none-any.whl (14 kB)
Collecting bareun-apis<0.13.0,>=0.12.0
Downloading bareun_apis-0.12.0-py3-none-any.whl (23 kB)
Requirement already satisfied: googleapis-common-protos<2.1.0,>=1.56.0 in /usr/local/lib/python3.8/dist-packages (from bareunpy) (1.58.0)
Requirement already satisfied: protobuf<4.0.0,>=3.19.4 in /usr/local/lib/python3.8/dist-packages (from bareunpy) (3.19.6)
Requirement already satisfied: grpcio<2.1.0,>=1.46.0 in /usr/local/lib/python3.8/dist-packages (from bareunpy) (1.51.1)
Installing collected packages: bareun-apis, bareunpy
Successfully installed bareun-apis-0.12.0 bareunpy-1.6.0
바른 파이썬 라이브러리 사용
바른 API를 사용합니다.
import sys
import bareunpy as brn
import google.protobuf.text_format as tf
# 아래에 "https://bareun.ai/"에서 이메일 인증 후 발급받은 API KEY("koba-...")를 입력해주세요. "로그인-내정보 확인"
API_KEY = "YOUR-API-KEY" # <- 본인의 API KEY로 교체
t = brn.Tagger(API_KEY, "localhost", 5656)
res = t.tags(["안녕하세요. 정말 좋은 날씨네요."])
m = res.msg()
tf.PrintMessage(m, out=sys.stdout, as_utf8=True)
sentences {
text {
content: "안녕하세요. 정말 좋은 날씨네요. 오늘도 힘내요."
length: 27
}
tokens {
text {
content: "안녕하세요."
length: 6
}
morphemes {
text {
content: "안녕하"
length: 3
}
tag: VA
out_of_vocab: IN_BUILTIN_DICT
}
morphemes {
text {
content: "시"
begin_offset: 3
length: 1
}
tag: EP
probability: 0.9998574
}
morphemes {
text {
content: "어요"
begin_offset: 3
length: 2
}
tag: EF
probability: 0.9906075
}
morphemes {
text {
content: "."
begin_offset: 5
length: 1
}
tag: SF
probability: 0.99191463
}
lemma: "안녕하"
tagged: "안녕하/VA+시/EP+어요/EF+./SF"
}
tokens {
text {
content: "정말"
begin_offset: 7
length: 2
}
morphemes {
text {
content: "정말"
begin_offset: 7
length: 2
}
tag: MAG
probability: 0.99328965
}
lemma: "정말"
tagged: "정말/MAG"
}
tokens {
text {
content: "좋은"
begin_offset: 10
length: 2
}
morphemes {
text {
content: "좋"
begin_offset: 10
length: 1
}
tag: VA
probability: 0.9867264
}
morphemes {
text {
content: "은"
begin_offset: 11
length: 1
}
tag: ETM
probability: 0.999984
}
lemma: "좋"
tagged: "좋/VA+은/ETM"
}
tokens {
text {
content: "날씨네요."
begin_offset: 13
length: 5
}
morphemes {
text {
content: "날씨"
begin_offset: 13
length: 2
}
tag: NNG
probability: 0.96861905
}
morphemes {
text {
content: "이"
begin_offset: 15
length: 1
}
tag: VCP
probability: 0.9999118
}
morphemes {
text {
content: "네"
begin_offset: 15
length: 1
}
tag: EF
probability: 0.98985213
}
morphemes {
text {
content: "요"
begin_offset: 16
length: 1
}
tag: JX
probability: 0.9987884
}
morphemes {
text {
content: "."
begin_offset: 17
length: 1
}
tag: SF
probability: 0.99076945
}
lemma: "날씨"
tagged: "날씨/NNG+이/VCP+네/EF+요/JX+./SF"
}
tokens {
text {
content: "오늘도"
begin_offset: 19
length: 3
}
morphemes {
text {
content: "오늘"
begin_offset: 19
length: 2
}
tag: NNG
probability: 0.9656843
}
morphemes {
text {
content: "도"
begin_offset: 21
length: 1
}
tag: JX
probability: 0.99952304
}
lemma: "오늘"
tagged: "오늘/NNG+도/JX"
}
tokens {
text {
content: "힘내요."
begin_offset: 23
length: 4
}
morphemes {
text {
content: "힘내"
begin_offset: 23
length: 2
}
tag: VV
probability: 0.979421
}
morphemes {
text {
content: "어요"
begin_offset: 24
length: 2
}
tag: EF
probability: 0.98856246
}
morphemes {
text {
content: "."
begin_offset: 26
length: 1
}
tag: SF
probability: 0.99589324
}
lemma: "힘내"
tagged: "힘내/VV+어요/EF+./SF"
}
refined: "안녕하세요. 정말 좋은 날씨네요. 오늘도 힘내요."
}
language: "ko_KR"
API에서 분석 받은 객체의 정보를 확인합니다.
- length of tokens in sentences
- length of morphemes of first token in sentences
- lemma of first token in sentences
- first morph of first token in sentences
- tag of first morph of first token in sentences
print(f'length of tokens in sentences[0] is {len(m.sentences[0].tokens)}')
print(f'length of morphemes of first token in sentences[0] is {len(m.sentences[0].tokens[0].morphemes)}')
print(f'lemma of first token in sentences[0] is {m.sentences[0].tokens[0].lemma}')
print(f'first morph of first token in sentences[0] is {m.sentences[0].tokens[0].morphemes[0]}')
print(f'tag of first morph of first token in sentences[0] is {m.sentences[0].tokens[0].morphemes[0].tag}')
length of tokens in sentences[0] is 4
length of morphemes of first token in sentences[0] is 4
lemma of first token in sentences[0] is 안녕하
first morph of first token in sentences[0] is text {
content: "\354\225\210\353\205\225\355\225\230"
length: 3
}
tag: VA
out_of_vocab: IN_BUILTIN_DICT
tag of first morph of first token in sentences[0] is 38
형태소 분석 실행한 객체를 json 형식으로 변환합니다.
{'sentences': [{'text': {'content': '안녕하세요. 정말 좋은 날씨네요.', 'length': 18, 'beginOffset': 0}, 'tokens': [{'text': {'content': '안녕하세요.', 'length': 6, 'beginOffset': 0}, 'morphemes': [{'text': {'content': '안녕하', 'length': 3, 'beginOffset': 0}, 'tag': 'VA', 'outOfVocab': 'IN_BUILTIN_DICT', 'probability': 0.0}, {'text': {'content': '시', 'beginOffset': 3, 'length': 1}, 'tag': 'EP', 'probability': 0.99986386, 'outOfVocab': 'IN_WORD_EMBEDDING'}, {'text': {'content': '어요', 'beginOffset': 3, 'length': 2}, 'tag': 'EF', 'probability': 0.9903047, 'outOfVocab': 'IN_WORD_EMBEDDING'}, {'text': {'content': '.', 'beginOffset': 5, 'length': 1}, 'tag': 'SF', 'probability': 0.99277085, 'outOfVocab': 'IN_WORD_EMBEDDING'}], 'lemma': '안녕하', 'tagged': '안녕하/VA+시/EP+어요/EF+./SF', 'modified': ''}, {'text': {'content': '정말', 'beginOffset': 7, 'length': 2}, 'morphemes': [{'text': {'content': '정말', 'beginOffset': 7, 'length': 2}, 'tag': 'MAG', 'probability': 0.9925209, 'outOfVocab': 'IN_WORD_EMBEDDING'}], 'lemma': '정말', 'tagged': '정말/MAG', 'modified': ''}, {'text': {'content': '좋은', 'beginOffset': 10, 'length': 2}, 'morphemes': [{'text': {'content': '좋', 'beginOffset': 10, 'length': 1}, 'tag': 'VA', 'probability': 0.98677385, 'outOfVocab': 'IN_WORD_EMBEDDING'}, {'text': {'content': '은', 'beginOffset': 11, 'length': 1}, 'tag': 'ETM', 'probability': 0.99996984, 'outOfVocab': 'IN_WORD_EMBEDDING'}], 'lemma': '좋', 'tagged': '좋/VA+은/ETM', 'modified': ''}, {'text': {'content': '날씨네요.', 'beginOffset': 13, 'length': 5}, 'morphemes': [{'text': {'content': '날씨', 'beginOffset': 13, 'length': 2}, 'tag': 'NNG', 'probability': 0.96757835, 'outOfVocab': 'IN_WORD_EMBEDDING'}, {'text': {'content': '이', 'beginOffset': 15, 'length': 1}, 'tag': 'VCP', 'probability': 0.99990535, 'outOfVocab': 'IN_WORD_EMBEDDING'}, {'text': {'content': '네', 'beginOffset': 15, 'length': 1}, 'tag': 'EF', 'probability': 0.99098045, 'outOfVocab': 'IN_WORD_EMBEDDING'}, {'text': {'content': '요', 'beginOffset': 16, 'length': 1}, 'tag': 'JX', 'probability': 0.99870336, 'outOfVocab': 'IN_WORD_EMBEDDING'}, {'text': {'content': '.', 'beginOffset': 17, 'length': 1}, 'tag': 'SF', 'probability': 0.9929885, 'outOfVocab': 'IN_WORD_EMBEDDING'}], 'lemma': '날씨', 'tagged': '날씨/NNG+이/VCP+네/EF+요/JX+./SF', 'modified': ''}], 'refined': '안녕하세요. 정말 좋은 날씨네요.'}], 'language': 'ko_KR'}
형태소 분석 실행한 객체를 튜플로 저장하거나, 명사, 동사만 추출할 수도 있습니다.
[('안녕하', 'VA'), ('시', 'EP'), ('어요', 'EF'), ('.', 'SF'), ('정말', 'MAG'), ('좋', 'VA'), ('은', 'ETM'), ('날씨', 'NNG'), ('이', 'VCP'), ('네', 'EF'), ('요', 'JX'), ('.', 'SF'), ('오늘', 'NNG'), ('도', 'JX'), ('힘내', 'VV'), ('어요', 'EF'), ('.', 'SF')]
['안녕하', '시', '어요', '.', '정말', '좋', '은', '날씨', '이', '네', '요', '.', '오늘', '도', '힘내', '어요', '.']
['날씨', '오늘']
['힘내']
고급 기능 예제
이 예제에서는 형태소 분석기 바른과 mecab의 분석 성능을 테스트하는 과정을 다룹니다.
분석 성능 비교를 위해 바른에서 구축한 한국어 중의성해소 평가 데이터세트 를 다운받고 불러옵니다.
mecab 설치
아래는 curl 명령어를 사용하여 Github에서 다운받아 mecab을 설치하는 과정입니다.
그리고 mecab 라이브러리를 불러와 형태소 분석 기능을 테스트합니다.
!curl -s https://raw.githubusercontent.com/teddylee777/machine-learning/master/99-Misc/01-Colab/mecab-colab.sh | bash
bareun 평가 실행
평가 데이터를 불러와서 전처리하는 함수입니다.
def dataload(path):
"""
json파일을 불러와서 정답, 문장으로 전처리합니다.
:param path: 평가 데이터의 path
:return: 평가 데이터세트
"""
import json
with open(path) as f:
sents = json.load(f)
ret = []
for idx, sent in enumerate(sents['sentences']):
final_answer = []
if '+' in sent['answer']:
tokens = sent['answer'].split('+')
temp = []
for i in range(len(tokens)):
form = tokens[i].split('/')[0]
tag = tokens[i].split('/')[1]
t = (form, tag)
temp.append(t)
final_answer.append(temp)
final_answer.append(sent['text'])
else:
tokens = sent['answer'].split('/')
form, tag = tokens[0], tokens[1]
temp = (form, tag)
final_answer.append(temp)
final_answer.append(sent['text'])
ret.append(final_answer)
return ret
구글 링크를 다운로드할 수 있는 라이브러리를 설치합니다.
평가 데이터세트 공유 구글 링크를 다운로드 합니다.
!gdown https://drive.google.com/file/d/1TwJB5Bp12GJh54ip2cUFzfzOA7fluMN1/view?usp=share_link -O ambiguity_sentences.json --fuzzy
다운 받은 평가 데이터세트의 일부를 프린트합니다.
[[[('쿠키', 'NNG'), ('와', 'JC')], '밀가루, 계란, 우유 반죽과 한참을 씨름한 끝에 마침내 오븐에서 결혼 전 발레리나였던 아내의 모습을 본 뜬 쿠키와 곧 태어날 아기에게 먹일 젖병 모양의 쿠키가 나왔다.'], [[('쿠키', 'NNG'), ('와', 'JKB')], '뭐 케이크 빵 쿠키와 같은 베이커립니다.'], [[('퀄리티', 'NNG'), ('가', 'JKS')], '고려은단은 고가의 영국산 원료를 사용함에도 불구하고 원료의 대량 구매 및 최신 자동화 설비를 통한 원가 절감으로 가격 대비 퀄리티가 높다는 평가를 받고 있다.'], [[('퀄리티', 'NNG'), ('가', 'JKC')], '이 정도는 쫌 어느 정도 퀄리티가 되는 글이 나와야 책으로 낼 수 있다.'], [('퀸', 'NNG'), '대상 및 특별상 수상자는 12월 여성가족부가 주최하는 ‘아이디어 퀸 공모전’ 본선에 참가하게 된다.']]
바른 모델을 평가하는 함수입니다.
def bareun_evaluate(dataset):
from tqdm import tqdm
from google.protobuf.json_format import MessageToDict
acc, tot = 0, 0
for index, (answer, exam) in enumerate(tqdm(dataset)):
correct = False
result = []
analyzed = MessageToDict(t.tags([exam]).msg())
for word in analyzed['sentences'][0]['tokens']:
for morph in word['morphemes']:
result.append((morph['text']['content'], morph['tag']))
answer_length = len(answer)
correct_cnt = 0
for idx, token in enumerate(result):
# 첫번째 토큰이 정답이면 정답의 길이만큼 다음 토큰을 계산한다.
i = 0
if isinstance(answer, list): # 정답이 두개 이상의 토큰이 경우(ex. [(쿠키, NNG), (와, JC)])
if (token[0] == answer[i][0]) and (token[1] == answer[i][1]):
correct_cnt += 1
while i <= answer_length:
i += 1
if i < answer_length:
try:
if (result[idx+i][0] == answer[i][0]) and (result[idx+i][1] == answer[i][1]):
correct_cnt +=1
if correct_cnt == answer_length:
correct = True
break
except: # 정답이 결과보다 많은 경우는 분석을 잘못한 경우이니 틀린 것이다.
correct = False
break
else: # 정답이 하나의 토큰인 경우(ex.밀가루, NNG)
if (token[0] == answer[0]) and (token[1] == answer[1]):
correct = True
acc += int(correct)
tot += 1
return acc / tot
바른 모델 평가를 시작합니다.
mecab 평가 실행
mecab 모델을 평가하는 함수입니다.
def mecab_evaluate(dataset):
from tqdm import tqdm
from google.protobuf.json_format import MessageToDict
acc, tot = 0, 0
for index, (answer, exam) in enumerate(tqdm(dataset)):
correct = False
result = mecab.pos(exam)
answer_length = len(answer)
correct_cnt = 0
for idx, token in enumerate(result):
# 첫번째 토큰이 정답이면 정답의 길이만큼 다음 토큰을 계산한다.
i = 0
if isinstance(answer, list): # 정답이 두개 이상의 토큰이 경우(ex. [(쿠키, NNG), (와, JC)])
if (token[0] == answer[i][0]) and (token[1] == answer[i][1]):
correct_cnt += 1
while i <= answer_length:
i += 1
if i < answer_length:
try:
if (result[idx+i][0] == answer[i][0]) and (result[idx+i][1] == answer[i][1]):
correct_cnt +=1
if correct_cnt == answer_length:
correct = True
break
except: # 정답이 결과보다 많은 경우는 분석을 잘못한 경우이니 틀린 것이다.
correct = False
break
else: # 정답이 하나의 토큰인 경우(ex.밀가루, NNG)
if (token[0] == answer[0]) and (token[1] == answer[1]):
correct = True
acc += int(correct)
tot += 1
return acc / tot
비교
분석 결과를 간단한 중의성해소 데이터 예문을 통해 확인합니다.
sents = [
"조길상의 음성은 김광석보다 조금 탁하고 가는 편이다.",
"그건 제가 그냥 갖고 있는 개인 킵니다.",
"이런 속도라면 20년 뒤에는 50만에서 200만 종이 멸종될 것으로 학자들은 예측하고 있다.",
"방안 가득 풀어놓으며 먹자고 했지만 화가 날 대로 나 있던 나는 ",
"어제 귀가 시간부터 오늘 아침까지는 남편으로, 아들로, 아빠로 지냈지만",
"회사가 진심이라면 먼저 성의 있는 안을 내놔야 한다”고 말했다.",
"한반도를 둘러싼 주변 네 강의 변화는 격세지감이 있다.",
"창의 융합 콘텐츠 개발을 위해",
"두 번째는 모두를 위한 창의 인성 교육을 확산시키겠다 하는거고요"
]
bareun_result = []
mecab_result = []
for sent in sents:
res1 = t.tags([sent]).pos()
bareun_result.append(res1)
res2 = mecab.pos(sent)
mecab_result.append(res2)
| 표면형 | 정답 | bareun 분석결과 | mecab 분석결과 |
|---|---|---|---|
| 가는 | 가늘/VV | 가늘/VV | 가/VV |
| 키 | 키/NNG | 키/NNG | 키/NNP |
| 종이 | 종/NNG+이/JKS | 종/NNG+이/JKS | 종이/NNG |
| 귀가 | 귀가/NNG | 귀가/NNG | 귀/NNG+가/JKS |
| 성의 | 성의/NNG | 성의/NNG | 성/NNG+의/JKG |
| 강의 | 강/NNG+의/JKG | 강/NNG+의/JKG | 강의/NNG |
| 창의 | 창의/NNG | 창의/NNG | 창/NNG+의/JKG |
| 창의 | 창의/NNG | 창의/NNG | 창/NNG+의/JKG |
바른의 결과
[('조길상', 'NNP'), ('의', 'JKG'), ('음성', 'NNG'), ('은', 'JX'), ('김광석', 'NNP'), ('보다', 'JKB'), ('조금', 'MAG'), ('탁하', 'VA'), ('고', 'EC'), ('가늘', 'VA'), ('ㄴ', 'ETM'), ('편', 'NNB'), ('이', 'VCP'), ('다', 'EF'), ('.', 'SF')]
[('그거', 'NP'), ('ㄴ', 'JX'), ('제', 'NP'), ('가', 'JKS'), ('그냥', 'MAG'), ('갖', 'VV'), ('고', 'EC'), ('있', 'VX'), ('는', 'ETM'), ('개인', 'NNG'), ('키', 'NNG'), ('이', 'VCP'), ('ㅂ니다', 'EF'), ('.', 'SF')]
[('이런', 'MMD'), ('속도', 'NNG'), ('이', 'VCP'), ('라면', 'EC'), ('20', 'SN'), ('년', 'NNB'), ('뒤', 'NNG'), ('에', 'JKB'), ('는', 'JX'), ('50', 'SN'), ('만', 'NR'), ('에서', 'JKB'), ('200', 'SN'), ('만', 'NR'), ('종', 'NNG'), ('이', 'JKS'), ('멸종되', 'VV'), ('ㄹ', 'ETM'), ('것', 'NNB'), ('으로', 'JKB'), ('학자', 'NNG'), ('들', 'XSN'), ('은', 'JX'), ('예측하', 'VV'), ('고', 'EC'), ('있', 'VX'), ('다', 'EF'), ('.', 'SF')]
[('방', 'NNG'), ('안', 'NNG'), ('가득', 'MAG'), ('풀어놓', 'VV'), ('으며', 'EC'), ('먹', 'VV'), ('자고', 'EC'), ('하', 'VV'), ('았', 'EP'), ('지만', 'EC'), ('화', 'NNG'), ('가', 'JKS'), ('나', 'VV'), ('ㄹ', 'ETM'), ('대로', 'NNB'), ('나', 'VV'), ('아', 'EC'), ('있', 'VX'), ('던', 'ETM'), ('나', 'NP'), ('는', 'JX')]
[('어제', 'NNG'), ('귀가', 'NNG'), ('시간', 'NNG'), ('부터', 'JX'), ('오늘', 'NNG'), ('아침', 'NNG'), ('까지', 'JX'), ('는', 'JX'), ('남편', 'NNG'), ('으로', 'JKB'), (',', 'SP'), ('아들', 'NNG'), ('로', 'JKB'), (',', 'SP'), ('아빠', 'NNG'), ('로', 'JKB'), ('지내', 'VV'), ('었', 'EP'), ('지만', 'EC')]
[('회사', 'NNG'), ('가', 'JKS'), ('진심', 'NNG'), ('이', 'VCP'), ('라면', 'EC'), ('먼저', 'MAG'), ('성의', 'NNG'), ('있', 'VA'), ('는', 'ETM'), ('안', 'NNG'), ('을', 'JKO'), ('내놓', 'VV'), ('아야', 'EC'), ('하', 'VX'), ('ㄴ다', 'EF'), ('”', 'SS'), ('고', 'JKQ'), ('말하', 'VV'), ('았', 'EP'), ('다', 'EF'), ('.', 'SF')]
[('한반도', 'NNP'), ('를', 'JKO'), ('둘러싸', 'VV'), ('ㄴ', 'ETM'), ('주변', 'NNG'), ('네', 'MMN'), ('강', 'NNG'), ('의', 'JKG'), ('변화', 'NNG'), ('는', 'JX'), ('격세지감', 'NNG'), ('이', 'JKS'), ('있', 'VA'), ('다', 'EF'), ('.', 'SF')]
[('창의', 'NNG'), ('융합', 'NNG'), ('콘텐츠', 'NNG'), ('개발', 'NNG'), ('을', 'JKO'), ('위하', 'VV'), ('아', 'EC')]
[('두', 'MMN'), ('번', 'NNB'), ('째', 'XSN'), ('는', 'JX'), ('모두', 'NNG'), ('를', 'JKO'), ('위하', 'VV'), ('ㄴ', 'ETM'), ('창의', 'NNG'), ('인성', 'NNG'), ('교육', 'NNG'), ('을', 'JKO'), ('확산', 'NNG'), ('시키', 'XSV'), ('겠', 'EP'), ('다', 'EF'), ('하', 'VV'), ('는', 'ETM'), ('거', 'NNB'), ('이', 'VCP'), ('고', 'EC'), ('요', 'JX')]
- mecab의 결과
[('조길상', 'NNP'), ('의', 'JKG'), ('음성', 'NNG'), ('은', 'JX'), ('김광석', 'NNP'), ('보다', 'JKB'), ('조금', 'MAG'), ('탁하', 'VV'), ('고', 'EC'), ('가', 'VX'), ('는', 'ETM'), ('편', 'NNB'), ('이', 'VCP'), ('다', 'EF'), ('.', 'SF')]
[('그건', 'NP+JX'), ('제', 'NP'), ('가', 'JKS'), ('그냥', 'MAG'), ('갖', 'VV'), ('고', 'EC'), ('있', 'VX'), ('는', 'ETM'), ('개인', 'NNG'), ('킵', 'NNP'), ('니다', 'VCP+EF'), ('.', 'SF')]
[('이런', 'MM'), ('속도', 'NNG'), ('라면', 'VCP+EC'), ('20', 'SN'), ('년', 'NNBC'), ('뒤', 'NNG'), ('에', 'JKB'), ('는', 'JX'), ('50', 'SN'), ('만', 'NNG'), ('에서', 'JKB'), ('200', 'SN'), ('만', 'NR'), ('종이', 'NNG'), ('멸종', 'NNG'), ('될', 'XSV+ETM'), ('것', 'NNB'), ('으로', 'JKB'), ('학자', 'NNG'), ('들', 'XSN'), ('은', 'JX'), ('예측', 'NNG'), ('하', 'XSV'), ('고', 'EC'), ('있', 'VX'), ('다', 'EF'), ('.', 'SF')]
[('방안', 'NNG'), ('가득', 'MAG'), ('풀어놓', 'VV'), ('으며', 'EC'), ('먹', 'VV'), ('자고', 'EC'), ('했', 'VX+EP'), ('지만', 'EC'), ('화', 'NNG'), ('가', 'JKS'), ('날', 'VV+ETM'), ('대로', 'NNB'), ('나', 'VV+EC'), ('있', 'VX'), ('던', 'ETM'), ('나', 'NP'), ('는', 'JX')]
[('어제', 'MAG'), ('귀', 'NNG'), ('가', 'JKS'), ('시간', 'NNG'), ('부터', 'JX'), ('오늘', 'MAG'), ('아침', 'NNG'), ('까지', 'JX'), ('는', 'JX'), ('남편', 'NNG'), ('으로', 'JKB'), (',', 'SC'), ('아들', 'NNG'), ('로', 'JKB'), (',', 'SC'), ('아빠', 'NNG'), ('로', 'JKB'), ('지냈', 'VV+EP'), ('지만', 'EC')]
[('회사', 'NNG'), ('가', 'JKS'), ('진심', 'NNG'), ('이', 'VCP'), ('라면', 'EC'), ('먼저', 'MAG'), ('성', 'NNG'), ('의', 'JKG'), ('있', 'VA'), ('는', 'ETM'), ('안', 'NNG'), ('을', 'JKO'), ('내놔야', 'VV+EC'), ('한다', 'VX+EC'), ('”', 'SSC'), ('고', 'EC'), ('말', 'NNG'), ('했', 'XSV+EP'), ('다', 'EF'), ('.', 'SF')]
[('한반도', 'NNP'), ('를', 'JKO'), ('둘러싼', 'VV+ETM'), ('주변', 'NNG'), ('네', 'XPN'), ('강의', 'NNG'), ('변화', 'NNG'), ('는', 'JX'), ('격세지감', 'NNG'), ('이', 'JKS'), ('있', 'VA'), ('다', 'EF'), ('.', 'SF')]
[('창', 'NNG'), ('의', 'JKG'), ('융합', 'NNG'), ('콘텐츠', 'NNG'), ('개발', 'NNG'), ('을', 'JKO'), ('위해', 'VV+EC')]
[('두', 'MM'), ('번', 'NNBC'), ('째', 'XSN'), ('는', 'JX'), ('모두', 'NNG'), ('를', 'JKO'), ('위한', 'VV+ETM'), ('창', 'NNG'), ('의', 'JKG'), ('인성', 'NNG'), ('교육', 'NNG'), ('을', 'JKO'), ('확산', 'NNG'), ('시키', 'XSV'), ('겠', 'EP'), ('다', 'EC'), ('하', 'VV'), ('는', 'ETM'), ('거', 'NNB'), ('고요', 'VCP+EF')]
도움이 되었나요?