Colab step-by-step guide
This page shows how to use Bareun in Colab.
Google Colaboratory, or Colab for short, is a cloud-based Jupyter notebook environment provided by Google.
With Colab, you can use a GPU for free through your Google account, and it supports languages such as Python, so you can run deep learning analysis work.
Colab runs in the browser, so you do not need to set up a separate development environment, and beginners can easily follow along with the example tutorial.
You can download the Bareun Colab example (colab_bareun_gpu.ipynb), go to Google Colaboratory, upload it, and run it. Run the command lines below in Colab one after another and check the results.
Preparing Bareun
Download Bareun
Download the Linux installer for Bareun.
!curl -LJks -H "uname:$(uname -a)" https://bareun.ai/api/get -o bareun-linux.deb
!ls
Install Bareun
Install Bareun from the downloaded file.
!uname -a
!dpkg -i bareun-linux.deb
Install ONNX
Below is the ONNX runtime library that you download so the Bareun model can use the GPU.
If you set "Runtime > Change runtime type > Hardware accelerator > select GPU > Save" in the top menu tab, model inference gets faster. With the free version, however, you must stay within Colab's daily usage limit.
It also works with the CPU by default.
!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 is a compatibility library for deep learning inference made by Microsoft. It lets you run inference quickly and easily on many kinds of AI models built with training tools such as TensorFlow and PyTorch. For details, see https://onnx.ai/.
Set up the environment
The code below sets BAREUN_ROOT and runs /opt/bareun/bin/bareun in the background.
- %env BAREUN_ROOT="/opt/bareun": sets the environment variable BAREUN_ROOT to "/opt/bareun".
- !BAREUN_ROOT="/opt/bareun" nohup /opt/bareun/bin/bareun& : runs bareun in the background.
%env BAREUN_ROOT="/opt/bareun"
!BAREUN_ROOT="/opt/bareun" nohup /opt/bareun/bin/bareun&
env: BAREUN_ROOT="/opt/bareun"
nohup: appending output to 'nohup.out'
This shows that the Bareun server is running.
!ps -ef | grep bareun
root 1572 1 0 06:15 ? 00:00:00 /opt/bareun/bin/bareun
root 1573 532 0 06:15 ? 00:00:00 /bin/bash -c ps -ef | grep bareun
root 1575 1573 0 06:15 ? 00:00:00 grep bareun
Get an API key
Sign up on the Bareun website (https://bareun.ai/) to get an API key. After you request sign-up, verify your email and check the key under "Log in > My info".
- Copy the API key
- Enter the issued API key after the -reg argument to register it.
!BAREUN_ROOT="/opt/bareun" /opt/bareun/bin/bareun -reg YOUR-API-KEY
Use config file: /opt/bareun/config/bareun.json
------
200 OK
sucessfully registered YOUR-API-KEY
Using Bareun
Install the pip package
Install the bareunpy package with pip.
!pip install -U 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
Use the Bareun Python library
Use the Bareun API.
import sys
import bareunpy as brn
import google.protobuf.text_format as tf
# Enter the API KEY ("koba-...") you received after email verification at "https://bareun.ai/" below. Check it under "Log in > My info".
API_KEY = "YOUR-API-KEY" # <- replace with your own 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"
Check the information of the object returned by the 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
Convert the object returned by the morphological analysis to JSON format.
# get json object
jo = res.as_json()
print(jo)
{'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'}
You can also store the analysis result as tuples, or extract only the nouns or verbs.
# get tuple of pos tagging.
pa = res.pos()
print(pa)
# another methods
ma = res.morphs()
print(ma)
na = res.nouns()
print(na)
va = res.verbs()
print(va)
[('안녕하', 'VA'), ('시', 'EP'), ('어요', 'EF'), ('.', 'SF'), ('정말', 'MAG'), ('좋', 'VA'), ('은', 'ETM'), ('날씨', 'NNG'), ('이', 'VCP'), ('네', 'EF'), ('요', 'JX'), ('.', 'SF'), ('오늘', 'NNG'), ('도', 'JX'), ('힘내', 'VV'), ('어요', 'EF'), ('.', 'SF')]
['안녕하', '시', '어요', '.', '정말', '좋', '은', '날씨', '이', '네', '요', '.', '오늘', '도', '힘내', '어요', '.']
['날씨', '오늘']
['힘내']
Advanced example
This example walks through testing the analysis performance of the morphological analyzer Bareun against mecab.
To compare analysis performance, download and load the Korean ambiguity resolution evaluation dataset that Bareun built.
Install mecab
Below is the process of downloading mecab from GitHub with the curl command and installing it.
Then load the mecab library and test the morphological analysis feature.
!curl -s https://raw.githubusercontent.com/teddylee777/machine-learning/master/99-Misc/01-Colab/mecab-colab.sh | bash
from konlpy.tag import Mecab
mecab = Mecab()
mecab.pos("안녕하세요")
[('안녕', 'NNG'), ('하', 'XSV'), ('세요', 'EP+EF')]
Run the bareun evaluation
This function loads the evaluation data and preprocesses it.
def dataload(path):
"""
Loads a JSON file and preprocesses it into answers and sentences.
:param path: path of the evaluation data
:return: the evaluation dataset
"""
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
Install a library that can download Google links.
!pip install -U gdown
Download the shared Google link for the evaluation dataset.
!gdown https://drive.google.com/file/d/1TwJB5Bp12GJh54ip2cUFzfzOA7fluMN1/view?usp=share_link -O ambiguity_sentences.json --fuzzy
Print a part of the downloaded evaluation dataset.
testset = dataload("./ambiguity_sentences.json")
print(testset[:5])
[[[('쿠키', 'NNG'), ('와', 'JC')], '밀가루, 계란, 우유 반죽과 한참을 씨름한 끝에 마침내 오븐에서 결혼 전 발레리나였던 아내의 모습을 본 뜬 쿠키와 곧 태어날 아기에게 먹일 젖병 모양의 쿠키가 나왔다.'], [[('쿠키', 'NNG'), ('와', 'JKB')], '뭐 케이크 빵 쿠키와 같은 베이커립니다.'], [[('퀄리티', 'NNG'), ('가', 'JKS')], '고려은단은 고가의 영국산 원료를 사용함에도 불구하고 원료의 대량 구매 및 최신 자동화 설비를 통한 원가 절감으로 가격 대비 퀄리티가 높다는 평가를 받고 있다.'], [[('퀄리티', 'NNG'), ('가', 'JKC')], '이 정도는 쫌 어느 정도 퀄리티가 되는 글이 나와야 책으로 낼 수 있다.'], [('퀸', 'NNG'), '대상 및 특별상 수상자는 12월 여성가족부가 주최하는 ‘아이디어 퀸 공모전’ 본선에 참가하게 된다.']]
This function evaluates the Bareun model.
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):
# If the first token is correct, check the following tokens up to the length of the answer.
i = 0
if isinstance(answer, list): # the answer has two or more tokens (e.g. [(쿠키, 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: # if the answer has more tokens than the result, the analysis was wrong, so it counts as incorrect.
correct = False
break
else: # the answer is a single token (e.g. 밀가루, NNG)
if (token[0] == answer[0]) and (token[1] == answer[1]):
correct = True
acc += int(correct)
tot += 1
return acc / tot
Start the Bareun model evaluation.
bareun_probability = bareun_evaluate(testset)
print(f'Accuracy: {bareun_probability*100:.2f}%')
100%|██████████| 35396/35396 [08:38<00:00, 68.20it/s]
Accuracy: 83.00%
Run the mecab evaluation
This function evaluates the mecab model.
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):
# If the first token is correct, check the following tokens up to the length of the answer.
i = 0
if isinstance(answer, list): # the answer has two or more tokens (e.g. [(쿠키, 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: # if the answer has more tokens than the result, the analysis was wrong, so it counts as incorrect.
correct = False
break
else: # the answer is a single token (e.g. 밀가루, NNG)
if (token[0] == answer[0]) and (token[1] == answer[1]):
correct = True
acc += int(correct)
tot += 1
return acc / tot
mecab_probability = mecab_evaluate(testset)
print(f'Accuracy: {mecab_probability*100:.2f}%')
100%|██████████| 35396/35396 [00:05<00:00, 6824.23it/s]
Accuracy: 45.86%
Comparison
Check the analysis results with a few simple ambiguity resolution example sentences.
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)
| Surface form | Answer | bareun result | mecab result |
|---|---|---|---|
| 가는 | 가늘/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 |
Bareunresults
for result in bareun_result:
print(result)
[('조길상', '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 results
for result in mecab_result:
print(result)
[('조길상', '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')]