Untitled

mail@pastecode.io avatar
unknown
plain_text
8 months ago
7.0 kB
1
Indexable
Never
from cleantext import clean
import re


def clean_text(text):
    text = clean(
        text,
        fix_unicode=True,  # Исправление юникода
        to_ascii=False,  # Отключаем транслитерацию в ASCII
        lower=True,  # Приведение к нижнему регистру
        no_line_breaks=True,  # Удаление переносов строк
        no_urls=True,  # Удаление URL, замена на ''
        no_emails=True,  # Удаление email, замена на ''
        no_phone_numbers=True,  # Удаление телефонных номеров, замена на ''
        no_numbers=False,  # Оставляем числа (если они важны)
        no_digits=True,  # Оставляем цифры (если они важны)
        no_currency_symbols=True,  # Удаление символов валют (при необходимости), замена на ''
        no_punct=True,  # Удаление пунктуации
        no_emoji=True,  # Удаление всех эмодзи
        replace_with_url="",  # Не заменяем URL на шаблонное слово
        replace_with_email="",  # Не заменяем email на шаблонное слово
        replace_with_phone_number="",  # Не заменяем телефонные номера на шаблонное слово
        replace_with_digit="",
        lang="ru",  # Язык текста - русский
    )

    text = re.sub(r'►|---', '', text)
    return text


data['описание_канала'] = data['описание_канала'].apply(clean_text)
data['Названия_видео_роликов'] = data['Названия_видео_роликов'].apply(clean_text)
data['метка_класса'] = data['метка_класса'].apply(lambda x: x.split(', ') if isinstance(x, str) else [])
all_classes = set([cls for sublist in data['метка_класса'] for cls in sublist])
unique_classes = list(all_classes)

class_to_index = {classname: index for index, classname in enumerate(unique_classes)}
data['метка_класса_id'] = data['метка_класса'].apply(
    lambda classes: [
        class_to_index[cls]
        for cls in classes
        if cls in class_to_index
    ]
)
data['combined_text'] = data['название_канала'] + ' ' + data['описание_канала'] + ' ' + data['Названия_видео_роликов']
nan_rows = data[data['название_канала'].isna() | data['описание_канала'].isna() | data['Названия_видео_роликов'].isna()]
data_cleaned = data.dropna(subset=['название_канала', 'описание_канала', 'Названия_видео_роликов'])

print(f"Размер оригинального датасета: {data.shape}")
print(f"Размер очищенного датасета: {data_cleaned.shape}")

data = data_cleaned




_______________________________________________________________________________________
ТОКЕНИЗАЦИЯ
_______________________________________________________________________________________
from transformers import BertTokenizer
from sklearn.preprocessing import MultiLabelBinarizer
from torch.utils.data import Dataset, DataLoader, random_split

class CustomDataset(Dataset):
    def __init__(self, texts, labels, tokenizer, max_length=512):
        self.tokenizer = tokenizer
        self.texts = texts
        self.labels = labels
        self.max_length = max_length

    def __len__(self):
        return len(self.texts)

    def __getitem__(self, idx):
        text = self.texts[idx]
        labels = self.labels[idx]
        encoding = self.tokenizer.encode_plus(
            text,
            add_special_tokens=True,
            max_length=self.max_length,
            padding="max_length",
            truncation=True,
            return_attention_mask=True,
            return_tensors='pt',
        )
        return {
            'input_ids': encoding['input_ids'].flatten(),
            'attention_mask': encoding['attention_mask'].flatten(),
            'labels': torch.tensor(labels, dtype=torch.float)
        }

tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased')
mlb = MultiLabelBinarizer()
labels_one_hot = mlb.fit_transform(data['метка_класса_id'].values)

dataset = CustomDataset(data['combined_text'].values, labels_one_hot, tokenizer)

train_size = int(0.9 * len(dataset))
val_size = len(dataset) - train_size
train_dataset, val_dataset = random_split(dataset, [train_size, val_size])

train_dataloader = DataLoader(train_dataset, shuffle=True)
val_dataloader = DataLoader(val_dataset)


________________________________________________________________________________________
ОБУЧЕНИЕ
_______________________________________________________________________________________
from transformers import Trainer, TrainingArguments, BertForSequenceClassification
from transformers import BertTokenizerFast
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
import torch

tokenizer = BertTokenizerFast.from_pretrained('bert-base-multilingual-cased')

def compute_metrics(eval_pred):
    logits, labels = eval_pred
    # Преобразование логитов в вероятности с помощью сигмоиды
    probabilities = torch.sigmoid(torch.tensor(logits)).numpy()
    # Преобразование вероятностей в бинарные предсказания
    predictions = (probabilities > 0.5).astype(int)
    # Вычисление метрик для каждого класса и усреднение
    precision, recall, f1, _ = precision_recall_fscore_support(labels, predictions, average='micro')
    acc = accuracy_score(labels, predictions)
    return {'accuracy': acc, 'f1': f1, 'precision': precision, 'recall': recall}

training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir='./logs',
    logging_steps=10,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    metric_for_best_model="f1",
)

model = BertForSequenceClassification.from_pretrained(
    'bert-base-multilingual-cased',
    problem_type="multi_label_classification",
    num_labels=len(unique_classes)
)

model.to(torch.device("cuda" if torch.cuda.is_available() else "cpu"))

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=val_dataset,
    compute_metrics=compute_metrics,
)

trainer.train()

# id2label = {str(index): label for label, index in class_to_index.items()}
# label2id = {label: str(index) for label, index in class_to_index.items()}
# model.config.id2label = id2label
# model.config.label2id = label2id

trainer.save_model("./best_model")
Leave a Comment