【问题标题】:How do I write a function to compare and rank many sets of boolean (true/false) answers?如何编写一个函数来比较和排列多组布尔(真/假)答案?
【发布时间】:2011-03-20 05:12:48
【问题描述】:

我开始了一个比我最初想象的要复杂得多的项目。我正在尝试规划一个基于布尔(真/假)问题和答案的系统。系统上的用户可以从大量布尔(真/假)问题中回答任何问题,并根据他们的答案显示最相似用户的列表(按相似度排序)。

我已经在 Google 上进行了广泛搜索,但仍然没有想出太多,所以我希望有人能指出我正确的方向。我想知道:

存储此类数据的最佳数据结构和方法是什么?我最初假设我可以在 SQL 数据库中创建两个表“问题”和“答案”。但是,我不知道如果它们都被列为数字字符串,比较两组答案是否会更简单。 IE。 0 = 未回答,1 = 正确,2 = 错误。在比较字符串时,可以添加“未回答”= 0、“相同答案”= 1、“相反答案”= -1 的权重,从而产生相似度分数。

我将如何比较两组答案?为了能够计算出这组答案之间的“相似性”,我将不得不编写一个比较函数。有谁知道哪种比较最适合这个问题?我研究了sequence alignment,我认为这可能是正确的方法,但我不确定,因为这要求数据是一个长序列,而且问题不相关,所以自然不是一个序列.

如何将此比较函数应用于大量数据? 编写比较函数后,我可以将每个用户的答案与其他每个用户的答案进行比较,但这并不能看起来非常有效,可能不会很好地扩展。我一直在研究cluster analysis 根据类似答案自动对用户进行分组的方法,您认为这可行吗?或者有人知道我可以研究的更好方法吗?

非常感谢任何有用的指示。谢谢!

【问题讨论】:

  • 对于什么数据库? MySQL 没有任何排名/窗口/分析功能...
  • 我不知道。我什至不知道数据库是否是存储这些数据的最佳方式。还有其他更适合此类问题的数据结构吗?
  • 我想我在 Jaccard 索引方面有所进展:en.wikipedia.org/wiki/Jaccard_index

标签: sql language-agnostic database-design data-structures computer-science


【解决方案1】:

如果您要在 SQL 中设置用户、问题和答案表,那么我相信以下 SQL 可用于让其他用户获得类似的响应。只需添加一个 TOP 子句即可获得您想要的数字。

我不知道性能如何,但这在很大程度上取决于您的数据大小。

SELECT
    U2.userid,
    SUM(CASE
            WHEN A1.answer = A2.answer THEN 1
            WHEN A1.answer <> A2.answer THEN -1
            WHEN A1.answer IS NULL OR A2.answer IS NULL THEN 0  -- A bit redundant, but I like to make it clear
            ELSE 0
        END) AS similarity_score
FROM
    Questions Q
LEFT OUTER JOIN Answers A1 ON
    A1.question_id = Q.question_id AND
    A1.userid = @userid
LEFT OUTER JOIN Answers A2 ON
    A2.question_id = A1.question_id AND
    A2.userid <> A1.userid
LEFT OUTER JOIN Users U2 ON
    U2.userid = A2.userid
GROUP BY
    U2.userid
ORDER BY
    similarity_score DESC

【讨论】:

  • 感谢您的回复。我认为这在较小的数据集上效果很好,但扩展性不是特别好。如果有 50 万用户每个人都有 100 个答案,那么我认为这可能会停止。我需要一些可以继续大规模工作的东西,所以为了使这可行,我想首先需要以某种方式过滤数据。
  • 我试图想办法用位图做到这一点并且接近了,但是你需要能够计算一个值的汉明权重,因为没有一个简单有效的方法以基于集合的方式做到这一点的方式有点障碍。
【解决方案2】:

数据存储: 我会说数据库是一个好主意(听起来像是一个相当大的数据集的潜力)。我不知道您计划有多少问题,但为了帮助简化分析(包括您的 SQL 查询),您可能希望将类似问题的答案分组到单独的表中。而且我同意使用数值(字节 0-2)代替布尔值或其他东西是一个很好的途径。您正在计算相似度分数,所以不妨从数字开始。

比较: 至于比较本身,我建议创建一个包含字节列表的类 SimilarQuestionAnswers 和一个包含这些 SimilarQuestionAnswers 列表的类 UserAnswers。它的作用是为您提到的聚类分析方法设置您的聚类。通过这种方式,您可以为某些集群添加权重。 (集群 a 是一个重要集群,因此它的分数乘以 20,而集群 b 不那么重要,因此它的分数仅乘以 10)这也允许您在需要时对每个集群应用不同的比较。

我知道您说这些问题不相关,但您仍然可以至少按问题的重要性对问题进行分组。我认为序列分析仍然可以工作,因为您的相似性矩阵将全为 1,这样可以稍微简化问题,但与此相关的其余数学应该足够了。

应用比较: 这就是让数据库后端派上用场的地方。使用 SQL 查询来最小化您正在处理的数据集。如果您将一个人与其他人进行比较,您可以对他们的答案使用 SQL 求和方法,以在每个集群内进行快速而肮脏的比较,并仅提取特定阈值内的人。这可能会导致一些重叠,但很容易消除。

另一个想法是为每个用户创建一个表,为每个集群创建一个列,并与对每个问题都回答正确的假用户进行比较。然后,您可以在该表中查询每个集群的当前用户分数范围。这会更快但不太准确。

无论哪种方式,最终您仍然需要与从该查询中获得的每个用户进行比较。因此,您可以越快进行比较越好。尽量坚持只涉及 +、-、*、/ 的公式,大多数 Math.Whatever() 方法会在大量调用中增加大量时间。

抱歉,这太长了,大多数问题都是开放式的,我不得不假设一些细节。我希望这会有所帮助。

【讨论】:

  • 谢谢,里面有一些非常有用的想法。我认为使用“假用户”或“控制用户”作为快速比较距离(相似性)的一种方式是有潜力的。然而,两个用户可能具有相同的 d 值(与控制的距离),但回答却截然不同。我认为您可能需要单独比较每个用户才能建立真正的比较。
  • 我同意您仍然需要进行最终比较,我只是想让控制用户比较粗略,以使您的数据集在更小和更易于管理上进行最终比较。我假设没有一个用户真的会查看所有 n 比较,如果那样的话,可能只是前 5%。
【解决方案3】:

我认为您可能需要基于所有用户的回答方式的每个问题的权重。作为一个极端情况,如果 1,000 人回答问题 A 和 B,结果是 A (2Y, 998N) 和 B (500Y, 500N),则 A 的两个“Y”比 B 中任何给定的 Y 都多得多。来自 B 的任何相似对都比来自 A 的任何 N 对更相似。

查看Bayesian Probability

【讨论】:

  • 我认为你是完全正确的。换句话说,对于任何给定用户的答案比较,匹配答案的可能性越小,相似度得分就应该越高。我可以将每个答案的权重存储在数据库中,每当问题被回答时,该权重就会更新。
【解决方案4】:

除了对用户进行聚类之外,您还可以考虑对问题进行聚类(例如OkCupid)。然后,您无需在所有答案上比较用户,而是在类别上进行比较。

【讨论】:

  • 你能解释一下你的意思吗?我看过 OKCupid,它与我计划做的非常相似。你知道他们使用哪种分类系统吗?
  • 我想他们在网站很小的时候手动按主题分类问题,现在有一些自动化的方法,但我没有任何内部知识。
猜你喜欢
  • 1970-01-01
  • 2014-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
相关资源
最近更新 更多