Untitled
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