์ด๋ฆฐ์ด ๊ต์ก ์ ํฉ์ฑ ๊ฒฝ์ ยท๊ธ์ต ๊ธฐ์ฌ ๋ถ๋ฅ ๋ชจ๋ธ
maninglearchine/kobert-article-classifier๋ ํ๊ตญ์ด ๊ฒฝ์ ยท๊ธ์ต ๊ธฐ์ฌ๋ฅผ ๋ง 13์ธ ์ดํ ์ด๋ฆฐ์ด์ ํ์ต ๋ชฉ์ ์ ์ ํฉํ์ง ์๋์ผ๋ก ํ๋ณํ๋ ์ด์ง ๋ถ๋ฅ ๋ชจ๋ธ์
๋๋ค.
klue/bert-base๋ฅผ GPT-4o-mini๋ก ๋ผ๋ฒจ๋งํ ํ๊ตญ์ด ๊ฒฝ์ ยท๊ธ์ต ๋ฐ์ดํฐ 5,000๊ฑด์ผ๋ก ํ์ธํ๋ํ์ต๋๋ค.
๋ผ๋ฒจ ์ฒด๊ณ
| ๋ผ๋ฒจ | ID | ์ค๋ช | ์์ ํค์๋ |
|---|---|---|---|
์ ์ |
1 | ์ด๋ฆฐ์ด ํ์ต์ ์ ํฉํ ๊ธฐ์ฌ | ์ ์ถ, ์ฉ๋, ๋ฌผ๊ฐ, ์ธ๊ธ, ๋ฌด์ญ, ํ๋์กฐํฉ |
๋ถ์ ์ |
0 | ์ด๋ฆฐ์ด์๊ฒ ๋ถ์ ํฉํ ๊ธฐ์ฌ | ELS, ๋ ๋ฒ๋ฆฌ์ง, ๊ณต๋งค๋, DSR, ํ์์ํ, ๊ฐ์ ์ฒญ์ฐ |
์ ์ ๊ธฐ์ค
- ๊ธฐ์ด ๊ฒฝ์ ๊ฐ๋ (์ ์ถ, ๋ฌผ๊ฐ, ์์ยท๊ณต๊ธ, ์ธ๊ธ์ ์ญํ ๋ฑ)
- ๊ธฐ์ ์ฑ์ฅ ์คํ ๋ฆฌ, ์ฐฝ์ ์ด์ผ๊ธฐ
- ํ๊ฒฝ๊ฒฝ์ , ๊ณต์ ๋ฌด์ญ, ์ฌํ์ ๊ธฐ์
- ์ผ์ ์ ๊ฒฝ์ ์๋ฆฌ๋ฅผ ์ฝ๊ฒ ์ค๋ช ํ ์ฝํ ์ธ
๋ถ์ ์ ๊ธฐ์ค
- ํ์์ํ (ELS, DLS, CFD, ์ ๋ฌผยท์ต์ )
- ๋ ๋ฒ๋ฆฌ์งยท๊ณต๋งค๋ยท๋ง์ง์ฝ ๋ฑ ํฌ๊ธฐ์ฑ ๊ฑฐ๋
- ๋ณต์กํ ๊ธ์ต ๊ท์ (๋ฐ์ คโ ข, IFRS17, DSR ๋ฑ)
- ๊ธฐ์ ๊ตฌ์กฐ์กฐ์ ยท๋ถ๋ยท๋ฒ์ ๊ด๋ฆฌ
์ฌ์ฉ ๋ฐฉ๋ฒ
๋น ๋ฅธ ์์ (pipeline)
from transformers import pipeline
clf = pipeline(
"text-classification",
model="maninglearchine/kobert-article-classifier",
)
samples = [
"์ฉ๋์ผ๋ก ๋ฐฐ์ฐ๋ ์ ์ถ์ ์ฒซ๊ฑธ์โฆ์ด๋ฆฐ์ด ๊ฒฝ์ ๊ต์ค ํ์ฅ",
"ELS ๋
น์ธ ๊ตฌ๊ฐ ์ง์
โฆ๋ ๋ฒ๋ฆฌ์ง ํฌ์์ ๊ฐ์ ์ฒญ์ฐ ์์ถ",
]
for text in samples:
result = clf(text)
print(f"{result[0]['label']} ({result[0]['score']:.3f}) | {text[:30]}")
# ์ถ๋ ฅ ์์:
# ์ ์ (0.999) | ์ฉ๋์ผ๋ก ๋ฐฐ์ฐ๋ ์ ์ถ์ ์ฒซ๊ฑธ์โฆ์ด๋ฆฐ์ด
# ๋ถ์ ์ (0.998) | ELS ๋
น์ธ ๊ตฌ๊ฐ ์ง์
โฆ๋ ๋ฒ๋ฆฌ์ง ํฌ์์
์์ธ ์ ์ด (AutoModel)
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
model_id = "maninglearchine/kobert-article-classifier"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSequenceClassification.from_pretrained(model_id)
model.eval()
def classify(text: str, max_length: int = 64) -> dict:
inputs = tokenizer(
text,
return_tensors="pt",
truncation=True,
padding="max_length",
max_length=max_length,
)
with torch.no_grad():
logits = model(**inputs).logits
probs = torch.softmax(logits, dim=-1)[0]
label = model.config.id2label[logits.argmax(-1).item()]
return {
"label": label,
"score": probs.max().item(),
"๋ถ์ ์ _prob": probs[0].item(),
"์ ์ _prob": probs[1].item(),
}
texts = [
"์ธ๊ธ์ ์ ๋ด์ผ ํ ๊น?โฆํ๊ตยท๋๋กยท์๋ฐฉ์๊ฐ ๋ง๋ค์ด์ง๋ ๋น๋ฐ",
"๊ณต๋งค๋ ์๊ณ ๊ธ์ฆโฆํ๊น ์ข
๋ชฉ ๋ณ๋์ฑ ์ฌํ๋ก ๋ฐ๋๋งค๋งค ์ํ ๊ณ ์กฐ",
"์์์ ๊ณต๊ธ์ด๋ ๋ฌด์์ธ๊ฐ?โฆ์์ฅ ๊ฐ๊ฒฉ์ด ๊ฒฐ์ ๋๋ ์๋ฆฌ",
"๋ฐ์ คโ
ข ์๋ณธ๊ท์ ๊ฐํโฆ์ํ๊ถ ์์กฐ์ ์ถ๊ฐ ์ ๋ฆฝ ๋ถ๋ด",
]
for text in texts:
r = classify(text)
print(f"[{r['label']}] ํ๋ฅ ={r['score']:.3f} | {text[:35]}")
๋ฐฐ์น ์ฒ๋ฆฌ (Excel ํ์ผ)
from transformers import pipeline
import pandas as pd
clf = pipeline(
"text-classification",
model="maninglearchine/kobert-article-classifier",
batch_size=32,
device=-1, # CPU ์ฌ์ฉ. GPU: device=0
)
df = pd.read_excel("articles.xlsx")
results = clf(df["๊ธฐ์ฌ๋ณธ๋ฌธ"].tolist())
df["label"] = [r["label"] for r in results]
df["confidence"] = [r["score"] for r in results]
df.to_excel("classified_articles.xlsx", index=False)
ํ์ต ์ ๋ณด
๋ฐ์ดํฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ์๋ณธ ๋ฐ์ดํฐ | ํ๊ตญ์ด ๊ฒฝ์ ยท๊ธ์ต ๊ธฐ์ฌ ํฉ์ฑ ๋ฐ์ดํฐ 5,000๊ฑด |
| ๋ผ๋ฒจ๋ง ๋ฐฉ๋ฒ | GPT-4o-mini ์๋ ๋ผ๋ฒจ๋ง |
| ํด๋์ค ๋ถํฌ | ์ ์ (1): 2,500๊ฑด / ๋ถ์ ์ (0): 2,500๊ฑด (50:50 ๊ท ํ) |
| ํ์ต ์ํ | ๊ท ํ ์ํ๋ง 2,000๊ฑด (ํด๋์ค๋น 1,000๊ฑด) |
| ๋ฐ์ดํฐ ๋ถํ | Train 1,600 / Val 200 / Test 200 (8:1:1, stratified) |
ํ์ต ์ค์
Base Model : klue/bert-base
Max Length : 64 tokens
Batch Size : 32
Epochs : 3
LR : 3e-5
Warmup : 10% (warmup_ratio=0.1)
Weight Decay : 0.01
Optimizer : AdamW
Eval Strategy: epoch (best model by F1 Macro)
Device : CPU
ํ์ต ์๊ฐ : ์ฝ 26.6๋ถ (1,598์ด)
Epoch๋ณ ํ์ต ๋ก๊ทธ
| Epoch | Train Loss | Val Loss | Val Accuracy | Val F1 Macro |
|---|---|---|---|---|
| 1 | 0.1241 | 0.000409 | 1.0000 | 1.0000 |
| 2 | 0.0089 | 0.000233 | 1.0000 | 1.0000 |
| 3 | 0.0004 | 0.000206 | 1.0000 | 1.0000 |
์ฑ๋ฅ ํ๊ฐ
Test ์ ๊ฒฐ๊ณผ (200๊ฑด)
| ์งํ | ๊ฐ |
|---|---|
| Accuracy | 1.0000 (100%) |
| F1 Macro | 1.0000 |
| Precision (Macro) | 1.0000 |
| Recall (Macro) | 1.0000 |
| F1 (๋ถ์ ์ ) | 1.0000 |
| F1 (์ ์ ) | 1.0000 |
Confusion Matrix
์์ธก: ๋ถ์ ์ ์์ธก: ์ ์
์ค์ : ๋ถ์ ์ 100 0
์ค์ : ์ ์ 0 100
TF-IDF ๋ชจ๋ธ๊ณผ ๋น๊ต
| ๋ชจ๋ธ | F1 Macro | ํ์ต ์๊ฐ | ๋ฌธ๋งฅ ์ดํด | ์ถ๊ฐ ํ์ต |
|---|---|---|---|---|
| LR + Word TF-IDF | 1.0000 | 0.3์ด | X | ์ด๋ ค์ |
| LinearSVC + Word | 1.0000 | 0.2์ด | X | ์ด๋ ค์ |
| RandomForest | 1.0000 | 1.1์ด | X | ์ด๋ ค์ |
| KoBERT (๋ณธ ๋ชจ๋ธ) | 1.0000 | 1,598์ด | O | ํ์ธํ๋ ๊ฐ๋ฅ |
ํฉ์ฑ ๋ฐ์ดํฐ์ ์ดํ ๋ถ๋ฆฌ๊ฐ ๋ช ํํด ๋ชจ๋ ๋ชจ๋ธ์ด 100%๋ฅผ ๋ฌ์ฑํ์ผ๋, ์ค์ ๋ด์ค ๊ธฐ์ฌ(๋ณตํฉ ์ฃผ์ , ๋ฌธ๋งฅ ์์กด ํํ)์์๋ KoBERT๊ฐ ํจ์ฌ ์ ๋ฆฌํฉ๋๋ค.
ํ๊ณ์ ๋ฐ ์ฃผ์์ฌํญ
- ํฉ์ฑ ๋ฐ์ดํฐ ํ์ต: ์ค์ ๋ด์ค ๊ธฐ์ฌ๊ฐ ์๋ ํ ํ๋ฆฟ ๊ธฐ๋ฐ ํฉ์ฑ ๋ฐ์ดํฐ๋ก ํ์ต๋์ต๋๋ค. ์ค์๋น์ค ์ ์ฉ ์ ์ค์ ๊ธฐ์ฌ ๋ฐ์ดํฐ๋ก ์ถ๊ฐ ํ์ธํ๋์ ๊ถ์ฅํฉ๋๋ค.
- ์ต๋ ๊ธธ์ด 64 ํ ํฐ: ์งง์ ํ ์คํธ์ ์ต์ ํ๋์ด ์์ต๋๋ค. ๊ธด ๊ธฐ์ฌ๋ ์ ๋ชฉ + ์ฒซ ๋จ๋ฝ๋ง ์ ๋ ฅํ์ธ์.
- ์ด์ง ๋ถ๋ฅ๋ง ์ง์: ์ ์ /๋ถ์ ์ ๋ ํด๋์ค๋ง ์ง์ํ๋ฉฐ, ์ฐ๋ น๋ณ ์ธ๋ถํ ๋ถ๋ฅ๋ ์ง์ํ์ง ์์ต๋๋ค.
์ถ๊ฐ ํ์ธํ๋
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from transformers import Trainer, TrainingArguments
model_id = "maninglearchine/kobert-article-classifier"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSequenceClassification.from_pretrained(model_id)
training_args = TrainingArguments(
output_dir="./finetuned",
num_train_epochs=2,
per_device_train_batch_size=16,
learning_rate=1e-5, # ๋ฎ์ LR์ผ๋ก ์ ์ง์ ํ์ธํ๋
eval_strategy="epoch",
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=your_train_dataset,
eval_dataset=your_eval_dataset,
)
trainer.train()
model.push_to_hub("maninglearchine/kobert-article-classifier-v2")
๋ผ์ด์ ์ค
MIT License โ ์์ ๋กญ๊ฒ ์ฌ์ฉ, ์์ , ๋ฐฐํฌ ๊ฐ๋ฅํฉ๋๋ค.
- Downloads last month
- 132
Model tree for maninglearchine/kobert-article-classifier
Base model
klue/bert-base