为什么 `sklearn.manifold.MDS` 是随机的,而 `skbio 的 pcoa` 不是?

Why is `sklearn.manifold.MDS` random when `skbio's pcoa` is not?

我正在尝试弄清楚如何使用各种距离度量来实现 Principal Coordinate Analysis。我偶然发现了 skbiosklearn 的实现。 我不明白为什么 sklearn 的实现每次都不同,而 skbio 是相同的? Multidimensional ScalingMultidimensional Scaling 有一定程度的随机性吗?特别是 Principal Coordinate Analysis?我看到所有的集群都非常相似,但为什么它们不同?我是否正确实施了这一点?

运行 Principal Coordinate Analysis 使用 Scikit-bio(即 Skbio)总是得到相同的结果:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn import decomposition
import seaborn as sns; sns.set_style("whitegrid", {'axes.grid' : False})
import skbio
from scipy.spatial import distance

%matplotlib inline
np.random.seed(0)

# Iris dataset
DF_data = pd.DataFrame(load_iris().data, 
                       index = ["iris_%d" % i for i in range(load_iris().data.shape[0])],
                       columns = load_iris().feature_names)
n,m = DF_data.shape
# print(n,m)
# 150 4

Se_targets = pd.Series(load_iris().target, 
                       index = ["iris_%d" % i for i in range(load_iris().data.shape[0])], 
                       name = "Species")

# Scaling mean = 0, var = 1
DF_standard = pd.DataFrame(StandardScaler().fit_transform(DF_data), 
                           index = DF_data.index,
                           columns = DF_data.columns)

# Distance Matrix
Ar_dist = distance.squareform(distance.pdist(DF_data, metric="braycurtis")) # (n x n) distance measure
DM_dist = skbio.stats.distance.DistanceMatrix(Ar_dist, ids=DF_standard.index)
PCoA = skbio.stats.ordination.pcoa(DM_dist)

现在 sklearnMultidimensional Scaling:

from sklearn.manifold import MDS
fig, ax=plt.subplots(ncols=5, figsize=(12,3))
for rs in range(5):
    M = MDS(n_components=2, metric=True, random_state=rs, dissimilarity='precomputed')
    A = M.fit(Ar_dist).embedding_
    ax[rs].scatter(A[:,0],A[:,1], c=[{0:"b", 1:"g", 2:"r"}[t] for t in Se_targets])

MDS是一个概率算法,有一个参数random_state可以用来固定随机种子,如果你想每次都得到相同的结果可以传这个。另一方面,PCA 是一种确定性算法,如果你使用 sklearn.decomposition.PCA,你应该每次都得到相同的结果。

scikit-bio 的 PCoA (skbio.stats.ordination.pcoa) 和 scikit-learn 的 MDS (sklearn.manifold.MDS) 使用完全不同的算法来转换数据。 scikit-bio 直接求解对称特征值问题,而 scikit-learn 使用迭代最小化过程 [1].

scikit-bio 的 PCoA 是确定性的,尽管根据在 [2] 上执行的系统,可以接收变换坐标的不同(任意)旋转。 scikit-learn 的 MDS 默认是随机的,除非使用固定的 random_staterandom_state 似乎用于初始化迭代最小化过程(scikit-learn 文档说 random_state 用于 "initialize the centers" [3] 虽然我不知道这到底是什么意思) .每个 random_state 可能会通过任意旋转 [4].

产生略微不同的嵌入

参考文献:[1], [2], [3], [4]