2017-03-09 92 views
2

我听说过K最近邻居找到一个项目所属的类别,但我想知道是否有算法会根据属性返回项目列表。按属性查找类似产品

例如,给定一个电影

[director: "Hill Thompson", starring-actor: "Will Smith", release-date: "Dec 1776"] 

结果将返回

​​

代替

[director: "Hill Thompson", starring-actor: "Poop Jenkins", release-date: "Sept 1822"] 

因为前者的结果一致的多个属性 “山·汤普森” 和“威尔史密斯“,而前者只有一场比赛 - 希尔汤普森。

余弦相似性会是一个很好的方法来解决这个问题吗?

+0

如何定义相似度?只需通过匹配键值的数量?领带怎么样? [导演:“Klay Thompson”,主演:“威尔史密斯”,发行日期:“1776年12月”]被认为比你以前的成绩更好(两人都有两场比赛)? – shole

+0

哦好问题,我想在这种情况下,如果我们得到相同数量的属性,那么我们将返回两个 –

+1

所以密钥中不会有重量/优先级? (例如,如果配合,匹配的董事权重高于匹配的发布日期)也意味着价值的相似性无关紧要? (例如,如果配对数量相同,导演:HiLL Thompson的意思与导演一样糟糕:idcwtfisthis)? – shole

回答

2

会余弦相似性是一个很好的方法来解决这个问题?

是的。这将是好的,但与TF-IDF

最常用的相似性措施是Jaccard SimilarityCosine similarity。 在给定的情况下,您可以直接使用Jaccard Similarity并获得您想要的结果。

说,

A = {director: "Hill Thompson", starring-actor: "Will Smith", release-date: "Dec 1776"} 
B = {director: "Hill Thompson", starring-actor: "Will Smith", release-date: "Jan 1996"} 
C = {director: "Hill Thompson", starring-actor: "Poop Jenkins", release-date: "Sept 1822"} 
D = {director: "Foo Bar", starring-actor: "Poop Jenkins", release-date: "Some date"} 

Jaccard Similarity将是:

J(A,B) = 2/4 = 0.5 
J(A,C) = 1/5 = 0.2 
J(C,D) = 1/5 = 0.2 

而作为J(A,B) > J(A,C)K nearest neighbour方法将挑选B第一和然后C。 在这种情况下,Jaccard similarity很好地捕捉了直觉。

为了演示如何Cosine Similarity比较好,增加一个属性:

A = {place filmed : "A", director: "Hill Thompson", starring-actor: "Will Smith", release-date: "Dec 1776"} 
B = {place filmed : "A", director: "Hill Thompson", starring-actor: "Will Smith", release-date: "Jan 1996"} 
C = {place filmed : "A", director: "Hill Thompson", starring-actor: "Poop Jenkins", release-date: "Sept 1822"} 
D = {place filmed : "A", director: "Foo Bar", starring-actor: "Poop Jenkins", release-date: "Some date"} 


J(A,B) = 3/5 = 0.6 
J(A,C) = 2/6 = 0.33 
J(C,D) = 2/6 = 0.33 

注意,J(C,A) = J(C,D)

这是错误直觉。

为什么? 因为地方A似乎是录制电影的常用地点。仅仅因为两部电影是在同一个地方录制的,我们不能断定它们是相似的。所以理想情况下它应该是Sim(C,D) > Sim(C,A)Jaccard Similarity无法捕捉到直觉,Cosine similarityTF-IDF优于此情况。

在这种情况下,Cosine Similarity的问题是实现。向量上定义了Cosine similarity。当数据不是数字时,很难创建一个向量。

创建矢量的一种方法是向量boolean

例如, 的载体将被形成为:

vector = [A,HillThompson,FooBar,WillSmith,Poop Jenkins,Dec 1776,Jan 1996, Sept 1822, Some date] 

的载体将是:

A = {1,1,0,1,0,1,0,0,0} 
C = {1,1,0,0,1,0,0,1,0} 
D = {1,0,1,0,1,0,0,0,1} 

J(C,A) = 5/12 
J(C,D) = 5/12 

注意,Jaccard Similarity仍然捕获错误直觉。如果TF-IDF没有完成,那么Cosine Similarity也是如此。

现在计算TF-IDF:

IDF(A)    = log(1 + 4/4) = 0.30 

IDF(HillThompson) = log(1 + 4/3) = 0.37 
IDF(FooBar)   = log(1 + 4/1) = 0.70 

IDF(WillSmith)  = log(1 + 4/2) = 0.48 
IDF(Poop Jenkins) = log(1 + 4/2) = 0.48 

IDF(Dec 1776)  = log(1 + 4/1) = 0.70 
IDF(Jan 1996)  = log(1 + 4/1) = 0.70 
IDF(Sept 1822)  = log(1 + 4/1) = 0.70 
IDF(Some date)  = log(1 + 4/1) = 0.70 

IF-IDF矢量现在将是:

A = {0.30/4, 0.37/4, 0,  0.48/4, 0,  0.70/4, 0, 0,  0} 
C = {0.30/4, 0.37/4, 0,  0,  0.48/4, 0,  0, 0.70/4, 0} 
D = {0.30/4,  0, 0.70/4, 0,  0.48/4, 0,  0, 0,  0.70/4} 

A = {0.075, 0.0925, 0,  0.12, 0,  0.175, 0, 0,  0 } 
C = {0.075, 0.0925, 0,  0,  0.12, 0,  0, 0.175, 0 } 
D = {0.075, 0,  0.175, 0,  0.12, 0,  0, 0,  0.175 } 

|A| = 0.2433 
|C| = 0.2433 
|D| = 0.2850 

计算余弦相似性:

Cosine(A,C) = 0.01418/(0.2433 * 0.2433) = 0.2395 
Cosine(C,D) = 0.0200/(0.2492 * 0.2850) = 0.2816 

因此,Cosine similarityTF-IDF捕捉到D更直观的直觉ar到CA是到C。因此它是优于Jaccard similarity

请注意我已经计算出监守我已经做了他们在PC上,而不是科学计算器。可能有错误的机会。万一你找到了,请纠正它。