将数据集划分为两个聚类,总等差异相等

将数据集划分为两个聚类,总等差异相等

问题描述:

我有一个数据集,它由多个元素组成 - 分为两个不同的类别(每个类别的元素数量相同) - 以及两个连续变量描述它们,就像这样:将数据集划分为两个聚类,总等差异相等

ID | Category | Variable_1 | Variable_2 
-------------------------------------------- 
1 | Triangle | 4.3522  | 5.2321 
2 | Triangle | 3.6423  | 6.3223 
3 | Circle | 5.2331  | 3.2452 
4 | Circle | 2.6334  | 7.3443 
... | ...  | ...   | ... 

现在,我想我的数据集分成尽可能与尽可能关于在各组的平均在于二维空间的两个新集,由Variable_1Variable_2定义。也就是说,两套之间的距离应尽可能接近。另外,如果可能的话(因为我知道这可能会使问题变得更加复杂),所以我希望两个集合中的差异尽可能匹配,例如我们可以在其中定义整个集合的方差作为每个变量的方差之和。在这里,我想你只是在你的空间中添加另一个方差来寻找方差,并试图找到由两个变量和方差组成的整个三维空间的最佳解决方案。

如何在R中实现这一点?

+0

听起来像你真的想**聚类**。具体分为2个集群。但是,您的等总差异度量标准是非标准的。请参阅http://en.wikipedia.org/wiki/K-means_clustering – smci 2014-10-29 23:27:03

+0

@speldosa恭敬地,我认为k-means在这种情况下是行不通的。 2个质心实际上是两个样本的平均值,显然不可能是相同的,否则我们不会有2个样本。质心是最好的,如果它们尽可能远离彼此。你也可以查看[这里](http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/kmeans.html)。附:我总是开放讨论:) – LyzandeR 2014-10-30 09:51:03

+0

@smci对不起,上面的消息是针对你而不是speldosa :)。对于那个很抱歉。 – LyzandeR 2014-10-30 10:02:58

我会尝试解决这个问题的方法是(如上所述)关心变量1和变量2之间的距离。 因此,我会创建一个名为distance的新字段(下面我将它命名为diff),它将被计算为variable1-variable2。然后,我会按该列对数据框进行排序,并逐行拆分数据帧,即每个奇数行将进入pot1,每个偶数行将进入pot2。这表现为以下代码作为示例:

id<-1:2000 
a<-runif(2000,-100,100) 
b<-runif(2000,-200,200) 
mydf <- data.frame(id,a,b) 

mydf['diff'] <- mydf[['a']] - mydf[['b']] 
mydf<-mydf[with(mydf, order(diff)), ] 

head(mydf,20) 

输出:

> head(mydf,20) #as you can see the dataframe is ordered by diff (ascending) 
     id   a  b  diff 
1732 1732 -95.96522 198.1666 -294.1318 
187 187 -94.24905 196.9341 -291.1831 
338 338 -95.31069 194.9997 -290.3104 
231 231 -91.98249 194.0672 -286.0497 
1513 1513 -97.01006 183.5874 -280.5974 
715 715 -94.53303 185.1026 -279.6356 
145 145 -99.73511 178.2460 -277.9811 
979 979 -87.73586 190.0489 -277.7848 
1165 1165 -85.53447 187.6254 -273.1598 
1243 1243 -94.75502 176.8572 -271.6122 
1208 1208 -77.32021 189.1589 -266.4791 
1826 1826 -92.23949 171.6341 -263.8736 
167 167 -98.84123 163.6960 -262.5372 
1283 1283 -76.54766 185.8721 -262.4197 
1391 1391 -72.04732 189.9422 -261.9896 
322 322 -77.53867 183.4744 -261.0131 
75  75 -88.04799 171.9066 -259.9546 
882 882 -65.11661 193.8533 -258.9699 
1119 1119 -77.59978 181.2392 -258.8390 
1624 1624 -81.81879 175.9795 -257.7983 

现在分裂数据帧:

samplea_1<-NULL 
samplea_2<-NULL 
sampleb_1<-NULL 
sampleb_2<-NULL 
id_1<-NULL 
id_2<-NULL 
diff_1<-NULL 
diff_2<-NULL 
for (i in 1:nrow(mydf)) { 
    if(i%%2==0) { 
    samplea_1 <- append(samplea_1,mydf$a[i]) 
    sampleb_1 <- append(sampleb_1,mydf$b[i]) 
    id_1  <- append(id_1,mydf$id[i]) 
    diff_1 <- append(diff_1,mydf$diff[i]) 
    } else { 
    samplea_2 <- append(samplea_2,mydf$a[i]) 
    sampleb_2 <- append(sampleb_2,mydf$b[i]) 
    id_2  <- append(id_2,mydf$id[i]) 
    diff_2 <- append(diff_2,mydf$diff[i]) 
    } 
} 

sample1<-data.frame(samplea_1,sampleb_1,id_1,diff_1) 
sample2<-data.frame(samplea_2,sampleb_2,id_2,diff_2) 
summary(sample1) 
summary(sample2) 

输出:

> summary(sample1) 
    samplea_1   sampleb_1    id_1   diff_1   
Min. :-99.2058 Min. :-199.519 Min. : 1.0 Min. :-291.183 
1st Qu.:-47.5615 1st Qu.:-100.917 1st Qu.: 495.8 1st Qu.:-105.851 
Median : 1.3997 Median : 7.004 Median : 980.5 Median : -1.333 
Mean : 0.7047 Mean : 2.044 Mean : 991.0 Mean : -1.340 
3rd Qu.: 50.4087 3rd Qu.: 101.678 3rd Qu.:1482.8 3rd Qu.: 99.381 
Max. : 99.8470 Max. : 199.833 Max. :2000.0 Max. : 291.797 
> summary(sample2) 
    samplea_2   sampleb_2    id_2   diff_2   
Min. :-99.7351 Min. :-199.9494 Min. : 2.0 Min. :-294.132 
1st Qu.:-48.4339 1st Qu.: -99.7880 1st Qu.: 509.8 1st Qu.:-106.338 
Median : -1.4627 Median : 6.8745 Median :1024.0 Median : -1.425 
Mean : -0.7104 Mean : 0.9099 Mean :1010.0 Mean : -1.620 
3rd Qu.: 48.1663 3rd Qu.: 94.7360 3rd Qu.:1513.2 3rd Qu.: 99.334 
Max. : 99.9496 Max. : 199.8544 Max. :1996.0 Max. : 288.840 

正如你可以看到diff列有alm因为我们根据该列对数据框进行了排序,但是正如您所看到的,列samplea和sampleb的大小相同,所以它们有点直观。发生这种情况是因为差异来源于a和b,但根据每个单独列a和b的方差有多高,结果将不太准确。

希望有帮助!

+0

如果我不想拿出其他东西,这可能会作为备份解决方案。谢谢! – Speldosa 2015-01-06 22:37:02

+0

酷!乐于帮助 :) – LyzandeR 2015-01-06 23:49:39