label_template = """์๋์ ๋ผ๋ฒจ๋ง ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋ผ ๋จ๊ณ์ ์ผ๋ก ์ฃผ์ด์ง ํ
์คํธ์ ๋ํ ํ์คํํ์ ๋ถ๋ฅํ์ธ์.
1. ํ์ค ํํ์ ์ ์: ํน์ ์ฌํ์ (์์์) ์ง๋จ์ ๋ํ ์ ๋์ ๋ฐ์ธ, ์กฐ๋กฑ, ํฌํํ, ํธ๊ฒฌ์ ์ฌ์์ฐํ๋ ํํ์ผ๋ก,
๋์์ ๋ํ ๊ณ ์ ๊ด๋
,๋์์ ํน์ฑ์ด๋ ์ฑํฅ์ ํน์ ํ ํต๋
์ ๊ณ ์ฐฉ์ํค๋ ๋ฐ์ธ์ ํฌํจ. ๋จ, ํ์ ์ค์ค๋ก๋ฅผ ์์กฐ์ ์ผ๋ก ํํํ๋ ๊ฒฝ์ฐ๋ ํ์ค ๋ฐ์ธ์ด ์๋
2. ๋ผ๋ฒจ๋ง ๋จ๊ณ:
- Step 1: ์ฃผ์ด์ง text๋ฅผ ํ์คํํ, ์
ํ/์์ค, clean ์ค ํ๋๋ก ๋ถ๋ฅ
- Clean: ํ์คํํ, ์์ค, ๋ถ์พ๊ฐ, ์๋์ฑ ๋ด์ฉ์ ํฌํจํ๊ณ ์์ง ์์ ์ผ๋ฐ ๋ฌธ์ฅ
- ์
ํ/์์ค: ์ด๋ค ์ง๋จ์ ํฅํ ํ์ค ํํ์ธ์ง ์ง์นญํ ์๋ ์์ง๋ง, ํ์ธ ํน์ ์ธ๋ชจ์ ๋ํ ๋นํ/์์ค์ด ํฌํจ๋์ด ์๊ฑฐ๋, ๋ถ์พ๊ฐ์ ์ฃผ๊ฑฐ๋, ์
ํ๊ณผ ์๋์ฑ ๋ฌธ์ฅ
- ํ์คํํ: Step2๋ก ์ด๋
- Step 2: ํ์คํํ์ผ ๊ฒฝ์ฐ ํ์ค ์นดํ
๊ณ ๋ฆฌ ์ค์์ ํด๋น๋๋ ์นดํ
๊ณ ๋ฆฌ๋ฅผ multi-label๋ก ๋ถ๋ฅ
- ์ฌ์ฑ/๊ฐ์กฑ: ์ฌ์ฑ์ฑ ๋ฐ ์ฌ์ฑ์ ์ฑ์ญํ ์ ๋ํ ํต๋
์ ๊ณ ์ฐฉ์ํค๋ ๋ฐ์ธ, ์ฌ์ฑ ์ฐจ๋ณ์ ํฌํํํ๋ ๋ฐ์ธ, ํ๋ฏธ๋์ฆยท์ฌ์ฑ๊ฐ์กฑ๋ถ ์ ๋ฐ์ ๋ํ ์
ํ, ๊ฐํธ์ฌ, ์ฌ๊ฒฝ ๋ฑ ์ฌ์ฑ์ ์ค์ฌ์ผ๋ก ๊ตฌ์ฑ๋ ์ง๋จ, ๋นํผ์ฃผ์์, ๋ฏธํผ๋ชจ, ๋์ฑ ๋ถ๋ถ ๋ฑ ์ ํต์ ์ด์ง ์์ ํ์์ ๊ฐ์กฑ์ ๋ํ ํ์ค ๋ฐ์ธ
- ๋จ์ฑ: ์ง๋จ์ผ๋ก์์ ๋จ์ฑ ์ผ๋ฐ์ ๋นํ, ์กฐ๋กฑ, ํฌํํํ๋ ๋ฐ์ธ
- ์ฑ์์์: ์ฑ์์์(๋ ์ฆ๋น์ธ, ๊ฒ์ด, ๋ฐ์ด์น์์ผ, ํธ๋์ค์ ๋ ๋ฑ)๋ฅผ ๋ฐฐ์ฒํ๋ ๋ฐ์ธ์ด๋ ์ด์ฑ์ ์ด์ธ์ ์น์์ผ๋ฆฌํฐ๋ฅผ ๋ถ์ ์ ์ผ๋ก ๋ฌ์ฌํ๊ฑฐ๋ ์ฑ์์์๋ฅผ ํฌํํํ๋ ํํ
- ์ธ์ข
/๊ตญ์ : ํน์ ์ธ์ข
๊ณผ ๊ตญ์ ์ ๋ํ ์์ค, ๊ณ ์ ๊ด๋
, ์กฐ๋กฑ. ์ข
๊ตยท์ธ์ข
ยท๊ตญ๊ฐ์ ๋ํด ์๋ฌต์ ์ผ๋ก ํจ๊ป ์ง์นญํ๋ ์์ฌ์ ๋ฐ์ธ
- ์ฐ๋ น:ํน์ ์ธ๋๋ ์ฐ๋ น์ ๋นํํ๋ ์์ด์ ์ฌ์ฉ ๋ฐ ํ์ค ํํ
- ์ง์ญ: ํน์ ์ง์ญ์ ๋ํ ์์ด ๋ฐ ํ์ค ํํ์ ๋ถ๋ฅ
- ์ข
๊ต: ํน์ ์ข
๊ต์ ๋ํ ํ์ค ๋ฐ ์ข
๊ต์ธ ์ง๋จ์ ๋ํ ๋น๋
- ๊ธฐํํ์ค: ์์์ ์ ์ํ ์นดํ
๊ณ ๋ฆฌ ์ด์ธ์ ์ง๋จ์ ๋์์ผ๋ก ํ๋ ํ์ค ํํ
"""
fewshot_template = """
{label_template}
For example:
text: "๊ผญ ํค ์์ ๊ธ์์ถฉ์ด ์ด๋ฐ ๊ธ ์"
label: "์ฐ๋ น"
Input:
text: "{text}"
{format_instructions}
"""
label_template
: ์ง์๋ฌธ + ๋ผ๋ฒจ๋ง ๊ฐ์ด๋๋ผ์ธ ์กฐํฉ์ ๊ธtext
: ๋ผ๋ฒจ๋งํ ํ๊ฒ ํ
์คํธformat_instructions
: ๋ชจ๋ธ์ ์์ํ์ด ๋ค์ด๊ฐ ๊ณณ์ผ๋ก, ๋ญ์ฒด์ธ์ StructuredOutputParser
๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ๊ฒฐ๊ณผ์ ๋ํ ํ์ฒ๋ฆฌ๊ฐ ์ฝ๋๋ก JSON ํํ๋ก ๋ง๋ค์ด์ฃผ๋ ํ๋กฌํํธ๋ฅผ ์๋์ผ๋ก ์ฃผ์
ํด์ค๋ค. ์๋์ฒ๋ผ ์ฌ์ฉํ๋ฉด๋๋คlabel_schema = ResponseSchema(
name="label",
description=""
)
response_schemas = [label_schema]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
format_instructions = output_parser.get_format_instructions()
โ๏ธํฌ๋งทํ
ํ ์ต์ข
ํ๋กฌํํธ ์์
์๋์ ๋ผ๋ฒจ๋ง ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋ผ ๋จ๊ณ์ ์ผ๋ก ์ฃผ์ด์ง ํ ์คํธ์ ๋ํ ํ์คํํ์ ๋ถ๋ฅํ์ธ์.
For example:
text: "๊ผญ ํค ์์ ๊ธ์์ถฉ์ด ์ด๋ฐ ๊ธ ์"
label: "์ฐ๋ น"
Input:
text: "๋จ์๋ผ๋ฆฌ ์จ๊ฐ์ด๋ฌธ์งํ๋ ๋ ์ฆ๋น์ธ๋๋ค ์ง์ง ๊ดด๋กญ์ง.."
The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "json" and "
":
{
"label": string //
}
chat = ChatOpenAI(temperature=0.0)
def autolabel_with_fewshot(input_text):
messages = prompt_template.format_messages(
label_template=label_template,
text = input_text, # input text
format_instructions = format_instructions
)
response = chat(messages)
return output_parser.parse(response.content)
exp1_result = []
for input_text in tqdm(test_df['๋ฌธ์ฅ'].values):
exp1_result.append(autolabel_with_fewshot(input_text))
precision recall f1-score support
์ฌ์ฑ/๊ฐ์กฑ 0.85 0.70 0.76 394
๋จ์ฑ 0.87 0.83 0.85 334
์ฑ์์์ 0.90 0.78 0.83 280
์ธ์ข
/๊ตญ์ 0.87 0.79 0.82 426
์ฐ๋ น 0.92 0.75 0.83 146
์ง์ญ 0.87 0.88 0.88 260
์ข
๊ต 0.87 0.86 0.87 290
๊ธฐํํ์ค 0.92 0.18 0.30 134
์
ํ/์์ค 0.76 0.59 0.67 786
clean 0.74 0.79 0.77 935
micro avg 0.82 0.73 0.77 3985
macro avg 0.86 0.72 0.76 3985
weighted avg 0.82 0.73 0.77 3985
samples avg 0.76 0.74 0.75 3985
๋ฐฉ๊ธ๊น์ง ์ฌ์ฉํ๋ ํ๋กฌํํธ๋ ํ๋กฌํํธ์ ์์ ๋ฅผ ๋ฃ์ด์ฃผ๊ธด ํ์ง๋ง ๋ผ๋ฒจ๋งํด์ผํ๋ ๋ฐ์ดํฐ์ ๊ด๊ณ์์ด ํญ์ ๋์ผํ ์์ ์๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๋! ์ ๋ ฅ๊ฐ์ ๋ฐ๋ผ ์์ ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ด๋จ๊น?
์ด๋ฐ ๊ธฐ๋ฅ์ ์ํํ๋ ๊ฒ์ด Example Selector๋ผ๋ ๋ญ์ฒด์ธ์ ๊ธฐ๋ฅ์ด๋ค
Example Selector๋ฅผ ์ํด์๋ ํ ์คํธ๋ฅผ ์๋ฒ ๋ฉ์ผ๋ก ๋ณํ, ์ฌ๋ฌ๊ฐ์ ์๋ฒ ๋ฉ ์ค์์ ์ ์ฌํ ์๋ฒ ๋ฉ์ ์ฐพ์๋ด๋ ๊ธฐ๋ฅ, ๊ทธ๋ ๊ฒ ์ฐพ์๋ธ ์๋ฒ ๋ฉ์ ๋์ํ๋ ์์ ๋ฅผ ํ๋กฌํํธ์ ์ฃผ์ ํ๋ ๊ธฐ๋ฅ์ ํ๋ํ๋ ๊ตฌํํด์ผํ๋๋ฐ ๊ทธ๋ด ํ์๊ฐ ์๋ ์์ฃผ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ด๋ค
๊ธฐ์กด์ ํ๋กฌํํธ๋ฅผ ๋ณ๊ฒฝํด๋ณด์!
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(
model_name = 'smilegate-ai/kor_unsmile'# 'sentence-transformers/all-mpnet-base-v2'
)
example_selector
๋ก ๊ต์ฒดํ๋ค# input formater
fewshot_template = """
{label_template}
{example_selector}
{format_instructions}
"""
prompt_template = ChatPromptTemplate.from_template(fewshot_template)
from langchain.prompts.example_selector import MaxMarginalRelevanceExampleSelector
from langchain.vectorstores import FAISS # ๋น ๋ฅด๊ฒ ์ ์ฌํ ์๋ฒ ๋ฉ์ ์ฐพ์์ฃผ๋ ์๊ณ ๋ฆฌ์ฆ
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
example_prompt = PromptTemplate(
input_variables=["text", "label"],
template='text: "{text}"\nlabel: "{label}"',
)
examples = [{'text': text, 'label': label} for text, label in zip(train_df['๋ฌธ์ฅ'].values, train_df['label'].values)]
MaxMarginalRelevanceExampleSelector
๋ผ๋ ๋ฐฉ์์ผ๋ก ์ด๋ป๊ฒ ์ ์ฌํ ์์ ๋ฅผ ์ฐพ์ ๊ฑด์ง ์ ์ํ ๊ฑฐ๋ค. ์ ์ฌํ ์์ ๋ฅผ ์ฐพ๋ ๋ฐฉ์์ ๊ฐ์ฅ ๋น์ทํ๊ฑฐ ์ฐพ๋๊ฒ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผํ
๋ฐ ์ด๋ฌ๋ฉด ์์ ์ ๋ค์์ฑ์ด ๊ฐ์๋ ์ ์๋ค, ๊ทธ๋์ ์ด๋์ ๋ ์ ์ฌํ N๊ฐ์ ์์ ๋ฅผ ์ฐพ์ ๋ค์์ ๊ทธ์ค์์ ๋๋คํ๊ฒ ์์ ๋ฅผ ์ ํํ๋ ๋ฐฉ์์ด๋คexample_selector = MaxMarginalRelevanceExampleSelector.from_examples(
examples,
embeddings,
FAISS,
k=2, # ๋ช๊ฐ์ ์์ ๋ฅผ ๋ฃ์๊ฑด์ง ์ ํด์ค๋ค
)
mmr_prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
prefix='For example:',
suffix='Input:\ntext:"{text}"',
input_variables=["text"],
)
def autolabel_with_embed(input_text):
messages = prompt_template.format_messages(
label_template=label_template,
example_selector=mmr_prompt.format(text=input_text),
format_instructions = format_instructions
)
response = chat(messages)
return output_parser.parse(response.content) # {'label': 'Academic'}
exp2_result = []
for input_text in tqdm(test_df['๋ฌธ์ฅ'].values[len(exp2_result):]):
exp2_result.append(autolabel_with_embed(input_text))