์์ฆ ํ์ฌ๋ ๊ธฐ๊ด์์ ๋ด๋ถ ๋งค๋ด์ผ, ๊ท์ ์ง, ๋ฌธ์ ๋ฑ์์
๋ด๊ฐ ๊ถ๊ธํ ๋ด์ฉ์ ์์ฐ์ด๋ก ๋ฌผ์ด๋ณด๋ฉด AI๊ฐ ๋ฑ ๋ง๋ ๋ต์ ์ฐพ์์ฃผ๋
์ค๋งํธ ๊ฒ์ ์์คํ
์ด ์ ์ ๋ ์ค์ํด์ง๊ณ ์์ฃ .
๊ธฐ์กด ํค์๋ ๊ฒ์์ ๋จ์ด๋ ํํ์ด ์กฐ๊ธ๋ง ๋ฌ๋ผ๋ ์ํ๋ ์ ๋ณด๋ฅผ ๋ชป ์ฐพ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์.
๊ทธ๋์ ์ ๋ ์๋ฏธ๋ก ๊ฒ์ํ๋ AI,
๋จ์ด๊ฐ ๋ฌ๋ผ๋ ๋ฌธ์ฅ์ ๋ป์ด ๋น์ทํ๋ฉด ๊ด๋ จ ๋ด์ฉ์ ์ฐพ์์ฃผ๋ ์์คํ
์ ๋์ ํด๋ณด๊ณ ์ถ์์ด์.
SQuAD ๋ฐ์ดํฐ์ ์ด๋?
SQuAD(Stanford Question Answering Dataset)๋
์ํคํผ๋์ ๋ฌธ์์์ ๋ฌธ๋จ(context), ์ง๋ฌธ(question), ์ ๋ต(answer)์ด ํ ์ธํธ๋ก ๋ฌถ์ฌ ์๋ ๋ํ ์์ด ์ง์์๋ต ๋ฐ์ดํฐ์
์
๋๋ค.
{
"data": [
{
"title": "๋ฌธ์ ์ ๋ชฉ",
"paragraphs": [
{
"context": "๋ฌธ๋จ(์ง๋ฌธ) ํ
์คํธ",
"qas": [
{
"id": "์ง๋ฌธ id",
"question": "์ง๋ฌธ ๋ด์ฉ",
"answers": [
{
"text": "์ ๋ต(๋ฌธ๋จ ๋ด ์ผ๋ถ)",
"answer_start": 123
}
]
}
]
}
]
}
]
}
์ด๋ฐ ํํ๋ก ๋์ด์์ด์.
context๋ ์ง๋ฌธ๊ณผ ์ ๋ต์ด ๋์ค๋ ์ง๋ฌธ์
๋๋ค.
qas๋ ์ด ๋ฌธ๋จ์ ๋ฐํ์ผ๋ก ๋ง๋ ์ฌ๋ฌ ์ง๋ฌธ/์ ๋ต ์ ๋ฆฌ์คํธ์์.
answers์๋ ์ค์ ์ ๋ต ๋ฌธ์์ด๊ณผ, ๊ทธ ์ ๋ต์ด context์์ ๋ช ๋ฒ์งธ ๊ธ์์์ ์์ํ๋์ง ์๋ ค์ฃผ๋ answer_start๊ฐ ๋ค์ด๊ฐ๋๋ค.
Q. context์ paragraph, qas์ ์ฐจ์ด์ ์?
paragraph: ๋ฌธ๋จ ์ ์ฒด ์ ๋ณด(๋ฌธ๋จ ํ
์คํธ + ์ง๋ฌธ/์ ๋ต ์ ๋ฆฌ์คํธ)๋ฅผ ๋ด์ ๋ฐ์ดํฐ ๊ตฌ์กฐ(๋์
๋๋ฆฌ)
context: paragraph ์์ ๋ค์ด์๋ ์ค์ ๋ฌธ๋จ(์ง๋ฌธ) ํ
์คํธ
qas: context๋ฅผ ๋ฐํ์ผ๋ก ๋ง๋ ์ฌ๋ฌ ์ง๋ฌธ/์ ๋ต ์์ ๋ฆฌ์คํธ
paragraph๋ “๋ฌธ๋จ์ ์ ๋ณด ๋ฉ์ด๋ฆฌ”,
context๋ “์ค์ ๋ฌธ๋จ ํ
์คํธ”,
qas๋ “์ด ๋ฌธ๋จ์์ ํ ์ ์๋ ์ง๋ฌธ/์ ๋ต ๋ฆฌ์คํธ”์
๋๋ค.
Q. ์ง๋ฌธ๊ณผ ์ ๋ต์ context์์ ์ฐพ์ ์ ์๋๋ฐ ์ qas๊ฐ ํ์ํด?
context๋ง ์์ผ๋ฉด “๋ฌด์จ ์ง๋ฌธ์ ํ ์ ์๋์ง” ์ ์ ์์ต๋๋ค.
qas๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ด๋ค ์ง๋ฌธ์ ํ ์ ์๊ณ ๊ทธ ์ง๋ฌธ์ ๋ํ ์ ๋ต์ด context์ ์ด๋์ ์๋์ง๋ฅผ ๋ช
ํํ๊ฒ ์ ์ ์์ต๋๋ค.
AI ๋ชจ๋ธ์ ํ์ต์ํค๊ฑฐ๋ ํ๊ฐํ ๋,
์ด ๋ฌธ๋จ์ ๋ณด๊ณ ์ด๋ฐ ์ง๋ฌธ์ ํ๋ฉด, ์ด ๋ถ๋ถ์ด ์ ๋ต์ด๋ค”๋ผ๋ ์ ๋ณด๋ฅผ ์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก qas์ ์ญํ ์
๋๋ค.
Q. ๊ทธ๋ผ AI๊ฐ ์ ํ์ํ๊ฑฐ์ผ. ๊ทธ๋ฅ ์ฝ๋ฉ ์๋๊ฐ?
(1) ๋ฌธ์ฅ/์ง๋ฌธ์ ์๋ฒ ๋ฉ์ผ๋ก ๋ณํ
์ฝ๋์์ ๋ชจ๋ ๋ฌธ์ฅ(๋๋ ๋ฌธ์ฅ+๋ฌธ๋งฅ ์), ์ง๋ฌธ์ Universal Sentence Encoder๋ก ์๋ฒ ๋ฉ(์ซ์ ๋ฒกํฐํ)ํด์.
์๋ฅผ ๋ค์ด, “์ฌ๊ณผ๋ ๋นจ๊ฐ๋ค.” → 0.13, -0.27, … “๋ฐ๋๋๋ ๋ฌด์จ ์์ด์ผ?” → 0.12, -0.25, …
์ด ์ซ์ ๋ฒกํฐ๋ ๋ฌธ์ฅ๋ผ๋ฆฌ ์๋ฏธ๊ฐ ๋น์ทํ๋ฉด ๊ฐ๋ ๋น์ทํ๊ฒ ๋์์.
(2) ์๋ฏธ๋ก ๊ฒ์
์ฌ์ฉ์๊ฐ ์ง๋ฌธ์ ์
๋ ฅํ๋ฉด, ๊ทธ ์ง๋ฌธ๋ ์๋ฒ ๋ฉ์ผ๋ก ๋ณํํด์.
๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ์
์ ๋ชจ๋ ๋ฌธ์ฅ ์๋ฒ ๋ฉ๊ณผ ๋น๊ตํด์, ๊ฐ์ฅ ๋น์ทํ(=์๋ฏธ์ ์ผ๋ก ๊ฐ๊น์ด) ๋ฌธ์ฅ์ ์ฐพ์์ค๋๋ค.
์๋ฅผ ๋ค์ด, ์ง๋ฌธ: “๋
ธ๋ ๊ณผ์ผ์ ๋ญ์ผ?” ๋ฐ์ดํฐ์ “๋ฐ๋๋๋ ๋
ธ๋์์ด๋ค.“๋ผ๋ ๋ฌธ์ฅ์ด ์์ผ๋ฉด
๋จ์ด๊ฐ ์์ ํ ๊ฐ์ง ์์๋, ์๋ฏธ๊ฐ ๋น์ทํ๋๊น AI๊ฐ ์ด ๋ฌธ์ฅ์ ์ฐพ์์ค ์ ์์ต๋๋ค.
์ ์ด๊ฒ AI?
๋จ์ํ ์ฝ๋ฉ(์: if๋ฌธ, for๋ฌธ, ๋จ์ด ์ผ์น ๊ฒ์)์ด ์๋๋ผ ๋ฅ๋ฌ๋ ๋ชจ๋ธ์ด ๋ฌธ์ฅ์ ์๋ฏธ๋ฅผ ์ซ์๋ก ํํํ๊ณ ,
๊ทธ ์ซ์(๋ฒกํฐ)๋ผ๋ฆฌ์ ์ ์ฌ๋๋ฅผ ๊ณ์ฐํด์ “์๋ฏธ๊ฐ ๋น์ทํ ๋ฌธ์ฅ”์ ์ฐพ์์ฃผ๋ ๊ฒ ๋ฐ๋ก AI์ ์ญํ ์ด์์.
์ด ๊ณผ์ ์ ์ฌ๋์ด ์ง์ ๊ท์น์ ์ผ์ผ์ด ์ง๋ ๊ฒ ์๋๋ผ, ๋๊ท๋ชจ ๋ฐ์ดํฐ์ ์ ๊ฒฝ๋ง ํ์ต์ ํตํด
“๋น์ทํ ์๋ฏธ๋ ๋น์ทํ ๋ฒกํฐ”๊ฐ ๋๋๋ก AI๊ฐ ์ค์ค๋ก ๋ฐฐ์ด ๊ฒฐ๊ณผ์
๋๋ค.
def extract_sentences_from_squad_json(squad):
all_sentences = []
for data in squad['data']:
for paragraph in data['paragraphs']:
sentences = nltk.tokenize.sent_tokenize(paragraph['context'])
all_sentences.extend(zip(sentences, [paragraph['context']] * len(sentences)))
return list(set(all_sentences))
๊ฐ ๋ฌธ๋จ(context)์ ๋ฌธ์ฅ ๋จ์๋ก ์ชผ๊ฐ๊ณ , ๊ฐ ๋ฌธ์ฅ๊ณผ ๊ทธ ๋ฌธ์ฅ์ด ์ํ ๋ฌธ๋จ(context)์ ํ ์์ผ๋ก ๋ฌถ์ด์ ๋ฆฌ์คํธ๋ก ๋ง๋ญ๋๋ค.
์์ ๋ฌธ๋จ(context):
“Python is easy to learn. It is used worldwide.”
→ (“Python is easy to learn.”, “Python is easy to learn. It is used worldwide.”)
(“It is used worldwide.”, “Python is easy to learn. It is used worldwide.”)
์ด๋ ๊ฒ (๋ฌธ์ฅ, ๋ฌธ๋จ) ์์ด ๋ง๋ค์ด์ง๋๋ค.
Universal Sentence Encoder Multilingual Q&A ๋ชจ๋ธ์ด๋?
์ด ํ๋ก์ ํธ์ ํต์ฌ์ Universal Sentence Encoder Multilingual Q&A๋ผ๋ ๊ตฌ๊ธ์ ๋ฅ๋ฌ๋ ๋ชจ๋ธ์ ํ์ฉํ๋ ๊ฒ์
๋๋ค.
์ด ๋ชจ๋ธ์ ๋ฌธ์ฅ, ์ง๋ฌธ, ๋ต๋ณ ๋ฑ ์์ฐ์ด ํ
์คํธ๋ฅผ “์ซ์ ๋ฒกํฐ(์๋ฒ ๋ฉ)“๋ก ๋ณํํด์ค๋๋ค.
์ด ์๋ฒ ๋ฉ์ ๋จ์ํ ๋จ์ด๊ฐ ๊ฐ์ ๋๋ง ๋น์ทํ ๊ฒ ์๋๋ผ,
์๋ฏธ๊ฐ ๋น์ทํ๋ฉด ๊ฐ๋ ๋น์ทํ๊ฒ ๋ง๋ค์ด์ง๋๋ค.
์ฆ, “ํ๋์ค์ ์๋๋ ์ด๋์ธ๊ฐ?” , “ํ๋์ค์ ์๋๋ฅผ ์๋ ค์ค.”
์ด๋ฐ ์ง๋ฌธ๋ค์ ๋จ์ด๊ฐ ๋ฌ๋ผ๋ ์๋ฒ ๋ฉ์ด ๊ฑฐ์ ๋น์ทํ๊ฒ ๋์์
# @title
%%capture
# Install the latest Tensorflow version.
!pip install -q tensorflow_text
!pip install -q simpleneighbors[annoy]
!pip install -q nltk
!pip install -q tqdm
import json
import nltk
import os
import pprint
import random
import simpleneighbors
import urllib
from IPython.display import HTML, display
from tqdm.notebook import tqdm
import tensorflow.compat.v2 as tf
import tensorflow_hub as hub
from tensorflow_text import SentencepieceTokenizer
nltk.download('punkt')
nltk.download('punkt_tab')
def download_squad(url):
return json.load(urllib.request.urlopen(url))
def extract_sentences_from_squad_json(squad):
all_sentences = []
for data in squad['data']:
for paragraph in data['paragraphs']:
sentences = nltk.tokenize.sent_tokenize(paragraph['context'])
all_sentences.extend(zip(sentences, [paragraph['context']] * len(sentences)))
return list(set(all_sentences)) # remove duplicates
def extract_questions_from_squad_json(squad):
questions = []
for data in squad['data']:
for paragraph in data['paragraphs']:
for qas in paragraph['qas']:
if qas['answers']:
questions.append((qas['question'], qas['answers'][0]['text']))
return list(set(questions))
def output_with_highlight(text, highlight):
output = "<li> "
i = text.find(highlight)
while True:
if i == -1:
output += text
break
output += text[0:i]
output += '<b>'+text[i:i+len(highlight)]+'</b>'
text = text[i+len(highlight):]
i = text.find(highlight)
return output + "</li>\n"
def display_nearest_neighbors(query_text, answer_text=None):
query_embedding = model.signatures['question_encoder'](tf.constant([query_text]))['outputs'][0]
search_results = index.nearest(query_embedding, n=num_results)
if answer_text:
result_md = '''
<p>Random Question from SQuAD:</p>
<p> <b>%s</b></p>
<p>Answer:</p>
<p> <b>%s</b></p>
''' % (query_text , answer_text)
else:
result_md = '''
<p>Question:</p>
<p> <b>%s</b></p>
''' % query_text
result_md += '''
<p>Retrieved sentences :
<ol>
'''
if answer_text:
for s in search_results:
result_md += output_with_highlight(s, answer_text)
else:
for s in search_results:
result_md += '<li>' + s + '</li>\n'
result_md += "</ol>"
display(HTML(result_md))
squad_url = 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json'
squad_json = download_squad(squad_url)
sentences = extract_sentences_from_squad_json(squad_json)
questions = extract_questions_from_squad_json(squad_json)
print("%s sentences, %s questions extracted from SQuAD %s" % (len(sentences), len(questions), squad_url))
print("\nExample sentence and context:\n")
sentence = random.choice(sentences)
print("sentence:\n")
pprint.pprint(sentence[0])
print("\ncontext:\n")
pprint.pprint(sentence[1])
print()
print("sentences ๊ธธ์ด:", len(sentences))
print("questions ๊ธธ์ด:", len(questions))
module_url = "https://tfhub.dev/google/universal-sentence-encoder-multilingual-qa/3"
model = hub.load(module_url)
batch_size = 100
encodings = model.signatures['response_encoder'](
input=tf.constant([sentences[0][0]]),
context=tf.constant([sentences[0][1]]))
index = simpleneighbors.SimpleNeighbors(
len(encodings['outputs'][0]), metric='angular')
print('Computing embeddings for %s sentences' % len(sentences))
slices = zip(*(iter(sentences),) * batch_size)
num_batches = int(len(sentences) / batch_size)
for s in tqdm(slices, total=num_batches):
response_batch = list([r for r, c in s])
context_batch = list([c for r, c in s])
encodings = model.signatures['response_encoder'](
input=tf.constant(response_batch),
context=tf.constant(context_batch)
)
for batch_index, batch in enumerate(response_batch):
index.add_one(batch, encodings['outputs'][batch_index])
index.build()
print('simpleneighbors index for %s sentences built.' % len(sentences))
num_results = 25
query = random.choice(questions)
display_nearest_neighbors(query[0], query[1])
SQuAD ๋ฐ์ดํฐ์ ์ ๋ถ๋ฌ์์ Universal Sentence Encoder Multilingual Q&A ๋ชจ๋ธ์ ์ ์ฉ ์ํจ ๊ตฌ์กฐ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋๋ค์ผ๋ก ์ง๋ฌธ์ ํ๋ ๋ถ๋ฌ์ ๋ต๋ณ์ ์ถ๋ ฅํด๋ณด์์ต๋๋ค.
์ ์ฌ์ง๊ณผ ๊ฐ์ด ์ง๋ฌธ๊ณผ ๋ต๋ณ์ด ์ ์์ ์ผ๋ก ๋์ค๋ ๊ฑธ ๋ณผ ์ ์์์ต๋๋ค.
์ด๊ฒ ์ฑ๋ด, ์ค๋งํธ ๊ฒ์, FAQ ์๋์๋ต ๋ฑ์ ์ฐ์ด๋ ๊ธฐ์ ์ ๋๋ค.
SQuAD ๋ฐ์ดํฐ์ ๊ตฌ์กฐ์ ์๋ฏธ๋ฅผ ์ง์ ํ์ ํ๋ฉด์ “์ง๋ฌธ/์ ๋ต/๋ฌธ๋จ”์ด ์ด๋ป๊ฒ ์ฐ๊ฒฐ๋๋์ง ์ดํดํ ์ ์์๋ ์ข์ ๊ธฐํ์์ต๋๋ค.
์ฌ๋ฌ๋ถ๋ SQuAD ๋ฐ์ดํฐ์ ๊ณผ Universal Sentence Encoder๋ง ์์ผ๋ฉด “๋ด๊ฐ ๊ฐ์ง ๋ฌธ์์์ ์๋ฏธ๋ก ๋ต์ ์ฐพ์์ฃผ๋ AI ๊ฒ์๊ธฐ”๋ฅผ ์ง์ ๋ง๋ค์ด๋ณผ ์ ์์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค.
'AI' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Colab ReviewRadar (0) | 2025.06.03 |
---|