嗨,大家好,
我有一个传感器,其输出数据由一个属性(单值)组成。打孔顺序数据的示例如下:
样品:
199
200
205
209
217
224
239
498
573
583
583
590
591
594
703
710
711
717
719
721
836
840
845
849
855
855
856
857
858
858
928
935
936
936
942
943
964
977
您可以从第一个图像输入中看到数据。
数据分为多个级别。为我提供了级别数(在此示例中为5个级别)。但是,每个级别的样本数量未知,并且级别之间的距离也未知。
我需要排除异常值并定义每个级别的中心(请看第二个图像输出。
红色样本代表离群值,黄色样本代表水平中心。有没有算法,数学公式,C++代码可以帮助我达到这一要求?
我尝试了KMeans(在此示例中,K = 5),但由于初始K质心随机,我得到了不好的结果。大多数时候,一些惯性质心共享同一级别,从而使该级别成为两个群集,而其他两个级别属于一个群集。如果我通过从每个级别中选择一个质心来手动设置初始质心,我会得到很好的结果。
任何帮助,将不胜感激!
最佳答案
这是@KarthikeyanMV答案的扩展。 +1。是的,您需要能够确定Delta值。这是一个可以做到的过程。我正在用R编写代码,但是我认为过程会很清楚。
大概,组之间的差距大于任何组内的差距,因此只需查看连续点之间的差异并询问大差距在哪里。由于您认为应该有5个小组,因此应该有4个大的差距,因此请看第4个最大的差异。
## Your data
dat = c(199, 200, 205, 209, 217, 224, 239, 498, 573, 583,
583, 590, 591, 594, 703, 710, 711, 717, 719, 721,
836, 840, 845, 849, 855, 855, 856, 857, 858, 858,
928, 935, 936, 936, 942, 943, 964, 977)
(Delta = sort(diff(dat), decreasing=TRUE)[4])
[1] 75
看起来Delta应该是75,但我们没有考虑异常值。从上一个下一个点到下一个点是否都存在比Delta大的点?是。
BigGaps = diff(dat) >= Delta
(Outliers = which(c(BigGaps, T) & c(T, BigGaps)))
[1] 8
点8距离太远,无法属于上方或下方的组。因此,让我们将其删除,然后重试。
dat = dat[-Outliers]
(Delta = sort(diff(dat), decreasing=TRUE)[4])
[1] 70
BigGaps = diff(dat) >= Delta
(Outliers = which(c(BigGaps, T) & c(T, BigGaps)))
integer(0)
删除点8后,新的Delta为70。我们使用新的Delta(70)检查异常值,没有发现异常值。因此,让我们使用Delta = 70进行聚类。
Cluster = cumsum(c(1, diff(dat)>=Delta))
plot(dat, pch=20, col=Cluster+1)
这主要是找到您想要的聚类,除了它在最高聚类中包括最后两个点,而不是将它们声明为离群值。我不明白为什么他们应该是离群值而不是这个组的一部分。也许您可以详细说明为什么您认为不应将它们包括在内。
我希望这个对你有用。
关于c++ - 仅知道等级数即可识别一维数据的等级,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49387903/