|
--- |
|
license: apache-2.0 |
|
tags: |
|
- ESG |
|
- finance |
|
language: |
|
- ru |
|
|
|
--- |
|
![esgify](ESGify.png) |
|
# About ESGify_ru |
|
<img src="ESGify_logo.jpeg" alt="image" width="20%" height="auto"> |
|
**ESGify_ru** is a model for multilabel russian language news classification with respect to ESG risks. Our custom methodology includes 46 ESG classes, 1 non-relevant to ESG class and Positive news class, resulting in 48 classes in total: |
|
|
|
![esgify_classes](ESGify_classes.jpg) |
|
|
|
# Usage |
|
|
|
ESGify is based on ruBert architecture but with a custom classification head. The ESGify_ru class is defined is follows. |
|
|
|
```python |
|
from collections import OrderedDict |
|
from transformers import BertPreTrainedModel, BertModel, AutoTokenizer |
|
import torch |
|
|
|
# Mean Pooling - Take attention mask into account for correct averaging |
|
def mean_pooling(model_output, attention_mask): |
|
token_embeddings = model_output #First element of model_output contains all token embeddings |
|
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float() |
|
return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9) |
|
|
|
# Definition of ESGify class because of custom,sentence-transformers like, mean pooling function and classifier head |
|
class ESGify_ru(BertPreTrainedModel): |
|
"""Model for Classification ESG risks from russian language text.""" |
|
|
|
def __init__(self,config): #tuning only the head |
|
""" |
|
""" |
|
super().__init__(config) |
|
# Instantiate Parts of model |
|
self.bert = BertModel(config,add_pooling_layer=False) |
|
self.id2label = config.id2label |
|
self.label2id = config.label2id |
|
self.classifier = torch.nn.Sequential(OrderedDict([('norm',torch.nn.BatchNorm1d(768)), |
|
('linear',torch.nn.Linear(768,512)), |
|
('act',torch.nn.ReLU()), |
|
('batch_n',torch.nn.BatchNorm1d(512)), |
|
('drop_class', torch.nn.Dropout(0.2)), |
|
('class_l',torch.nn.Linear(512 ,48))])) |
|
|
|
|
|
def forward(self, input_ids, attention_mask): |
|
# Feed input to bert model |
|
outputs = self.bert(input_ids=input_ids, |
|
attention_mask=attention_mask) |
|
|
|
# mean pooling dataset and eed input to classifier to compute logits |
|
logits = self.classifier( mean_pooling(outputs['last_hidden_state'],attention_mask)) |
|
|
|
# apply sigmoid |
|
logits = 1.0 / (1.0 + torch.exp(-logits)) |
|
return logits |
|
``` |
|
|
|
After defining model class, we initialize ESGify and tokenizer with the pre-trained weights |
|
|
|
```python |
|
model = ESGify_ru.from_pretrained('ai-lab/ESGify_ru') |
|
tokenizer = AutoTokenizer.from_pretrained('ai-lab/ESGify_ru') |
|
``` |
|
|
|
Getting results from the model: |
|
|
|
```python |
|
texts = ['text1','text2'] |
|
to_model = tokenizer.batch_encode_plus( |
|
texts, |
|
add_special_tokens=True, |
|
max_length=512, |
|
return_token_type_ids=False, |
|
padding="max_length", |
|
truncation=True, |
|
return_attention_mask=True, |
|
return_tensors='pt', |
|
) |
|
results = model(**to_model) |
|
``` |
|
|
|
To identify top-3 classes by relevance and their scores: |
|
|
|
```python |
|
for i in torch.topk(results, k=3).indices.tolist()[0]: |
|
print(f"{model.id2label[i]}: {np.round(results.flatten()[i].item(), 3)}") |
|
``` |
|
|
|
For example, for the news: |
|
'''Профсоюз попросил "Аэрофлот" пересмотреть систему оплаты труда пилотов. |
|
Профсоюз летного состава предупредил "Аэрофлот" о риске дефицита пилотов из-за низких зарплат. |
|
Шереметьевский профсоюз летного состава (ШПЛС) написал письмо гендиректору "Аэрофлота" Михаилу Полубояринову, |
|
призвав пересмотреть систему оплаты работы пилотов, обращение размещено на сайте профсоюза. |
|
Как пояснил глава профсоюза Игорь Дельдюжов, новые правила оплаты труда, в которых сокращена доплата за час полетного времени, |
|
вступили в силу в начале прошлого года на фоне снижения объема перевозок пассажиров из-за пандемии коронавируса. |
|
Тогда летный состав согласился на новые условия оплаты, учитывая сложную ситуацию, в которой оказались авиаперевозчики. |
|
Однако теперь, как говорится в обращении, объемы авиаперевозок по России достигли допандемийного уровня, |
|
возобновляется и международное авиасообщение, у летного состава растет нагрузка, однако зарплата при этом пропорционально не растет. |
|
Из-за этого, по словам Дельдюжова, растет недовольство системой оплаты труда. |
|
Пилоты "Аэрофлота" вновь начали менять место работы, уходя в те авиакомпании, где "лучше условия труда". |
|
Глава профсоюза предупредил, что если не будут срочно приняты меры, авиакомпанию ждет нехватка квалифицированного летного состава.''' |
|
|
|
we get the following top-3 labels: |
|
``` |
|
Labor Relations Management |
|
Employee Health and Safety |
|
Retrenchment |
|
``` |
|
|
|
|
|
# Training procedure |
|
|
|
We use the pretrained [`ai-forever/ruBert-base`](https://huggingface.co/ai-forever/ruBert-base) model. |
|
Next, we do the domain-adaptation procedure by Mask Language Modeling with using texts of ESG reports. |
|
Finally, we fine-tune our model on 2500 texts with manually annotation of ESG specialists. |
|
|
|
|