1 余弦定理与新闻分类
余弦定理应用最广泛的应该就是新闻分类了,前段时间看算法觉得挺简单的没去实现,近几日无事便写了一个余弦定理程序,发现并非想象那般,有很多有意思的发现。
先说一下余弦定理判断相似度的步骤:
- 分词
- 求权重(TF-IDF)
- 生成特征向量
- 求向量余弦
通常在第三步骤特征向量的长度是所有词的总和(大概是64000),但我觉得向量太长了有那么多0没啥意义,就把两段文字分词后的词语整合在一起,去重,作为特征向量的长度了。
2 实验
2.1 实验1
- S1:小明,吃饭了。
- S2:小张,吃饭了。
先分词:
- 小明/吃饭/了/
- 小张/吃饭/了/
计算权重:
- 小明##1.4607546/吃饭##0.041101746/了##9.617965E-4/
- 小张##1.0201119/吃饭##0.041101746/了##9.617965E-4/
整合词语:
- 了 吃饭 小张 小明
生成向量:
- 9.617965E-4 0.041101746 0.0 1.4607546
- 9.617965E-4 0.041101746 1.0201119 0.0
计算余弦:
- 0.0011329448
纳尼,这、、程序错了吧!是不是字符串太短了,再试一次。
2.2 实验2
- S1:小明,你妈妈叫你回家吃饭了!
- S2:小张,你妈妈叫你回家吃饭了!
先分词:
- 小明/你/妈妈/叫你/回家/吃饭/了/
- 小张/你/妈妈/叫你/回家/吃饭/了/
计算权重:
- 小明##0.6260377/你##8.252138E-4/妈妈##0.06170727/叫你##0.0659164/回家##0.011865113/吃饭##0.017615033/了##4.121985E-4/
- 小张##0.43719083/你##8.252138E-4/妈妈##0.06170727/叫你##0.0659164/回家##0.011865113/吃饭##0.017615033/了##4.121985E-4/
整合词语:
- 了 你 叫你 吃饭 回家 妈妈 小张 小明
生成向量:
- 4.121985E-4 8.252138E-4 0.0659164 0.017615033 0.011865113 0.06170727 0.0 0.6260377
- 4.121985E-4 8.252138E-4 0.0659164 0.017615033 0.011865113 0.06170727 0.43719083 0.0
计算余弦:
- 0.030421823
同样的结果?手工算一篇、、一样?权重改一下(全都设成1)。
2.3 实验3
- S1:小明,你妈妈叫你回家吃饭了!
- S2:小张,你妈妈叫你回家吃饭了!
先分词:
- 小明/你/妈妈/叫你/回家/吃饭/了/
- 小张/你/妈妈/叫你/回家/吃饭/了/
计算权重(TF-IDF没有,全都设置成1):
- 小明##0.6260377/你##8.252138E-4/妈妈##0.06170727/叫你##0.0659164/回家##0.011865113/吃饭##0.017615033/了##4.121985E-4/
- 小张##0.43719083/你##8.252138E-4/妈妈##0.06170727/叫你##0.0659164/回家##0.011865113/吃饭##0.017615033/了##4.121985E-4/
整合词语:
- 了 你 叫你 吃饭 回家 妈妈 小张 小明
生成向量:
- 1.0 1.0 1.0 1.0 1.0 1.0 0.0 1.0
- 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0
计算余弦:
- 0.8571429
果然是权重的问题啊!
再看前两个实验,每个字符串,相对于人名来讲,其他词的权重要显得小很多,我们暂且把它们忽略,那么也就剩人名在进行余弦相似度的计算了,这也就难怪相似度那么低了。
下面把“吃饭”换成“打篮球”试试,因为“打篮球”总要比“吃饭”的权重高吧!
2.4 实验4
- S1:小明,你妈妈叫你回家打篮球了!
- S2:小张,你妈妈叫你回家打篮球了!
先分词:
- 小明/你/妈妈/叫你/回家/打篮球/了/
- 小张/你/妈妈/叫你/回家/打篮球/了/
计算权重:
- 小明##0.6260377/你##8.252138E-4/妈妈##0.06170727/叫你##0.0659164/回家##0.011865113/打篮球##0.53962886/了##4.121985E-4/
- 小张##0.43719083/你##8.252138E-4/妈妈##0.06170727/叫你##0.0659164/回家##0.011865113/打篮球##0.53962886/了##4.121985E-4/
整合词语:
- 了 你 叫你 回家 妈妈 小张 小明 打篮球
生成向量:
- 4.121985E-4 8.252138E-4 0.0659164 0.011865113 0.06170727 0.0 0.6260377 0.53962886
- 4.121985E-4 8.252138E-4 0.0659164 0.011865113 0.06170727 0.43719083 0.0 0.53962886
计算余弦:
- 0.51421046
相似度明显提高啊!因为其他词相对于人名都可以忽略(因为小),但“打篮球”这个词就不能忽略了,因为它跟人名的权重差不多一样大。
再换一下,改成“打橄榄球”。
2.5 实验5
- S1:小明,你妈妈叫你回家打橄榄球了!
- S2:小张,你妈妈叫你回家打橄榄球了!
先分词:
- 小明/你/妈妈/叫你/回家/打/橄榄球/了/
- 小张/你/妈妈/叫你/回家/打/橄榄球/了/
计算权重:
- 小明##0.54778296/你##7.22062E-4/妈妈##0.05399386/叫你##0.057676844/回家##0.010381973/打##0.0014470452/橄榄球##0.75754195/了##3.6067367E-4/
- 小张##0.38254195/你##7.22062E-4/妈妈##0.05399386/叫你##0.057676844/回家##0.010381973/打##0.0014470452/橄榄球##0.75754195/了##3.6067367E-4/
整合词语:
- 了 你 叫你 回家 妈妈 小张 小明 打 橄榄球
生成向量:
- 3.6067367E-4 7.22062E-4 0.057676844 0.010381973 0.05399386 0.0 0.54778296 0.0014470452 0.75754195
- 3.6067367E-4 7.22062E-4 0.057676844 0.010381973 0.05399386 0.38254195 0.0 0.0014470452 0.75754195
计算余弦:
- 0.7255143
又有明显的提高了。
3 说点啥
经测试,发现程序并没有问题,问题出在TF-IDF上。
此时我认为:相对于SimHash来讲(因为SimHash也用到了TF-IDF),TF-IDF在余弦定理上更显得更为突出。
那么为什么新闻分类是用余弦定理,而不是是用其他相似度量方法呢?可能就是因为权重问题。
现在假设:
有10个类别的新闻,每个类别的新闻都有与其对应的1篇模板,以体育类为例。
在判断一篇文章是否为体育类时,我们需要把这篇文章与体育类的模板计算余弦。
在计算TF-IDF时,文本库显得尤为重要,因为它直接关乎权重的大小。
那么在对体育类判断时,关于体育方面的一些专有名词的权重一定要高,才能最大程度上判断其相似。
怎么让权重高呢?在文本库中不要涉及有关体育的文章,但其他各方面的文章一定要全,这样在计算TF-IDF时,体育类的就会高。
判断其他类的也是一样,自身不要包含在TF-IDF的文件库中。
4 关于SimHash
还没结束,突然想到SimHash,前段时间测试时,人名改了,计算出来的相似度变化很大,有可能也是权重的原因。
- S1:小明,你妈妈叫你回家吃饭了!
- S2:小张,你妈妈叫你回家吃饭了!
计算相似度:
- 经检测,上述两个文本的海明距离为:68(共128位),相似度为:46.88%
- S1:小明,你妈妈叫你回家打篮球了!
- S2:小张,你妈妈叫你回家打篮球了!
计算相似度:
- 经检测,上述两个文本的海明距离为:41(共128位),相似度为:67.97%
- S1:小明,你妈妈叫你回家打橄榄球了!
- S2:小张,你妈妈叫你回家打橄榄球了!
计算相似度:
- 经检测,上述两个文本的海明距离为:0(共128位),相似度为:100.00%
这就解释了上一次老师提出的问题,不完全是因为文本太短的问题,还有权重的问题!