AIWIN2023 研報類型識別 baseline

賽題背景

在投資管理業(ye) 務的研究過程中,研究人員需要閱讀和分析各個(ge) 券商機構製作的研究分析報告。他們(men) 需要從(cong) 這些報告中提取出有價(jia) 值的關(guan) 鍵信息,包括研報分析的個(ge) 股、當前評級、目標價(jia) 和盈利預測數據等。這部分研究工作較為(wei) 繁瑣,會(hui) 耗費研究人員大量的時間和精力。

比賽鏈接:https://ailab.aiwin.org.cn/competitions/87

基於(yu) 上述分析,我們(men) 希望利用人工智能技術從(cong) 研報PDF中自動抽取出關(guan) 鍵信息並組織成結構化的數據進行分析。具體(ti) 地,我們(men) 結合自然語言處理與(yu) 計算機視覺相關(guan) 技術,設計了一套研究報告(以下簡稱研報)關(guan) 鍵信息要素抽取解決(jue) 方案。該方案包含研報文件解析、研報類型分析和研報要素抽取等功能。

賽題任務

本賽題任務是利用機器學習(xi) 、深度學習(xi) 等方法訓練一個(ge) 預測模型,該模型主要針對各種各樣的研報進行類型分析。賽題的難點在於(yu) 不同機構、券商研報形式多樣以及需要借助PDF的解析或者多模態的應用。

  • 本賽題可以使用外部預訓練模型(包括GPT類的LLM等)用於數據處理和建模過程,但不得直接使用ChatGPT類的應用作為產出最終分類結果的直接工具
  • 請注意在研報數據上微調過程中不能引入其他數據,所有數據預處理隻能在這些研報數據上。

賽題數據集

本賽題將10中類型的研報數據會(hui) 劃分為(wei) 訓練集、測試集。訓練集用於(yu) 模型架構設計、模型訓練,在測試集上驗證效果。以macro precision/recall/f1三個(ge) 指標為(wei) 驗證標準(f1分數為(wei) 排名依據)。

初賽提供研報首頁的結果結果,包括header 和title。在初賽的基礎上,複賽將隻提供研報原文,並期望選手能充分解析和利用研報中文本、圖形等多模態的信息用於(yu) 優(you) 化模型。

初賽提供的數據集如下:

  • 研報數據首頁解析結果
  • 研報數據對應類型標簽

複賽提供的數據集如下:

  • 完整研報原文
  • 研報數據對應類型標簽

賽題思路

賽題在初賽可以視為(wei) 典型的文本分類任務,因此可以直接參考文本分類的流程進行。接下來我們(men) 將展示BERT思路比較關(guan) 鍵的部分代碼,完成代碼見文末。

步驟1:初始化訓練配置

class Config(): train_data = 'data/train_dataset.npy' # 訓練集 predict_data = 'data/eval_dataset.npy' # 測試集 result_data_save = 'result/submission.csv' # 預測結果 device = 'cpu' # 訓練驅動

model_path = 'hfl/chinese-roberta-wwm-ext' # 預訓練模型 model_save_path = 'result/model' # 保存模型 tokenizer = None # 預訓練模型的tokenizer # 數據標簽 label_dict = {'晨會(hui) 早報': 0, '宏觀研報': 1, '策略研報': 2, '行業(ye) 研報': 3, '公司研報': 4, '基金研報': 5, '債(zhai) 券研報': 6, '金融工程': 7, '其他研報': 8, '個(ge) 股研報': 9}
num_labels = len(label_dict) # 標簽數量 max_seq_len = 128 # 最大句子長度 test_size = 0.15 # 校驗集大小 random_seed = 42 # 隨機種子 batch_size = 64 # 訓練數據批大小 val_batch_size = 8 # 校驗/預測批大小 epochs = 10 # 訓練次數 learning_rate = 1e-5 # 學習(xi) 率 l2_weight_decay = 0.05 print_log = 20 # 日誌打印步驟

config = Config()
config.device = 'cuda' if torch.cuda.is_available() else 'cpu'

步驟2:自定義(yi) 數據讀取

# 自定義(yi) dataset class MyDataset(Dataset): def __init__(self, config: Config, data: list, label: list = None): self.data = data
        self.tokenizer = config.tokenizer 
        self.max_seq_len = config.max_seq_len
        self.len = len(data)
        self.label = label

def __getitem__(self, idx): text = self.data[idx] # tokenizer inputs = self.tokenizer.encode_plus(text, return_token_type_ids=True, return_attention_mask=True,
max_length=self.max_seq_len, padding='max_length', truncation=True)

# 打包預處理結果 result = {'input_ids': torch.tensor(inputs['input_ids'], dtype=torch.long), 'token_type_ids': torch.tensor(inputs['token_type_ids'], dtype=torch.long), 'attention_mask': torch.tensor(inputs['attention_mask'], dtype=torch.long)} if self.label is not None:
result['labels'] = torch.tensor([self.label[idx]], dtype=torch.long) # 返回 return result

def __len__(self): return self.len

步驟3:加載預訓練模型

tokenizer = AutoTokenizer.from_pretrained(config.model_path)
model = AutoModelForSequenceClassification.from_pretrained(config.model_path, num_labels=config.num_labels)

config.tokenizer = tokenizer

步驟4:模型訓練與(yu) 驗證

# 校驗方法 def val(model, val_dataloader: DataLoader):
    model.eval()
    total_acc, total_f1, total_loss, test_num_batch = 0., 0., 0., 0 for iter_id, batch in enumerate(val_dataloader): # 轉GPU batch_cuda = {item: value.to(config.device) for item, value in batch.items()} # 模型計算 output = model(batch_cuda) # 獲取結果 loss = output[0]
        logits = torch.argmax(output[1], dim=1)

y_pred = [[i] for i in logits.cpu().detach().numpy()]
y_true = batch_cuda['labels'].cpu().detach().numpy() # 計算指標 acc = accuracy_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred, average='weighted')
total_loss += loss.item()
total_acc += acc
total_f1 += f1
test_num_batch += 1

return total_loss/test_num_batch, total_acc/test_num_batch, total_f1/test_num_batch

def train(model, config: Config, train_dataloader: DataLoader, val_dataloader: DataLoader): # 模型寫(xie) 入GPU model.to(config.device)

# 獲取BERT模型的所有可訓練參數 params = list(model.named_parameters()) # 對除了bias和LayerNorm層的所有參數應用L2正則化 no_decay = ['bias', 'LayerNorm.bias', 'LayerNorm.weight']
optimizer_grouped_parameters = [
{'params': [p for n, p in params if not any(nd in n for nd in no_decay)], 'weight_decay': config.l2_weight_decay},
{'params': [p for n, p in params if any(nd in n for nd in no_decay)], 'weight_decay': 0.0}
] # 創建優(you) 化器並使用正則化更新模型參數 opt = torch.optim.AdamW(optimizer_grouped_parameters, lr=config.learning_rate) # 梯度衰減 scheduler = optim.lr_scheduler.CosineAnnealingLR(opt, len(train_dataloader) * config.epochs)

完整代碼鏈接:

https://github.com/datawhalechina/competition-baseline/tree/master/competition/AIWIN2023

學習(xi) 資料匯總:

https://coggle.club/blog/compete/aiwin2023

改進方法

在baseline中給出的基礎的BERT分類思路,可以獲得0.94左右的分析,還有很大的上分空間:

  • 多折交叉驗證
  • BERT模型預訓練
  • 增加輸入長度
  • 修改預訓練模型

【競賽報名/項目谘詢+微信:mollywei007】

上一篇

上海浦東區有哪些國際學校?

下一篇

申請美國大學該選美國公立還是私立大學?

你也可能喜歡

  • 暫無相關文章!

評論已經被關(guan) 閉。

插入圖片
返回頂部