이탈리아어용 NLP: 구체적인 과제 및 솔루션
이탈리아어는 형태학적 관점에서 볼 때 가장 복잡한 로망스어 중 하나입니다. 문법적 성별, 어형 변화, 형용사-명사 일치, 불규칙 동사 형태 유연한 구문 구조로 NLP 전처리 및 모델링이 가능합니다. 영어보다 훨씬 더 어렵습니다. 그러나 대다수는 NLP 및 영어 튜토리얼 중 가장 잘 알려진 모델은 종종 영어에 최적화되어 있습니다.
이 기사는 그 격차를 메워줍니다. 우리는 이탈리아어의 구체적인 과제를 탐구할 것입니다. 사용 가능한 데이터 세트인 이탈리아 BERT 모델(느껴봐, 알베르토, dbmdz BERT), 이탈리아어에 대한 특정 전처리, 이탈리아어에 대한 감정 분석 시스템을 단계별로 구축하는 방법을 알아보세요.
이것은 시리즈의 네 번째 부분입니다 최신 NLP: BERT에서 LLM까지. 그리고 거기 이탈리아어로 된 유일한 시리즈 특히 전처리를 다룹니다. 이탈리아어에 대한 NLP 모델링.
무엇을 배울 것인가
- 이탈리아어의 형태학적 문제: 성별, 어형변화, 불규칙 동사
- 특정 전처리: 이탈리아어 불용어, spaCy를 사용한 표제어 추출, 정규화
- 이탈리아 BERT 모델: Feel-it-italian-sentiment, AlBERTo, dbmdz BERT, GilBERTo
- 이탈리아어용 데이터세트: SENTIPOLC, TweetSent-IT, ItalianSentiment
- 사용자 정의 데이터에 대한 느낌 미세 조정
- 구어체, 이탈리아어 방언, 신조어 관리
- 이탈리아어 텍스트에 대한 감정 분석을 위한 완벽한 파이프라인
- 이탈리아어와 다국어 BERT 모델 비교
1. NLP에서 이탈리아어의 구체적인 과제
이탈리아어는 NLP를 더욱 복잡하게 만드는 언어적 특성을 가지고 있습니다. 영어에 비해. 이러한 과제를 이해하는 것은 구축의 기본입니다. 효과적인 시스템.
1.1 풍부한 형태
영어와 달리 이탈리아어에는 매우 풍부한 형태: 동일한 동사 어근은 수십 가지 형태를 생성하며 형용사는 일반적으로 동의합니다. 명사와 숫자. 이로 인해 데이터에 희소성 문제가 발생합니다.
예: 이탈리아어의 동사 "Andare"
- 가, 가, 가, 가, 가, 가 (현재)
- 내가 갔어요, 당신이 갔어요, 당신은 갔어요, 당신은 갔어요, 당신은 갔어요 (불완전함)
- 안드로, 안드라이, 안드라, 우리는 갈 것이다, 당신은 갈 것이다, 그들은 갈 것이다(미래)
- 내가 갔다, 당신이 갔다, 내가 갔다, 우리가 갔다, 당신이 갔다, 그들이 갔다 (먼 과거)
- has gone, have gone (과거 가정법)
영어에서 "to go"는 형태가 거의 없습니다. NLP 모델의 경우 각 모양은 처음에는 다른 토큰입니다.
1.2 Enclitics 및 복합어
이탈리아어에서는 대명사가 동사(enclitics)에 붙을 수 있습니다. 표준 토크나이저가 제대로 처리할 수 없는 복잡한 토큰을 생성합니다.
# Problemi comuni con i tokenizzatori per l'italiano
# Enclitici: pronomi attaccati al verbo
examples = [
"Dimmelo", # dimmi + lo
"Portarmelo", # portare + mi + lo
"Fallo", # fai + lo
"Dateglielo", # date + glie + lo
]
# Truncation sbagliata con tokenizzatori non italiani
from transformers import BertTokenizer
tokenizer_en = BertTokenizer.from_pretrained('bert-base-uncased')
tokenizer_it = BertTokenizer.from_pretrained('dbmdz/bert-base-italian-cased')
word = "Dimmelo"
print(f"EN tokenizer: {tokenizer_en.tokenize(word)}")
# ['dim', '##mel', '##o'] - non coglie la struttura
print(f"IT tokenizer: {tokenizer_it.tokenize(word)}")
# ['Dim', '##me', '##lo'] - migliore ma non perfetto
# La soluzione ottimale e la lemmatizzazione prima del tokenize
1.3 구두점 및 구어체 철자법
이탈리아어 온라인 텍스트(소셜 미디어, 리뷰)에서 다음을 찾을 수 있습니다.
- 아포스트로피로 대체된 악센트: "can" 대신 "can"
- 반복되는 문자: "아름답다!!!"
- 일반적인 약어: "cmq"(그러나), "nn"(아님), "xke"(왜냐하면)
- 영어로 코드 전환: "제품은 정말 최고 품질입니다."
- 지역 방언: "mizzica"(시칠리아), "mannaggia"(남부)
2. 이탈리아어 전용 전처리
2.1 이탈리아어 spaCy
스파시 이탈리아어(it_core_news_sm/md/lg)
표제어 분석, POS 태깅 및 종속성 구문 분석을 사용합니다.
# Installa il modello italiano: python -m spacy download it_core_news_lg
import spacy
nlp = spacy.load("it_core_news_lg")
def preprocess_italian(text: str,
remove_stopwords: bool = True,
lemmatize: bool = True) -> str:
"""Preprocessing completo per testi italiani."""
doc = nlp(text)
tokens = []
for token in doc:
# Salta punteggiatura, spazi, numeri (se non rilevanti)
if token.is_punct or token.is_space:
continue
# Normalizza a minuscolo
word = token.text.lower()
# Rimuovi stopwords italiane
if remove_stopwords and token.is_stop:
continue
# Lemmatizza
if lemmatize:
word = token.lemma_.lower()
tokens.append(word)
return ' '.join(tokens)
# Test
texts = [
"I prodotti sono stati consegnati rapidamente e tutto funzionava perfettamente",
"Ho comprato questo telefono tre mesi fa e sono rimasto deluso dalla batteria",
"PRODOTTO FANTASTICO! Lo consiglio assolutamente a tutti voi amici!!!"
]
for text in texts:
processed = preprocess_italian(text)
print(f"Original: {text}")
print(f"Processed: {processed}")
print()
2.2 비공식 텍스트의 정규화
import re
import unicodedata
def normalize_italian_text(text: str) -> str:
"""
Normalizzazione per testi italiani informali (social media, recensioni).
"""
# 1. Normalizza unicode (accenti)
text = unicodedata.normalize('NFC', text)
# 2. Sostituisci accenti con apostrofo (comune online)
accent_map = {
"a'": "a", # può' -> può
"e'": "e'", # mantenuto per 'e' (voce del verbo essere)
"i'": "i",
"o'": "o",
"u'": "u"
}
# Non sostituiamo indiscriminatamente per evitare ambiguità
# 3. Espandi abbreviazioni comuni
abbreviations = {
r'\bcmq\b': 'comunque',
r'\bnn\b': 'non',
r'\bxke\b': 'perchè',
r'\bxche\b': 'perchè',
r'\bx\b': 'per',
r'\bke\b': 'che',
r'\bkm\b': 'come',
r'\bqs\b': 'questo',
r'\btv\b': 'televisione',
r'\bgg\b': 'giorni',
r'\bprof\b': 'professore',
}
for abbr, expanded in abbreviations.items():
text = re.sub(abbr, expanded, text, flags=re.IGNORECASE)
# 4. Rimuovi caratteri ripetuti eccessivi (bellissimoooo -> bellissimo)
text = re.sub(r'(.)\1{2,}', r'\1\1', text) # max 2 ripetizioni
# 5. Rimuovi emoji (opzionale - può essere informativo per il sentiment)
# text = re.sub(r'[^\w\s.,!?;:\'\"()-]', ' ', text)
# 6. Normalizza spazi multipli
text = re.sub(r'\s+', ' ', text).strip()
return text
# Test
informal_texts = [
"cmq il prodotto e' fantasticooo!!!",
"nn mi e piaciuto x niente, sto cercando di restituirlo xke nn funziona",
"Amici... COMPRATE QUESTOOO!!! e' il TOP del TOP!!!",
]
for text in informal_texts:
normalized = normalize_italian_text(text)
print(f"Originale: {text}")
print(f"Normalizzato: {normalized}")
print()
3. 이탈리아어를 위한 BERT 모델
이탈리아어 말뭉치에 대해 사전 훈련된 여러 BERT 모델을 사용할 수 있습니다. 모델 선택은 특정 도메인과 작업에 따라 다릅니다.
3.1 이탈리아 감성을 느껴보세요
느껴봐 감정 분석을 위한 특정 데이터 세트 및 모델 이탈리아어로 감정 감지. 이는 트위터를 기반으로 하며 다음과 같은 교육을 받았습니다. 느낌(긍정적/부정적)과 감정(기쁨, 슬픔, 분노, 두려움, 혐오, 놀라움).
from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
import torch
# feel-it per sentiment (positivo/negativo)
sentiment_model = pipeline(
"text-classification",
model="MilaNLProc/feel-it-italian-sentiment",
tokenizer="MilaNLProc/feel-it-italian-sentiment"
)
# feel-it per emozioni (gioia, tristezza, rabbia, paura, disgusto, sorpresa)
emotion_model = pipeline(
"text-classification",
model="MilaNLProc/feel-it-italian-emotion",
tokenizer="MilaNLProc/feel-it-italian-emotion"
)
# Test su testi italiani
texts = [
"Sono molto felice del mio acquisto, qualità eccellente!",
"Ho perso tutto il mio lavoro, sono devastato.",
"Questa e la situazione più ridicola che abbia mai visto.",
"Non credevo che potesse funzionare cosi bene, sono stupito!",
]
print("=== SENTIMENT ===")
for text in texts:
result = sentiment_model(text)[0]
print(f" [{result['label']}: {result['score']:.3f}] {text[:60]}")
print("\n=== EMOTION ===")
for text in texts:
result = emotion_model(text)[0]
print(f" [{result['label']}: {result['score']:.3f}] {text[:60]}")
3.2 AlBERTo: 이탈리아 소셜 미디어용 BERT
알베르토 이탈리아 트윗 모음에 대해 사전 훈련을 받았습니다. (2억 개 이상의 트윗) 특히 비공식적인 텍스트에 효과적입니다. 소셜 미디어와 이탈리아어 구어체.
from transformers import AutoTokenizer, AutoModel
import torch
# AlBERTo - BERT uncased per Twitter italiano
alberto_name = "m-polignano-uniba/bert_uncased_L-12_H-768_A-12_Italian_alb3rt0"
tokenizer = AutoTokenizer.from_pretrained(alberto_name)
model = AutoModel.from_pretrained(alberto_name)
# Test di tokenizzazione su testo colloquiale
informal_texts = [
"PRODOTTO TOP! ma la spedizione ha fatto schifo cmq",
"mizzica quanto e bello sto telefono!! ci ho messo 2gg ma ne valeva la pena",
"ok mi avete rotto... non lo compro più #delusione",
]
for text in informal_texts:
tokens = tokenizer.tokenize(text)
print(f"Testo: {text[:50]}")
print(f"Tokens ({len(tokens)}): {tokens[:10]}...")
print()
# Estrazione embeddings
def get_sentence_embedding(text, model, tokenizer, pooling='cls'):
inputs = tokenizer(text, return_tensors='pt',
truncation=True, max_length=128, padding=True)
with torch.no_grad():
outputs = model(**inputs)
if pooling == 'cls':
return outputs.last_hidden_state[:, 0, :] # [CLS] token
elif pooling == 'mean':
mask = inputs['attention_mask'].unsqueeze(-1)
return (outputs.last_hidden_state * mask).sum(1) / mask.sum(1)
emb = get_sentence_embedding(informal_texts[0], model, tokenizer)
print(f"Embedding shape: {emb.shape}") # (1, 768)
3.3 dbmdz BERT 영어
모델 dbmdz/bert-base-italian-cased 그리고 사전 훈련을 받은 이탈리아어 Wikipedia 및 OPUS 코퍼스에 있습니다. 그리고 최고의 출발점은 공식 텍스트(뉴스, 법률 문서, 학술 텍스트).
from transformers import BertTokenizer, BertForSequenceClassification
from transformers import TrainingArguments, Trainer
from datasets import Dataset
import torch
# Modello base per l'italiano
MODEL = "dbmdz/bert-base-italian-cased"
tokenizer = BertTokenizer.from_pretrained(MODEL)
# Crea un classificatore di sentiment per l'italiano
model = BertForSequenceClassification.from_pretrained(
MODEL,
num_labels=2,
id2label={0: "NEGATIVO", 1: "POSITIVO"},
label2id={"NEGATIVO": 0, "POSITIVO": 1}
)
# Dataset di esempio in italiano
train_data = {
"text": [
"Il prodotto e arrivato in perfette condizioni, molto soddisfatto",
"qualità pessima, si e rotto dopo due giorni",
"Eccellente rapporto qualità/prezzo, lo consiglio",
"Imballaggio scarso, prodotto danneggiato alla consegna",
"Supera le aspettative, ottimo acquisto",
"Servizio clienti inesistente, rimborso impossibile",
"Materiali di qualità, costruzione solida",
"Non corrisponde alla descrizione, immagine ingannevole",
],
"label": [1, 0, 1, 0, 1, 0, 1, 0]
}
def tokenize_fn(examples):
return tokenizer(examples["text"], truncation=True,
padding="max_length", max_length=128)
dataset = Dataset.from_dict(train_data)
tokenized = dataset.map(tokenize_fn, batched=True)
# Training veloce (pochi dati = pochissime epoche)
args = TrainingArguments(
output_dir="./models/bert-italian-sentiment",
num_train_epochs=5,
per_device_train_batch_size=8,
learning_rate=3e-5,
warmup_ratio=0.1,
weight_decay=0.01,
save_steps=100,
logging_steps=10,
report_to="none"
)
trainer = Trainer(
model=model,
args=args,
train_dataset=tokenized,
)
trainer.train()
3.4 이탈리아 모델 비교
어떤 모델을 사용할 것인가?
| 모델 | 최적의 도메인 | 더 나은 작업 | 크기 |
|---|---|---|---|
| 느낌-감정 | 소셜 미디어, 의견 | 감정, 감정 감지 | ~440MB |
| 느낌-감정 | 소셜 미디어, 의견 | 6가지 기본 감정 | ~440MB |
| 알베르토 | 트위터, 채팅, SMS | 감정, NER, 분류 | ~420MB |
| dbmdz BERT 케이스 | 뉴스, 공식 문서 | NER, 분류, QA | ~420MB |
| 길베르토 | 이탈리아어 일반 텍스트 | 일반 NLU 작업 | ~440MB |
| 엠버트 | 다국어 | 다국어 전이 학습 | ~670MB |
4. 감정 분석을 위한 이탈리아 데이터세트
from datasets import load_dataset
# SENTIPOLC 2016 - dataset italiano per polarity detection su Twitter
# Disponibile su: http://www.di.unito.it/~tutreeb/sentipolc-evalita16/
# Etichette: OBJ (oggettivo), POS (positivo), NEG (negativo), MIX
# Dataset disponibile su HuggingFace
try:
dataset = load_dataset("gsarti/itacola")
print("ITA-CoLA dataset:", dataset)
except Exception:
print("Dataset non disponibile direttamente, usa URL manuale")
# Costruzione dataset personalizzato da CSV
import pandas as pd
from datasets import Dataset
# Esempio: caricare recensioni italiane da CSV
# Formato atteso: colonne 'text' e 'label'
def load_italian_dataset(csv_path):
df = pd.read_csv(csv_path)
# Validazione
assert 'text' in df.columns, "Manca colonna 'text'"
assert 'label' in df.columns, "Manca colonna 'label'"
# Rimuovi righe con testo vuoto
df = df.dropna(subset=['text', 'label'])
df = df[df['text'].str.strip() != '']
# Normalizza etichette
label_map = {
'positivo': 1, 'pos': 1, '1': 1, 1: 1,
'negativo': 0, 'neg': 0, '0': 0, 0: 0
}
df['label'] = df['label'].map(label_map)
df = df.dropna(subset=['label'])
df['label'] = df['label'].astype(int)
return Dataset.from_pandas(df[['text', 'label']])
5. 이탈리아어를 위한 완벽한 파이프라인
우리는 이탈리아어로 감정 분석을 위해 모든 것을 생산 가능한 파이프라인에 통합합니다.
import re
import spacy
from transformers import pipeline as hf_pipeline
from typing import Optional
import unicodedata
class ItalianSentimentPipeline:
"""
Pipeline completa per il sentiment analysis in italiano.
Combina preprocessing specifico e feel-it per il sentiment.
"""
def __init__(self,
sentiment_model: str = "MilaNLProc/feel-it-italian-sentiment",
emotion_model: Optional[str] = "MilaNLProc/feel-it-italian-emotion",
use_spacy: bool = True,
confidence_threshold: float = 0.6):
# Carica modelli sentiment ed emotion
self.sentiment = hf_pipeline(
"text-classification",
model=sentiment_model,
truncation=True,
max_length=128
)
self.emotion = hf_pipeline(
"text-classification",
model=emotion_model,
truncation=True,
max_length=128
) if emotion_model else None
# spaCy per preprocessing avanzato
if use_spacy:
try:
self.nlp = spacy.load("it_core_news_sm")
except OSError:
print("Modello spaCy 'it_core_news_sm' non trovato.")
print("Installa con: python -m spacy download it_core_news_sm")
self.nlp = None
else:
self.nlp = None
self.threshold = confidence_threshold
def preprocess(self, text: str) -> str:
"""Preprocessing specifico per italiano."""
if not text or not text.strip():
return ""
# Normalizza unicode
text = unicodedata.normalize('NFC', text)
# Abbreviazioni comuni italiane
abbr_map = {
r'\bcmq\b': 'comunque',
r'\bnn\b': 'non',
r'\bxke\b': 'perchè',
r'\bx\b': 'per',
}
for pattern, replacement in abbr_map.items():
text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)
# Riduzione caratteri ripetuti
text = re.sub(r'(.)\1{2,}', r'\1\1', text)
# Normalizza spazi
text = re.sub(r'\s+', ' ', text).strip()
return text
def analyze(self, text: str) -> dict:
"""Analisi completa: sentiment + emozione + preprocessing."""
if not text or not text.strip():
return {"error": "Testo vuoto"}
preprocessed = self.preprocess(text)
# Sentiment
sent_result = self.sentiment(preprocessed)[0]
sentiment_label = sent_result['label']
sentiment_score = sent_result['score']
result = {
"text_originale": text,
"text_preprocessato": preprocessed,
"sentiment": sentiment_label,
"sentiment_score": round(sentiment_score, 4),
"confident": sentiment_score >= self.threshold
}
# Emozione (se disponibile)
if self.emotion:
em_result = self.emotion(preprocessed)[0]
result["emotion"] = em_result['label']
result["emotion_score"] = round(em_result['score'], 4)
return result
def analyze_batch(self, texts: list) -> list:
return [self.analyze(t) for t in texts]
# Utilizzo
pipeline = ItalianSentimentPipeline()
test_texts = [
"Il prodotto e arrivato in perfette condizioni, sono molto soddisfatto dell'acquisto!",
"Pessima esperienza. Il pacco era danneggiato e il servizio clienti non risponde.",
"Mah, diciamo che si poteva fare meglio. Non e ne buono ne cattivo.",
"INCREDIBILE! Non avrei mai pensato che fosse cosi bello!!! Sto piangendo di gioia",
"Nn ci credo... mi ha di nuovo fregato sto negozio di schifo",
]
for text in test_texts:
result = pipeline.analyze(text)
print(f"Testo: {text[:60]}...")
print(f"Sentiment: {result['sentiment']} ({result['sentiment_score']:.3f})")
if 'emotion' in result:
print(f"Emozione: {result['emotion']} ({result['emotion_score']:.3f})")
print(f"Affidabile: {result['confident']}")
print()
6. 특정 도메인에 대한 미세 조정
Feel-it은 트위터에서 훈련을 받았습니다. 제품 리뷰와 같은 특정 도메인의 경우 의학적 의견이나 법률 문서, 추가적인 미세 조정이 필요한 경우가 많습니다.
from transformers import (
AutoTokenizer, AutoModelForSequenceClassification,
TrainingArguments, Trainer
)
from datasets import Dataset
import evaluate
import numpy as np
# Strategia 1: Fine-tuning di feel-it su dati dominio
def finetune_for_domain(
base_model: str,
train_texts: list,
train_labels: list,
val_texts: list,
val_labels: list,
output_dir: str,
num_epochs: int = 3
):
tokenizer = AutoTokenizer.from_pretrained(base_model)
model = AutoModelForSequenceClassification.from_pretrained(
base_model,
num_labels=2,
ignore_mismatched_sizes=True # per modelli già fine-tuned
)
def tokenize(examples):
return tokenizer(examples["text"], truncation=True,
padding="max_length", max_length=128)
train_ds = Dataset.from_dict({"text": train_texts, "label": train_labels})
val_ds = Dataset.from_dict({"text": val_texts, "label": val_labels})
train_tok = train_ds.map(tokenize, batched=True)
val_tok = val_ds.map(tokenize, batched=True)
accuracy = evaluate.load("accuracy")
def compute_metrics(eval_pred):
logits, labels = eval_pred
preds = np.argmax(logits, axis=-1)
return accuracy.compute(predictions=preds, references=labels)
args = TrainingArguments(
output_dir=output_dir,
num_train_epochs=num_epochs,
per_device_train_batch_size=16,
per_device_eval_batch_size=32,
learning_rate=2e-5,
warmup_ratio=0.1,
weight_decay=0.01,
evaluation_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
metric_for_best_model="accuracy",
report_to="none"
)
trainer = Trainer(
model=model,
args=args,
train_dataset=train_tok,
eval_dataset=val_tok,
compute_metrics=compute_metrics
)
trainer.train()
trainer.save_model(output_dir)
tokenizer.save_pretrained(output_dir)
return trainer
# Strategia 2: Confronto modelli italiani
def compare_italian_models(texts, true_labels):
"""Confronto automatico di diversi modelli BERT italiani."""
models = {
"feel-it": "MilaNLProc/feel-it-italian-sentiment",
"AlBERTo-fine": "m-polignano-uniba/bert_uncased_L-12_H-768_A-12_Italian_alb3rt0",
"mBERT": "bert-base-multilingual-cased"
}
results = {}
for name, model_id in models.items():
try:
clf = hf_pipeline("text-classification", model=model_id,
truncation=True, max_length=128)
preds = clf(texts)
# ... calcola metriche
print(f"{name}: modello caricato correttamente")
except Exception as e:
print(f"{name}: errore - {e}")
return results
7. 지역 방언 및 변종 관리
이탈리아는 강한 방언 전통을 가지고 있습니다. 소셜 미디어 게시물, 리뷰 비공식 메시지에는 표준 이탈리아어와 방언이 혼합되어 있는 경우가 많습니다. 특히 남부 (나폴리, 시칠리아, 바리, 칼라브리아).
방언 텍스트 전략
- 빛 정규화: 가장 일반적인 방언 형식을 변환합니다. 표준 이탈리아어(예: 나폴리에서는 "maje" → "mai")
- 알베르토 사용: 트위터 교육에는 다양한 방언 형식이 포함되어 있습니다. 이탈리아 소셜미디어의 특성상
- 다국어 BERT: 때로는 방언을 언어로 더 잘 처리합니다. 이탈리아 표준을 기대하는 이탈리아 모델과 비교하면 "알 수 없음"
- 도메인별 데이터 수집: 데이터세트에 다음이 포함된 경우 많은 변증법, 미세 조정을 위한 주석이 달린 예 수집
8. 이탈리아어에 대한 벤치마크 및 지표
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np
def benchmark_italian_sentiment(model_pipeline, test_data):
"""
Benchmark completo per modelli di sentiment italiano.
test_data: lista di tuple (testo, label)
"""
texts = [d[0] for d in test_data]
true_labels = [d[1] for d in test_data]
predictions = model_pipeline(texts)
pred_labels = []
for pred in predictions:
label = pred['label'].upper()
if label in ['POSITIVE', 'POSITIVO', 'POS']:
pred_labels.append(1)
else:
pred_labels.append(0)
print("=== REPORT CLASSIFICAZIONE ===")
print(classification_report(
true_labels, pred_labels,
target_names=['NEGATIVO', 'POSITIVO'],
digits=4
))
# Analisi per categoria di testo
categories = {
'formale': [i for i, t in enumerate(texts) if len(t.split()) > 20],
'informale': [i for i, t in enumerate(texts) if len(t.split()) <= 20],
}
for cat_name, indices in categories.items():
if indices:
cat_true = [true_labels[i] for i in indices]
cat_pred = [pred_labels[i] for i in indices]
report = classification_report(cat_true, cat_pred, output_dict=True)
acc = report['accuracy']
print(f"\nCategoria '{cat_name}' ({len(indices)} esempi): accuracy={acc:.4f}")
return pred_labels
9. 개인화 데이터에 대한 느낌의 미세 조정
느낌-훌륭한 출발점이지만 최고의 성능을 얻습니다. 항상 특정 도메인에 모델을 적용합니다. 다음은 전체 작업 흐름입니다. 이탈리아 사용자 정의 데이터를 미세 조정합니다.
from transformers import (
AutoTokenizer, AutoModelForSequenceClassification,
TrainingArguments, Trainer
)
from datasets import Dataset
import numpy as np
import evaluate
# 1. Dataset personalizzato (es. recensioni e-commerce italiane)
custom_data = {
"text": [
"Prodotto eccellente, consegna rapidissima. Super consigliato!",
"qualità pessima, si e rotto dopo una settimana. Deluso.",
"Ok, nella media. Ne potevo fare a meno.",
"Fantastico! Esattamente come descritto, sono molto soddisfatto.",
"Spedizione veloce ma il prodotto non corrisponde alla descrizione.",
"Materiale scadente, non vale il prezzo. Non ricompro.",
"Ottimo rapporto qualità/prezzo, lo consiglio a tutti.",
"Funziona perfettamente, esattamente quello che cercavo.",
],
"label": [1, 0, 0, 1, 0, 0, 1, 1] # 0=negativo, 1=positivo
}
# 2. Carica tokenizer feel-it
model_name = "MilaNLProc/feel-it-italian-sentiment"
tokenizer = AutoTokenizer.from_pretrained(model_name)
def tokenize(examples):
return tokenizer(
examples["text"],
padding="max_length",
truncation=True,
max_length=128
)
dataset = Dataset.from_dict(custom_data)
dataset = dataset.train_test_split(test_size=0.2, seed=42)
tokenized = dataset.map(tokenize, batched=True)
# 3. Carica modello con nuova classification head
model = AutoModelForSequenceClassification.from_pretrained(
model_name,
num_labels=2,
ignore_mismatched_sizes=True, # la head originale ha etichette diverse
id2label={0: "NEGATIVO", 1: "POSITIVO"},
label2id={"NEGATIVO": 0, "POSITIVO": 1}
)
# 4. Metriche di valutazione
accuracy_metric = evaluate.load("accuracy")
f1_metric = evaluate.load("f1")
def compute_metrics(eval_pred):
logits, labels = eval_pred
preds = np.argmax(logits, axis=-1)
return {
"accuracy": accuracy_metric.compute(predictions=preds, references=labels)["accuracy"],
"f1": f1_metric.compute(predictions=preds, references=labels)["f1"]
}
# 5. Training arguments calibrati per dataset piccoli
training_args = TrainingArguments(
output_dir="./feel-it-finetuned",
num_train_epochs=5, # più epoche per dataset piccoli
per_device_train_batch_size=8,
per_device_eval_batch_size=16,
learning_rate=2e-5,
warmup_ratio=0.2, # warmup più lungo per stabilità
weight_decay=0.01,
evaluation_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
metric_for_best_model="f1",
fp16=False, # disabilita per GPU piccole o CPU
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized["train"],
eval_dataset=tokenized["test"],
compute_metrics=compute_metrics,
)
trainer.train()
results = trainer.evaluate()
print(f"Accuracy: {results['eval_accuracy']:.4f}")
print(f"F1: {results['eval_f1']:.4f}")
# 6. Salva e publica su HuggingFace Hub (opzionale)
trainer.save_model("./feel-it-custom-ecommerce")
tokenizer.save_pretrained("./feel-it-custom-ecommerce")
10. 선택 표: 선택할 이탈리아 모델
이탈리아 모델 선택 가이드
| 사용 사례 | 추천 모델 | 동기 부여 | 대안 |
|---|---|---|---|
| 바이너리 감정(pos/neg) | 느껴봐 | 이탈리아 정서를 위해 명시적으로 훈련됨 | UmBERTo 미세 조정 |
| 감정 감지(6개 클래스) | 느껴봐 | 6가지 감성을 지닌 독특한 이탈리아 모델 | XLM-RoBERTa 멀티라벨 |
| 소셜 미디어/트위터 | 알베르토 | 1억 9600만 개의 이탈리아어 트윗에 대한 교육을 받았습니다. | 정규화로 느껴보세요 |
| 공식 텍스트(뉴스, 문서) | dbmdz/bert-base-italian-xxl-cased | 학술 자료 및 이탈리아어 뉴스 | 움베르토 |
| 이탈리아 NER | dbmdz/bert-base-italian-xxl-cased + NER 헤드 | 더욱 풍부한 이탈리아어 어휘 | spaCy it_core_news_lg |
| 다국어 업무(IT+EN+...) | xlm-로버타-대형 | XNLI의 Top-1, 100개 언어 지원 | mDeBERTa-v3-베이스 |
| 낮은 대기 시간 생산 | DistilBERT 다국어 양자화 | 60% 더 빨라지고 97% 품질 유지 | Feel-it + ONNX 내보내기 |
결론 및 다음 단계
이탈리아어를 위한 NLP에는 특별한 주의가 필요합니다: 풍부한 형태, 언어 구어체, 변증법, 주석이 달린 자원의 부족으로 인해 이 영역이 만들어졌습니다. 도전적이지만 매우 흥미롭습니다. 다음과 같은 모델 느껴봐 e 알베르토 최근 몇 년 동안 상황이 크게 개선되었습니다.
핵심 사항
- 미국 느껴봐 이탈리아어로 감정과 감정의 출발점으로
- 소셜 미디어 및 비공식 텍스트의 경우 알베르토 그리고 종종 우월하다
- 공식적인 텍스트(뉴스, 문서)의 경우 다음을 사용하세요. dbmdz BERT 케이스
- 특정 전처리(약어 정규화, 표제어 추출)로 결과가 향상됩니다.
- 최상의 결과를 얻으려면 항상 특정 도메인 데이터를 미세 조정하세요.
- 지속적인 피드백 수집: 이탈리아어는 빠르게 발전합니다(신조어, 영국식)
시리즈는 계속됩니다
- 다음: 명명된 엔터티 인식 — spaCy 및 BERT를 사용하여 텍스트에서 엔터티 추출
- 제6조: 다중 레이블 텍스트 분류 — 텍스트에 여러 카테고리가 있는 경우
- 제7조: HuggingFace Transformers: 전체 가이드 — API 트레이너 및 모델 허브
- 제8조: LoRA 미세 조정 — 소비자 GPU에서 대규모 모델 훈련
- 관련 시리즈: AI 엔지니어링/RAG — 의미 검색을 위한 이탈리아어 임베딩







