与风景对话_交互式旅游推荐系统_数据预处理与分析(二)基于pytorch的标签识别数据填充

一.文本需求分析

  在我们的旅游计划中,很重要的一个部分就是时间与地点的规划,不一样的时间所看到的风景是完全不一样的,因此时间是一个非常重要的内容,首先我们的数据爬取是根据地点来进行的,因此我们需要对数据进行处理,使每一个数据都具有时间特点,因此我们考虑给每一个数据都加上时间,考虑到我们有很多具有时间特征的数据,因此我们考虑通过神经网络的方法来实现我们的设想。夏天的济南秋天的济南

二.步骤设计

1.准备数据

首先我们在之前的数据中将其分为有月份的和没有月份的两个部分,之后将其用来训练和测试模型,我们使用python来进行分类,首先在我们的数据中,instruction中有一系列的标签,我们选择有月份的来进行训练,将其summary进行训练,将月份进行测试。

2.文本预处理

我们将使用一个BERT模型进行文本处理和特征提取,因此需要首先将文本转化为BERT模型可接受的格式

3.构建模型

我们将使用一个预训练的模型进行微调以识别月份信息

4.模型推理

训练完成后,我们将使用训练好的模型对新文本进行月份识别。

三.实现步骤

1.安装必要的库

pip install torch transformers

2.准备数据

创建一个包含文本和标签的数据集,标签采用BIO标记

解决联合标注问题的最简单的方法,就是将其转化为原始标注问题。标准做法就是使用BIO标注。

      BIO标注:将每个元素标注为“B-X”、“I-X”或者“O”。其中,“B-X”表示此元素所在的片段属于X类型并且此元素在此片段的开头,“I-X”表示此元素所在的片段属于X类型并且此元素在此片段的中间位置,“O”表示不属于任何类型。

      比如,我们将 X 表示为名词短语(Noun Phrase, NP),则BIO的三个标记为:

(1)B-NP:名词短语的开头

(2)I-NP:名词短语的中间

(3)O:不是名词短语

import pandas as pd

data = {
    'text': [
        "我计划在今年的5月和10月去旅行,5月份去北京,10月份去上海。",
        "另外,我还考虑在7月去广州。"
    ],
    'labels': [
        "O O O O O O B-MONTH O B-MONTH O O O O O O B-MONTH O B-MONTH O O O O O O O",
        "O O O O O O O B-MONTH O O O O O"
    ]
}

df = pd.DataFrame(data)
df.to_csv('month_recognition_data.csv', index=False)

3.文本预处理

使用 transformers 库中的 BertTokenizer 进行文本预处理。

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')

def preprocess(texts, labels, tokenizer, max_len=128):
    input_ids = []
    attention_masks = []
    label_ids = []
    
    for text, label in zip(texts, labels):
        encoding = tokenizer.encode_plus(
            text,
            max_length=max_len,
            padding='max_length',
            truncation=True,
            return_attention_mask=True,
            return_tensors='pt'
        )
        
        input_ids.append(encoding['input_ids'])
        attention_masks.append(encoding['attention_mask'])
        
        label_id = [0 if lbl == 'O' else 1 for lbl in label.split()]
        label_id = label_id + [0] * (max_len - len(label_id))
        label_ids.append(label_id)
    
    return torch.cat(input_ids, dim=0), torch.cat(attention_masks, dim=0), torch.tensor(label_ids)

texts = df['text'].values
labels = df['labels'].values

input_ids, attention_masks, label_ids = preprocess(texts, labels, tokenizer)

4.进行训练

使用预训练的 BERT 模型进行微调。

import torch
from torch.utils.data import DataLoader, TensorDataset, RandomSampler
from transformers import BertForTokenClassification, AdamW

# 创建数据加载器
batch_size = 16
dataset = TensorDataset(input_ids, attention_masks, label_ids)
dataloader = DataLoader(dataset, sampler=RandomSampler(dataset), batch_size=batch_size)

# 加载预训练的 BERT 模型
model = BertForTokenClassification.from_pretrained('bert-base-chinese', num_labels=2)
model.cuda()

# 设置优化器
optimizer = AdamW(model.parameters(), lr=5e-5)

# 训练模型
epochs = 3
for epoch in range(epochs):
    model.train()
    total_loss = 0
    for step, batch in enumerate(dataloader):
        batch_input_ids, batch_attention_masks, batch_labels = tuple(t.to('cuda') for t in batch)
        
        model.zero_grad()
        outputs = model(batch_input_ids, attention_mask=batch_attention_masks, labels=batch_labels)
        loss = outputs.loss
        total_loss += loss.item()
        
        loss.backward()
        optimizer.step()
    
    avg_loss = total_loss / len(dataloader)
    print(f"Epoch {epoch+1}/{epochs} - Loss: {avg_loss}")

5. 模型推理

使用训练好的模型进行月份识别。

def predict(text, model, tokenizer):
    model.eval()
    encoding = tokenizer.encode_plus(
        text,
        max_length=128,
        padding='max_length',
        truncation=True,
        return_attention_mask=True,
        return_tensors='pt'
    )
    
    input_ids = encoding['input_ids'].to('cuda')
    attention_mask = encoding['attention_mask'].to('cuda')
    
    with torch.no_grad():
        outputs = model(input_ids, attention_mask=attention_mask)
    
    logits = outputs.logits
    predictions = torch.argmax(logits, dim=2)
    
    tokens = tokenizer.convert_ids_to_tokens(input_ids[0])
    predicted_labels = [label for token, label in zip(tokens, predictions[0].tolist()) if token != '[PAD]']
    
    return predicted_labels

text = "我计划在今年的5月和10月去旅行,5月份去北京,10月份去上海。"
predicted_labels = predict(text, model, tokenizer)
print(predicted_labels)

之后我们很遗憾的发现,该模型要求的数据量远大于我们的数据集,我们采取的方法很难实现我们的要求,在进行训练时loss值持续震荡,对新数据拟合程度不高,因此我们决定放弃该方法,选择其他的方法来实现我们的设想

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值