如果我有一个包含值[6712, 7023, 7510, 7509, 6718, 7514, 7509, 6247]
的数组,并且我想要4组相似的数字,那么输出就是4个矩阵:
[6247]
[6712, 6718]
[7023]
[7510, 7509, 7514, 7509]
实现这一目标的最佳方法是什么?
答案 0 :(得分:6)
我相信您要找的字词是 clustering 。例如,我们可以应用Kmeans algorithm将数据分组为4个集群:
X = [6712, 7023, 7510, 7509, 6718, 7514, 7509, 6247];
[IDX,C] = kmeans(X, 4, 'EmptyAction','singleton');
G = cell(4,1);
for i=1:4
G{i} = X(IDX==i);
end
这是我得到的结果之一:
>> G{:}
ans =
7510 7509 7514 7509
ans =
7023
ans =
6247
ans =
6712 6718
通常这对于更多点来说效果最好(也适用于多维数据)
答案 1 :(得分:1)
实际上,对于您的具体情况,实际上不需要任何类型的复杂(并且非常难以理解)的聚类过程,也不需要任何(看似简单的)基于显式排序的解决方案。
现在假设您的值彼此接近(或多或少,如abs(x- x_0)<= 50
)定义组(感兴趣的),那么为什么不只是以一种非常简单和直接的方式进行。
因此,通过互相利用你们价值观的“最自然”proximity;你可以按照以下步骤进行操作:
>>> x= [6712 7023 7510 7509 6718 7514 7509 6247]; g= round(x/ 50)
g =
134 140 150 150 134 150 150 125
>>> groups= {}; for g_u= unique(g), groups{end+ 1}= x(g_u== g); end
>>> groups
groups =
{
[1,1] = 6247
[1,2] = 6712 6718
[1,3] = 7023
[1,4] = 7510 7509 7514 7509
}
答案 2 :(得分:0)
“相似”是什么意思?例如,为什么6718与7023不相似?我们的意思是“组中连续整数之间的差异&lt; N”?
如果是这样,请对数组进行排序,然后单步执行,确定需要它们的边界(即差异太大时)。然后简单地拆分一个新阵列。
比如......
GroupSimilar(values)
1. result := list()
2. values' := sort(values)
3. temp := list()
4. for i := 1 to |values'| - 1 do
5. if values'[i+1] - values'[i] <= diff then
6. temp.add(values'[i])
7. else
8. result.add(temp)
9. temp := list()
10. return result
答案 3 :(得分:0)
您必须首先确定确定组边界的标准。例如,您可以将阈值设置为50,因此任何与其最接近的较大或较小值不同的值都被视为属于不同的组。
您可以通过首先使用函数SORT对数组进行排序,然后在排序数组中找到相邻值之间的差异大于阈值(即组边界的位置)的索引,以矢量化方式解决此问题是)使用函数DIFF和FIND。获取这些索引之间的差异(再次使用函数DIFF)为您提供每个组的大小向量,可以使用函数MAT2CELL将排序的数组分解为单元格数组。这是代码的样子:
threshold = 50;
array = [6712 7023 7510 7509 6718 7514 7509 6247];
sortedArray = sort(array);
nPerGroup = diff(find([1 (diff(sortedArray) > threshold) 1]));
groupArray = mat2cell(sortedArray,1,nPerGroup);
groupArray
将是一个1乘4的单元格数组,其中每个单元格包含一组值的值。以下示例的groupArray
内容如下:
>> groupArray{:}
ans =
6247
ans =
6712 6718
ans =
7023
ans =
7509 7509 7510 7514