如何从相似矩阵绘制 MDS?
How to plot a MDS from a similarity matrix?
我正在使用值介于 0 和 1 之间的相似度矩阵(1 表示元素相等),并且我正在尝试使用 python 和 scikit-learn 绘制 MDS。
我找到了多个示例,但我不确定将什么作为 mds.fit() 的输入。
现在,我的数据看起来像这样 (file.csv) :
; A ; B ; C ; D ; E
A ; 1 ; 0.1 ; 0.2 ; 0.5 ; 0.2
B ; 0.1 ; 1 ; 0.3 ; 1 ; 0
C ; 0.2 ; 0.3 ; 1 ; 0.8 ; 0.6
D ; 0.5 ; 1 ; 0.8 ; 1 ; 0.2
E ; 0.2 ; 0 ; 0.6 ; 0.2 ; 1
我目前正在使用此代码:
import pandas
from sklearn import manifold
import matplotlib.pyplot as plt
data = pandas.read_table("file.csv", ";", header=0, index_col=0)
mds = manifold.MDS(n_components=2, random_state=1, dissimilarity="precomputed")
mds.fit(data)
points = mds.embedding_
# Prepare axes
ax = plt.axes([0,0,2,2])
ax.set_aspect(aspect='equal')
# Plot points
plt.scatter(points[:,0], points[:,1], color='silver', s=150)
# Add labels
for i in range(data.shape[0]):
ax.annotate(data.index[i], (points[i,0], points[i,1]), color='blue')
#plt.show() # Open display and show at screen
plt.savefig('out.png', format='png', bbox_inches='tight') # PNG
#plt.savefig('out.jpg', format='jpg', bbox_inches='tight') # JPG
我不确定 sklearn 在做什么。我读了很多例子,其中人们使用中间为 0(而不是 1)的“相异矩阵”。
要不要转型?或不 ?如果是,应该进行哪种转换?
(我读到 there 一个简单的减法就足够了......但其他方法存在......我有点迷路:( )
sklearn 和 MDS 会自动理解输入吗? (作为中间为 0 或 1 的相似或相异矩阵?)
还是使用距离矩阵? (这样的话,如何从相似度矩阵中得到呢?)
在这个 link 中,他们说相似度介于 1 和 -1 之间...我使用的相似度介于 0 和 1 之间...我想我应该转换我的数据?应该使用哪种转换?
我与 XLSTAT(一个 excel 扩展)进行了比较,以便尝试很多场景并比较如何做。
首先:我的输入矩阵是一个“相似性”矩阵,因为我可以将其解释为:“A 和 A 100% 相等”。
由于 MDS 将相异矩阵作为输入,我必须应用转换。
- 在文献Ricco Rakotomalala's french course on data science (p 208-209)中,简单的方法是将最大值减去每个单元格(进行“1 - 单元格”操作)。
所以你可以很容易地制作一个 python 程序,或者(因为我跟踪每个矩阵)一个 AWK pre-processing 程序:
similarity-to-dissimilarity-simple.awk
# We keep the tags around the CSV matrix
# X ; Word1 ; Word2 ; ...
# Header
NR == 1 {
# First column is just "X" (or space)
printf("%s", "X");
# For each column, print the word
for (i = 2; i <= NF; i++)
{
col = $i;
printf("%s%s", OFS, col);
}
# End of line
printf("\n");
}
# Other lines are processed
# WordN ; 1 ; 0.5 ; 0.2 ; ...
NR != 1 {
# First column is the word/tag
col = ;
printf("%s", col);
# For each column, process the number
for (i = 2; i <= NF; i++)
{
# dissimilarity = (1 - similarity)
NUM = $i;
VAL = 1 - NUM;
printf("%s%s", OFS, VAL);
}
printf("\n");
}
可以使用命令调用:
awk -F ";" -v OFS=";" -f similarity-to-dissimilarity-simple.awk input.csv > output-simple.csv
- 一种更复杂的计算方式(我找不到参考资料,抱歉 :( ) 是基于对每个单元格的另一个转换 :
如果对角线不包含相同的值(我看到there一个co-occurrence矩阵......它应该适用于他的cas),这种方法似乎可以完美适应。
在我的例子中,由于对角线总是充满 1,我将其减少为:
因此进行此转换的 AWK 程序(由于我的数据,我实施了简化的程序)是:
similarity-to-dissimilarity-complex.awk
# Header
# X ; Word1 ; Word2 ; ...
NR == 1 {
# First column is just "X" (or space)
printf("%s", "X");
# For each column, print the word
for (i = 2; i <= NF; i++)
{
col = $i;
printf("%s%s", OFS, col);
}
# End of line
printf("\n");
}
# Other lines are processed
# WordN ; 1 ; 0.5 ; 0.2 ; ...
NR != 1 {
# First column is the word
col = ;
printf("%s", col);
# For each column, process the number
for (i = 2; i <= NF; i++)
{
# dissimilarity = (2 - 2 * similarity)^-1/2
NUM = $i;
VAL = sqrt(2 - 2 * NUM);
printf("%s%s", OFS, VAL);
}
printf("\n");
}
你可以用这个命令调用它:
awk -F ";" -v OFS=";" -f similarity-to-dissimilarity-complex.awk input.csv > output-complex.csv
当我使用 Kruskal 的压力来检查哪个版本更好时......在我的情况下,简单相似性与相异性(1 - 细胞)是最好的(我将压力保持在 0,34 和 0,32 之间... 这不好... 其中复数显示的值大于 0,34,这更糟)。
我正在使用值介于 0 和 1 之间的相似度矩阵(1 表示元素相等),并且我正在尝试使用 python 和 scikit-learn 绘制 MDS。
我找到了多个示例,但我不确定将什么作为 mds.fit() 的输入。
现在,我的数据看起来像这样 (file.csv) :
; A ; B ; C ; D ; E
A ; 1 ; 0.1 ; 0.2 ; 0.5 ; 0.2
B ; 0.1 ; 1 ; 0.3 ; 1 ; 0
C ; 0.2 ; 0.3 ; 1 ; 0.8 ; 0.6
D ; 0.5 ; 1 ; 0.8 ; 1 ; 0.2
E ; 0.2 ; 0 ; 0.6 ; 0.2 ; 1
我目前正在使用此代码:
import pandas
from sklearn import manifold
import matplotlib.pyplot as plt
data = pandas.read_table("file.csv", ";", header=0, index_col=0)
mds = manifold.MDS(n_components=2, random_state=1, dissimilarity="precomputed")
mds.fit(data)
points = mds.embedding_
# Prepare axes
ax = plt.axes([0,0,2,2])
ax.set_aspect(aspect='equal')
# Plot points
plt.scatter(points[:,0], points[:,1], color='silver', s=150)
# Add labels
for i in range(data.shape[0]):
ax.annotate(data.index[i], (points[i,0], points[i,1]), color='blue')
#plt.show() # Open display and show at screen
plt.savefig('out.png', format='png', bbox_inches='tight') # PNG
#plt.savefig('out.jpg', format='jpg', bbox_inches='tight') # JPG
我不确定 sklearn 在做什么。我读了很多例子,其中人们使用中间为 0(而不是 1)的“相异矩阵”。
要不要转型?或不 ?如果是,应该进行哪种转换? (我读到 there 一个简单的减法就足够了......但其他方法存在......我有点迷路:( )
sklearn 和 MDS 会自动理解输入吗? (作为中间为 0 或 1 的相似或相异矩阵?) 还是使用距离矩阵? (这样的话,如何从相似度矩阵中得到呢?)
在这个 link 中,他们说相似度介于 1 和 -1 之间...我使用的相似度介于 0 和 1 之间...我想我应该转换我的数据?应该使用哪种转换?
我与 XLSTAT(一个 excel 扩展)进行了比较,以便尝试很多场景并比较如何做。
首先:我的输入矩阵是一个“相似性”矩阵,因为我可以将其解释为:“A 和 A 100% 相等”。 由于 MDS 将相异矩阵作为输入,我必须应用转换。
- 在文献Ricco Rakotomalala's french course on data science (p 208-209)中,简单的方法是将最大值减去每个单元格(进行“1 - 单元格”操作)。 所以你可以很容易地制作一个 python 程序,或者(因为我跟踪每个矩阵)一个 AWK pre-processing 程序:
similarity-to-dissimilarity-simple.awk
# We keep the tags around the CSV matrix
# X ; Word1 ; Word2 ; ...
# Header
NR == 1 {
# First column is just "X" (or space)
printf("%s", "X");
# For each column, print the word
for (i = 2; i <= NF; i++)
{
col = $i;
printf("%s%s", OFS, col);
}
# End of line
printf("\n");
}
# Other lines are processed
# WordN ; 1 ; 0.5 ; 0.2 ; ...
NR != 1 {
# First column is the word/tag
col = ;
printf("%s", col);
# For each column, process the number
for (i = 2; i <= NF; i++)
{
# dissimilarity = (1 - similarity)
NUM = $i;
VAL = 1 - NUM;
printf("%s%s", OFS, VAL);
}
printf("\n");
}
可以使用命令调用:
awk -F ";" -v OFS=";" -f similarity-to-dissimilarity-simple.awk input.csv > output-simple.csv
- 一种更复杂的计算方式(我找不到参考资料,抱歉 :( ) 是基于对每个单元格的另一个转换 :
如果对角线不包含相同的值(我看到there一个co-occurrence矩阵......它应该适用于他的cas),这种方法似乎可以完美适应。 在我的例子中,由于对角线总是充满 1,我将其减少为:
因此进行此转换的 AWK 程序(由于我的数据,我实施了简化的程序)是:
similarity-to-dissimilarity-complex.awk
# Header
# X ; Word1 ; Word2 ; ...
NR == 1 {
# First column is just "X" (or space)
printf("%s", "X");
# For each column, print the word
for (i = 2; i <= NF; i++)
{
col = $i;
printf("%s%s", OFS, col);
}
# End of line
printf("\n");
}
# Other lines are processed
# WordN ; 1 ; 0.5 ; 0.2 ; ...
NR != 1 {
# First column is the word
col = ;
printf("%s", col);
# For each column, process the number
for (i = 2; i <= NF; i++)
{
# dissimilarity = (2 - 2 * similarity)^-1/2
NUM = $i;
VAL = sqrt(2 - 2 * NUM);
printf("%s%s", OFS, VAL);
}
printf("\n");
}
你可以用这个命令调用它:
awk -F ";" -v OFS=";" -f similarity-to-dissimilarity-complex.awk input.csv > output-complex.csv
当我使用 Kruskal 的压力来检查哪个版本更好时......在我的情况下,简单相似性与相异性(1 - 细胞)是最好的(我将压力保持在 0,34 和 0,32 之间... 这不好... 其中复数显示的值大于 0,34,这更糟)。