1

我有一个传感器,其输出数据由一个属性(单值)组成。序列数据打孔示例如下:

sample: 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 质心,我得到了不好的结果。大多数时候,一些初始质心共享相同的级别,使该级别成为两个集群,而其他两个级别属于一个集群。如果我通过从每个级别中选择一个质心来手动设置初始质心,我会得到非常好的结果。

4

4 回答 4

3

如果两个连续数据点之间的差异大于特定值(将此视为 Delta ),则它属于不同的集群。

for this data set : 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 为 15(基于 Sensor 微调)如果连续数据点的差异不大于 15,那么它们属于同一个集群。您可以通过找到集群的中间值来找到中心点。如果点附近的点有差异,那么它可以被认为是异常值。另一个选项是我们可以根据数据集的当前值改变增量。

于 2018-03-21T07:34:19.850 回答
2

这是@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)

聚类数据

这主要找到了您想要的集群,除了它包括最高集群中的最后两个点,而不是将它们声明为异常值。我不明白为什么他们应该是异常值而不是该组的一部分。也许您可以详细说明为什么您认为不应将它们包括在内。

我希望这个对你有用。

于 2018-03-23T17:11:27.497 回答
0

我建议 DBSCAN 而不是 K-Means。

它是一种基于密度的聚类算法,可以对彼此接近的数据点进行分组,而无需定义初始 k 或 K-Means 等质心。

在 DBSCAN 中,距离和 k 邻居是用户定义的。如果您知道 Index 具有一致的间隔,则 DBSCAN 可能适合解决您的问题。

于 2018-04-10T10:46:00.137 回答
0

我注意到这些级别看起来有点像线条。你可以这样做:

1. sort the points
2. take the first two unprocessed points into an ordered set called the current line
3. lay a line between the first and last point of the set
4. test whether the line formed by the first point and the next unprocessed point
    form a line that has an angle lower than some threshold to the other line
5. If yes, add the point and go to 3
6. If no, store the current line somewhere and start again at 2

您还可以首先检查这样一条线的前两个点与 x 轴的角度是否高于另一个阈值,如果是,则将第一个点存储为奇异值。异常值。

另一个版本是仅通过两点与 x 轴的连接角度。在水平变化时,角度(倾斜、坡度)将比水平上的两点之间的角度大得多。

于 2018-04-10T11:13:53.977 回答