├── .DS_Store ├── LSTM.md ├── pic ├── .DS_Store ├── 2cnn.png ├── DLAS.png ├── HAN.png ├── Jointplot.png ├── LSI-K.png ├── LSTM-3GATE.png ├── LSTM2-notation.png ├── LSTM3-SimpleRNN.png ├── LSTM3-chain.png ├── LSTM3-focus-f.png ├── LSTM3-var-GRU.png ├── QQ20170721-145413.png ├── QQ20170721-154434.png ├── QQ20170721-164709.png ├── RNN-longtermdependencies.png ├── adaboost.png ├── arc1.png ├── arc2.png ├── arc21.png ├── atten1.png ├── atten2.png ├── atten4.png ├── atten5.png ├── cal-q.png ├── cbow-sam.png ├── cdssm_arch.png ├── cnn-imple.png ├── cnn-imple2.png ├── cnnill.png ├── consim.png ├── cossim.png ├── dam1.png ├── dmkehishua1.png ├── dmkehishua2.png ├── dmkehishua3.png ├── dssm_arch.png ├── dssm_lstm_arch.png ├── ed.png ├── ende.png ├── ende2.png ├── ende3.png ├── ende4.png ├── ende5.png ├── fgate-cal.png ├── fm.png ├── gru.png ├── hsoftmax.png ├── huofumantree.png ├── if.png ├── jacsim.png ├── lda1.png ├── lda2.png ├── lda3.png ├── lda4.png ├── lsi-a.png ├── lstm-gate.png ├── match.png ├── metric.png ├── mi.png ├── mi2.png ├── ns.png ├── pairplot.png ├── pym_res.png ├── pym_res2.png ├── pymloss.png ├── pyramid.png ├── softmax1.png ├── svd.png ├── svdalg1.png ├── svdalg2.png ├── svdalg3.png ├── svdalg4.png ├── svdincl.png ├── svdobj.png ├── textrank1.png ├── times.png ├── times1.png ├── whitenoise.png ├── word-A.png └── x2.png ├── word2vec.md ├── 主题模型 -- LSI & LDA.md ├── 损失函数总结.md ├── 推荐系统相关 ├── .DS_Store ├── A Guide to Singular Value Decomposition for Collaborative Filtering.pdf ├── FM-FFM模型.md ├── SVD应用于协同过滤.md ├── svdRec.py └── svdppRec.py ├── 数据挖掘竞赛操作指南 -- 结构化数据篇.md ├── 文本分类 -- HAN 模型.md ├── 文本分类 -- 特征选择.md ├── 文本相似度--BM25.md ├── 文本自动摘要 -- 抽取式算法.md ├── 注意力机制 Attention Mechanism.md ├── 深度语义匹配模型系列 -- DLAS.md ├── 深度语义匹配模型系列 -- DSSM.md ├── 深度语义匹配模型系列--ARC.md ├── 深度语义匹配模型系列--Decomposable Attention Model.md ├── 深度语义匹配模型系列--MatchPyramid.md └── 距离度量和相似度度量公式.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/.DS_Store -------------------------------------------------------------------------------- /LSTM.md: -------------------------------------------------------------------------------- 1 | # LSTM 2 | 3 | ### 上下文长期依赖问题 4 | 5 | 预测一句话“the clouds are in the sky,”的最后一个词,不需要更长的上文信息,但是对于“I grew up in France… I speak fluent French.” 就需要比较长的上文信息了。 6 | 理论上 RNNs 可以捕获较长的上下文信息,但是在实际中这比较困难。 7 | ![avatar](./pic/RNN-longtermdependencies.png) 8 | ![avater](./pic/LSTM3-SimpleRNN.png) 9 | RNNs 中的循环结构 10 | 11 | ### LSTM 网络结构 12 | 13 | LSTMs 的设计被用于来避免长短依赖问题,主要结构如下图所示 14 | ![avater](./pic/LSTM3-chain.png) 15 | ![avater](./pic/LSTM2-notation.png) 16 | 17 | 穿过流程图上方的平行直线是LSTM的关键,它像一个数据传送带,对数据仅进行简单的线性变化,它很方便的将数据信息进行传送。LSTM 有一个门限机制(遗忘门),它可以控制信息的过滤,是由一个 sigmoid 神经元和一个点乘操作组成。sigmoid 层的输出在0至1之间,描述了可以让多少信息通过,0表示不让任何信息通过,1表示让所有信息通过。 18 | ![avater](./pic/LSTM3-focus-f.png) 19 | 遗忘门 20 | 21 | ![avater](./pic/fgate-cal.png) 22 | 23 | 遗忘门的计算 24 | 25 | LSTM的思路是使用三个控制开关。第一个开关,负责控制继续保存长期状态c;第二个开关,负责控制把即时状态输入到长期状态c;第三个开关,负责控制是否把长期状态c作为当前的LSTM的输出。三个开关的作用如下图所示: 26 | ![avater](./pic/lstm-gate.png) 27 | 28 | LSTM用两个门来控制单元状态c的内容,一个是遗忘门(forget gate),它决定了上一时刻的单元状态 $c_{t-1}$ 有多少保留到当前时刻 $$c_t$$;另一个是输入门(input gate),它决定了当前时刻网络的输入 $x_t$ 有多少保存到单元状态 $C_t$ 。LSTM用输出门(output gate)来控制单元状态 $C_t$ 有多少输出到LSTM的当前输出值 $h_t$。 29 | 30 | ![avater](./pic/LSTM-3GATE.png) 31 | 32 | ### LSTM 网络的训练 33 | 34 | - ft, it, ct, ot,ht五个向量的计算; 35 | - LSTM误差项的反向传播也是包括两个方向:一个是沿时间的反向传播,即从当前t时刻开始,计算每个时刻的误差项;一个是将误差项向上一层传播。 36 | 37 | sigmoid和tanh函数的导数都是原函数的函数。这样,我们一旦计算原函数的值,就可以用它来计算出导数的值。 38 | 39 | # GRU 40 | 41 | ![avater](./pic/LSTM3-var-GRU.png) 42 | 43 | GRU对LSTM做了两个大改动: 44 | 45 | 将输入门、遗忘门、输出门变为两个门:更新门(Update Gate)zt 和重置门(Reset Gate)rt。 46 | 将单元状态与输出合并为一个状态:h。 47 | 48 | ![avater](./pic/gru.png) 49 | 50 | -------------------------------------------------------------------------------- /pic/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/.DS_Store -------------------------------------------------------------------------------- /pic/2cnn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/2cnn.png -------------------------------------------------------------------------------- /pic/DLAS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/DLAS.png -------------------------------------------------------------------------------- /pic/HAN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/HAN.png -------------------------------------------------------------------------------- /pic/Jointplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/Jointplot.png -------------------------------------------------------------------------------- /pic/LSI-K.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/LSI-K.png -------------------------------------------------------------------------------- /pic/LSTM-3GATE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/LSTM-3GATE.png -------------------------------------------------------------------------------- /pic/LSTM2-notation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/LSTM2-notation.png -------------------------------------------------------------------------------- /pic/LSTM3-SimpleRNN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/LSTM3-SimpleRNN.png -------------------------------------------------------------------------------- /pic/LSTM3-chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/LSTM3-chain.png -------------------------------------------------------------------------------- /pic/LSTM3-focus-f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/LSTM3-focus-f.png -------------------------------------------------------------------------------- /pic/LSTM3-var-GRU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/LSTM3-var-GRU.png -------------------------------------------------------------------------------- /pic/QQ20170721-145413.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/QQ20170721-145413.png -------------------------------------------------------------------------------- /pic/QQ20170721-154434.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/QQ20170721-154434.png -------------------------------------------------------------------------------- /pic/QQ20170721-164709.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/QQ20170721-164709.png -------------------------------------------------------------------------------- /pic/RNN-longtermdependencies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/RNN-longtermdependencies.png -------------------------------------------------------------------------------- /pic/adaboost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/adaboost.png -------------------------------------------------------------------------------- /pic/arc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/arc1.png -------------------------------------------------------------------------------- /pic/arc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/arc2.png -------------------------------------------------------------------------------- /pic/arc21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/arc21.png -------------------------------------------------------------------------------- /pic/atten1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/atten1.png -------------------------------------------------------------------------------- /pic/atten2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/atten2.png -------------------------------------------------------------------------------- /pic/atten4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/atten4.png -------------------------------------------------------------------------------- /pic/atten5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/atten5.png -------------------------------------------------------------------------------- /pic/cal-q.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/cal-q.png -------------------------------------------------------------------------------- /pic/cbow-sam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/cbow-sam.png -------------------------------------------------------------------------------- /pic/cdssm_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/cdssm_arch.png -------------------------------------------------------------------------------- /pic/cnn-imple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/cnn-imple.png -------------------------------------------------------------------------------- /pic/cnn-imple2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/cnn-imple2.png -------------------------------------------------------------------------------- /pic/cnnill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/cnnill.png -------------------------------------------------------------------------------- /pic/consim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/consim.png -------------------------------------------------------------------------------- /pic/cossim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/cossim.png -------------------------------------------------------------------------------- /pic/dam1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/dam1.png -------------------------------------------------------------------------------- /pic/dmkehishua1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/dmkehishua1.png -------------------------------------------------------------------------------- /pic/dmkehishua2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/dmkehishua2.png -------------------------------------------------------------------------------- /pic/dmkehishua3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/dmkehishua3.png -------------------------------------------------------------------------------- /pic/dssm_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/dssm_arch.png -------------------------------------------------------------------------------- /pic/dssm_lstm_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/dssm_lstm_arch.png -------------------------------------------------------------------------------- /pic/ed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/ed.png -------------------------------------------------------------------------------- /pic/ende.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/ende.png -------------------------------------------------------------------------------- /pic/ende2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/ende2.png -------------------------------------------------------------------------------- /pic/ende3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/ende3.png -------------------------------------------------------------------------------- /pic/ende4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/ende4.png -------------------------------------------------------------------------------- /pic/ende5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/ende5.png -------------------------------------------------------------------------------- /pic/fgate-cal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/fgate-cal.png -------------------------------------------------------------------------------- /pic/fm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/fm.png -------------------------------------------------------------------------------- /pic/gru.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/gru.png -------------------------------------------------------------------------------- /pic/hsoftmax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/hsoftmax.png -------------------------------------------------------------------------------- /pic/huofumantree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/huofumantree.png -------------------------------------------------------------------------------- /pic/if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/if.png -------------------------------------------------------------------------------- /pic/jacsim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/jacsim.png -------------------------------------------------------------------------------- /pic/lda1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/lda1.png -------------------------------------------------------------------------------- /pic/lda2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/lda2.png -------------------------------------------------------------------------------- /pic/lda3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/lda3.png -------------------------------------------------------------------------------- /pic/lda4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/lda4.png -------------------------------------------------------------------------------- /pic/lsi-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/lsi-a.png -------------------------------------------------------------------------------- /pic/lstm-gate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/lstm-gate.png -------------------------------------------------------------------------------- /pic/match.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/match.png -------------------------------------------------------------------------------- /pic/metric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/metric.png -------------------------------------------------------------------------------- /pic/mi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/mi.png -------------------------------------------------------------------------------- /pic/mi2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/mi2.png -------------------------------------------------------------------------------- /pic/ns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/ns.png -------------------------------------------------------------------------------- /pic/pairplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/pairplot.png -------------------------------------------------------------------------------- /pic/pym_res.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/pym_res.png -------------------------------------------------------------------------------- /pic/pym_res2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/pym_res2.png -------------------------------------------------------------------------------- /pic/pymloss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/pymloss.png -------------------------------------------------------------------------------- /pic/pyramid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/pyramid.png -------------------------------------------------------------------------------- /pic/softmax1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/softmax1.png -------------------------------------------------------------------------------- /pic/svd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/svd.png -------------------------------------------------------------------------------- /pic/svdalg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/svdalg1.png -------------------------------------------------------------------------------- /pic/svdalg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/svdalg2.png -------------------------------------------------------------------------------- /pic/svdalg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/svdalg3.png -------------------------------------------------------------------------------- /pic/svdalg4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/svdalg4.png -------------------------------------------------------------------------------- /pic/svdincl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/svdincl.png -------------------------------------------------------------------------------- /pic/svdobj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/svdobj.png -------------------------------------------------------------------------------- /pic/textrank1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/textrank1.png -------------------------------------------------------------------------------- /pic/times.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/times.png -------------------------------------------------------------------------------- /pic/times1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/times1.png -------------------------------------------------------------------------------- /pic/whitenoise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/whitenoise.png -------------------------------------------------------------------------------- /pic/word-A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/word-A.png -------------------------------------------------------------------------------- /pic/x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/pic/x2.png -------------------------------------------------------------------------------- /word2vec.md: -------------------------------------------------------------------------------- 1 | # word2vec 2 | 3 | 为应对 One hot representation 词向量的高维稀疏问题所带来的内存灾难以及词和词之间的独立性造成的缺陷,word2vec 技术将词投射到一个低维空间,将词的 one hot 编码方式转换为低维稠密的 Dristributed representation。这种向量可以通过余弦相似度等距离计算方式计算词和词之间的关系。 4 | 5 | ## 一、CBOW与Skip-Gram 6 | 7 | CBOW模型的训练输入是某一个特征词的上下文相关的词对应的 one-hot 词向量,而输出就是一个经过softmax处理之后的概率向量,训练目标就是最大化该特定词的概率。比如下面这段话,我们的上下文大小取值为4,特定的这个词是"Learning",也就是我们需要的输出词向量,上下文对应的词有8个,前后各4个,这8个词是我们模型的输入。 8 | 9 | ![avater](./pic/cbow-sam.png) 10 | 11 | 经过前向传播,模型预测的是整个词表 $$V$$ 中每个词的概率,训练目标就是最大化 “learning” 的概率。然后通过反向传播不断更新隐藏层参数,获得所有所有词的隐层表达。 12 | 13 | Skip-Gram 模型和 CBOW 的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。还是上面的例子,我们的上下文大小取值为4, 特定的这个词 "Learning" 是我们的输入,而这8个上下文词是我们的输出。 14 | 15 | DNN 模型的上述两个模型的处理过程非常耗时。我们的词汇表一般在百万级别以上,这意味着我们 DNN 的输出层需要进行 softmax 计算各个词的输出概率的的计算量很大。有没有简化一点点的方法呢? 16 | 17 | ## 二、霍夫曼树 18 | 19 | word2vec 使用霍夫曼树来代替隐藏层和输出层的神经元,霍夫曼树的叶子节点起到输出层神经元的作用,叶子节点的个数即为词汇表的小大。 而内部节点则起到隐藏层神经元的作用。 20 | 21 | 统计训练语料中所有词的词频,每个词代表一个节点,词频表示该节点的权重,重复选择所有节点中权重最小的两个节点进行合并,直到所有节点都包含在一棵树中,于是建立起了霍夫曼树,如下图所示 22 | 23 | ![avater](./pic/huofumantree.png) 24 | 25 | 在上述霍夫曼树中,可以看到所有叶子节点都代表一个词,词频越高的词离根节点越近。当对所有词进行编码时,我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合我们的信息论,即我们希望越常用的词拥有更短的编码。如何编码呢?一般对于一个霍夫曼树的节点(根节点除外),可以约定左子树编码为0,右子树编码为1.如上图,则可以得到 c 的编码是 00。 26 | 27 | 在 word2vec 中,约定编码方式和上面的例子相反,即约定左子树编码为1,右子树编码为0,同时约定左子树的权重不小于右子树的权重。 28 | 29 | ## 三、Hierarchical Softmax 30 | 31 | ![avater](./pic/softmax1.png) 32 | 33 | 如上图所示,传统神经网络训练词向量使用三层的神经网络,输出层使用 softmax ,这样造成的困难在于需要计算所有输出词的概率,然后将所有概率归一化,计算量大。 34 | 35 | word2vec 对这个模型做了改进,首先,对于从输入层到隐藏层的映射,没有采取神经网络的线性变换加激活函数的方法,而是采用简单的对所有输入词向量求和并取平均的方法。比如输入的是三个4维词向量:(1,2,3,4),(9,6,11,8),(5,10,7,12),那么我们word2vec映射后的词向量就是(5,6,7,8)。由于这里是从多个词向量变成了一个词向量。 36 | 37 | 第二个改进就是从隐藏层到输出的softmax层这里的计算量个改进。为了避免要计算所有词的softmax 概率,word2vec 采样了霍夫曼树来代替从隐藏层到输出 softmax 层的映射。我们在上一节已经介绍了霍夫曼树的原理。如何映射呢?这里就是理解 word2vec 的关键所在了。 38 | 39 | 由于我们把之前所有都要计算的从输出softmax层的概率计算变成了一颗二叉霍夫曼树,那么我们的softmax概率计算只需要沿着树形结构进行就可以了。如下图所示,我们可以沿着霍夫曼树从根节点一直走到我们的叶子节点的词w2。 40 | 41 | ![avater](./pic/hsoftmax.png) 42 | 43 | 和之前的神经网络语言模型相比,我们的霍夫曼树的所有内部节点就类似之前神经网络隐藏层的神经元,其中,根节点的词向量对应我们的投影后的词向量,而所有叶子节点就类似于之前神经网络softmax输出层的神经元,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"。 44 | 45 | 如何“沿着霍夫曼树一步步完成”呢?在word2vec中,我们采用了二元逻辑回归的方法,即规定沿着左子树走,那么就是负类(霍夫曼树编码1),沿着右子树走,那么就是正类(霍夫曼树编码0)。判别正类和负类的方法是使用sigmoid函数,即: 46 | 47 | $$P(+)=\sigma (x_{w}^T \theta)=\frac{1}{1+e^{-x_{w}^T \theta}}$$ 48 | 49 | 其中$$x_w$$是当前内部节点的词向量,而 θ 则是我们需要从训练样本求出的逻辑回归的模型参数。 50 | 51 | 使用霍夫曼树有什么好处呢?首先,由于是二叉树,之前计算量为V,现在变成了log2V。第二,由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想。 52 | 53 | 容易理解,被划分为左子树而成为负类的概率为P(−)=1−P(+)。在某一个内部节点,要判断是沿左子树还是右子树走的标准就是看P(−),P(+)谁的概率值大。而控制P(−),P(+)谁的概率值大的因素一个是当前节点的词向量,另一个是当前节点的模型参数θ。 54 | 55 | 使用霍夫曼树来代替传统的神经网络,可以 **提高模型训练的效率**。但是如果我们的**训练样本里的中心词 $$w$$ 是一个很生僻的词,那么就得在霍夫曼树中辛苦的向下走很久了**。能不能不用搞这么复杂的一颗霍夫曼树,将模型变的更加简单呢? 56 | 57 | ## 四、Negative Sampling 58 | 59 | 有一个训练样本,中心词是w,它周围上下文共有2c个词,记为 context(w)。由于这个中心词w,的确和 context(w) 相关存在,因此它是一个真实的正例。通过 Negative Sampling 采样,我们得到 neg 个和 w 不同的中心词 wi,i=1,2,..neg,这样context(w)和 $$w_i$$ 就组成了 neg 个并不真实存在的负例。利用这一个正例和 neg 个负例,我们进行二元逻辑回归,得到负采样对应每个词 $$w_i$$ 对应的模型参数 $$\theta_i$$,和每个词的词向量。 60 | 61 | 从上面的描述可以看出,Negative Sampling 由于没有采用霍夫曼树,每次只是通过采样neg个不同的中心词做负例,就可以训练模型,因此整个过程要比 Hierarchical Softmax 简单。 62 | 63 | 讲到这里,那么自然需要解决两个问题:1)如何通过一个正例和 neg 个负例进行二元逻辑回归呢? 2) 如何进行负采样呢? 64 | 65 | ### 基于Negative Sampling的模型梯度计算 66 | 67 | Negative Sampling 也是采用了二元逻辑回归来求解模型参数,通过负采样,我们得到了neg 个负例 (context(w),wi);i=1,2,..neg。为了统一描述,我们将正例定义为 w0。 68 | 69 | 在逻辑回归中,我们的正例应该期望满足: 70 | 71 | $$P(context(w_0),w_i)=\sigma (x^T_{wi}θ^{wi}),y_i=1,i=0$$ 72 | 73 | 我们的负例期望满足: 74 | 75 | $$P(context(w_0),w_i)= 1−\sigma (x^T_iθ^{wi}),y_i=0,i=1,2,..,neg $$ 76 | 77 | 我们期望可以最大化下式: 78 | 79 | $$\prod_{i=0}^{neg} P(context(w_0),w_i) = \sigma (x^Tw_0 \theta ^{w0}) \prod _{i=1}^{neg}(1−\sigma (x^Tw_i \theta ^{wi}))$$ 80 | 81 | 我们容易写出此时模型的似然函数为: 82 | 83 | $$\prod_{i=0}^{neg} \sigma (x^Tw_i \theta ^{wi})^{yi}(1−\sigma (x^Tw_i \theta ^{wi}))^{1−y_i}$$ 84 | 85 | 此时对应的对数似然函数为: 86 | 87 | $$L= \sum _{i=0} ^{neg} yi log(\sigma (x^Tw_i \theta ^{wi}))+(1−y_i) log(1−\sigma (x^Tw_i \theta ^{wi}))$$ 88 | 89 | 和 Hierarchical Softmax 类似,我们采用随机梯度上升法,仅仅每次只用一个样本更新梯度,来进行迭代更新得到我们需要的 $$x_{wi},θ^{wi},i= 0,1,..neg$$ , 这里我们需要求出 $$x_{wi},θ^{wi},i=0,1,..neg$$ 的梯度。 90 | 91 | 首先我们计算 $$θ^{wi}$$ 的梯度: 92 | 93 | $$ \frac{\partial L}{\partial θ^{wi}} = y_i(1− \sigma (x^T_{wi} θ^{wi}))x_{wi} −(1−y_i) \sigma (x^T_{wi} \theta ^{wi})x_{wi}=(y_i− \sigma (x^T_{wi}θ^{wi}))x_{wi}$$ 94 | 95 | 同样的方法,我们可以求出xwi的梯度如下: 96 | 97 | $$\frac{\partial L}{\partial x_{wi}} =(y_i− \sigma (x^T_{wi} θ^{wi})) \theta ^{wi}$$ 98 | 99 | 有了梯度表达式,我们就可以用梯度上升法进行迭代来一步步的求解我们需要的 $$x_{wi},θ^{wi},i= 0,1,..neg$$ 。 100 | 101 | ### Negative Sampling负采样方法 102 | 103 | 现在我们来看看如何进行负采样,得到 neg 个负例。word2vec 采样的方法并不复杂,如果词汇表的大小为 V,那么我们就将一段长度为 1 的线段分成 V 份,每份对应词汇表中的一个词。当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短。每个词 w的线段长度由下式决定: 104 | 105 | $$len(w)= \frac {count(w)}{\sum _{u \in vocab} count(u)}$$ 106 | 107 | 在word2vec中,分子和分母都取了3/4次幂如下: 108 | 109 | $$len(w)= \frac {count(w)^{3/4}}{\sum _{u \in vocab} count(u)^{3/4}}$$ 110 | 111 | 在采样前,我们将这段长度为1的线段划分成M等份,这里M >> V,这样可以保证每个词对应的线段都会划分成对应的小块。而M份中的每一份都会落在某一个词对应的线段上。在采样的时候,我们只需要从 M 个位置中采样出 neg 个位置就行,此时采样到的每一个位置对应到的线段所属的词就是我们的负例词。 112 | 113 | ![avater](./pic/ns.png) 114 | 115 | 在word2vec中,M 取值默认为$$10^8$$。 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /主题模型 -- LSI & LDA.md: -------------------------------------------------------------------------------- 1 | # 主题模型 -- LSI & LDA 2 | 3 | 聚类算法关注于从样本特征的相似度方面将数据聚类。比如通过数据样本之间的欧式距离,曼哈顿距离的大小聚类等。而主题模型,顾名思义,就是对文字中隐含主题的一种建模方法。比如从“人民的名义”和“达康书记”这两个词我们很容易发现对应的文本有很大的主题相关度,但是如果通过词特征来聚类的话则很难找出,因为聚类方法不能考虑到到隐含的主题这一块。 4 | 5 | 那么主题聚类是怎样进行呢?假设以一定的概率选择了一个主题,然后以一定的概率选择当前主题的词。最后这些词组成了我们当前的文本。所有词的统计概率分布可以从语料库获得,具体如何以“一定的概率选择”,这就是各种具体的主题模型算法的任务了。 6 | 7 | 当然还有一些不是基于统计的方法,比如我们下面讲到的LSI。 8 | 9 | ## LSI 10 | 11 | $$A_{m×n} ≈ U_{m×k} Σ _{k×k} V^T_{k×n}$$ 12 | 13 | 如果把上式用到我们的主题模型,则 SVD 可以这样解释:我们输入的有 m 个文本,每个文本有n 个词。而 $$A_{ij}$$ 则对应第 i 个文本的第 j 个词的特征值,这里最常用的是基于预处理后的标准化 TF-IDF 值。k 是我们假设的主题数,一般要比文本数少。SVD 分解后,$$U_{il}$$ 对应第 i 个文本和第 l 个主题的相关度。$$V_{jm}$$ 对应第 j 个词和第 m 个词义的相关度。$$Σ_{lm}$$对应第 l 个主题和第 m 个词义的相关度。 14 | 15 | $$U, Σ, V$$ 对应的关系:文本 <---> 主题 <---> 词义 <---> 词 16 | 17 | 也可以反过来解释:我们输入的有 m 个词,对应 n 个文本。而 $$A_{ij}$$ 则对应第i个词档的第 j 个文本的特征值,这里最常用的是基于预处理后的标准化 TF-IDF 值。k 是我们假设的主题数,一般要比文本数少。SVD分解后,$$U_{il}$$ 对应第 i 个词和第 l 个词义的相关度。$$V_{jm}$$ 对应第 j 个文本和第 m 个主题的相关度。$$Σ_{lm}$$ 对应第 l 个词义和第 m 个主题的相关度。 18 | 19 | 这样我们通过一次SVD,就可以得到文档和主题的相关度,词和词义的相关度以及词义和主题的相关度。 20 | 21 | ### LSI 的使用 22 | 23 | 已有三篇文档: 24 | 25 | - d1: Shipment of gold damaged in a fire. 26 | - d2: Delivery of silver arrived in a silver truck. 27 | - d3: Shipment of gold arrived in a truck. 28 | 29 | 构建词库和文档矩阵: 30 | 31 | ![avater](./pic/lsi-a.png) 32 | 33 | 进行矩阵分解:$$A = U*S*V^T$$ 34 | ![avater](./pic/svd.png) 35 | 36 | 选取top2大的奇异值 37 | 38 | ![avater](./pic/LSI-K.png) 39 | 40 | 得到三篇文档的向量表达: 41 | 42 | - $$d1:[-0.4945,0.6492]$$ 43 | - $$d2:[-0.6458,-0.7194]$$ 44 | - $$d3:[-0.5817,0.2469]$$ 45 | 46 | 使用公式 $$q = q^T*U_k*S_k^{-1}$$ 计算查询语句的向量表达: 47 | ![avater](./pic/cal-q.png) 48 | 49 | 计算查询向量和三篇文档的相似度 50 | ![avater](./pic/cossim.png) 51 | 52 | ### LSI 总结 53 | 54 | LSI是最早出现的主题模型了,它的算法原理很简单,一次奇异值分解就可以得到主题模型,同时解决词义的问题,非常漂亮。但是LSI有很多不足,导致它在当前实际的主题模型中已基本不再使用。 55 | 56 | 主要的问题有: 57 | 58 | 1. SVD计算非常的耗时,尤其是我们的文本处理,词和文本数都是非常大的,对于这样的高维度矩阵做奇异值分解是非常难的。 59 | 2. 主题值的选取对结果的影响非常大,很难选择合适的k值。 60 | 3. LSI得到的不是一个概率模型,缺乏统计基础,结果难以直观的解释。 61 | 62 | 对于问题1,主题模型非负矩阵分解(NMF)可以解决矩阵分解的速度问题。对于问题2,这是老大难了,大部分主题模型的主题的个数选取一般都是凭经验的,较新的层次狄利克雷过程(HDP)可以自动选择主题个数。对于问题3,牛人们整出了pLSI(也叫pLSA)和隐含狄利克雷分布(LDA)这类基于概率分布的主题模型来替代基于矩阵分解的主题模型。 63 | 64 | 回到LSI本身,对于一些规模较小的问题,如果想快速粗粒度的找出一些主题分布的关系,则LSI是比较好的一个选择,其他时候,如果你需要使用主题模型,推荐使用LDA和HDP。 -------------------------------------------------------------------------------- /损失函数总结.md: -------------------------------------------------------------------------------- 1 | # 损失函数总结 2 | 3 | ## 对数似然函数 4 | 5 | 在逻辑斯蒂回归模型中使用对数似然函数估计模型参数,假设 $$P(Y=1|x)=\pi(x)$$,$$P(Y=0|x)=1-\pi(x)$$,似然函数为: 6 | 7 | $$\prod_{i=1}^N[\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i}$$ 8 | 9 | 对数似然函数为: 10 | 11 | $$L(w)=\sum_{i=1}^N[y_ilog\pi(x_i) + (1-y_i)log(1-\pi(x_i))]$$ 12 | 13 | $$=\sum_{i=1}^N[y_i(w.x_i) - log(1+exp(w.x_i))]$$ 14 | 15 | 也就是$$-\frac{1}{N} \sum _{i=1}^N(y_i*log (t_i) + (1-y_i)*log(1-t_i))$$,这种写法只当标签 $$y \in \{0,1\}$$ 时成立;当标签为$$y \in \{-1,1\}$$ 时,对数损失函数应该写成 $$-\frac{1}{N} \sum _{i=1}^N log(1+exp(-y_i*t_i))$$ 16 | 17 | ## softamx cross entropy loss 18 | 19 | 在多分类任务中,经常使用 softamx 交叉熵损失函数,当任务为二分类是,退化为 logloss 对数损失函数。 20 | 21 | $$E(t,y)=−\sum _jt_jlog y_j$$ 22 | 23 | 其中,t 和 y 分别表示神经网络的目标标签和和神经网络的类别概率输出,对于多分类,我们的类别概率是使用 softmax 进行归一化的: 24 | 25 | $$y_j=softmax(z_j)= \frac{e^{zj}}{\sum_j e^{zj}}$$ 26 | 27 | 这个公式需要输入没有经过缩放变换的logits,还有就是使用本目标损失函数的时候不要在网络的最后一层使用 softmax 层或者激活函数,会导致结果不正确。 28 | 29 | ## Categorical Crossentropy 30 | 31 | 交叉熵损失函数是也是常用的一种损失函数,它表示预测值y与目标值t之间的距离。主要应用在互相排斥的分类任务中,公式为: 32 | 33 | $$H(y,t)=H_t(y)=−\sum _it_i log y_i$$ 34 | 35 | ## Binary Crossentropy 36 | 37 | 这个损失函数主要是用来计算预测值y与目标值t之间的 sigmoid 交叉熵,主要用来多分类任务中,但是这个分类任务不是互斥的,和上面的损失函数不同,这个对同一个输入可以输出多个标签。公式为: 38 | 39 | $$y−y∗t+log(1+exp(−y))$$ 40 | 41 | 为了防止溢出,我们进行如下变换: 42 | 43 | $$ max(y,0)−y∗t+log(1+exp(−abs(y)))$$ 44 | 45 | ## Weighted Crossentropy 46 | 47 | 主要用来计算神经元之间的权值的交叉熵损失函数,t表示目标标签,y表示输入的预测值。该损失函数和上一个损失函数很像,唯一一点不同的就是: 48 | 49 | 该损失函数允许对负误差或者正误差加权 来调整precision 和recall 50 | 51 | 一般的交叉损失函数为: 52 | 53 | $$t∗−log(sigmoid(y))+(1−t)∗−log(1−sigmoid(y))$$ 54 | 55 | 当我们乘上 pos_weight 之后的公式就变成: 56 | 57 | $$t∗−log(sigmoid(y))∗pos\_weight+(1−t)∗−log(1−sigmoid(y))$$ 58 | 59 | 为了避免溢出,我们将公式变为: 60 | 61 | $$(1−t)∗y+l∗(log(1+exp(−abs(y)))+max(−y,0))$$ 62 | 63 | 其中,l 表示: 64 | 65 | $$l=(1+(pos\_weight−1)∗t)$$ 66 | 67 | ## Mean Square Loss 68 | 69 | 这个损失函数就很常见了,t 表示目标值,y 表示预测值输出。公式为: 70 | 71 | $$MSE=\frac{1}{n} \sum_{i=1}^n(y_i−t_i)^2$$ 72 | 73 | ## Hinge Loss 74 | 75 | 在支持向量机中,模型的分离平面 $$w^*.x + b = 0$$,决策函数为 $$f(x)=sign(w^*.x + b)$$,目标函数如下: 76 | 77 | $$\sum_{i=1}^n[1-y_i(w^*.x_i + b)]_+ + \lambda ||w||^2$$ 78 | 79 | 使用的是合页损失函数,这个也是很常见的一个loss函数, t 表示目标值,y 表示预测值输出。公式为: 80 | 81 | $$\partial (y)=max(0, 1−t∗y)$$ 82 | 83 | 当实例点$$(x_i,y_i)$$被分类正确时,损失是 0,否则损失是 $$1-y_i(w^*.x_i + b)$$ 84 | 85 | ## Contrastive Loss 86 | 87 | 对比损失函数。这个损失函数主要用在Siamese network中,参见论文 [链接](http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf)。d 表示目标值,y 表示预测值输出。 88 | 89 | $$L=\frac{1}{2N}\sum _{n=1}^Nyd^2+(1−y)max(margin−d,0)^2$$ 90 | 91 | 其中 d 表示两个样本特征的欧氏距离 92 | 93 | $$d=||x_i−x_j||^2$$ -------------------------------------------------------------------------------- /推荐系统相关/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/推荐系统相关/.DS_Store -------------------------------------------------------------------------------- /推荐系统相关/A Guide to Singular Value Decomposition for Collaborative Filtering.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangle1218/my-learning-notes/214c8db0df35c4915b56f0cd596fc9151d2be9c3/推荐系统相关/A Guide to Singular Value Decomposition for Collaborative Filtering.pdf -------------------------------------------------------------------------------- /推荐系统相关/FM-FFM模型.md: -------------------------------------------------------------------------------- 1 | # FM&FFM模型 2 | 3 | ### 线性模型 4 | 5 | 早期点击率预估模型中,一般使用线性模型,它简单易解释,但是存在许多问题,比如它只考虑了每个特征对结果的单独影响,忽略了特征之间的组合对结果的影响。线性回归的形式如下: 6 | 7 | $$f(x) = \omega_0 + \omega_1x_1+\omega_2x_2+...+\omega_nx_n =\omega_0+\sum_{i=1}^n{\omega_ix_i}$$ 8 | 9 | ### 二项式模型 10 | 11 | 为了对组合特征进行建模,我们可以建立二项式模型,如下所示: 12 | 13 | $$f(x) = \omega_0 + \sum_{i=1}^n \omega_ix_i + \sum_{i=1}^{n-1}\sum_{j=i+1}^n \omega_{i,j}x_ix_j$$ 14 | 15 | 从上式可以看到,对于参数 $$\omega_{i}$$ 的训练,只要这个样本中对应的 $$x_i$$ 不为0,则可以完成一次训练,但是对于参数 $$\omega_{i,j}$$,则需要 $$x_i,x_j$$ 同时不为0,才可以训练一次,但是在数据稀疏的应用场景中,$$x_i,x_j$$ 同时不为0的样本比较稀少,这就导致参数 $$\omega_{i,j}$$ 非常难以训练,这样训练出来的参数也不准确。 16 | 17 | ## FM模型 18 | 19 | 为了解决上述数据稀疏引起的训练不足的问题,FM 模型的思想就是为每个特征维度 $$x_i$$ 引入一个辅助向量: 20 | 21 | $$V_i=(v_{i1},v_{i2},v_{i3},...,v_{ik})^T ∈ ℝ^k,i=1,2,3,...,n$$ 22 | 23 | 其中k为辅助变量的维度,依经验而定,一般而言,对于特征维度足够多的样本,k<8. 对于因子分解机FM来说,最大的特点是对于稀疏的数据具有很好的学习能力。 24 | 25 | ### FM参数求解 26 | 27 | 我们的目标是要求得以下交互矩阵 28 | 29 | $$W =(\omega_{i,j})_{n*n} \ \ i,j = 1,2,...,n$$ 30 | 31 | 引入隐变量: 32 | 33 | $$V = (v_{ij})_{n*k} = [V_1^T,V_2^T,...,V_n^T]^T; \ \ i=1,2,..,n \ ;\ j=1,2,..,k$$ 34 | 35 | 令 $$VV^T = W$$,如果可以先求得 $$V$$ ,则可以得到 $$W$$。理论研究表明:当 k 足够大时,对于任意对称正定的实矩阵 $$W ∈ ℝ^{n×n}$$,均存在实矩阵$$V ∈ ℝ^{n×k}$$,使得$$W=VV^T$$。理论分析中要求参数 k 足够的大,但在高度稀疏数据的场景中,由于 没有足够的样本,因此k通常取较小的值。事实上,对参数 k 的限制,在一定程度上可以提高模型的泛化能力。 36 | 37 | **参数个数**:$$1+n+nk$$ 38 | 39 | ***FM 模型***就是二项式模型加入隐变量之后可以写成如下形式: 40 | 41 | $$f(x) = \omega_0 + \sum_{i=1}^n \omega_ix_i + \sum_{i=1}^{n-1}\sum_{j=i+1}^n (V_i^TV_j)x_ix_j$$ 42 | 43 | 可以看出时间复杂度是$$O(kn^2)$$。但我们对上述式子的最后一项作变换后,可以得出一个$$O(kn)$$的时间复杂度表达式。 44 | 45 | $$ 46 | \sum_{i=1}^{n-1}\sum_{j=i+1}^n(V_i^TV_j)x_ix_j 47 | = \frac{1}{2}\left(\sum_{i=1}^n\sum_{j=1}^n(V_i^TV_j)x_ix_j-\sum_{i=1}^n(V_i^TV_i)x_ix_i\right)\\ 48 | =\frac{1}{2}\left(\sum_{i=1}^n\sum_{j=1}^n\sum_{l=1}^kv_{il}v_{jl}x_ix_j-\sum_{i=1}^n\sum_{l=1}^k v_{il}^2x_i^2\right)\\\ 49 | =\frac{1}{2}\sum_{l=1}^k\left(\sum_{i=1}^n(v_{il}x_i)\sum_{j=1}^n(v_{jl}x_j)-\sum_{i=1}^nv_{il}^2x_i^2\right)\\ 50 | =\frac{1}{2}\sum_{l=1}^k\left(\left(\sum_{i=1}^n(v_{il}x_i)\right)^2-\sum_{i=1}^nv_{il}^2x_i^2\right)\\ 51 | $$ 52 | 53 | 上述式子中的 $$\sum^n_{i=1}(v_{il}x_i)$$ 只需要计算一次就好,因此,可以看出上述模型的复杂度为 $$O(kn)$$。 54 | 55 | ![avater](../pic/fm.png) 56 | 57 | ### 训练时间复杂度 58 | 59 | 由上述式(15)可以得到: 60 | 61 | $$x_l \sum_{i=1,i≠l}^n v_{im}x_i = xl \sum_{i=1}^nv_{im}x_i−v_{lm}x^2_l$$ 62 | 63 | 对于上式中的前半部分 $$\sum ^n_{i=1}v_{im}x_i$$,对于每个样本只需要计算一次,所以时间复杂度为O(n),对于k个隐变量的维度分别计算一次,则复杂度为O(kn)。其它项的时间复杂度都小于这一项,因此,模型训练的时间复杂度为O(kn)。 64 | 65 | ## FFM 模型 66 | 67 | 在FM模型中,每一个特征会对应一个隐变量,但在FFM模型中,认为应该将特征分为多个field,每个特征对应每个field分别有一个隐变量。 68 | 69 | 举个例子,我们的样本有3种类型的字段:publisher, advertiser, gender,分别可以代表媒体,广告主或者是具体的商品,性别。其中publisher有5种数据,advertiser有10种数据,gender有男女2种,经过one-hot编码以后,每个样本有17个特征,其中只有3个特征非空。 70 | 71 | 如果使用FM模型,则17个特征,每个特征对应一个隐变量。 72 | 如果使用FFM模型,则17个特征,每个特征对应3个隐变量,即每个类型对应一个隐变量,具体而言,就是对应publisher, advertiser, gender三个 field 各有一个隐变量。 73 | 74 | **FFM 模型**定义如下: 75 | 76 | $$f(x)= \omega_0 + \sum_{i=1}^n \omega_ix_i+ \sum_{j1=1}^{n−1} \sum _{j2=i+1}^n(V^T_{j1,f2}V_{j2,f1})x_{j1}x_{j2}$$ 77 | 78 | 其中 $$j_1,j_2$$ 表示特征的索引。我们假设 $$j_1$$ 特征属于 $$f_1$$ 这个 field,$$j_2$$ 特征属于 $$f_2$$ 这个 field,则 $$V_{j1},f_2$$ 表示 $$j_1$$ 这个特征对应 $$f_2$$ ($$j_2$$ 所属的field)的隐变量,同时 $$V_{j2},f_1$$表示 $$j_2$$ 这个特征对应 $$f_1$$ ($$j_1$$ 所属的field)的隐变量。 79 | 80 | 事实上,在大多数情况下,**FFM模型只保留了二次项**,即: 81 | 82 | $$\phi (V,x)=\sum_{j1=1}^{n−1} \sum _{j2=i+1}^n(V^T_{j1,f2}V_{j2,f1})x_{j1}x_{j2}$$ 83 | 84 | ### 损失函数 85 | 86 | $$min \frac{λ}{2}||V||^2_2+ \sum_{i=1}^m log(1+exp(−y_i \phi(V,x)))$$ 87 | 88 | 上面加号的前面部分使用了 $$L2$$ 范式,后面部分是逻辑回归的损失函数。m表示样本的数量,yi表示训练样本的真实值(如是否点击的-1/1),$$ϕ(V,x)$$ 表示使用当前的 $$V$$ 代入式(18)计算得到的值。 89 | 90 | 注意,以上的损失函数适用于样本分布为 $$\{-1,1\}$$的情况。 91 | 92 | ### 关于初始参数的设定 93 | 94 | 文献1中如此建议: 95 | 96 | 1. $$\eta$$:没有具体的建议,用户根据经验指定即可,一般会取0.1,0.01,0.001。 97 | 2. $$V$$:在区间$$[0,1/\sqrt k]$$ 间的随机值,均匀分布即可。 98 | 3. $$G$$:设置为1,以避免 $$(G_{j1,f2})^{−\frac{1}{2}}_d$$ 出现很大的值,$$G$$为累积梯度平方。 99 | 100 | **时间复杂度**: $$O(kn^2)+1+2k+2k+2k=O(kn^2)$$ 101 | 102 | ## 模型优化 103 | 104 | ### 特征编码连续 105 | 106 | 如果特征的编码不连续,比如编码是有意义的,或者预留空间给之后的编码。如果直接使用最大编码值的作为参数数据尺寸,则会导致大量内存空间的浪费,因此有2种解决方案: 107 | 108 | (1)使用hashmap,而非数组。 109 | 110 | (2)将有意义的编码映射到一个连续的编码空间。 111 | 112 | 目前我们使用方式(1),理论上方式(2)的计算速度会更快。 113 | 114 | ### 一次项缺失的影响 115 | 116 | 正如上面式(18)所言,我们经常会忽略了一次项的影响,因此我们可以为每个样本加上一个辅助特征,这相特征的值恒为1,这相当于引入了一次项。 117 | 118 | 另一种更常规的方法是直接作为一次项的逻辑回归来作训练。 119 | 120 | ### 样本归一化 121 | 122 | 文献1还建议,将样本向量的长度归一化后,性能有少量的提升。 123 | $$R[i]=\frac{1}{||X||} $$ 124 | 125 | FFM默认是进行样本数据的归一化,即 为真;若此参数设置为假,很容易造成数据inf溢出,进而引起梯度计算的nan错误。因此,样本层面的数据是推荐进行归一化的。 126 | 127 | ### 特征归一化 128 | 129 | 某些特征(如购买个数)有可能很大,而一些类别参数则恒为1,这将导致不同特征最终对模型的影响相关很大,这很不合理。 130 | 131 | CTR/CVR模型采用了多种类型的源特征,包括数值型和 categorical 类型等。但是,categorical 类编码后的特征取值只有 0 或 1,较大的数值型特征会造成样本归一化后categorical 类生成特征的值非常小,没有区分性。例如,一条用户-商品记录,用户为 “男” 性,商品的销量是 5000 个(假设其它特征的值为零),那么归一化后征 “sex=male”(性别为男)的值略小于 0.0002,而 “volume”(销量)的值近似为 1。特征 “sex=male” 在这个样本中的作用几乎可以忽略不计,这是相当不合理的。因此,将源数值型特征的值归一化到 是非常必要的。 132 | 133 | ### 省略零值特征 134 | 135 | 从FFM模型的表达式可以看出,零值特征对模型完全没有贡献。包含零值特征的一次项和组合项均为零,对于训练模型参数或者目标值预估是没有作用的。因此,可以省去零值特征,提高FFM模型训练和预测的速度,这也是稀疏样本采用FFM的显著优势。 -------------------------------------------------------------------------------- /推荐系统相关/SVD应用于协同过滤.md: -------------------------------------------------------------------------------- 1 | # 推荐系统--SVD应用于协同过滤 2 | 3 | SVD 应用于协同过滤 4 | 5 | 协同过滤是一种从大量用户给出的兴趣爱好集合中预测用户的偏好和兴趣的技术。 它的**基本假设**是,对某个事物,人们过去喜欢那么将来也会喜欢。 协作过滤可以用于推荐系统,该推荐系统自动向用户建议他/她的首选产品。 6 | 7 | ### 问题定义 8 | 9 | 如果有 n 个用户和 m 个物品,已知有一些用户对某些物品进行过 1-5 分的评分,但是很多用户也不可能对大多数物品都有评分记录,因此我们可以构建出一个非常大的稀疏矩阵。假设这个矩阵为 $$V \in R^{n*m}$$ ,令 $$I_{ij}$$ 为用户 i 对物品 j 的评分,可以知道 $$I_{ij}$$ 的取值为 $$I \in \{0,1\}$$,这里假设有评分记录就为 1,否则为 0 。 10 | 11 | 我们使用矩阵 $$V$$ 作为协同过滤算法的训练数据,目的就是预测出那些 $$V_{i,j}=0$$ 的位置的值(也就是没有评分的缺失值)。令 $$A \in R^{n*m}$$ 作为包含所有或部分的确实投票数据的稀疏矩阵,作为真实值结果(ground-truth answer),令$$P \in R^{n*m}$$ 作为预测矩阵,令 $$J \in \{0,1\}^{n*m}$$ 作为矩阵 A 中元素值的指示函数;我们可以用 RMSE 指标来做训练损失函数: 12 | 13 | $$RMSE(P,A)=\sqrt{\frac{\sum_{i=1}^n \sum_{j=1}^m J_{ij}(A_{ij}-P_{ij})^2}{\sum_{i=1}^n \sum_{j=1}^m J_{ij}}}$$ 14 | 15 | 从上式可以看出,分母部分消除了评分矩阵 A 中评分数量多寡的影响。有了训练数据,那么测试数据怎么选取呢?根据 *Netflix Prize* 的做法,他们选取固定数量的用户在训练集数据以外的时间段对物品的最新评分作为测试集。在进行模型训练时,我们知道,历史数据越多越有利于参数的训练,因此对于那些在过去只进行少量评分次数的用户,或者新用户来说,预测他们的兴趣将是协同过滤的一大挑战。 16 | 17 | ## SVD 18 | 19 | 已知我们有矩阵 $$V$$,SVD 的目的在于寻找两个矩阵 $$U \in R^{f*n}$$ 和 $$M \in R^{f*m}$$ 分别代表用户特征矩阵和物品特征矩阵。预测函数 p 被用于预测 V 中的缺失值的值。假设 $$U_i$$ 表示用户 i 的特征向量,$$M_j$$ 表示物品 j 的特征向量,那么我们有 20 | 21 | $$V_{ij} = p(U_i,M_j)$$ 22 | 23 | 计算矩阵 U 和 M 可以使用 RMSE 来优化,使用以下公式来表示: 24 | 25 | $$E = \frac{1}{2}\sum_{i=1}^n \sum_{j=1}^m J_{ij}I_{ij}(V_{ij}-p(U_i,M_j))^2 + \frac{k_u}{2}\sum_{i=1}^n ||U_i||^2 + \frac{k_m}{2}\sum_{j=1}^m ||M_j||^2$$ 26 | 27 | $$k_u, k_m$$ 分别是用户和物品项的正则系数,可以看出上式的两部分正则项所起到的作何和上文讲的 RMSE 公式的作用是一致的,都是用来抑制评分矩阵中评分数量的多寡所带来的影响。 28 | 29 | 预测函数 p 一般使用特征向量的点积,因此有: 30 | 31 | $$ p(U_i,M_j) = U_i^TM_j$$ 32 | 33 | 然而在实际应用中,用户的实际评分 $$V_{ij} $$ 是有一个范围的 [a,b],比如电影评分只在区间 [1,5],因此对于预测函数 P 有以下形式来对预测值做修正: 34 | 35 | $$ 36 | (公式3-1)\ p(U_i,M_j)=\begin{cases} 37 | a,\quad \quad \quad \quad if\ U_i^TM_j<0\\ 38 | a + U_i^TM_j, \quad if\ 0<=U_i^TM_j<=b-a\\ 39 | b, \quad \quad \quad \quad if \ U_i^TM_j>b-a 40 | \end{cases} 41 | $$ 42 | 43 | 在这篇论文中只考虑了用户是否对物品进行了评分,而没有考虑评多少分;对于有评分数值的应用,预测函数在其他文献有另一种写法,加入使用向量 $$b_i$$ 表示电影 i 的评分相对于平均评分的偏差,向量 $$b_u$$ 表示用户 u 做出的评分相对于平均评分的偏差,将平均评分记做 $$\mu$$,则评分函数可以写成: 44 | 45 | $$p(U_i,M_j) = \mu + b_i + b_u + U_i^TM_j \ (公式3-2)$$ 46 | 47 | 加上偏差 b ,我的理解是,不同用户的心里评分标准是不同的。比如张三,他对所有影片的评分都在 1-3分之间,而李四对于所有电影的评分都在 3-5之间,也就是他们对电影的评分习惯和对电影的严苛挑刺程度是不同的,所以我们训练模型时应当去学习这种用户特性,在对未知测试数据进行预测时也要考虑这样的差异。 48 | 49 | 目标函数和负梯度形式: 50 | 51 | ![avater](../pic/svdobj.png) 52 | 53 | ### 训练算法(SVD 批量训练) 54 | 55 | ![avater](../pic/svdalg1.png) 56 | 57 | 在进行梯度下降训练时,我们需要对矩阵 U ,M 进行初始化,然后根据计算出的梯度来逐步更新矩阵中的元素(参数);那么怎么初始化呢?一种方式是随机初始化,但是这样会导致训练结果的不稳定,随机性太大。我们可以使用已有分数的平均值来初始化两个矩阵,如下: 58 | 59 | $$U_{ij},M_{ij} = \sqrt{\frac{\overline V -a}{f}} + n(r) \ \ for\ each\ i,j$$ 60 | 61 | 其中 a 是评分区间的下限,f 是 SVD 的维度,n(r) 是随机噪声,它服从均匀分布 [-r,r],r 设置一个较小的数就可以。如果没有随机噪声的话,那么在优化时,用户和物品的特征将会一直具有相同的梯度。 62 | 63 | 批量学习是 SVD 的标准方法,但是对于大规模的稀疏矩阵,计算的梯度将会具有很大的方差,需要较小的学习率来预防 divergence. 64 | 65 | ## SVD 变体 66 | 67 | ### 不完全增量学习 68 | 69 | 批量学习方法对于大规模数据训练缓慢,如果每次增加新的训练数据就去训练一次,可能就太花时间了,那么能不能不用从头开始的训练方式呢?我们可以使用增量学习来解决这个问题,即,在后期迭代模型时,我们只训练之前没参与训练的数据就行了。 70 | 71 | 例如,对于用户 i ,如果我们又有了他的新的评分数据,与该用户相关的变量如下: 72 | 73 | ![avater](../pic/svdincl.png) 74 | 75 | 可以看到,当 $$I_{ij}=0$$ 时,梯度 $$M_J$$ 等于 0 ,因此,那些用户 i 没有进行评分的物品向量的参数没有进行更新,也就是不需要重新学习,我们仅需要重新学习用户有过打分行为的物品的参数。 76 | 77 | ![avater](../pic/svdalg2.png) 78 | 79 | ### 完全增量学习 80 | 81 | ![avater](../pic/svdalg3.png) 82 | 83 | ### 带动量的批量学习 84 | 85 | 使用增量学习方式可以节省一些训练时间,另外我们也可以使用带动量的学习方式来加大学习率以加快训练速度。 86 | 87 | ![avater](../pic/svdalg4.png) 88 | 89 | ## SVD++ 90 | 91 | 在 SVD 中,预测函数 (公式3-2) 中,在预测用户 i 对商品 j 的评分时,只考虑了用户特征向量和商品特征向量,以及评分相对于平均分的偏置向量。在SVD++ 中,更进一步的多考虑了用户对其所有有过评分行为的商品的隐式反馈。预测函数 p 变为以下形式: 92 | 93 | $$p(U_i,M_j) = \mu + b_i + b_u + M_j^T (U_i + \frac{1}{\sqrt{|N_i|^2}}*\sum_{j\in N_i}y_j)$$ 94 | 95 | 这里的 $$N_i$$ 表示用户 i 行为记录(包括浏览的和评过分的商品集合)。$$y_j$$ 为隐藏的评价了物品 j 的个人喜好偏置。这里除以$$\sqrt{|N_i|^2}$$ 的目的是为了抑制用户的评分商品数量对模型的影响。 96 | 97 | $$y_j$$ 的更新公式为: 98 | 99 | $$y_j := y_j + \eta \{[\sum_{j\in M,i\in U}(p(U_i,M_j)-V_{ij})*q_i \frac{1}{\sqrt{|N_i|^2}}]-\lambda *y_j\}$$ 100 | 101 | SVD++ 中的代价函数就是将 SVD 的代价函数替换一下预测函数部分为上式就行了。 -------------------------------------------------------------------------------- /推荐系统相关/svdRec.py: -------------------------------------------------------------------------------- 1 | # -*- encoding:utf-8 -*- 2 | # author: wangle 3 | 4 | import numpy as np 5 | import random 6 | import time 7 | 8 | class SVD(object): 9 | """ 10 | implementation of SVD for CF 11 | Reference: 12 | A Guide to Singular Value Decomposition for Collaborative Filtering 13 | """ 14 | def __init__(self, epoch, eta, userNums, itemNums, ku=0.001, km=0.001, \ 15 | f=30,save_model=False): 16 | super(SVD, self).__init__() 17 | self.epoch = epoch 18 | self.userNums = userNums 19 | self.itemNums = itemNums 20 | self.eta = eta 21 | self.ku = ku 22 | self.km = km 23 | self.f = f 24 | self.save_model = save_model 25 | 26 | self.U = None 27 | self.M = None 28 | 29 | def fit(self, train, val=None): 30 | rateNums = train.shape[0] 31 | self.meanV = np.sum(train[:,2]) / rateNums 32 | initv = np.sqrt((self.meanV - 1) / self.f) 33 | self.U = initv + np.random.uniform(-0.01,0.01,(self.userNums+1,self.f)) 34 | self.M = initv + np.random.uniform(-0.01,0.01,(self.itemNums+1,self.f)) 35 | self.bu = np.zeros(self.userNums + 1) 36 | self.bi = np.zeros(self.itemNums + 1) 37 | 38 | start = time.time() 39 | for i in range(self.epoch): 40 | sumRmse = 0.0 41 | for sample in train: 42 | uid = sample[0] 43 | iid = sample[1] 44 | vij = float(sample[2]) 45 | # p(U_i,M_j) = mu + b_i + b_u + U_i^TM_j 46 | p = self.meanV + self.bu[uid] + self.bi[iid] + \ 47 | np.sum(self.U[uid] * self.M[iid]) 48 | error = vij - p 49 | sumRmse += error**2 50 | # 计算Ui,Mj的梯度 51 | deltaU = error * self.M[iid] - self.ku * self.U[uid] 52 | deltaM = error * self.U[uid] - self.km * self.M[iid] 53 | # 更新参数 54 | self.U[uid] += self.eta * deltaU 55 | self.M[iid] += self.eta * deltaM 56 | 57 | self.bu[uid] += self.eta * (error - self.ku * self.bu[uid]) 58 | self.bi[iid] += self.eta * (error - self.km * self.bi[iid]) 59 | 60 | trainRmse = np.sqrt(sumRmse/rateNums) 61 | 62 | if val.any(): 63 | _ , valRmse = self.evaluate(val) 64 | print("Epoch %d cost time %.4f, train RMSE: %.4f, validation RMSE: %.4f" % \ 65 | (i, time.time()-start, trainRmse, valRmse)) 66 | else: 67 | print("Epoch %d cost time %.4f, train RMSE: %.4f" % \ 68 | (i, time.time()-start, trainRmse)) 69 | 70 | if self.save_model: 71 | model = (self.meanV, self.bu, self.bi, self.U, self.M) 72 | pickle.dump(model, open(save_model + '/svcRecModel.pkl', 'wb')) 73 | 74 | 75 | def evaluate(self, val): 76 | loss = 0 77 | pred = [] 78 | for sample in val: 79 | uid = sample[0] 80 | iid = sample[1] 81 | if uid > self.userNums or iid > self.itemNums: 82 | continue 83 | 84 | predi = self.meanV + self.bu[uid] + self.bi[iid] \ 85 | + np.sum(self.U[uid] * self.M[iid]) 86 | if predi < 1: 87 | predi = 1 88 | elif predi > 5: 89 | predi = 5 90 | pred.append(predi) 91 | 92 | if val.shape[1] == 3: 93 | vij = sample[2] 94 | loss += (predi - vij)**2 95 | 96 | if val.shape[1] == 3: 97 | rmse = np.sqrt(loss/val.shape[0]) 98 | return pred, rmse 99 | 100 | return pred 101 | 102 | def predict(self,test): 103 | return self.evaluate(test) 104 | 105 | def test(): 106 | import pandas as pd 107 | data_path = 'ratings.dat' 108 | data = pd.read_csv(data_path, sep='::', header=None, \ 109 | names = ['user','item','rate','time'],engine='python') 110 | 111 | data = data.sample(frac=1) 112 | print(data.head()) 113 | 114 | del data['time'] 115 | trainNum = int(data.shape[0] * 0.8) 116 | train = data[:trainNum].values 117 | val = data[trainNum:].values 118 | 119 | userNums = data['user'].max() 120 | itemNums = data['item'].max() 121 | svd = SVD(35, 0.001, userNums, itemNums, f=50) 122 | svd.fit(train,val=val) 123 | 124 | if __name__ == '__main__': 125 | test() 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /推荐系统相关/svdppRec.py: -------------------------------------------------------------------------------- 1 | # -*- encoding:utf-8 -*- 2 | # author: wangle 3 | 4 | import numpy as np 5 | import random 6 | import time 7 | 8 | class SVDPP(object): 9 | """ 10 | implementation of SVD++ for CF 11 | """ 12 | def __init__(self, epoch, eta, userNums, itemNums, ku=0.001, km=0.001, \ 13 | f=30,save_model=False): 14 | super(SVDPP, self).__init__() 15 | self.epoch = epoch 16 | self.userNums = userNums 17 | self.itemNums = itemNums 18 | self.eta = eta 19 | self.ku = ku 20 | self.km = km 21 | self.f = f 22 | self.save_model = save_model 23 | 24 | self.U = None 25 | self.M = None 26 | 27 | def fit(self, train, val=None): 28 | # 构造每个用户有过评分行为字典 29 | self.Udict = {} 30 | for i in range(train.shape[0]): 31 | uid = train[i,0] 32 | iid = train[i,1] 33 | self.Udict.setdefault(uid,[]) 34 | self.Udict[uid].append(iid) 35 | 36 | rateNums = train.shape[0] 37 | self.meanV = np.sum(train[:,2]) / rateNums 38 | initv = np.sqrt((self.meanV - 1) / self.f) 39 | self.U = initv + np.random.uniform(-0.01,0.01,(self.userNums+1,self.f)) 40 | self.M = initv + np.random.uniform(-0.01,0.01,(self.itemNums+1,self.f)) 41 | self.bu = np.zeros(self.userNums + 1) 42 | self.bi = np.zeros(self.itemNums + 1) 43 | self.y = np.zeros((self.itemNums+1, self.f)) + 0.1 44 | 45 | start = time.time() 46 | for i in range(self.epoch): 47 | sumRmse = 0.0 48 | for sample in train: 49 | uid = sample[0] 50 | iid = sample[1] 51 | vij = float(sample[2]) 52 | 53 | sumYj, sqrt_Ni = self.get_Yi(uid) 54 | # p(U_i,M_j) = \mu + b_i + b_u + U_i^T (M_j + \frac{1}{\sqrt{|N_i|^2}}*\sum_{j\in N_i}y_j) 55 | p = self.meanV + self.bu[uid] + self.bi[iid] + \ 56 | np.sum(self.M[iid] * (self.U[uid] + sumYj)) 57 | 58 | error = vij - p 59 | sumRmse += error**2 60 | # 计算Ui,Mj的梯度 61 | deltaU = error * self.M[iid] - self.ku * self.U[uid] 62 | deltaM = error * (self.U[uid] + sumYj) - self.km * self.M[iid] 63 | # 更新参数 64 | self.U[uid] += self.eta * deltaU 65 | self.M[iid] += self.eta * deltaM 66 | 67 | self.bu[uid] += self.eta * (error - self.ku * self.bu[uid]) 68 | self.bi[iid] += self.eta * (error - self.km * self.bi[iid]) 69 | 70 | # for j in self.Udict[uid]: 71 | # self.y[j] += self.eta * (error * self.M[j]/sqrt_Ni - self.ku * self.y[j]) 72 | 73 | rating_list = self.Udict[uid] 74 | self.y[rating_list] += self.eta * (error * self.M[rating_list]/sqrt_Ni - \ 75 | self.ku * self.y[rating_list]) 76 | 77 | trainRmse = np.sqrt(sumRmse/rateNums) 78 | 79 | if val.any(): 80 | _ , valRmse = self.evaluate(val) 81 | print("Epoch %d cost time %.4f, train RMSE: %.4f, validation RMSE: %.4f" % \ 82 | (i, time.time()-start, trainRmse, valRmse)) 83 | else: 84 | print("Epoch %d cost time %.4f, train RMSE: %.4f" % \ 85 | (i, time.time()-start, trainRmse)) 86 | 87 | if self.save_model: 88 | model = (self.meanV, self.bu, self.bi, self.U, self.M) 89 | pickle.dump(model, open(save_model + '/svcRecModel.pkl', 'wb')) 90 | 91 | 92 | def evaluate(self, val): 93 | loss = 0 94 | pred = [] 95 | for sample in val: 96 | uid = sample[0] 97 | iid = sample[1] 98 | if uid > self.userNums or iid > self.itemNums: 99 | continue 100 | sumYj, _ = self.get_Yi(uid) 101 | predi = self.meanV + self.bu[uid] + self.bi[iid] \ 102 | + np.sum(self.M[iid] * (self.U[uid] + sumYj)) 103 | if predi < 1: 104 | predi = 1 105 | elif predi > 5: 106 | predi = 5 107 | pred.append(predi) 108 | 109 | if val.shape[1] == 3: 110 | vij = sample[2] 111 | loss += (predi - vij)**2 112 | 113 | if val.shape[1] == 3: 114 | rmse = np.sqrt(loss/val.shape[0]) 115 | return pred, rmse 116 | 117 | return pred 118 | 119 | def predict(self,test): 120 | 121 | return self.evaluate(test) 122 | 123 | # 计算 sqrt_Ni 和 ∑yj 124 | def get_Yi(self,uid): 125 | Ni = self.Udict[uid] 126 | numNi = len(Ni) 127 | sqrt_Ni = np.sqrt(numNi) 128 | yj = np.zeros((1, self.f)) 129 | if numNi == 0: 130 | sumYj = yj + 0.1 131 | else: 132 | yj = np.mean(self.y[Ni],axis=0) 133 | sumYj = yj / sqrt_Ni 134 | return sumYj, sqrt_Ni 135 | 136 | def test(): 137 | import pandas as pd 138 | data_path = 'ratings.dat' 139 | data = pd.read_csv(data_path, sep='::', header=None, \ 140 | names = ['user','item','rate','time'],engine='python') 141 | 142 | data = data.sample(frac=1) 143 | print(data.head()) 144 | 145 | del data['time'] 146 | trainNum = int(data.shape[0] * 0.8) 147 | train = data[:trainNum].values 148 | val = data[trainNum:].values 149 | 150 | userNums = data['user'].max() 151 | itemNums = data['item'].max() 152 | svd = SVDPP(35, 0.001, userNums, itemNums, f=50) 153 | svd.fit(train,val=val) 154 | 155 | if __name__ == '__main__': 156 | test() 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /数据挖掘竞赛操作指南 -- 结构化数据篇.md: -------------------------------------------------------------------------------- 1 | # 数据挖掘竞赛操作指南 -- 结构化数据篇 2 | 3 | 结构化的数据是指可以使用关系型数据库表示和存储,表现为二维形式的数据。一般特点是:数据以行为单位,一行数据表示一个实体的信息,每一行数据的属性是相同的。举一个例子: 4 | 5 | ``` 6 | id name age gender 7 | 1 lyh 12 male 8 | 2 liangyh 13 female 9 | 3 liang 18 male 10 | ``` 11 | 各个平台举办的数据挖掘类竞赛中,大部分都是结构化数据,特别是早期;近年来随着自然语言处理和计算机视觉的兴起,非结构化数据类型的数据挖掘竞赛也越来越多。针对结构化数据挖掘竞赛,这里总结一下基本的竞赛操作指南。 12 | 13 | ## 1、数据探索分析 14 | 15 | 拿到数据,我们首先需要做的是对数据进行探索分析,从整体了解数据,把握数据。 16 | 17 | ### 分布分析 18 | 19 | 1. 定量数据:频率分析、频率分布表、直方图、茎叶图 20 | 2. 定性数据:饼图、条形图 21 | 22 | ### ①特征变量分析 23 | 24 | 分析*变量之间两两的分布和相关度*,可以用于发现高相关和共线性的特征。我们可以看看数据中各个特征的协方差矩阵和相似度矩阵: 25 | 26 | ```python 27 | data_df.cov() 28 | data_df.corr() 29 | ``` 30 | 31 | 协方差的值接近于 0 表明两个变量不具有(线性)关系。对于**数据探索,相关性比协方差更可取**。相关矩阵 R 的第 ij 个元素是数据的第 i 个和第 j 个属性之间的相关性。 32 | 33 | $$r_{ij} = correlation(x_i,x_j)= covariance(x_i,x_j)/s_is_j$$ 34 | 35 | 其中 $$s_i$$ 和 $$s_j$$ 分别是 $$x_i,x_j$$ 的方差。 36 | 37 | 线性相关性指标: 38 | 39 | - $$|r|<=0.3$$ 为不存在线性相关 40 | - $$0.3<|r|<=0.5$$ 为低度线性相关 41 | - $$0.5<|r|<=0.8$$ 为显著线性相关 42 | - $$|r|> 0.8$$ 为高度线性相关 43 | 44 | ### ②目标变量的分布 45 | 46 | - 目标变量为连续值(回归):查看其值域范围是否较大,如果较大,可以考虑对其进行对数变换,并以变换后的值作为新的目标变量进行建模(在这种情况下,需要对预测结果进行逆变换)。一般情况下,可以对连续变量进行Box-Cox变换。通过变换可以使得模型更好的优化,通常也会带来效果上的提升。 47 | - 目标变量为离散值(分类):如果数据分布不平衡,考虑是否需要上采样/下采样;如果目标变量在某个ID上面分布不平衡,在划分本地训练集和验证集的时候,需要考虑分层采样(Stratified Sampling) 48 | 49 | ### 统计量分析 50 | 51 | 用统计学指标对定量数据进行描述性分析,例如均值,中位数,众数;极差,标准差,四分位数间距等。 52 | 53 | 散布度量:极差和方差,这种度量表明属性值是否散布很宽,或者是否相对集中在单个点(如均值)附近。 54 | 55 | 给定一个属性x,它具有 m 个值 $${x1,x2,...,xm}$$,x 的极差定义为:$$range(x)=max(x)-min(x)$$。尽管极差标识最大散布,但是如果大部分值都集中在一个较小的范围内,并且更极端的值的个数相对较少,则可能会引起误解。因此,**作为散布的度量,方差和标准差更可取**。 56 | 57 | 使用 DataFrame 进行统计分析,如果是分类任务,我们可以看看每个类别下各个特征的分布有没有区别。 58 | 59 | ```python 60 | data_df[data_df['target']==0].describe() 61 | data_df[data_df['target']==1].describe() 62 | data_df[data_df['target']==2].describe() 63 | ``` 64 | 65 | ### 缺失值分析 66 | 67 | 缺失值产生的原因: 68 | 69 | 1. 有些信息暂时无法获取,或者获取信息的代价太大。 70 | 2. 有些信息是被遗漏的。可能是因为输入时认为不重要、忘记填写或对数据理解错误等一些人为因素而遗漏,也可能是由于数据采集设备的故障、存储介质的故障、传输媒体的故障等非人为原因而丢失。 71 | 3. 属性值不存在。在某些情况下,缺失值并不意味着数据有错误。对一些对象来说某些属性值是不存在的,如一个未婚者的配偶姓名、一个儿童的固定收入等。 72 | 73 | ### 异常值分析 74 | 75 | 异常可能由于测量、输入错误或系统运行错误而造成,也可能是由数据内在特性引起的,或异常行为所导致。异常值分析是检验数据是否含有不合理的数据。由于异常产生的机制是不确定的,因此,异常检测算法检测出的“异常”是否真正地对应为实际的异常行为,不是由异常检测算法来说明、解释的,只能由领域专家来解释。 76 | 77 | **异常值分析常用方法:** 78 | 79 | 1. 描述性统计分析 80 | 2. Z得分 81 | 3. 箱形图分析 82 | 83 | ### 可视化 84 | 85 | 为了总体的,更直观的观察数据的分布,我们可以使用可视化技术来分析数据。常用的工具有:`matplotlib,seaborn` 。 86 | 87 | 一些基本绘图操作: 88 | 89 | 1. 单变量 90 | 91 | 直方图:`plt.hist(x, bins=10)`。 92 | 93 | Kdeplot:`sns.kdeplot(x,shade=True)`。 94 | 95 | Distplot:`sns.distplot(x, bins=20, kde=False, rug=True)`,通过观察bin来对数据进行切分并做one-hot编码形成新的特征。 96 | 97 | 2. 双变量 98 | 99 | Scatterplot:`plt.scatter(df['x'].values,df['y'].values)`,当数据比较多的时候,建议采样观察,不然真的很耗时.通过Scatterplot我们可以很容易的发现一些数据的分布规律,是否有簇的存在等等,在涉及类似于经纬度的问题时,我们经常会通过scatterplot看数据,然后考虑聚类等操作. 100 | 101 | Jointplot:`sns.jointplot(x="x", y="y", data=df)`;Hexbin绘图和KDE绘图,这两个绘图大致可以更加直观的炫酷的看出数据的一个分布情况(例如hex图,越白的地方数据就越少,基本都没有数据在那里)。`sns.jointplot(x="x", y="y", data=df,kind ='hex' )` 102 | 103 | ![avater](./pic/Jointplot.png) 104 | 105 | pairplot: 该函数会同时绘制数据中所有特征两两之间的关系图.因为pairplot是建立在pairgrid之上,所以可以将中间的很多函数进行变换,例如下面的kde的例子. 106 | 107 | ``` 108 | iris = sns.load_dataset("iris") 109 | sns.pairplot(iris); 110 | ``` 111 | 112 | ![avater](./pic/pairplot.png) 113 | 114 | 对于分类数据而言,由于我们可以用颜色或者标记去区别不同的类,所以我们的坐标轴可以全部用于属性的表示,比如说在这里我们可以用一个二维图来表示每个样本对应的两个属性的分布 115 | 116 | ```python 117 | from matplotlib import pyplot as plt 118 | plt.plot(data_df[data_df['target']==0]['petal length (cm)'],data_df[data_df['target']==0]['petal width (cm)'],'r*',label='0') 119 | plt.plot(data_df[data_df['target']==1]['petal length (cm)'],data_df[data_df['target']==1]['petal width (cm)'],'ro',label='1') 120 | plt.plot(data_df[data_df['target']==2]['petal length (cm)'],data_df[data_df['target']==2]['petal width (cm)'],'bx',label='2') 121 | plt.xlabel('petal length (cm)') 122 | plt.ylabel('petal width (cm)') 123 | plt.legend(loc='best') 124 | plt.grid() 125 | plt.show() 126 | ``` 127 | 128 | ![avater](./pic/dmkehishua1.png) 129 | 130 | 使用直方图可以观察并比较每个类别的各项属性的分布,通过箱形图我们则可以比较不同类别的各项属性的分布及集中程度。 131 | 132 | ```python 133 | from matplotlib import pyplot as plt 134 | plt.hist(data_df[data_df['target']==0]['petal length (cm)'],color='blue',label='Class 0',alpha=0.5,bins=20) 135 | plt.hist(data_df[data_df['target']==1]['petal length (cm)'],color='red',label='Class 1',alpha=0.5,bins=20) 136 | plt.hist(data_df[data_df['target']==2]['petal length (cm)'],color='green',label='Class 2',alpha=0.5,bins=20) 137 | plt.legend(loc='best') 138 | plt.grid() 139 | plt.show() 140 | data_df.boxplot(by='target',layout=(2,2)) 141 | plt.show() 142 | ``` 143 | 144 | ![avater](./pic/dmkehishua2.png) 145 | ![avater](./pic/dmkehishua3.png) 146 | 147 | 使用热力图分析各个特征的相关性: 148 | 149 | 150 | ### 时间序列数据分析 151 | 152 | - 绘图查看时序是否出现断层,中间是有一段时间没有记录;序列是否存在较大的波动,是否存在冲突。 153 | - 序列是否存在周期性,序列最近变现出什么趋势。 154 | 155 | 时间序列的几大模式: 156 | 157 | - 趋势:明显的长期增长或下降(线性或者震荡) 158 | - 季节性:如年份、每周、季节性 159 | - 循环性:指数据不以固定的频率展现出上升以及下降趋势 160 | 161 | **自相关性** 162 | 163 | 在时间序列里存在一些自相关稀疏,例如 r1 可以用来评估 y1 和 y2 之间的关系,计算公式如下: 164 | 165 | $$r_k = \frac{\sum_{t=k+1}^T (y_t-\overline y)(y_{t-k}-\overline y)}{\sum_{t=1}^T (y_t-\overline y)^2}$$ 166 | 167 | T 为时间序列长度。 168 | 169 | ![avater](./pic/times.png) 170 | 171 | 从上图可以看到: 172 | 173 | 1. r4相对比较大,可能是因为周期为4的原因 174 | 2. r2 相对较小,可能是因为周期为 4 ,而 2 恰好在峰值之后的中间 175 | 3. 蓝色的虚线表示相关性是否和 0 严格不同 176 | 177 | 季节性和趋势给自相关带来的影响: 178 | 179 | 1. 当数据是季节性的(周期性),自相关稀疏会在季节性的位置(lag = k,2k,3k,..)获得较大的值;如果我们的时间序列以 k 为周期的话,那么我们的 rk 会较大; 180 | 2. 当数据存在趋势,则对于小的 lag(如1,2)的自相关系数就会变得较大,但是当把 lag 设置大一点的时候,就会得到缓解。 181 | 182 | **白噪音** 183 | 184 | 当时间序列没有显示自相关性是,我们称这种时间序列为白噪音。 185 | 186 | ![avater](./pic/whitenoise.png) 187 | 188 | ## 2、数据清洗 189 | 190 | 数据清洗工作包括数据转换、数据离散化、数据缺失替换和数据异常点处理等。 191 | 192 | ### 数据转换 193 | 194 | 1. 光滑: 195 | 2. 聚集: 196 | 3. 数据泛化: 197 | 4. 规范化: 198 | 5. 属性构造: 199 | 200 | 数据去重` pd.drop_duplicates()` 201 | 202 | ### 特征缺失值的处理 203 | 204 | - 特征值为连续值:按不同的分布类型对缺失值进行补全:偏正态分布,使用均值代替,可以保持数据的均值;偏长尾分布,使用中值代替,避免受 outlier 的影响; 205 | - 特征值为离散值:使用众数代替。 206 | 207 | 另外可以对只有少数缺失值的特征进行插值填充,或者使用贝叶斯公式、回归、决策树推断出缺失的数据(最常用)。缺点是,数据可能并不正确。 208 | 209 | ### 异常样本的处理 210 | 211 | 异常数据容易对数据集造成噪声,对于噪声数据,我们可以: 212 | 213 | 1. 分箱:箱均值平滑、箱中值平滑、箱边界平滑;应用场景:噪声数据不能删除,使用其他数据替换噪声数据 214 | 2. 聚类:应用场景:找出离群点(去除数据) 215 | 216 | ## 3、数据集划分 217 | 218 | ## 3、特征工程 219 | 220 | 特征工程依赖于前面的数据探索分析,也依赖于专业业务知识。 221 | 222 | ### ①连续值特征 223 | 224 | - 如果为长尾分布并且考虑使用线性模型,可以对变量进行幂变换或者对数变换。 225 | - 离散化,这样让特征更加鲁棒性。 226 | - 特征之间进行“加减乘除”之类的特征组合。 227 | 228 | ### ②离散值 ID 类特征 229 | 230 | - 观察每个离散值的频率分布,对于频次较低的特征,可以考虑统一编码为“其他”类别。 231 | - 对于单值离散特征,可以考虑 one-hot 编码,`LabelEncoder,OneHotEncoder`。 232 | - 对于多值离散特征可以考虑使用 bag-of-word,或者采用嵌入式词向量,比如一个有先后行为顺序的点击流特征,我们可以将特征按照时间先后顺序排序,然后进行词向量训练得到 embedding 表达,最后使用所以特征取值的 embedding 平均值做特征。 233 | - 对于单值离散特征可以将其进行两两或者多个之间组合,进行组合特征的交叉统计转化率。 234 | 235 | 对于取值较多的类别特征,可以进行一下处理: 236 | 237 | - 统计每个取值在样本中出现的频率,取 Top N 的取值进行 One-hot 编码,剩下的类别分到“其他“类目下,其中 N 需要根据模型效果进行调优; 238 | - 统计每个 ID 特征的一些统计量(譬如历史平均点击率,历史平均浏览率)等代替该 ID 取值作为特征。 239 | 240 | ### ③时间序列特征 241 | 242 | 很多数据挖掘任务重通常需要对时间相关的数据进行分析,然后对之后某段时间的某个目标值进行预测。对于预测的质量,它依赖于以下一些因素: 243 | 244 | - 因素如何影响我们的结果; 245 | - 我们拥有多少数据; 246 | - 我们的预测是否会影响我们预测的结果。 247 | 248 | 构造特征权重随时间的衰减机制,时间越久之前的行为对现在的影响越小;同时可以利用随时间移动的特征变化差值反映用户行为的变化趋势。 249 | 250 | - 滑动窗口时间段内的各个特征的统计特征。 251 | - 一阶、二阶差分特征 252 | 253 | 254 | ### ④特征选择 255 | 256 | 好的特征选择能够提升模型的性能,更能帮助我们理解数据的特点、底层结构,这对进一步改善模型、算法都有着重要作用。 257 | 258 | 特征选择主要有两个功能: 259 | 260 | 1. 减少特征数量、降维,使模型泛化能力更强,减少过拟合 261 | 2. 增强对特征和特征值之间的理解 262 | 263 | **①去掉取值变化小的特征** 264 | 265 | 假设某特征的特征值只有0和1,并且在所有输入样本中,95%的实例的该特征取值都是1,那就可以认为这个特征作用不大。如果100%都是1,那这个特征就没意义了。当特征值都是离散型变量的时候这种方法才能用,如果是连续型变量,就需要将连续变量离散化之后才能用。 266 | 267 | **②单变量特征选择** 268 | 269 | 对于分类任务可以使用卡方检验、信息熵等技术判断该特征对分类是否有贡献;对于回顾任务,可以检查该特征和目标变量之间的皮尔逊相关系数等,相关性较低就可以丢掉。 270 | 271 | 把互信息直接用于特征选择其实不是太方便:1、它不属于度量方式,也没有办法归一化,在不同数据及上的结果无法做比较;2、对于连续变量的计算不是很方便(X和Y都是集合,x,y都是离散的取值),通常变量需要先离散化,而互信息的结果对离散化的方式很敏感。 272 | 273 | 最大信息系数克服了这两个问题。它首先寻找一种最优的离散化方式,然后把互信息取值转换成一种度量方式,取值区间在[0,1]。 minepy 提供了MIC功能。 274 | 275 | 反过头来看y=x^2这个例子,MIC算出来的互信息值为1(最大的取值)。 276 | 277 | ```python 278 | from minepy import MINE 279 | m = MINE() 280 | x = np.random.uniform(-1, 1, 10000) 281 | m.compute_score(x, x**2) 282 | print m.mic() 283 | ``` 284 | 285 | 皮尔森相关系数是一种最简单的,能帮助理解特征和响应变量之间关系的方法,该方法衡量的是变量之间的线性相关性,结果的取值区间为[-1,1],-1表示完全的负相关(这个变量下降,那个就会上升),+1表示完全的正相关,0表示没有线性相关。 286 | 287 | Pearson Correlation 速度快、易于计算,经常在拿到数据(经过清洗和特征提取之后的)之后第一时间就执行。Scipy的 pearsonr 方法能够同时计算相关系数和 p-value,p-value 较小说明相关性越大。 288 | 289 | ```python 290 | import numpy as np 291 | from scipy.stats import pearsonr 292 | np.random.seed(0) 293 | size = 300 294 | x = np.random.normal(0, 1, size) 295 | print "Lower noise", pearsonr(x, x + np.random.normal(0, 1, size)) 296 | print "Higher noise", pearsonr(x, x + np.random.normal(0, 10, size)) 297 | ``` 298 | Pearson相关系数的一个明显缺陷是,作为特征排序机制,他只对线性关系敏感。如果关系是非线性的,即便两个变量具有一一对应的关系,Pearson相关性也可能会接近0,比如 x 和 x^2,皮尔逊相关性接近0. 299 | 300 | **③基于学习模型的特征排序 wrapper** 301 | 302 | 直接使用你要用的机器学习算法,针对每个单独的特征和响应变量建立预测模型。其实Pearson相关系数等价于线性回归里的标准化回归系数。假如某个特征和响应变量之间的关系是非线性的,可以用基于树的方法(决策树、随机森林)、或者扩展的线性模型等。基于树的方法比较易于使用,因为他们对非线性关系的建模比较好,并且不需要太多的调试。但要注意过拟合问题,因此树的深度最好不要太大,再就是运用交叉验证。 303 | 304 | ```python 305 | from sklearn.cross_validation import cross_val_score, ShuffleSplit 306 | from sklearn.datasets import load_boston 307 | from sklearn.ensemble import RandomForestRegressor 308 | 309 | #Load boston housing dataset as an example 310 | boston = load_boston() 311 | X = boston["data"] 312 | Y = boston["target"] 313 | names = boston["feature_names"] 314 | 315 | rf = RandomForestRegressor(n_estimators=20, max_depth=4) 316 | scores = [] 317 | for i in range(X.shape[1]): 318 | score = cross_val_score(rf, X[:, i:i+1], Y, scoring="r2", 319 | cv=ShuffleSplit(len(X), 3, .3)) 320 | scores.append((round(np.mean(score), 3), names[i])) 321 | print sorted(scores, reverse=True) 322 | ``` 323 | 输出特征重要性的分:[(0.636, ‘LSTAT’), (0.59, ‘RM’), (0.472, ‘NOX’), (0.369, ‘INDUS’), (0.311, ‘PTRATIO’), (0.24, ‘TAX’), (0.24, ‘CRIM’), (0.185, ‘RAD’), (0.16, ‘ZN’), (0.087, ‘B’), (0.062, ‘DIS’), (0.036, ‘CHAS’), (0.027, ‘AGE’)] 324 | 325 | **④ 线性模型和正则化 wrapper** 326 | 327 | 下面将介绍如何用回归模型的系数来选择特征。越是重要的特征在模型中对应的系数就会越大,而跟输出变量越是无关的特征对应的系数就会越接近于0。在噪音不多的数据上,或者是数据量远远大于特征数的数据上,如果特征之间相对来说是比较独立的,那么即便是运用最简单的线性回归模型也一样能取得非常好的效果。 328 | 329 | ```python 330 | from sklearn.linear_model import LinearRegression 331 | import numpy as np 332 | np.random.seed(0) 333 | size = 5000 334 | #A dataset with 3 features 335 | X = np.random.normal(0, 1, (size, 3)) 336 | #Y = X0 + 2*X1 + noise 337 | Y = X[:,0] + 2*X[:,1] + np.random.normal(0, 2, size) 338 | lr = LinearRegression() 339 | lr.fit(X, Y) 340 | #A helper method for pretty-printing linear models 341 | def pretty_print_linear(coefs, names = None, sort = False): 342 | if names == None: 343 | names = ["X%s" % x for x in range(len(coefs))] 344 | lst = zip(coefs, names) 345 | if sort: 346 | lst = sorted(lst, key = lambda x:-np.abs(x[0])) 347 | return " + ".join("%s * %s" % (round(coef, 3), name) 348 | for coef, name in lst) 349 | print "Linear model:", pretty_print_linear(lr.coef_) 350 | ``` 351 | 352 | 在很多实际的数据当中,往往存在多个互相关联的特征,这时候模型就会变得不稳定,数据中细微的变化就可能导致模型的巨大变化(模型的变化本质上是系数,或者叫参数,可以理解成W),这会让模型的预测变得困难,这种现象也称为多重共线性。例如,假设我们有个数据集,它的真实模型应该是Y=X1+X2,当我们观察的时候,发现Y’=X1+X2+e,e是噪音。如果X1和X2之间存在线性关系,例如X1约等于X2,这个时候由于噪音e的存在,我们学到的模型可能就不是Y=X1+X2了,有可能是Y=2X1,或者Y=-X1+3X2。 353 | 354 | 355 | 356 | ## 4、模型选择 357 | 358 | 359 | 360 | ## 6、模型集成 -------------------------------------------------------------------------------- /文本分类 -- HAN 模型.md: -------------------------------------------------------------------------------- 1 | # 文本分类 -- HAN 模型 2 | 3 | Hierarchical Attention Network (HAN) that is designed to capture two basic insights about document structure. First, since documents have a hierarchical structure (words form sentences, sentences form a document), we likewise construct a document representation by first building representations of sentences and then aggregating those into 4 | a document representation. Second, it is observed that different words and sentences in a documents are differentially informative. Moreover, the importance of words and sentences are highly context dependent, 5 | i.e. the same word or sentence may be differentially important in different context . 6 | 7 | HAN 的设计是用来捕获文档的两种结构。由于文档具有层次性,文档包含句子,句子包含词;HAN 首先提取句子的表达特征,然后将其聚合成文档的表达特征。 8 | 9 | ![avater](./pic/HAN.png) 10 | 11 | HAN 关注 document-level 级别的文档分类,它使用双向 GRU 对句子进行编码,在词和句子两个层面都添加了注意力机制。 12 | 13 | ### document-level 14 | 15 | ![avater](./pic/word-A.png) 16 | 17 | 经过 GRU 编码后得到词的语义 $$h_{it}$$,然后将该语义通过一个 MLP 层,得到非线性转换后的语义$$u_{it}$$,然后通过$$u_{it}$$和 $$u_{w}$$ 的相似度计算词的重要性(相似性),经过 softmax 之后得到归一化的注意力权重 $$\alpha_{it}$$。词的上下文向量 $$u_{w}$$ 是随机初始化的,可以在训练中进行学习更新。 18 | 19 | 句子层面的编码和注意力机制类似。 20 | 21 | -------------------------------------------------------------------------------- /文本分类 -- 特征选择.md: -------------------------------------------------------------------------------- 1 | # 文本分类 -- 特征选择 2 | 3 | ## 1、TF-IDF 4 | $$TF$$ 称为词频, 用于计算该词描述文档内容的能力;$$IDF$$ 称为逆文档频率, 用于计算该词区分文档的能力。$$TF*IDF$$ 的指导思想建立在这样一条基本假设之上: 在一个文本中出现很多次的单词, 在另一个同类文本中出现次数也会很多, 反之亦然。所以如果特征空间坐标系取TF 词频作为测度, 就可以体现同类文本的特点。另外还要考虑单词区别不同类别的能力,$$TF*IDF$$ 法认为一个单词出现的文本频率越小, 它区别不同类别的能力就越大, 所以引入了逆文本频度$$IDF$$ 的概念, 以$$TF$$ 和$$IDF$$ 的乘积作为特征空间坐标系的取值测度。 5 | 6 | ### 词频的计算 7 | 8 | - 词频(TF) = 某个词在文章中的出现次数 9 | 10 | 由于文章有长短之分,为了便于不同文章的比较,需要做"词频"标准化。 11 | 12 | - 词频(TF) = 某个词在文章中的出现次数 / 文章总词数 13 | 14 | - 词频(TF) = 某个词在文章中的出现次数 / 拥有最高词频的词的次数 15 | 16 | ### 逆文档频率 17 | 18 | - 逆文档频率(IDF) = log(语料库的文档总数/包含该词的文档总数+1) 19 | 20 | 分母加 1 的原因在于确保分母不为0. 21 | 22 | TF-IDF算法中并没有体现出单词的位置信息,对于Web文档而言,权重的计算方法应该体现出HTML的结构特征。特征词在不同的标记符中对文章内容的反映程度不同,其权重的计算方法也应不同。因此应该对于处于网页不同位置的特征词分别赋予不同的系数,然后乘以特征词的词频,以提高文本表示的效果。 23 | 24 | ## 词频 25 | 26 | 词频是一个词在文档中出现的次数。通过词频进行特征选择就是将词频小于某一阈值的词删除,从而降低特征空间的维数。这个方法是基于这样一个假设,即出现频率小的词对过滤的影响也较小。但是在信息检索的研究中认为,有时频率小的词含有更多的信息。因此,在特征选择的过程中不宜简单地根据词频大幅度删词。 27 | 28 | ## 文档频数 29 | 30 | 文档频数(Document Frequency, DF)是最为简单的一种特征选择算法,它指的是在整个数据集中有多少个文本包含这个单词。在训练文本集中对每个特征计一算它的文档频次,并且根据预先设定的阑值去除那些文档频次特别低和特别高的特征。文档频次通过在训练文档数量中计算线性近似复杂度来衡量巨大的文档集,计算复杂度较低,能够适用于任何语料,因此是特征降维的常用方法。在训练文本集中对每个特征计算它的文档频数,若该项的DF 值小于某个阈值则将其删除,若其DF 值大于某个阈值也将其去掉。因为他们分别代表了“没有代表性”和“没有区分度”两种极端的情况。DF 特征选取使稀有词要么不含有用信息,要么太少而不足以对分类产生影响,要么是噪音,所以可删去。DF 的优点在于计算量小, 速度快,它的时间复杂度和文本数量成线性关系,所以非常适合于超大规模文本数据集的特征选择。不仅如此,文档频数还非常地高效,在有监督的特征选择应用中当删除90%单词的时候其性能与信息增益和x2 统计的性能还不相上下。但如果某一稀有词条主要出现在某类训练集中,却能很好地反映类别的特征,而因低于某个设定的阈值而滤除掉,包含着重要的判断信息被舍弃,这样就会对分类精度有一定的影响。 31 | 32 | ## 卡方检验 33 | 34 | 卡方检验 $$\chi ^2 test$$,是一种常用的特征选择方法,尤其是在生物和金融领域。$$\chi ^2 test$$ 用来描述两个事件的独立性或者说描述实际观察值与期望值的偏离程度。$$\chi ^2$$值越大,则表明实际观察值与期望值偏离越大,也说明两个事件的相互独立性越弱。 35 | 36 | ![avater](./pic/x2.png) 37 | 38 | ### 例子 39 | 40 | 现在有一个生物学问题,我们需要从采样的5个基因 gene1,…,gene4 中找到某种疾病的1个致病基因。下表我们分别统计了患病和不患病人群5种基因的出现频率。当我们把一种基因看做一种特征的时候,找到致病基因就可以看做是选择一种特征使得患病-不患病的二分类问题准确率最高。 41 | 42 | || gene1 |gene2|gene3 | gene4| 43 | |--- | --- | --- |--- |--- | 44 | |患病 | 0.73 | 0.24| 0.21| 0.54| 45 | |不患病|0.71| 0.26 | 0.87 | 0.55| 46 | 47 | 首先,我们**做出假设 “患病与gene_x无关”** 48 | 49 | ``` 50 | 以gene1为例,分布比较稳定,\chi ^2 值应该比较小,即两事件相互独立性比较强,即假设成立。 51 | 再以gene3为例,分布偏差很大,\chi ^2 值应该很大,即两事件相互独立性很弱,即假设不成立,因此最后我们选择gene3作为致病基因。 52 | ``` 53 | 接下来我们讲怎样具体地计算 $$\chi ^2$$ 值。 54 | 55 | 先直接上公式: 56 | 57 | $$X^2(t,c) = 58 | \sum_{e_t \in { 0,1 } } 59 | \sum_{e_c \in { 0,1 } } 60 | \frac{(N_{e_t e_c}-E_{e_t e_c})^2}{E_{e_t e_c}}$$ 61 | 62 | 其中$$t$$,即某个特征有或无,$$c$$ ,即类别1或0(这里只支持2分类)。$$N$$ 是观察值, $$E$$ 是期望值。则 $$E_{11}$$ 表示出现特征 $$t$$ 且类别 $$c=1$$。 63 | 64 | 现在,我们以第一节中的 gene3 为例,来计算$$\chi ^2$$值,当然按照公式我们首先应该计算各种期望和观测值。首先,我们来虚构一个完整的患病-基因数据集。假如我们记录了10个人的gene3出现情况,得到类似于下面的表格: 65 | 66 | |样本编号|gene3是否出现|是否患病| 67 | |---|---|---| 68 | |1 |1 |0| 69 | |2 |1| 0| 70 | |3 |1 |1| 71 | 4 |1|0| 72 | 5|1| 0| 73 | 6| 0| 1| 74 | 7| 1| 0| 75 | 8| 0| 1| 76 | 9| 1| 0| 77 | 10| 0| 1| 78 | 79 | 据此我们可以很容易的计算所有的观测值以及期望值。 80 | 81 | 首先是观测值 82 | 83 | $$N_{11} = 患病且出现gene3的人数=1$$ 84 | 85 | $$N_{01} = 患病且不出现gene3的人数=3$$ 86 | 87 | $$N_{10} = 不患病出现gene3的人数=6$$ 88 | 89 | $$N_{00} = 不患病不出现gene3的人数=0$$ 90 | 91 | 然后是期望值:(因为我们的假设是 t 和 c 独立,因此可以直接按照下式计算) 92 | 93 | $$E_{11} = 10\times P(t=1)\times P(c=1)=2.8$$ 94 | 95 | $$N_{01} = 10\times P(t=0)\times P(c=1)=1.2$$ 96 | 97 | $$N_{10} = 10\times P(t=1)\times P(c=0)=4.2$$ 98 | 99 | $$N_{00} = 10\times P(t=0)\times P(c=0)=1.8$$ 100 | 101 | 代入公式有: 102 | 103 | $$X^2(t,c) = \frac{(1-2.8)^2}{2.8} + \frac{(3-1.2)^2}{1.2} + \frac{(6-4.2)^2}{4.2} + \frac{(0-1.8)^2}{1.8} = 6.4286 $$ 104 | 105 | 我们已经得到了$$\chi ^2$$ 值,但是这并不够直接明了的说明问题。因此,我们还需要将 $$\chi ^2$$值转化为 p-value。p-value是一种给定原假设为真时样本结果出现的概率,我们可以通过简单查表来进行转化。如下表:自由度=1时的转化表格。(自由度=分类数-1,因此这里自由度=1.) 106 | 107 | |p-value| $$\chi ^2$$| 108 | |---|---| 109 | |0.1 |2.71| 110 | |0.05| 3.84| 111 | |0.01| 6.63| 112 | |0.005| 7.88| 113 | |0.001 |10.83| 114 | 115 | 我们的$$\chi^2$$值为 6.4286,转化为p-value约为 0.01,意思是假设患病和gene3无关的情况下,只有约 0.01 的概率会出现这样的样本结果。因此,我们就有约 0.99 的概率认为原假设错误,则 gene3 与患病有关。 116 | 117 | ## 互信息 118 | 119 | 互信息是用来评价一个事件的出现对于另一个事件的出现所贡献的信息量,具体的计算公式为: 120 | 121 | ![avater](./pic/mi.png) 122 | 123 | 其中U、C 代表两个事件,e 的取值可以为 0 或者 1,1 代表出现这个事件,0 代表不出现。 124 | 125 | 把上述公式拆解为统计形式为: 126 | 127 | ![avater](./pic/mi2.png) 128 | 129 | 其中$$N_{11}$$是表示全部数据中两个事件同时出现的概率,N 表示全部事件出现的次数,而$$N_{0.}$$则表示 $$N_{01}+N_{00}$$。 130 | 131 | 实际做单特征选择的时候,我们把某个特征是否出现和分类是否正确这两个事件放在一起计算。把得分较高的特征进行保留。 132 | 133 | 需要注意的是计算时会遇到四种情况也就是,10,11,01,00,对于其中的某一种情况,当计算得到的值是0 时,代表了两者没有关联,当计算出的值是正值时,表示两者共同出现的概率比较高,当值为负时,表示两者是负相关。例如:00 情况是负值是,表示两者互相排斥,出现A时,B出现的概率就比较小,这个时候往往01情况和10情况的值为正(check) 134 | 135 | **卡方检验对于出现次数较少的特征更容易给出高分。例如某一个特征就出现过一次在分类正确的数据中,则该特征会得到相对高的分数,而互信息则给分较低。其主要原因还是由于互信息在外部乘上了一个该类型出现的概率值,从而打压了出现较少特征的分数。** -------------------------------------------------------------------------------- /文本相似度--BM25.md: -------------------------------------------------------------------------------- 1 | # 文本相似度--BM25 2 | 3 | BM25算法是一种常见用来做相关度打分的公式,思路比较简单,主要就是计算一个query里面所有词q1,q2,...,qn 和文档的相关度,然后再把分数做累加操作。公式如下: 4 | 5 | $$Score(Q,d)= \sum_i^n Wi*R(q_i,d)$$ 6 | 7 | 其中 $$R(q_i,d)$$ 是查询语句 query 中每个词 qi 和文档 d 的相关度值,$$W_i$$ 是该词的权重。 8 | 9 | Wi 一般情况下为IDF(InverseDocumentFrequency)值,即逆向文档频率。 10 | 11 | $$R(qi,d)$$ 公式如下: 12 | 13 | $$R(qi,d)=\frac{f_i*(k_1+1)}{f_i+K} * \frac{qf_i*(k_2+1)}{qf_i+k_2}$$ 14 | 15 | $$K=k1⋅(1−b+b* \frac{dl}{avgdl})$$ 16 | 17 | 其中 $$k_1,k_2,b$$ 都是调节因子,一般 $$k_1=1,k_2=1,b=0.75$$。 18 | 19 | 式中 $$qf_i$$为词 $$q_i$$ 在查询语句 query 中的出现频率,$$f_i$$ 为 $$q_i$$ 在文档 $$d$$ 中的出现频率。由于绝大多数情况下一条简短的查询语句 query 中,词 $$q_i$$ 只会出现一次,即 $$qf_i=1$$。 20 | 21 | dl 为文档 d 的长度,avgdl 为所有文档的平均长度。意即该文档d的长度和平均长度比越大,则K 越大,则相关度 $$R(q_i,d)$$ 越小,b 为调节因子,b 越大,则文档长度所占的影响因素越大,反之则越小。 22 | 23 | ``` 24 | 例子: 25 | query:诸葛亮在哪里去世的? 26 | document1:诸葛亮在五丈原积劳成疾,最终去世; 27 | document2:司马懿与诸葛亮多次在五丈原交锋; 28 | document3:为一整本中国历史书的内容。 29 | 30 | 显然document3中肯定包含了大量[诸葛亮]、[哪里]、[去世]这些词语,可是由于document3 31 | 文档长度太大,所以K非常大,所以和 query 中每个词 qi 的相关度 R(qi,d) 非常小。 32 | ``` 33 | 综上所述,可将BM25相关度打分算法的公式整理为: 34 | 35 | $$Score(Q,d)=\sum_i^n IDF(q_i)* \frac{f_i*(k_1+1)}{f_i+k_1*(1−b +b* \frac{dl}{avgdl})}$$ 36 | 37 | 38 | ## BM25优缺点 39 | 40 | 适用于:在文档包含查询词的情况下,或者说查询词精确命中文档的前提下,如何计算相似度,如何对内容进行排序。 41 | 42 | 不适用于:基于传统检索模型的方法会存在一个固有缺陷,就是检索模型只能处理 Query 与 Document 有重合词的情况,传统检索模型无法处理词语的语义相关性。 43 | 44 | 也就是 BM25 算法只能计算 字面 相似度,而不能计算语义之间的相似度。 -------------------------------------------------------------------------------- /文本自动摘要 -- 抽取式算法.md: -------------------------------------------------------------------------------- 1 | # 文本自动摘要 -- 抽取式算法 2 | 3 | 自动提取文档摘要的算法,主流方法分为两类:Extractive 抽取式、Abstractive 概要式。抽取式摘要是指从原始文档集中抽取一些具有代表性的文本片段构成摘要,这些片段可以是整个文档中的句子、子句、段落或者小节。 4 | 5 | 抽取式方法有两个问题,如何对文本单元排序打分;如何抽取文本单元的一个子集生成摘要。分别对应着排序单元和抽取单元。 6 | 7 | 通俗讲就是,先用排序单元把文档中的单元进行重要性排序,选择排名靠前的单元,再用抽取单元去除选出来的单元之间的冗余信息,得到最后的自动摘要。 8 | 9 | 目前主要方法有: 10 | 11 | - 基于统计:统计词频,位置等信息,计算句子权值,再简选取权值高的句子作为文摘,特点:简单易用,但对词句的使用大多仅停留在表面信息。 12 | - 基于图模型:构建拓扑结构图,对词句进行排序。例如,TextRank/LexRank 13 | - 基于潜在语义:使用主题模型,挖掘词句隐藏信息。例如,采用LDA,HMM 14 | - 基于整数规划:将文摘问题转为整数线性规划,求全局最优解。 15 | 16 | ## ILP(基于整数规划) 17 | 18 | ILP 是一种常用的用来抽取摘要的算法,它能够尽可能的去除冗余。假设有: 19 | 20 | - 排序单元(句子或概念)$$x_i$$; 21 | - 排序函数 $$f(x_i)$$; 22 | - 抽取单元 $$u_j$$,即句子,$$||u_j||$$ 便是 $$u_j$$ 中单词的个数; 23 | - 指示变量 $$z_j^x$$,表明排序单元 $$x_i$$ 是否出现在摘要中; 24 | - 指示变量 $$z_j^u$$,表示抽取单元 $$u_j$$ 是否包含在摘要中; 25 | - 二元常量 $$I(i,j)$$,表示 $$x_i$$ 是否狐仙在 $$u_j$$ 中; 26 | - $$L$$ 表示摘要长度限制; 27 | - $$sim(x_i,x_j)$$ 用来处理冗余的相似性度量; 28 | - $$\delta $$ 表示冗余阈值 29 | 30 | 那么我们可以使用以下式子来进行整数规划运算,进行抽取摘要: 31 | 32 | $$ 33 | max \Bigg\{ \sum_i f(x_i) * z_j^x \Bigg\}\\ 34 | s.t \ \sum_j z_j^u *|u_j| \leq L \\ 35 | \sum_j z_j^u * I(i,j) \geq z_i^x ,\ 对任意 i \\ 36 | (z_i^x+ z_j^x) *sim(x_i, x_j) < \delta \ 对任意 \ i,j \\ 37 | z_i^x, z_j^u \in \{0,1\}, \ 对任意 \ i,j 38 | $$ 39 | 40 | 上式中第一个公式约束摘要的长度;第二个公式是一致性约束,它保证如果摘要包含排序单元 $$x_i$$ 则该摘要必须包含至少一个函数 $$x_i$$ 的抽取单元;第三个约束考虑冗余去除,如果排序单元是句子,则 $$sim(x_i,x_j)$$ 表示句子之间的相似度,此时该约束表示如果两个句子的相似度大于 $$\frac{\delta }{2}$$ ,则他们不能同时出现在摘要中,如果排序单元是概念,则相似度公式为: 41 | 42 | $$sim(x_i,x_j) = \begin{cases} 43 | 1, \quad x_i = x_j\\ 44 | 0, \quad otherwise 45 | \end{cases} $$ 46 | 47 | 求解上面的整数规划,我们就可以得到哪些句子是需要抽取出来,组成摘要的。 48 | 49 | ## TextRank 50 | 51 | ### TextRank 提取关键词 52 | 53 | TextRank 算法源于 PageRank 算法,可以用来丛关键词提取,也可以用来做文本的自动摘要。TextRank 思想非常简单:通过词之间的相邻关系构建网络,然后用 PageRank 迭代计算每个节点的rank值,排序rank值即可得到关键词。PageRank本来是用来解决网页排名的问题,网页之间的链接关系即为图的边,迭代计算公式如下: 54 | 55 | $$PR(V_i) = (1-d)+d* \sum _{j \in In(V_i)} \frac{1}{|Out(V_j)|} PR(V_j)$$ 56 | 57 | 其中,$$PR(V_i)$$ 表示结点 $$V_i$$ 的 rank 值,$$In(V_i)$$ 表示结点 $$V_i$$ 的前驱结点集合,$$Out(V_j)$$ 表示结点 $$V_j$$ 的后继结点集合,d 为阻尼因子,用于做平滑,取值范围为 0 到 1, 代表从图中某一特定点指向其他任意点的概率, 一般取值为 0.85。 58 | 59 | 那么怎么把一个句子(可以看作词的序列)构建成图呢?TextRank将某一个词与其前面的N个词、以及后面的N个词均具有图相邻关系(类似于N-gram语法模型)。具体实现:设置一个长度为N的滑动窗口,所有在这个窗口之内的词都视作词结点的相邻结点;则TextRank构建的词图为无向图。下图给出了由一个文档构建的词图(去掉了停用词并按词性做了筛选): 60 | 61 | ![avater](./pic/textrank1.png) 62 | 63 | 考虑到不同词对可能有不同的共现(co-occurrence),TextRank将共现作为无向图边的权值。那么,TextRank的迭代计算公式如下: 64 | 65 | $$WS(V_i) = (1-d)+d* \sum _{j \in In(V_i)} \frac{1}{|Out(V_j)|} WS(V_j)$$ 66 | 67 | **若原文本中存在若干个关键词相邻的情况,那么这些关键词可以构成一个关键短语**。 例如,在一篇介绍 “支持向量机” 的文章中,可以找到三个关键词支持、向量、机,通过关键短语提取,可以得到支持向量机。 68 | 69 | ### TextRank 提取摘要 70 | 71 | 构建图 $$G =(V,E)$$,其中 $$V$$ 为句子集,$$E$$ 为边集。将每个句子看成图中的一个节点,若两个句子之间有相似性,认为对应的两个节点之间有一个无向有权边,权值是相似度。采用如下公式进行计算句子的相似性: 72 | 73 | $$Similarity(S_i,S_j) = \frac{\{w_k| (w_k \in S_i) \bigcap ( w_k \in S_j)\}}{log(|S_i|) + log(||S_j)}$$ 74 | 75 | 也就是将两个句子的共有词的个数除以两个句子的对数和,可以看到这种相似度计算方法**只考虑了句子的字面相似度**。若两个句子之间的相似度大于给定的阈值,就认为这两个句子语义相关并将它们连接起来。 76 | 77 | 迭代公式和计算关键词的迭代公式一样。经过迭代之后,得到句子重要性的排序列表,然后直接将排在前 k 个句子按原来的顺序输出就得到摘要了,可以看到原始的 TextRank 算法并没有考虑对摘要进行冗余信息去重。 78 | 79 | ## TextTeaser 80 | 81 | TextTeaser 摘要算法是属于基于统计的摘要算法。基本的统计指标有: 82 | 83 | 1. 句子长度,长度为某个长度的句子为最理想的长度,依照距离这个长度的远近来打分。 84 | 2. 句子位置,根据句子在全文中的位置,给出分数。(比如每段的第一句是核心句的比例大概是70%) 85 | 3. 句子是否包含标题词,根据句子中包含标题词的多少来打分。 86 | 4. 句子关键词打分,文本进行预处理之后,按照词频统计出排名前10的关键词,通过比较句子中包含关键词的情况,以及关键词分布的情况来打分。 87 | 88 | 综合上述3步的打分做累加,然后倒排得到每个句子的重要性得分,此时要考虑到摘要的可读性,通俗的做法是按照句子在文章中出现的顺序来输出。 89 | 90 | 排序之后的结果只考虑了相关性并没有考虑新颖性,非常有可能出现排名靠前的几句话表达的都是相似的意思。所以需要引入一个惩罚因子,将新颖性考虑进去。对所有的句子重新打分,如下公式: 91 | 92 | $$score(i) = a * score(i) + (1-a) * similarity(i,i-1), \ i = 2,3,…,N $$ 93 | 94 | 序号 i 表示排序后的顺序,从第二句开始,排第一的句子不需要重新计算,后面的句子必须被和前一句的相似度进行惩罚。 95 | 96 | 句子的相似性算法有很多,比如比较常用的BM25法算法。 97 | 98 | ## 总结 99 | 100 | 上面讲的摘要算法几乎都需要对句子进行相似度计算,但是由于这些算法提出的年代比较久远,因此在相似度计算方面都智能做到字面意思上的计算,只有使用基于 LDA 的算法才会考虑到浅层的语义相关性;现在拿过来重新使用的话,我们可以将词向量考虑进去,比如将句子表示成词向量的加权平均,加权可以使用词的 tf-idf 权重。 101 | 102 | 另外一方面将上述算法结合起来也不失为一个号方法。 103 | 104 | -------------------------------------------------------------------------------- /注意力机制 Attention Mechanism.md: -------------------------------------------------------------------------------- 1 | # 注意力机制 Attention Mechanism 2 | 3 | 本文介绍一下注意力机制在 NLP 中的应用。 4 | 5 | 注意力机制的直觉是:人类视觉通过快速扫描全局图像,获得需要重点关注的目标区域,也就是一般所说的注意力焦点,而后对这一区域投入更多注意力资源,以获取更多所需要关注目标的细节信息,而抑制其他无用信息。这是人类**利用有限的注意力资源从大量信息中快速筛选出高价值信息的手段**,是人类在长期进化中形成的一种生存机制,人类视觉注意力机制极大地提高了视觉信息处理的效率与准确性。 6 | 7 | ## Encoder-Decoder框架 8 | 9 | 许多注意力机制的应用都依附于 Encoder-Decoder 框架,因此首先了解一下 Encoder-Decoder框架也是必要的。当然注意力作为一种通用的思想,它并不仅仅依赖特定的框架。 10 | 11 | ![avater](./pic/ende.png) 12 | 13 | 如上图所示,该框架是文本处理领域常用的 Encoder-Decoder 框架,我们可以将左侧看做输入,右侧看做输出,输入输出都是句子,我们可以将他们表示为句子对 $$$$。那么神经网络是如何将 source 变为 target 呢?其实就是 Encoder-Decoder 的过程了,首先将输入进行编码(encoder),得到中间的语义编码,最后将语义编码进行解码(decoder)从而得到输出。Source和Target可以是同一种语言,也可以是两种不同的语言。而Source和Target分别由各自的单词序列构成,使用公式表示如下所示: 14 | 15 | $$source=$$ 16 | 17 | $$target = $$ 18 | 19 | 语义编码,将输出转化成中间语义表示 C: 20 | 21 | $$C = F(x_1,x_2,...,x_m)$$ 22 | 23 | 语义解码,将中间语义表示和历史信息 $$y_1,y_2,..,y_{i-1}$$ 来生成 i 时刻生成的单词 $$y_i$$: 24 | 25 | $$y_i = G(C,y_1,y_2,...,y_{i-1})$$ 26 | 27 | 每个yi都依次这么产生,那么看起来就是整个系统根据输入句子Source生成了目标句子Target。如果Source是中文句子,Target是英文句子,那么这就是解决机器翻译问题的Encoder-Decoder框架;如果Source是一篇文章,Target是概括性的几句描述语句,那么这是文本摘要的Encoder-Decoder框架;如果Source是一句问句,Target是一句回答,那么这是问答系统或者对话机器人的Encoder-Decoder框架。由此可见,在文本处理领域,Encoder-Decoder的应用领域相当广泛。 28 | 29 | 一般而言,文本处理和语音识别的Encoder部分通常采用RNN模型,图像处理的Encoder一般采用CNN模型。 30 | 31 | **然而,可以看到,在解码的时候,不管生成哪个时刻的 yi ,使用的都是相同的中间语义 C,显然这有缺陷的。比如在翻译模型中,将 “Tom chase Jerry” 进行翻译,Encoder-Decoder框架逐步生成中文单词:“汤姆”,“追逐”,“杰瑞” ,模型里面的每个英文单词对于翻译目标单词“杰瑞”贡献是相同的,很明显这里不太合理,显然 “Jerry” 对于翻译成 “杰瑞” 更重要,但是一般模型是无法体现这一点的。** 32 | 33 | ## Attention 模型 34 | 35 | ### Soft Attention模型 36 | 37 | 没有引入注意力的模型在输入句子比较短的时候问题不大,但是如果输入句子比较长,此时所有语义完全通过一个中间语义向量来表示,单词自身的信息已经消失,可想而知会丢失很多细节信息,这也是为何要引入注意力模型的重要原因。 38 | 39 | 在上节最后的例子中,如果引入Attention 机制的话,应该在翻译“杰瑞”的时候,体现出英文单词对于翻译当前中文单词不同的影响程度,比如给出类似下面一个概率分布值: 40 | 41 | (Tom,0.3)(Chase,0.2) (Jerry,0.5) 42 | 43 | 每个英文单词的概率代表了翻译当前单词“杰瑞”时,注意力分配模型分配给不同英文单词的注意力大小。这对于正确翻译目标语单词肯定是有帮助的,因为引入了新的信息。同理,目标句子中的每个单词都应该学会其对应的源语句子中单词的注意力分配概率信息。这意味着在生成每个单词 $$y_i$$ 的时候,原先都是相同的中间语义表示 C 会被替换成根据当前生成单词而不断变化的 $$C_i$$ 。理解 Attention 模型的关键就是这里,即由固定的中间语义表示 C 换成了根据当前输出单词来调整成加入注意力模型的变化的 $$C_i$$。增加了注意力模型的Encoder-Decoder框架理解起来如下图所示。 44 | 45 | ![avater](./pic/ende2.png) 46 | 47 | 加入注意力之后,生成目标句子单词的过程成了如下的形式: 48 | 49 | $$ 50 | \begin{align} 51 | y_1 &= f1(C_1) \\ 52 | y_2 &= f1(C_2,y_1) \\ 53 | y_1 &= f1(C_3,y_1,y_2) 54 | \end{align} 55 | $$ 56 | 57 | 每个中间语义表示 $$C_i$$ 对应着不同源语句子单词的注意力分配概率分布。 58 | 59 | ![avater](./pic/ende3.png) 60 | 61 | 其中,f2 函数代表 Encoder 对输入英文单词的某种变换函数,比如如果 Encoder 是用的RNN 模型的话,这个 f2 函数的结果往往是某个时刻输入 $$X_i$$ 后隐层节点的状态值;g 代表 Encoder 根据单词的中间表示合成整个句子中间语义表示的变换函数,一般的做法中,g函数就是对构成元素加权求和,即下列公式: 62 | 63 | $$C_i = \sum _{j=1}^{L_x} \alpha _{ij} h_j$$ 64 | 65 | 其中,$$L_x$$ 代表输入句子Source 的长度,$$\alpha _{ij}$$ 代表在 Target 输出第 i 个单词时 Source 输入句子中第 j 个单词的注意力分配系数,而 $$h_j$$ 则是Source 输入句子中第 j 个单词的语义编码。假设 $$C_i$$ 下标 i 就是上面例子所说的“ 汤姆” ,那么 $$L_x$$ 就是 3,h1=f(“Tom”),h2=f(“Chase”),h3=f(“Jerry”)分别是输入句子每个单词的语义编码,对应的注意力模型权值则分别是0.6,0.2,0.2,所以 g 函数本质上就是个**加权求和函数**。如果形象表示的话,翻译中文单词“汤姆”的时候,数学公式对应的中间语义表示 $$C_i$$ 的形成过程类似图4。 66 | 67 | ![avater](./pic/ende4.png) 68 | 69 | 那么,**生成目标句子某个单词,比如“汤姆”的时候,如何知道Attention模型所需要的输入句子单词注意力分配概率分布值呢?** 我们看看下图: 70 | 71 | ![avater](./pic/ende5.png) 72 | 73 | 对于采用 RNN 的 Decoder 来说,在时刻 i,如果要生成 yi 单词,我们是可以知道 Target在生成 $$y_i$$ 之前的时刻 i-1 时,隐层节点 i-1 时刻的输出值 $$H_{i-1}$$ 的,而我们的目的是要计算生成 $$y_i$$ 时输入句子中的单词 “Tom”、 “Chase”、 “Jerry” 对 $$y_i$$ 来说的注意力分配概率分布,那么可以用 Target 输出句子 i-1 时刻的隐层节点状态 $$H_{i-1}$$ 去一一和输入句子 Source 中每个单词对应的RNN隐层节点状态 hj 进行对比,即通过函数 $$F(h_j,H_{i-1})$$ 来获得目标单词 $$y_i$$ 和每个输入单词对应的对齐可能性,这个 $$F$$ 函数在不同论文里可能会采取不同的方法,然后函数 $$F$$ 的输出经过 Softmax 进行归一化就得到了符合概率分布取值区间的注意力分配概率分布数值。 74 | 75 | 绝大多数 Attention 模型都是采取上述的计算框架来计算注意力分配概率分布信息,区别只是在 $$F$$ 的定义上可能有所不同。 76 | 77 | **上述内容就是经典的 Soft Attention 模型的基本思想** 78 | 79 | ## Attention 机制的本质思想 80 | 81 | 如果把Attention机制从上文讲述例子中的Encoder-Decoder框架中剥离,并进一步做抽象,可以更容易看懂Attention机制的本质思想。 82 | 83 | ![avater](./pic/atten1.png) 84 | 85 | 如上图所示:将 Source 中的构成元素想象成是由一系列的 数据对构成,此时给定 Target 中的某个元素 Query,通过计算 Query 和各个 Key 的相似性或者相关性,得到每个 Key 对应 Value 的权重系数,然后对 Value 进行加权求和,即得到了最终的Attention 数值。所以本质上 Attention 机制是对 Source 中元素的 Value 值进行加权求和,而 Query 和 Key 用来计算对应 Value 的权重系数。即可以将其本质思想改写为如下公式: 86 | 87 | $$Attention(Query, Source)=\sum _{i=1}^{L_x} Similarity(Query,key_i)*Value_i $$ 88 | 89 | 其中,Lx = ||Source||代表 Source 的长度,公式含义即如上所述。上文所举的机器翻译的例子里,因为在计算Attention的过程中,Source 中的 Key 和 Value 合二为一,指向的是同一个东西,也即输入句子中每个单词对应的语义编码,所以可能不容易看出这种能够体现本质思想的结构。 90 | 91 | 当然,从概念上理解,把 Attention 仍然理解为从大量信息中有选择地筛选出少量重要信息并聚焦到这些重要信息上,忽略大多不重要的信息,这种思路仍然成立。聚焦的过程体现在权重系数的计算上,权重越大越聚焦于其对应的 Value 值上,即权重代表了信息的重要性,而Value是其对应的信息。 92 | 93 | 至于Attention机制的具体计算过程,如果对目前大多数方法进行抽象的话,可以将其归纳为两个过程:第一个过程是根据Query和Key计算权重系数,第二个过程根据权重系数对Value进行加权求和。而第一个过程又可以细分为两个阶段:第一个阶段根据Query和Key计算两者的相似性或者相关性;第二个阶段对第一阶段的原始分值进行归一化处理;这样,可以将Attention的计算过程抽象为如下图展示的三个阶段。 94 | 95 | ![avater,width = "100" height = "100"](./pic/atten2.png) 96 | 97 | 98 | 在第一个阶段,可以引入不同的函数和计算机制,根据 Query 和某个 $$key_i$$,计算两者的相似性或者相关性,最常见的方法包括:求两者的向量点积、求两者的向量Cosine相似性或者通过再引入额外的神经网络来求值,即如下方式: 99 | 100 | 点积:$$Similarity(Query,key_i) = Query \cdot key_i$$ 101 | 102 | 余弦相似性:$$Similarity(Query,key_i) = \frac{Query \cdot key_i}{||Query ||\cdot ||key_i||}$$ 103 | 104 | MLP 网络:$$Similarity(Query,key_i) = MLP(Query,key_i)$$ 105 | 106 | 第一阶段产生的分值根据具体产生的方法不同其数值取值范围也不一样,第二阶段引入类似SoftMax的计算方式对第一阶段的得分进行数值转换,一方面可以进行归一化,将原始计算分值整理成所有元素权重之和为1的概率分布;另一方面也可以通过SoftMax的内在机制更加突出重要元素的权重。即一般采用如下公式计算: 107 | 108 | $$\alpha _i = Softmax(Sim_i) = \frac{e^{Sim_i}}{\sum_{j=1} ^{L_x} e^{Sim_j}}$$ 109 | 110 | 第二阶段的计算结果 $$\alpha_i$$ 即为 $$Value_i$$ 对应的权重系数,然后进行加权求和即可得到 Attention 数值: 111 | 112 | $$Attention(Query, Source)=\sum _{i=1}^{L_x} \alpha_i \cdot Value_i$$ 113 | 114 | 通过如上三个阶段的计算,即可求出针对 Query 的 Attention 数值,目前绝大多数具体的注意力机制计算方法都符合上述的三阶段抽象计算过程。 115 | 116 | ### Self Attention 机制 117 | 118 | 通过上述对 Attention 本质思想的梳理,我们可以更容易理解本节介绍的 Self Attention模型。Self Attention 也经常被称为 intra Attention(内部Attention),最近一年也获得了比较广泛的使用,比如 Google 最新的机器翻译模型内部大量采用了 Self Attention 模型。 119 | 120 | 在一般任务的 Encoder-Decoder 框架中,输入 Source 和输出 Target 内容是不一样的,比如对于英-中机器翻译来说,Source 是英文句子,Target 是对应的翻译出的中文句子,Attention 机制发生在 Target 的元素 Query 和 Source 中的所有元素之间。而Self Attention 顾名思义,指的不是 Target 和 Source 之间的 Attention 机制,而是 Source 内部元素之间或者 Target 内部元素之间发生的 Attention 机制,也可以理解为 Target=Source 这种特殊情况下的注意力计算机制。其具体计算过程是一样的,只是计算对象发生了变化而已,所以此处不再赘述其计算过程细节。 121 | 122 | 如果是常规的 Target 不等于 Source 情形下的注意力计算,其物理含义正如上文所讲,比如对于机器翻译来说,本质上是目标语单词和源语单词之间的一种单词对齐机制。那么如果是 Self Attention 机制,一个很自然的问题是:通过 Self Attention 到底学到了哪些规律或者抽取出了哪些特征呢?或者说引入 Self Attention 有什么增益或者好处呢?我们仍然以机器翻译中的 Self Attention 来说明,下面两图是可视化地表示 Self Attention 在同一个英语句子内单词间产生的联系。 123 | 124 |
![avater,width = "100" height = "50"](./pic/atten4.png) 125 | 126 | ![avater,width = "100" height = "100"](./pic/atten5.png) 127 | 128 | 从两张图可以看出,Self Attention 可以捕获同一个句子中单词之间的一些句法特征(比如第一个图展示的有一定距离的短语结构)或者语义特征(比如图2展示的 its 的指代对象 Law)。 129 | 130 | 很明显,引入 Self Attention 后会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN 或者 LSTM,需要依次序序列计算,对于远距离的相互依赖的特征,要经过若干时间步步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。 131 | 132 | 但是 Self Attention 在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来,所以远距离依赖特征之间的距离被极大缩短,有利于有效地利用这些特征。除此外,Self Attention 对于增加计算的并行性也有直接帮助作用。这是为何 Self Attention 逐渐被广泛使用的主要原因。 133 | 134 | ## Tensorflow 中的 Attention 实现 135 | 136 | 137 | -------------------------------------------------------------------------------- /深度语义匹配模型系列 -- DLAS.md: -------------------------------------------------------------------------------- 1 | # 深度语义匹配模型系列 -- DLAS 2 | 3 | APPLYING DEEP LEARNING TO ANSWER SELECTION: A STUDY AND AN OPEN TASK 4 | 5 | 给定一个问题 q 和一些候选回答集合,目的是在回答集合里面挑选一个最合适的回答。如果挑选的回答 a 在正确的回答集合中,则认为是挑选对了,反之认为挑选错误;从这个定义来说,问答匹配可以认为是一个二分类问题。 6 | 7 | 训练时,每一个样本有一个问题 Q,一个正例回答 $$A^+$$ 和一个负例回答(错误回答) $$A^—$$, 深度学习框架提取问题和两个回答的向量表达:$$V_Q, V_{A^+}, V_{A^\_}$$ , 计算问题和两个回答的余弦相似度,然后比较两个相似度的 margin:$$cos(V_Q, V_{A^+})-cos(V_Q, V_{A^\_}) < m $$,当上式条件满足时,表示模型的所提取的向量表达使得正例在负例之下,表明需要更新参数;反之,不需要更新参数。损失函数定义如下: 8 | 9 | $$L = max\{0, m - cos(V_Q, V_{A^+}) + cos(V_Q, V_{A^\_})\} $$ 10 | 11 | 在预测时,我们计算问题和候选答案的余弦相似度 $$cos(V_Q, V_{candidate})$$,$$V_{candidate}$$ 的维度为500维,余弦相似度最大的候选答案被选为正确答案。 12 | 13 | ### 网络结构 14 | 15 | ![avater](./pic/DLAS.png) 16 | 17 | The hidden layer (HL) is defined as $$z = tanh(W x+B)$$. W is the weight matrix; $$B$$ is the bias vector; $$x$$ is input; $$z$$ is the output of the activation function $$tanh$$. The output then flows to the CNN layer $$CNN_Q$$, applied to extract question side features. $$P$$ is the MaxPooling layer (we always use 1-MaxPooling in this paper) and $$T$$ is the $$tanh$$ layer. 18 | 19 | ### 双层 CNN 结构 20 | 21 | ![avater](./pic/2cnn.png) 22 | ![avater](./pic/cnn-imple.png) 23 | ![avater](./pic/cnn-imple2.png) 24 | 25 | 表3中的相似性可以分为三类:基于L1范数的度量,其是Q的语义距离和从每个坐标轴求和的A; 基于L2范数的度量,是Q和A的直线语义距离; 测量Q和A之间角度的基于内积的度量。我们提出了两个新的度量,它们通过乘法(欧几里德距离和Sigmoid点积的GESD几何平均值)和加法(欧几里德和Sigmoid 点积的AESD算术平均值)组合L2范数和内积)。这两个指标是所有比较指标中最好的。最后,在表3的底部,很明显,使用更多过滤器,建议的度量标准可以实现更好的性能。 26 | 27 | ![avater](./pic/metric.png) 28 | 29 | 框架2好于框架1的原因在于使用共享的卷积层,可以提取 Q和A 中相对应位置的语义向量都是同一个卷积核所提取的,保证了两个用来计算相似度的语义向量是在同一个语义空间。 30 | 31 | -------------------------------------------------------------------------------- /深度语义匹配模型系列 -- DSSM.md: -------------------------------------------------------------------------------- 1 | # 深度语义匹配模型系列 -- DSSM系列 2 | 3 | Learning Deep Structured Semantic Models for Web Search using Clickthrough Data 4 | 5 | ### 1、DSSM 6 | 7 | ![avater](./pic/dssm_arch.png) 8 | 9 | - 输入的是一个 query 和这个query相关的 doc ,这里的输入特征可以是最简单的 one-hot ,而需要 train 的是这个query下各个doc的相关性( DSSM里面使用点击率来代替相关性)。 10 | - 文本以 one-hot 的方式编码作为输入,针对vocabulary 太大和 oov 问题,论文中做了 Word Hashinging 的操作。比如 good ,他可以写成 #good# ,然后按tri-grams来进行分解为 #go goo ood od# ,再将这个tri-grams灌入到 bag-of-word 中;3个字母的组合有限,容易枚举。 11 | - 忽略了文本的上下文信息和一词多意、多义词的情况。 12 | 13 | 相关性计算公式: 14 | 15 | $$P(D|Q) = \frac{exp(\gamma R(Q,D))}{\sum_{d_i \in D} exp(\gamma R(Q,D))}$$ 16 | 17 | 最终他需要优化的损失函数为: 18 | $$L(\Lambda) = - \text{log} \prod_{(Q,D^+)} P(D^+|Q)$$ 19 | 20 | $$D^+$$ 表示被点击的文档,这里就是最大化点击文档的相关性的最大似然。 21 | 22 | ### 2、CDSSM 23 | 24 | ![avater](./pic/cdssm_arch.png) 25 | 26 | CDSSM 保持了语句的局部有序性 27 | 28 | ### 3、DSSM-LSTM 29 | 30 | 既然是为了记录输入句子的上下文,这个无疑是 Lstm 这个模型更为擅长,因此又有了一种 Lstm 来构造的 DSSM 模型。 31 | 32 | ![avater](./pic/dssm_lstm_arch.png) 33 | 34 | 35 | -------------------------------------------------------------------------------- /深度语义匹配模型系列--ARC.md: -------------------------------------------------------------------------------- 1 | # 深度语义匹配模型系列 -- ARC 2 | Convolutional Neural Network Architectures for Matching Natural Language Sentences 3 | 4 | Baotian Hu, Zhengdong Lu, Hang Li, Qingcai Chen 5 | 6 | ARC 模型有两个变体,ARC-I 和 ARC-II。第一种是基于表示的方法,模型先提取两个句子的语义表达,然后使用多层感知器比较两个语义向量;第二种是基于交互的方式。 7 | 8 | ## Architecture-I (ARC-I) 9 | 10 | ![avater](./pic/arc1.png) 11 | 12 | 该模型具有孪生结构,因此也继承了孪生机构模型的缺点,比如在全连接层之前,两个句子所提取的语义特征没有进行任何的交互,这样可能导致在提取特征时损失了一些重要的可以用来做语义匹配的语句细节;换句话说就是,在模型的前向过程中相匹配的两个句子的语义表达彼此之间不包含对方的任何信息,这使得在后向(反向传播)过程中卷积模型不能充分提取到一些必要的特征。 13 | 14 | ## Architecture-II (ARC-II) 15 | 16 | ![avater](./pic/arc2.png) 17 | 18 | 基于结构 ARC-I 的缺陷,ARC-II 模型在提取句子结构的高级特征之前就让两个句子的表达向量进行交互,同时保留两个句子的特征抽象发展空间。 19 | 20 | ![avater](./pic/arc21.png) 21 | 22 | 模型能够保持语句中的顺序结构,实验证明 ARC-II 在三元组样本 $$(S_X,S_Y,\overline S_y)$$ ($$\overline S_y$$是在$$S_Y$$的基础上随机打乱语句顺序)中,有能力找到正确匹配句子$$S_Y$$的概率比$$\overline S_y$$高,但在模型ARC-I 中不会这样。 23 | 24 | ## 训练 25 | 26 | ### ranking-based 代价损失函数 27 | 28 | $$e(X,y^+,y^-;\theta) = max(0,1+s(X,y^-)-s(X,y^+))$$ 29 | 30 | $$s(X,y)$$ 表示句子 x,y 之间的匹配分数,三元组$$(X,y^+,y^-)$$表示 X 匹配 y+ 高于 y-。 31 | 32 | 在正则化技术选择方面,作者发现,对于中型或大型数据集(50W样本以上)两种结构模型只要使用早停就行;而对于 10万样本的数据集需要结合早停和 dropout 技术以防止过拟合。 33 | 34 | We use 3-word window throughout all experiments2 , but test various numbers of feature maps (typically from 200 to 500), for optimal performance. ARC-II models for all tasks have eight layers (three for convolution, three for pooling, and two for MLP), while ARC-I performs better with less layers (two for convolution, two for pooling, and two for MLP) and more hidden nodes. We use ReLu [7] as the activation function for all of models (convolution and MLP), which yields comparable or better results to sigmoid-like functions, but converges faster. 35 | 36 | ## Experiment I: Sentence Completion 37 | 38 | This is an artificial task designed to elucidate how different matching models can capture the correspondence between two clauses within a sentence. 39 | 40 | ``` 41 | S_X: Although the state has only four votes in the Electoral College, 42 | S^+_Y: its loss would be a symbolic blow to republican presidential candi 43 | date Bob Dole. 44 | S^−_Y: but it failed to garner enough votes to override an expected veto bypresident Clinton 45 | ``` 46 | 47 | ## Experiment II: Matching A Response to A Tweet 48 | 49 | For each positive pair, we find ten random responses as negative examples, rendering 45 million triples for training. One example (translated to English) is given below, with $$S_X$$ standing for the tweet, $$S^+_Y$$ the original response, and $$S^−_Y$$ the randomly selected response: 50 | 51 | ``` 52 | S_X: Damn, I have to work overtimethis weekend! 53 | S^+_Y: Try to have some rest buddy. 54 | S^−_Y: It is hard to find a job, better start polishing your resume. 55 | ``` 56 | 57 | ## Experiment III: Paraphrase Identification 58 | 59 | 判断两句话是不是同义句。 60 | 61 | Nevertheless, our generic matching models still manage to perform reasonably well, achieving an accuracy and F1 score close to the best performer in 2008 based on hand-crafted features, but still significantly lower than the state-of-the-art (76.8%/83.6%) 62 | -------------------------------------------------------------------------------- /深度语义匹配模型系列--Decomposable Attention Model.md: -------------------------------------------------------------------------------- 1 | # 深度语义匹配模型系列--Decomposable Attention Model 2 | 3 | 论文提出的模型为解决自然语言推理的问题,自然语言推理(NLI)指的是确定前提和假设之间的蕴涵和矛盾关系的问题。本模型的特点是,模型参数少,但是精度高。 4 | 5 | 模型输入为两个匹配的句子和标签组成的三元组,假设输入语句1为 $$a = (a_1,a_2,..,a_{l_a})$$,语句2为 $$b = (b_1,b_2,..,b_{l_b})$$,$$l_a,l_b$$ 分别是两个句子的长度。$$a_i,b_i \in R^d$$,表示词向量的维度为 d ,每个句子使用 NULL 预先填充。标签 $$y^{(n)}=(y_1^{(n)},...,y_C^{(n)})$$ 表示标签,C 表示类别数。 6 | 7 | 模型的主要结构有三部分,分别是 Attend,Compare,Aggregate ,如下图所示: 8 | 9 | ![avater](./pic/dam1.png) 10 | 11 | ## Attend 12 | 13 | 使用注意力机制的变体形式将两个句子 a,b进行软对齐(soft-align),然后将问题分解为对齐的子短语的比较。 14 | 15 | 首先使用$$F'$$ 函数计算未归一化的 attention 权重 $$e_{i,j}$$,可以使用 $$F$$ 函数来分解 $$F'$$ 函数 ,如下所示: 16 | 17 | $$e_{i,j} := F'(\overline a_i, \overline b_i) := F(\overline a_i)^T F(\overline b_i)$$ 18 | 19 | 这种分解将避免了 $$l_a * l_b$$ 的平方次复杂度,而仅仅需要 $$l_a + l_b$$ 的复杂度。这里 $$F$$ 函数是使用 relu 激活函数的前馈神经网络。 20 | 21 | attention 权重归一化: 22 | 23 | $$\beta _i := \sum _{j=1}^{l_b} \frac{exp(e_{i,j})}{\sum _{k=1}^{l_b} exp(e_{ik})} \overline b_j$$ 24 | 25 | $$\alpha _j := \sum _{i=1}^{l_a} \frac{exp(e_{i,j})}{\sum _{k=1}^{l_a} exp(e_{kj})} \overline a_i$$ 26 | 27 | 这里 $$\beta _i$$ 是 $$\overline b$$ 中子短语和 $$ \overline a_i$$ 的对齐;同理 $$ \overline a_i$$。 28 | 29 | ## Compare 30 | 31 | 分别比较句子的每一个子短语和另外一个句子的子短语,使用前馈神经网络函数 G 对句子 a 生成一个向量集合 $$\{V_{1,i}\}_{i=1}^{l_a}$$,对 b 生成 $$\{V_{2,j}\}_{j=1}^{l_b}$$。每个 $$V_{1,i}$$ 指 $$a_i$$ 和它的软对齐的 b 中的短语之间的非线性组合;同理 $$V_{1,j}$$ 针对 $$b_i$$。 32 | 33 | $$V_{1,i} := G([\overline a_i, \beta _i]) \ i \in [1,2,..,l_a]$$ 34 | 35 | $$V_{2,j} := G([\overline b_j, \alpha _j]) \ j \in [1,2,..,l_b]$$ 36 | 37 | 这里 $$[.,.]$$ 表示向量的拼接。 38 | 39 | ## Aggregate 40 | 41 | 聚合 $$\{V_{1,i}\}_{i=1}^{l_a}$$,和 $$\{V_{2,j}\}_{j=1}^{l_b}$$,使用它们的结果作为预测标签。 42 | 43 | 得到两个向量比较集合 $$\{V_{1,i}\}_{i=1}^{l_a}$$、 $$\{V_{2,j}\}_{j=1}^{l_b}$$ 后 ,首先需要将每个集合的值进行加和: 44 | 45 | $$V_1 = \sum _{i=1}^{l_a}V_{1,i}, \ V_2 = \sum _{j=1}^{l_b}V_{2,j}$$ 46 | 47 | 然后将结果输入给分类器 H ,H 是一个前馈神经网络的线性层: 48 | 49 | $$\overline y = H([V_1,V_2])$$ 50 | 51 | y 表示每个类别的得分,可以通过 softmax 给出属于每个类别的概率。训练时使用多分类交叉熵损失函数,如下: 52 | 53 | $$L(\theta _F ,\theta _G,\theta _H) = \frac{1}{N}\sum _{n=1}^N \sum _{c=1}^C y_c ^{(n)} log \frac{exp(\overline y_c)}{\sum _{c'=1}^C exp(\overline y_{c'})}$$ 54 | 55 | ## Intra-Sentence Attention 56 | 57 | 输入表达在普通版的设置中直接使用的是词向量,但是,我们可以通过 Intra-Sentence Attention 来改善这种输入表示,以编码每个句子中单词之间的成分关系。 58 | 59 | $$f_{ij} := F_{intra}(a_i)^T F_{intra}(a_j)$$ 60 | 61 | 这里 $$F_{intra}$$ 是前馈神经网络,根据上式,我们可以得到自对齐短语: 62 | 63 | $$\alpha _i := \sum _{i=1}^{l_a} \frac{exp(f_{ij} + d_{i-j})}{\sum _{k=1}^{l_a} exp(f_{ik} + d_{i-k})} \overline a_j$$ 64 | 65 | 这里 distance-sensitive 偏置项 $$d_{i-j} \in R $$ 为模型提供最少量的序列信息,同时保持可并行化。 这些词语的离散化,使得大于10个字的所有距离共享相同的偏差。输入表达由此被定义成 $$\overline a_i := [a_i, a'_i]$$,$$\overline b_i := [b_i, b'_i]$$ 66 | 67 | -------------------------------------------------------------------------------- /深度语义匹配模型系列--MatchPyramid.md: -------------------------------------------------------------------------------- 1 | # 深度语义匹配模型系列--MatchPyramid 2 | 3 | Text Matching as Image Recognition 4 | 5 | Liang Pang, Yanyan Lan, Jiafeng Guo 6 | 7 | 语义匹配算法需要捕获两个句子之中丰富的交互结构信息,比如词、短语和句子,以判断两个句子是否表达的是同一个句子。对于以下两句话,需要获取词的匹配 “down”,相似词的匹配 “famous” 和 “popular,n-gram 的匹配““down the age”,顺序不一致的 n-term 匹配 “ noodles and dumpling”和 ““dumplings and noodle”,以及语义相似的 n-gram 匹配 “were famous Chinese foo” 和 “were popular in Chin”。 8 | 9 | ``` 10 | T1 : Down the ages noodles and dumplings were famous Chinese food. 11 | T2 : Down the ages dumplings and noodles were popular in China 12 | ``` 13 | 14 | ![avater](./pic/pyramid.png) 15 | 16 | 为了让文本匹配可以像图像识别的方式一样使用卷积操作,作者将文本输入形式转换成匹配矩阵 M ,M 中的每个元素 $$M_{ij}$$ 表示基本的交互,比如词$$w_i$$ 和 $$v_j$$ 之间的相似度 17 | 18 | $$M_{ij} = w_i \bigotimes v_j$$ 19 | 20 | 通过这种方式 匹配矩阵 M 可以看做一张图像。$$\bigotimes $$ 可以使用不同的交互模型。比如知识函数 Indicator Function: 21 | 22 | ![avater](./pic/if.png) 23 | 24 | 这种指示函数无法表达相似词的匹配,这对这一点,作者使用词向量来对词和词之间进行计算相似度,分别有使用余弦相似度和点乘。 25 | 26 | ![avater](./pic/match.png) 27 | 28 | 由于相匹配的两个句子,在不同样本中长度不同,所以构建成的匹配矩阵 M 尺寸也不相等,因此使用动态池化操作策略来获取定长特征图。 29 | 30 | ![avater](./pic/cnnill.png) 31 | 32 | ### Matching Score and Training 33 | 34 | $$(s_0,s_1)^T = W_2\sigma(W_1z+b_1)+b_2 $$ 35 | 36 | 37 | where $$s_0$$ and $$s_1$$ are the matching scores of the corresponding 38 | class, $$z$$ is the output of the hierarchical convolution, $$W_i$$ 39 | is the weight of the $$i_{th}$$ MLP layer and $$\sigma $$ denotes the activation function. 40 | 41 | 损失函数如下所示: 42 | 43 | ![avater](./pic/pymloss.png) 44 | 45 | It performs better when we use the mini-batch strategy (32∼50 in size), 46 | which can be easily parallelized on single machine with multi-cores. For regularization, we find that some common strategies like early stopping (Giles 2001) and dropout (Hinton et al. 2012) are enough for our model. 47 | 48 | There are three versions of MatchPyramid, depending on different methods used for constructing the matching matrices, denoted as MP-IND, MP-COS, and MP-DOT, respectively. All these models use **two convolutional layers**, **two max-pooling layers**(one of which is a dynamic pooling layer for variable length) and **two full connection layers**. The number of feature maps is 8 and 16 for the first and second convolutional layer, respectively. While the kernel size is set to be **5 × 5 and 3 × 3**, respectively. Unlike ARC-II which initiates with Word2Vec trained on Wikipedia, we **initiate the word vectors in MP-COS and MP-DOT randomly** from a unit ball. Thus our model do not require any external sources. 49 | 50 | ### Experiment I: Paraphrase Identification 51 | 52 | ![avater](./pic/pym_res.png) 53 | 54 | ### Experiment II: Paper Citation Matching 55 | 56 | 使用一些列的论文和它们的摘要,将论文的引文和摘要作为一对匹配。 57 | 58 | ``` 59 | T1 : this article describes pulsed thermal time of flight ttof flow 60 | sensor system as two subsystems pulsed wire system and heat flow system 61 | the entire flow sensor is regarded system theoretically as linear. 62 | 63 | T2 : the authors report on novel linear time invariant lti modeling of 64 | flow sensor system based on thermal time of flight tof principle by 65 | using pulsed hot wire anemometry thermal he at pulses. 66 | ``` 67 | 68 | ![avater](./pic/pym_res2.png) 69 | -------------------------------------------------------------------------------- /距离度量和相似度度量公式.md: -------------------------------------------------------------------------------- 1 | # 距离度量和相似度度量公式 2 | 3 | ### 相关系数 4 | 5 | 相关系数(Correlation coefficient) 是用以反映变量之间相关关系密切程度的统计指标。依据相关现象之间的不同特征,其统计指标的名称有所不同。如将反映两变量间线性相关关系的统计指标称为相关系数(相关系数的平方称为判定系数);将反映两变量间曲线相关关系的统计指标称为非线性相关系数、非线性判定系数;将反映多元线性相关关系的统计指标称为复相关系数、复判定系数等。 6 | 7 | 协方差:$$Cov(x,y)=\frac{\sum_{i=1}^n(x_i- \overline x)(y_i - \overline y)}{n}$$ 8 | 9 | 皮尔逊相关系数 $$p = \frac{Cov(x,y)}{\sigma _ x \sigma _y}$$ 10 | 11 | $$p = \frac{\sum_{i=1}^n(x_i- \overline x)(y_i - \overline y)}{\sqrt{\sum_{i=1}^n(x_i- \overline x)^2}\sqrt{\sum_{i=1}^n(y_i- \overline y)^2}}$$ 12 | 13 | 相关系数有一个明显的缺点,即它接近于1的程度与数据组数 n 相关,这容易给人一种假象。因为,当 n 较小时,相关系数的波动较大,对有些样本相关系数的绝对值易接近于1;当n较大时,相关系数的绝对值容易偏小。特别是当 n=2 时,相关系数的绝对值总为1。因此在样本容量 n 较小时,我们仅凭相关系数较大就判定变量 x 与 y 之间有密切的线性关系是不妥当的。 14 | 15 | ### 余弦相似度 Cosine Similarity 16 | 17 | 余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。相比距离度量,余弦相似度更加注重两个向量在方向上的差异,而非距离或长度上。 18 | 19 | ![avater](./pic/consim.png) 20 | 21 | ### Jaccard Similarity 22 | Jaccard系数主要用于计算符号度量或布尔值度量的个体间的相似度,因为个体的特征属性都是由符号度量或者布尔值标识,因此无法衡量差异具 体值的大小,只能获得“是否相同”这个结果,所以Jaccard系数只关心个体间共同具有的特征是否一致这个问题。 23 | 24 | $$Jaccard(X,Y)=\frac{X\bigcap Y}{X\bigcup Y} = \frac{X\bigcap Y}{|X|+|Y|-X\bigcap Y}$$ 25 | 26 | ![avater](./pic/jacsim.png) 27 | 28 | ## 距离度量 29 | ### 欧几里得距离(Eucledian Distance) 30 | 31 | 欧氏距离是最常用的距离计算公式,衡量的是多维空间中各个点之间的绝对距离,当数据很稠密并且连续时,这是一种很好的计算方式。 32 | 33 | 因为计算是基于各维度特征的绝对数值,所以欧氏度量需要保证各维度指标在相同的刻度级别,比如对身高(cm)和体重(kg)两个单位不同的指标使用欧式距离可能使结果失效。 34 | 35 | ![avater](./pic/ed.png) 36 | 37 | ### 曼哈顿距离(Manhattan Distance) 38 | 39 | $$Manhattan distance = |x_1 – x_2| + |y_1 – y_2|$$ 40 | 41 | p1 at (x1, y1) and p2 at (x2, y2) 42 | 43 | ### 明可夫斯基距离(Minkowski distance) 44 | 45 | 明氏距离是欧氏距离的推广,是对多个距离度量公式的概括性的表述, 46 | 47 | - 当p == 1,“明可夫斯基距离”变成“曼哈顿距离” 48 | - 当p == 2,“明可夫斯基距离”变成“欧几里得距离” 49 | - 当p == ∞,“明可夫斯基距离”变成“切比雪夫距离” 50 | 51 | $$dist(X,Y)=(\sum_{i=1}^n|x_i - y_i|^p)^{1/p}$$ 52 | 53 | --------------------------------------------------------------------------------