• 如果你的数据集比较小,最好不要自己训练词向量,容易过拟合,直接download别人在某些语料库上训练好的词向量fix下来比较好
  • 但是如果你的数据集比较大,你可以随机初始化你的词向量并且在训练过程中训练他们
  • window classification是最简单的NLP问题之一,你只是把语料库中用一个window圈起来几个单词,然后预测中间那个单词的类别,可以是情感分析,也可以是地点、时间、人名这些,网络的输入是window中单词的词向量的concatenate,输出是类别
  • max margin loss:每次计算一个正例和一个负例的分数,计算loss,希望正例的分数比负例的分数要大1,也就是说希望正例和负例的分数分得开一点,然后如果足够开,比如相差1以上,那么loss会是0,也就是网络不再更新对这部分已经能正确区分的数据集的参数,而专注于对那些还没预测得足够正确的数据进行梯度下降
  • 计算机科学中的context free grammars = 语言学家口中的phrase structure grammars = constituency,就是我们学英语学的名词介词形容词等等这些语法,这个是一种用于计算机科学的句法模型。另一种模型就是dependency structure,称之为依存分析,比如barking dog,barking用来修饰dog,就是barking is a dependent of dog, 可以用箭头来表示依存关系:
  • 根据依存关系标记的数据库被广泛使用,称之为treebanks,现在主流语言模型,无论是计算机科学还是语言学,都是基于依存分析(dependency parsing)的
  • 依存分析中通常为一个句子加一个伪结点,认为他是整个句子的root,这样句中找不到父节点的单词以root为父节点,导致每个单词都有一个父节点。同时注意,不是所有人的箭头都是从父节点指向dependent的,有的人会反过来指,所以要先注意好论文中是怎么解释箭头的方向。
  • 依存分析的方法有好几种,主流是下面的第四种
  • arc-standard transition-based parsing的做法是如下,当你拿到一个句子,你有三个选择:shift、left arc、right arc,shift是把buffer中最左边的单词送入stack的最右端,left arc和rignht arc是把stack顶端两个单词之一出栈,并且确认依存关系为从右往左还是从左往右。这样就可以对一个句子确认依存关系。每一时刻到底该做shift还是right arc或者left arc,可以用机器学习实现,也就是说,我们有一堆建立好依存关系的treebanks,利用这些treebanks可以对每一个单词产生唯一的指令序列,用这些句子和对应的指令序列来训练,最终希望得到这样一个预测器,以句子为输入,以指令序列为输出,那么这个预测器就可以用于依存分析,对一个句子建立依存关系。
  • 此外,可以对这种分析进行拓展,实际上依存关系可以利用类似于context-free grammars 的理论进一步拓展为好多类依存关系,比如主语对宾语的依存关系,定语对其修饰词的依存关系等等,这些标记被称为part of speech tags(POS),有一些treebanks是带有这些拓展的标记的,用这些treebanks可以训练出可以标记拓展关系的81类预测器,那么这个预测器就可以对句子进行拓展的依存分析。没有拓展的依存分析产生的是un-type dependency tree。
  • 这些预测器的输入特征可以有多种选择,看你建立怎样的模型去利用这样一个stack和buffer的结构来产生下一步的指令,可以是只看top of buffer和top of stack的词性(多数treebanks会给单词标注词性),等等。最简单的是NO search方法,没有细讲,反正知道有各种方法可以使用就行:
  • 这样的依存分析有几个问题:一是特征稀疏,你可能有几百万的数据集,但是你有几千万的feature;第二个是数据集总是不能展示所有情况,你总会遇到数据集中没有的情况;第三个是在从句子的单词中取得特征是,是从一个巨大的哈希表中去查找,虽然是线性时间,但是仍然代价很高。本质上这是由于稀疏引起的而且这是传统机器学习的通病,为了解决这些问题,可以用神经网络的方法来建立紧致的特征表,实验表明用神经网络可以加快10倍左右,代价是准确率有一点点降低,所以如果你要进行的任务文本比较大,选神经网络比较好,如果比较小,选传统方法比较好。