hitvoice / DrQA

A pytorch implementation of Reading Wikipedia to Answer Open-Domain Questions.
401 stars 109 forks source link

UNK过多 #1

Closed cairoHy closed 7 years ago

cairoHy commented 7 years ago

在用squad_preprocess.py预处理之后,用load_squad函数load出来的context和question里面UNK太多了,最后的vocab数量40000+,如下图。 image 但是我把data.msgpack里面存储的id形式的context和question用vocab转化为string形式后,发现UNK太多了,想问一下怎么处理呢? image

cairoHy commented 7 years ago

感觉没说清楚: 首先感谢你的代码~ 我想通过你的预处理过程获取所有的id化的context,question以及answer和answer span,但是这个id化的过程中最好尽可能不要有UNK,我想问一下在哪里能够参数化的控制这个过程呢

hitvoice commented 7 years ago

你好: 首先,这里的UNK是由这个词是否出现在GloVe中决定的,最终得到的词表长度符合预期;其次,在这一步融入UNK的原因是因为整数id将会用于embedding matrix的索引(而不是为了还原文本),这样做会让所有的UNK共享同一个embedding vector,为了模型训练的考虑这正是所需要的。

如果要还原原始文本,正确的做法是根据词语在原始文本中的范围(context_span)进行还原。具体做法可以参考drqa/model.py中的predict函数。具体地说,假如要还原第i篇文章第s_i个词到第e_i个词的内容,可以用如下代码:

def get_original_text(data, i, s_i, e_i):
    return data[i][-2][data[i][-1][s_i][0]: data[i][-1][e_i][1]]
text = get_original_text(train, 0, 2, 4) # text from 2nd word to 4th word in 0-th training example

对于第二条评论,能否进一步补充进行完整id化的动机?目前我并未看出这样做的意义。 谢谢你的反馈。

cairoHy commented 7 years ago

这样做会让所有的UNK共享同一个embedding vector,为了模型训练的考虑这正是所需要的。

我的疑问主要在这个地方,我之前建立vocab的时候是在性能可以接受的前提下尽量增加词典数量,即使用预训练的词向量,请问把所有在Glove以外的词都统一为UNK有什么好处吗?感觉会损失过多的信息。

cairoHy commented 7 years ago

额,这个问题解决了,还有一个想请问的地方,就是load_squad的时候,feature、tag和ents分别表示了什么意义呢,我看这三个量的长度是相同的。

hitvoice commented 7 years ago

你好: 第一个问题,这么做的先验信念是:SQuAD数据集就是从Wikipedia中采集而来的,只包含五百多篇文章(尽管有10万问答对),数据量可能不够支撑众多罕见词的训练,使得这些词的词向量容易过拟合,因此不如让模型学会应对UNK,毕竟在测试阶段还会遇到很多先前没见过的UNK;当然实践中可能会有不一样的结论,如果你有兴趣进行对比实验,欢迎分享实验结果 :) 第二个问题,三个分别对应论文中的match特征+TF特征、POS和NER。

cairoHy commented 7 years ago

奥,了解了解,谢谢。