2016-01-28 34 views
1

我想在Python中对虹膜数据集的内部相似性进行编码。 这是来自同一班级的元素之间的距离。 例如对集:Python - 内部相似度

1 2 3 4 |0 
5 6 7 8 |0 
1 3 5 6 |1 
11 12 13 14 |0 
10 2 4 6 |1 

distance1 = (1-5)^2 + (2-6)^2 + (3 - 7)^2 + (4-8)^2 
distance1 = sqrt(distance1) 
distance2 = (1- 11)^2 + (2-12)^2 + (3 - 13)^2 + (4-14)^2 
distance2 = sqrt(distance2) 
similarityClass0 = (ditance1 + distance2)/2 

然后,我将不得不做1级,2,3等相同。

现在我的代码是我认为功能,但很丑陋
在输入我有X和Y.当我完成计算tab0,我做同样的 为tab1,tab2等

我的问题是:如何创建一个代码为n类?我的目标是还要对每一行内的相似程度

from sklearn import datasets 
import numpy as np 


iris = datasets.load_iris() 

iris.data.shape, iris.target.shape 

X = iris.data 
#0 = Setosa // 1 = Versicolor // 2 = Virginica 
y = iris.target 

#At first, we retrieve the indexes of each classes 
#For example if tab0 has classes on ligne 1,2,6. Tab0 will store 1,2,6 
tab0 = list() 
tab1 = list() 
tab2 = list() 
j = 0 

for output in y: 
    if output == 0 : 
     tab0.append(j) 
    if output == 1 : 
     tab1.append(j) 
    if output == 2 : 
     tab2.append(j) 
    j = j + 1 

######################################################################## 
#Computation intra similarity# 
import math 

sim0_intra = list() 
sim1_intra = list() 
sim2_intra = list() 

#Classes stores 1,2,3 (the 3classes), count the number of elements in each classes 
classes, count = np.unique(y, return_counts=True) 

temp = 0 

for i in tab0: 
    temp = 0 
    for j in tab0: 
     for k in range(len(X[0])): 
      temp = temp + np.square(X[i][k] - X[j][k]) 

    sim0_intra.append(np.sqrt(temp/(count[0] - 1))) 

回答

0

您可以使用sklearn.metrics.pairwise.pairwise_distances返回你的距离矩阵,默认情况下它使用“欧几里德”相似性(你在你的例子计算功能)。

你会发现这里的一切 http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.pairwise_distances.html

这里,一些代码;)

import numpy as np 
from sklearn import datasets 
from sklearn.metrics import pairwise 

iris = datasets.load_iris() 

X = iris.data 
Y = iris.target 

# dividing X by classes {0,1,2} to perform intra-distances 
X0 = X[np.where(Y==0)] 
X1 = X[np.where(Y==1)] 
X2 = X[np.where(Y==2)] 

sim0_intra = pairwise.pairwise_distances(X0, metric='euclidean') 
sim1_intra = pairwise.pairwise_distances(X1, metric='euclidean') 
sim2_intra = pairwise.pairwise_distances(X2, metric='euclidean') 

随着文档状态,pairwise_distances返回“距离矩阵d,使得D_ {I,J }是给定矩阵的第i个和第j个向量之间的距离X

因此,在我们的情况下,例如: sim0_intra[0][1] --> 0.53851648071346281是类0的第一个和第二个元素之间的距离。如果您要求类似sim0_intra[5][5] --> 0.0的东西并且观察距离为0,因为您要求与元素本身的距离不是:)

最后,你可以要求在每个矩阵的平均值,并且会给你的内部相似度:

similarityClass0 = sim0_intra.sum()/(50*50-50) # output: 0.69812194319103826 
similarityClass1 = sim1_intra.sum()/(50*50-50) # output: 0.99736067331161615 
similarityClass2 = sim2_intra.sum()/(50*50-50) # output: 1.1767808010528609 

我自己计算的平均值(应该有更漂亮的方式来做到这一点)。我将所有距离(通过两次加法)加起来除以元素总数(50 * 50),但减去对角线中的元素。

注:我已经试过几件事情,因为np.triu它给你的矩阵的上半部分,然后试图打电话mean但考虑到基体的下部为好,是不平均现在0.所以...如果有更漂亮的方法来实现它,请分享! :)