将float数组划分为类似的段(聚类)

我有一个像这样的浮点数组:

[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]将被视为exception值,因为群集支持较少

我必须为几个数组找到这种段,我不知道分区大小应该是多少。 我试图通过使用层次聚类(Agglomerative)来做到这一点,它给我带来满意的结果。 然而,问题是,我被建议不要将聚类算法用于一维问题,因为它们没有理论上的理由(因为它们用于多维数据)。

我花了很多时间来寻找解决方案。 但是,建议看起来很不一样: 这个和这个 VS. 这和这个和这个 。

我发现了另一个建议,而不是聚类,即自然中断优化 。 但是,这也需要声明分区号,如K-means(右?)。

这很混乱(特别是因为我必须在几个arrays上执行这种分段,并且不可能知道最佳分区号)。

有什么方法可以找到分区(因此我们可以减少分区内的差异并最大化分区之间的差异),并提供一些理论上的理由吗?

任何指向文章/论文的指针(如果有可用的C / C ++ / Java实现)都有一些理论上的理由对我很有用。

我想我会对数据进行排序(如果还没有),那么请考虑相邻的差异。 将差异除以数字中较小的数字,即获得百分比变化之间的差异。 设置阈值,当更改超过该阈值时,启动新的“群集”。

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

 #include  #include  #include  #include  #include  #include  int main() { std::vector 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 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()); // 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; } 

结果:

 1.91 2.87 3.61 10.91 11.91 12.82 100.71 100.73 101.89 200 

聚类通常假设多维数据。

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

在一维中,问题变得非常容易,因为数据可以被分类。 如果您使用聚类算法,遗憾的是不会利用它,因此请使用1维方法!

考虑找到1维数据中的最大差距。 它是微不足道的:排序(n log n,但在实践中尽可能快),然后查看两个相邻的值以获得最大的差异。

现在尝试在2维中定义“最大间隙”,并找到一种有效的算法来定位它…