python - 使用 BERT 进行 NER 分类的高度不平衡的 conllu 数据集
问题描述
我正在将 Bert 用于带有 conllu 英语数据集的 NER。如您所见,它非常不平衡:
Counter({'O': 16348, 'B-PER': 980, 'B-ORG': 421, 'B-GPE_LOC': 112, 'B-DRV': 75, 'B-GPE_ORG': 72, 'B-PROD': 43, 'B-LOC': 39, 'B-EVT': 8})
当我把它分成训练和验证时
from conllu import parse
data = parse(open("english.conllu", "r").read())
train_df, val_df = train_test_split(data, test_size = 0.2)
然后我得到这个分布
[training] Counter({'O': 13083, 'B-PER': 795, 'B-ORG': 328, 'B-GPE_LOC': 86, 'B-DRV': 61, 'B-GPE_ORG': 59, 'B-LOC': 31, 'B-PROD': 29, 'B-EVT': 6})
[validation] Counter({'O': 3265, 'B-PER': 185, 'B-ORG': 93, 'B-GPE_LOC': 26, 'B-DRV': 14, 'B-PROD': 14, 'B-GPE_ORG': 13, 'B-LOC': 8, 'B-EVT': 2})
f1 得分为 0.96,但显然这并不代表模型的性能,正如您在此处看到的那样
precision recall f1-score support
B-DRV 0.00 0.00 0.00 136
B-EVT 0.00 0.00 0.00 36
B-GPE_LOC 0.00 0.00 0.00 472
B-GPE_ORG 0.00 0.00 0.00 83
B-LOC 0.00 0.00 0.00 140
B-ORG 0.00 0.00 0.00 623
B-PER 0.00 0.00 0.00 949
B-PROD 0.00 0.00 0.00 164
I-DRV 0.00 0.00 0.00 25
I-EVT 0.00 0.00 0.00 17
I-GPE_LOC 0.00 0.00 0.00 49
I-GPE_ORG 0.00 0.00 0.00 6
I-LOC 0.00 0.00 0.00 61
I-ORG 0.00 0.00 0.00 217
I-PER 0.00 0.00 0.00 520
I-PROD 0.00 0.00 0.00 172
O 0.93 1.00 0.97 52359
accuracy 0.93 56029
macro avg 0.05 0.06 0.06 56029
weighted avg 0.87 0.93 0.90 56029
我的损失函数和优化器是:
criterion = nn.CrossEntropyLoss()
optimizer = AdamW(model.parameters(), lr=2e-5, eps=1e-8)
我该如何处理这种不平衡?我尝试获取权重并像这样在 CrossEntropy 中使用它们
idx2label = train_dataset.inverse_indexer
count_label = dict(Counter(train_dataset.flat))
inverse_counts = {key:1./value for key, value in count_label.items()}
weights = torch.Tensor(list(inverse_counts.values()))
print(weights)
sum_inverse = np.sum([count for _, count in inverse_counts.items()])
inverse_normalized = {key:value/sum_inverse for key, value in inverse_counts.items()}
weights = np.array([0.3+inverse_normalized[idx2label[i]] for i in range(len(idx2label))])
weights = [math.log(i) for i in weights]
weights = torch.Tensor(weights)
标准 = nn.CrossEntropyLoss(ignore_index=-1, weight=weights)
但结果是一样的。
解决方案
推荐阅读
- ruby-on-rails - 使 Active Storage has_one_attatched 不为空
- javascript - 使用 React 将索引作为状态传递给组件
- windows - FASM 汇编程序在退出前等待
- python - 由于生成的密钥上的密码错误,python gnupg 解密失败
- ruby-on-rails - 在 Rails 中更新 DB 中的多行,每行都有唯一的值
- r - 两行传单图例名称
- swift - 在 Swift 中,在循环中声明变量有多糟糕
- javascript - 选定文本的非粗体部分不起作用
- gpu - 在英特尔 iGPU 上测量内核内的时间
- python - 在类中使用函数