我是一名计算机科学家,致力于解决需要一些统计措施的问题,但(不是非常精通统计)我不太确定要使用什么统计数据。
概述:
我有一组问题(当然来自 StackExchange 站点),我正在探索算法,这些算法将找到与我提供的问题相似的问题。是的,StackExchange 站点已经执行此功能,许多其他问答站点也是如此。我要做的是分析人们用来完成这项任务的方法和算法,看看哪些方法表现最好。我的问题是找到合适的统计方法来定量确定“哪些方法表现最好”。
数据:
我有一组 StackExchange 问题,每个问题都像这样保存:{'questionID':"...", 'questionText':"..."}
. 对于每个问题,我都有一组与之相关的或与之相关的其他问题。StackExchange 网站上的问答者通常会在他们的答案中添加指向其他类似帖子的链接,即“您是否阅读过某某某某的这篇文章 [插入此处发布的链接]?他们正在解决一个类似的问题问题......”我认为这些相关的问题彼此“相似”。
更具体地说,假设我们有 question A
。QuestionA
有一系列链接的问题{B, C, D}
。所以 A_linked = {B, C, D}
。我的直觉告诉我,传递性在这里并不适用。也就是说,仅仅因为A
与 相似B
,并且A
与 相似C
,我无法确认B
与 相似C
。(或者我可以吗?)但是,我可以自信地说,如果A
类似于B
,那么B
类似于A
。
因此,为了简化这些关系,我将创建一组相似的配对:{A, B}, {A, C}, {A, D}
这些配对将作为某种基本事实。这些是我们知道彼此相似的问题,因此它们的相似性置信度值等于 1。所以similarityConfidence({A,B}) = 1
关于这种设置需要注意的是,对于数据集中的每个问题,我们只知道几个类似的问题。我们不知道的是其他一些问题E
是否也与A
. 可能相似,也可能不相似,我们不知道。所以我们的“基本事实”实际上只是一些事实。
算法:
该算法的简化伪代码版本如下:
for q in questions: #remember q = {'questionID':"...", 'questionText':"..."}
similarities = {} # will hold a mapping from questionID to similarity to q
q_Vector = vectorize(q) # create a vector from question text (each word is a dimension, value is unimportant)
for o in questions: #such that q!=o
o_Vector = vectorize(o)
similarities[o['questionID']] = cosineSimilarity(q_Vector,o_Vector) # values will be in the range of 1.0=identical to 0.0=not similar at all
#now what???
所以现在我有了 q 和我的数据集中所有其他问题之间的余弦相似度分数的完整映射。我的最终目标是为vectorize()
函数的许多变体运行此代码(每个变体将返回略有不同的向量),并确定哪种变体在余弦分数方面表现最佳。
问题:
所以这是我的问题。怎么办?我如何定量测量这些余弦分数的好坏?
这些是我集思广益的一些测量想法(尽管我觉得它们不完善,不完整):
某种类似于均方根误差 (RMSE) 的误差函数。因此,对于真实相似度列表中的每个文档,累积平方误差(误差大致定义为
1-similarities[questionID]
)。然后,我们将该累积除以相似对的总数*2
(因为我们将考虑a->b
以及b->a
)。最后,我们将取这个误差的平方根。- 这需要一些思考,因为这些值可能需要标准化。尽管 的所有变体
vectorize()
都会产生 0 到 1 范围内的余弦分数,但两个vectorize()
函数的余弦分数可能无法相互比较。vectorize_1()
每个问题的余弦分数可能通常很高,因此 0.5 的分数可能是一个非常低的分数。或者,vectorize_2()
每个问题的余弦分数通常较低,因此 0.5 可能是一个非常高的分数。我需要以某种方式解释这种变化。 - 另外,我提出了一个误差函数
1-similarities[questionID]
。我选择 1 是因为我们知道这两个问题是相似的,因此我们的相似度置信度为 1。但是,余弦相似度得分为 1 意味着这两个问题是相同的。我们并不是说我们的“相关”问题是相同的,只是它们是相似的。这是一个问题吗?
- 这需要一些思考,因为这些值可能需要标准化。尽管 的所有变体
我们可以找到召回率(返回的相似文档的数量/相似文档的数量),只要我们设置一个阈值,哪些问题我们返回为“相似”,哪些问题不返回。
- 尽管出于上述原因,这不应该是一个预定义的阈值,
similarity[documentID]>7
因为每个vectorize()
函数可能返回不同的值。
- 尽管出于上述原因,这不应该是一个预定义的阈值,
我们可以找到recall@k,我们只分析前k 个帖子。
- 不过,这可能是有问题的,因为我们没有完整的基本事实。如果我们设置,并且我们知道相关的 3 个
k=5
文档( )中只有 1 个文档( )在前 5 个中,我们不知道其他 4 个最重要的文档实际上是否与我们知道的 3 个相同或更相似,但没有人将它们联系起来。B
{B,C,D}
A
- 不过,这可能是有问题的,因为我们没有完整的基本事实。如果我们设置,并且我们知道相关的 3 个
你还有其他建议吗?如何定量测量哪个vectorize()
功能表现最好?