卡片召唤师
精华
|
战斗力 鹅
|
回帖 0
注册时间 2022-2-23
|
本帖最后由 sqlist 于 2023-10-12 15:39 编辑
rt,我自己在拿kaggle上老竞赛项目当练手项目的时候遇到了一个很麻烦的问题。具体情况是这样的:kaggle上有个竞赛是tweet sentiment. 简单来说,这个竞赛的训练集包含原始文本、筛选文本和情感词三列,测试集包括原始文本和情感词两列。 这个比赛的目标,是把模型训练到可以从原始文本里挑出能代表感情色彩的词。 举一个简单的例子:原文本是my boss is bullying me... 情感标签是negative。模型要筛选出来文本是bullying me 。
我的思路是,把情感词和原始文本拼接,用tokenizer将筛选文本和原始文本token化后,逐个比对出一个列表。-1表示原文本对应词没有选中,1表示选中,0表示填充部分。loss函数是自己拿交叉熵小改了一下。用bert预训练模型修改以后学习。如果用上面的举例,比对之后,生成的标签就应该是[0 -1 -1 -1 -1 1 1 0 ...]这样的。
但是这样一来有两个问题:虽然我训练集和测试集都有掩码,但是标签没有掩码,由于文本需要被填充到一样的长度,标签也要填充到相同长度。模型会给标签里被填充的部分也赋予概率。此外,由于每个句子不一样长,分配给词的概率也没有一个统一水平。句子长,分给每个词的概率就小,反之就大。我的做法,还需要把概率再转回 0-1标签。但这种情况根本不能过滤。我是自己一点点学的,这种情况是第一次遇见,坛友做机器学习相关的能不能给点解决方法?
我把少量代码直接放在这里吧,这是训练集数据的处理和对应标签的生成:
def generate_labels(text_token, selected_text_token):
len1=len(text_token)
labels=[-1]*len1
labels[0]=-1
j=1
for i in range(1,len1):
if(j>=len(selected_text_token)-1):
break
if(text_token==selected_text_token[j]):
labels=1
j+=1
else:
labels=-1
labels=-1
return labels
X_data=train['sentiment']+' '+train['text']
for i in range(len(X_data)):
if(i%1000==0): print(i)
input_ids=tokenizer.encode(X_data,max_length=MAXLEN)
selected_text_ids=tokenizer.encode(train.loc[i,'selected_text'], max_length=MAXLEN)
labels=generate_labels(input_ids,selected_text_ids)
padding_length=MAXLEN-len(input_ids)
train_input_ids.append(input_ids+[0]*padding_length)
train_labels.append(labels+[0]*padding_length)
train_attention_mask.append([1]*len(input_ids)+[0]*padding_length)
train_token_type_ids.append([0]*MAXLEN)
|
|