【问题标题】:Algorithm to score similarness of sets of numbers对数字集的相似性进行评分的算法
【发布时间】:2008-09-26 14:18:50
【问题描述】:

将多组数字与目标组进行比较以确定哪些数字最“相似”的算法是什么?

此算法的一个用途是将今天的每小时天气预报与历史天气记录进行比较,以找出天气相似的一天。

两个集合的相似度有点主观,所以算法真的只需要区分好匹配和坏匹配。我们有很多历史数据,所以我想通过自动丢弃不接近的集合并尝试将“最佳”匹配项放在顶部来尝试缩小用户需要查看的天数列表。

编辑: 理想情况下,算法的结果将与使用不同数据集的结果相当。例如,使用Niles 建议的均方误差会产生很好的结果,但是比较温度时生成的数字无法与其他数据(例如风速或降水)生成的数字进行比较,因为数据的规模不同.一些非天气数据非常大,所以均方误差算法产生的数字是几十万,而使用温度产生的数字是几十或几百。

【问题讨论】:

  • 我实际上有类似的用途,我希望能从中得到一些好的答案。

标签: algorithm statistics


【解决方案1】:

我认为均方误差度量可能适用于天气比较等应用。它很容易计算并给出有意义的数字。

由于您想比较一段时间内的测量值,您可以在计算中忽略缺失值。

对于没有时间限制甚至未排序的值,多维分散数据有点困难。选择一个好的距离度量成为分析此类数据的艺术的一部分。

【讨论】:

    【解决方案2】:

    使用皮尔逊相关系数。我想出了如何在 SQL 查询中计算它,可以在这里找到:http://vanheusden.com/misc/pearson.php

    【讨论】:

      【解决方案3】:

      在金融领域,他们使用 Beta 来衡量 2 个数字系列的相关性。例如,Beta 可以回答“在过去一年中,在标准普尔 500 指数上涨 5% 的一天,IBM 的价格会上涨多少?”它处理移动的百分比,因此 2 系列可以有不同的比例。

      在我的示例中,Beta 是 Covariance(IBM, S&P 500) / Variance(S&P 500)。

      维基百科有解释CovarianceVariance和Beta的页面:http://en.wikipedia.org/wiki/Beta_(finance)

      【讨论】:

        【解决方案4】:

        查看统计网站。我认为您正在寻找相关性。

        【讨论】:

        • 相关性是我检查的第一件事,但它只测量曲线的相似性,而不是实际值。如果温度每小时上升和下降的幅度相同,但相差 100 度,则相关性仍为 1。
        【解决方案5】:

        例如,我假设您正在测量温度、风和降水。我们将这些项目称为“功能”。所以有效值可能是:

        • 温度:-50 到 100F(我在美国明尼苏达州)
        • 风速:0 到 120 英里/小时(不确定这是否现实,但请耐心等待)
        • 沉淀:0 到 100

        首先标准化您的数据。 Temp 的范围为 150 个单位,Wind 为 120 个单位,Precip 为 100 个单位。将你的风单位乘以 1.25 和 Precip 乘以 1.5,使它们与你的温度大致相同的“比例”。您可以在这里花哨并制定规则,使一项功能比其他功能更有价值。在此示例中,风的范围可能很大,但通常保持在较小的范围内,因此您希望减少其权重以防止它影响您的结果。

        现在,将每个测量值想象成多维空间中的一个点。此示例测量 3d 空间(温度、风、降水)。好消息是,如果我们添加更多特征,我们只是增加了空间的维度,但数学保持不变。无论如何,我们想找到最接近我们当前点的历史点。最简单的方法是Euclidean distance。所以测量我们当前点到每个历史点的距离并保持最接近的匹配:

        for each historicalpoint
        
            distance = sqrt(
                pow(currentpoint.temp - historicalpoint.temp, 2) + 
                pow(currentpoint.wind - historicalpoint.wind, 2) +
                pow(currentpoint.precip - historicalpoint.precip, 2))
        
            if distance is smaller than the largest distance in our match collection
                add historicalpoint to our match collection
                remove the match with the largest distance from our match collection
        
        next
        

        这是一种蛮力方法。如果你有时间,你可以变得更漂亮。多维数据可以表示为像kd-treesr-trees 这样的树。如果您有大量数据,将您当前的观察结果与每个历史观察结果进行比较将太慢。树木可以加快您的搜索速度。您可能想看看Data ClusteringNearest Neighbor Search

        干杯。

        【讨论】:

          【解决方案6】:

          与统计学家交谈。

          说真的。

          他们以做这种事情为生。

          您写道“两个集合的相似性有点主观”,但它根本不是主观的——这是为您的问题域确定适当的相似性标准的问题。 p>

          在这种情况下,您最好与专业人士交谈,而不是向一群程序员提问。

          【讨论】:

            【解决方案7】:

            首先,问问自己这些是集合还是有序集合。

            我假设这些是带有重复的有序集合。最明显的算法是选择一个数字被认为相同的容差,并计算在该度量下数字相同的槽数。

            【讨论】:

            • 在这种情况下,我所有的集合都是有序的,每个集合包含 24 小时值。选择容差水平的问题是在运行之前我不知道值的比例。
            • 等等……你知道这些是天气数据,但你不知道比例吗?如果真是这样,为什么不通过分析数据的标准差来动态选择容差呢?
            【解决方案8】:

            我确实在我的应用程序中为此实施了解决方案,但我正在寻找是否有更好或更“正确”的东西。对于每个历史日,我都会执行以下操作:

            function calculate_score(historical_set, forecast_set)
            {
                double c = correlation(historical_set, forecast_set);
                double avg_history = average(historical_set);
                double avg_forecast = average(forecast_set);
                double penalty = abs(avg_history - avg_forecast) / avg_forecast
                return c - penalty;
            }
            

            然后我将所有结果从高到低排序。

            由于相关性是一个从 -1 到 1 的值,表示数字是一起下降还是一起上升,所以我用百分比差异来“惩罚”这两组数字的平均值。

            【讨论】:

              【解决方案9】:

              您曾多次提到您不知道数据的分布情况,这当然是正确的。我的意思是,明天可能会有华氏 150 度的一天,风速为 2000 公里/小时,但这似乎不太可能。

              我认为你对分布有很好的了解,因为你有很长的历史记录。鉴于此,您可以根据历史分布的分位数来放置所有内容,并使用所有度量上的分位数的绝对差或平方差来做一些事情。这是另一种归一化方法,但它解释了数据中的非线性。

              任何风格的标准化都应该使所有变量具有可比性。

              例如,假设某天风很大,很热:温度分位数可能是 0.75,风分位数可能是 0.75。热量的 0.76 分位数可能在 1 度之外,而风的分位数可能在 3 公里/小时之外。

              这种对经验分布的关注也很容易理解,并且可能比正态估计(如均方误差)更稳健。

              【讨论】:

              • 天气只是该算法可用于数据的一种示例类型。我不知道将输入什么类型的数据。可能是棒球场的热狗销售、高速公路上行驶的汽车数量、电力负荷等。
              【解决方案10】:

              这两个数据集是否有序?

              如果排序,索引是否相同?等距?

              如果指数是共同的(例如,在同一天(但在不同地点)测量的温度),您可以将第一个数据集与第二个数据集进行回归, 然后测试斜率等于1,截距为0。
              http://stattrek.com/AP-Statistics-4/Test-Slope.aspx?Tutorial=AP

              否则,您可以对 y=values 与它们的索引进行两次回归。 http://en.wikipedia.org/wiki/Correlation。您仍然需要比较斜率和截距。

              ====

              如果是无序的,我想你想看看累积分布函数 http://en.wikipedia.org/wiki/Cumulative_distribution_function

              一个相关的测试是 Kolmogorov-Smirnov: http://en.wikipedia.org/wiki/Kolmogorov-Smirnov_test

              你也可以看看

              学生的 t 检验, http://en.wikipedia.org/wiki/Student%27s_t-test

              或 Wilcoxon 符号秩检验 http://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test

              测试两个样本之间均值的相等性。

              您可以使用 Levene 测试 http://www.itl.nist.gov/div898/handbook/eda/section3/eda35a.htm 测试方差是否相等

              注意:不同的数据集可能具有相同的均值和方差 - 根据您想要的严格程度(以及您拥有的数据量),您可以考虑测试也适用于更高时刻的平等。

              【讨论】:

                【解决方案11】:

                也许您可以将您的一组数字视为一个向量(该组的每个数字都是该向量的一个分量)。

                然后您可以简单地使用点积来计算 2 个给定向量(即一组数字)的相似度。

                你可能需要标准化你的向量。

                更多:Cosine similarity

                【讨论】:

                  猜你喜欢
                  • 2011-07-06
                  • 2020-05-26
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-11-06
                  • 1970-01-01
                  • 2018-11-27
                  • 2011-02-17
                  • 2012-01-27
                  相关资源
                  最近更新 更多