Java 将浮点数组划分为相似的段(群集)

Java 将浮点数组划分为相似的段(群集),java,c++,algorithm,cluster-analysis,data-partitioning,Java,C++,Algorithm,Cluster Analysis,Data Partitioning,我有一个如下的浮动数组: [1.91, 2.87, 3.61, 10.91, 11.91, 12.82, 100.73, 100.71, 101.89, 200] [[1.91, 2.87, 3.61] , [10.91, 11.91, 12.82] , [100.73, 100.71, 101.89] , [200]] 现在,我想对数组进行如下分区: [1.91, 2.87, 3.61, 10.91, 11.91, 12.82, 100.73, 100.71, 101.89, 200]

我有一个如下的浮动数组:

[1.91, 2.87, 3.61, 10.91, 11.91, 12.82, 100.73, 100.71, 101.89, 200]
[[1.91, 2.87, 3.61] , [10.91, 11.91, 12.82] , [100.73, 100.71, 101.89] , [200]]
现在,我想对数组进行如下分区:

[1.91, 2.87, 3.61, 10.91, 11.91, 12.82, 100.73, 100.71, 101.89, 200]
[[1.91, 2.87, 3.61] , [10.91, 11.91, 12.82] , [100.73, 100.71, 101.89] , [200]]
//[200]将被视为异常值,因为较少的群集支持

我必须为几个数组找到这种类型的段,我不知道分区大小应该是多少。我试着用它来做,它给了我满意的结果。然而,问题是,有人建议我不要对一维问题使用聚类算法,因为这样做并没有理论依据(就像多维数据一样)

我花了很多时间寻找解决办法。然而,建议似乎完全不同,如:和与和

我发现了另一个建议,而不是聚类,即。然而,这也需要像K-means一样声明分区号(对吗?)

这是相当混乱的(特别是因为我必须在几个数组上执行这种分割,并且不可能知道最佳分区数)

有没有什么方法可以找到分区(这样我们就可以减少分区内的差异并最大化分区间的差异)并从理论上证明

任何有理论依据的文章/论文(如果有C/C++/Java实现)都会对我很有帮助。

我想我应该对数据进行排序(如果还没有),然后取相邻的差异。将差值除以两者之间的较小数值,得到百分比变化。设置一个阈值,当更改超过该阈值时,启动一个新的“集群”

编辑:C++中的快速演示代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>
#include <functional>

int main() {
    std::vector<double> data{ 
        1.91, 2.87, 3.61, 10.91, 11.91, 12.82, 100.73, 100.71, 101.89, 200 
    };

    // sort the input data
    std::sort(data.begin(), data.end());

    // find the difference between each number and its predecessor
    std::vector<double> diffs;
    std::adjacent_difference(data.begin(), data.end(), std::back_inserter(diffs));

    // convert differences to percentage changes
    std::transform(diffs.begin(), diffs.end(), data.begin(), diffs.begin(),
        std::divides<double>());

    // print out the results
    for (int i = 0; i < data.size(); i++) {

        // if a difference exceeds 40%, start a new group:
        if (diffs[i] > 0.4)
            std::cout << "\n";

        // print out an item:
        std::cout << data[i] << "\t";
    }

    return 0;
}

聚类通常假设多维数据

如果您有一维数据,对其进行排序,然后使用内核密度估计,或者只扫描最大间隙

在一维中,由于数据可以排序,问题变得简单多了。如果你使用一个聚类算法,不幸的是它不会利用这一点,所以使用一维方法代替

考虑在一维数据中查找最大间隙。这很简单:排序(n logn,但实际上要尽可能快),然后查看两个相邻值的最大差异


现在,请尝试在二维中定义“最大间距”,并使用一种有效的算法来定位它……

我很好奇为什么聚类不适合一维数据-如果您以某种方式增加维度,例如,添加sqrt(n)作为维度,有点像支持向量机中发生的情况,会怎么样?@ZiyaoWei,“为什么聚类不适合一维数据”-我真的不知道。我在课堂上被告知,在一维数据中使用聚类是疯狂的。但是,我没有找到一篇文章说明为什么我不能(或可以).@ZiyaoWei无缘无故地增加维度似乎不是一个好的解决方案。不,不是,只是认为一维和多维数据之间没有真正的区别。或者它们是吗?“…减少分区内的差异,最大化分区间的差异。。。“如果你能确切地告诉我们你的意思,也许我们能帮上忙。你的意思是最小化((分区内的平均方差)-(分区间的平均方差))还是什么?你能详细说明一下吗?我不能得到它(如果可能的话,可能是伪代码)?我尝试了更大的样本。看起来它不起作用了[78、89、74、42、89、22、48、26、28、92、100、96、35、5、70、76、11、70、12、91、7、38、19、68、58、2、89、20、30、81、95、11、97、81、86、43、52、48、71、91、4、64、94、41、82、16、35、13、57、50]@deep_rugs:我想你误解了意图。对数据进行排序时,只有一个中断,因为数据中没有一个数字与下一个数字之间的变化大于40%的位置。如果您关心以原始顺序更改数据,请删除
std::sort
行,并将
If(diff[i]>0.4)
更改为
If(std::abs(diff[i])>0.4)