πŸŽ‰ 75% of content is free forever β€” Unlock Premium from $10/mo β†’
CW
Search courses…
πŸ’Ό Servicesℹ️ Aboutβœ‰οΈ ContactView Pricing Plansfrom $10

Multidimensional Scaling (MDS)

Advanced Statistical MethodsDimensionality Reduction🟒 Free Lesson

Advertisement

Introduction

Advanced Statistical Methods

Visualizing Similarity as Spatial Maps

Multidimensional scaling transforms proximity data into a geometric configuration where distances reflect similarities. Both metric and non-metric MDS preserve relational structure in low-dimensional maps.

  • Marketing research β€” Visualize how consumers perceive brand similarities in perceptual maps
  • Psychology β€” Map cognitive distances between stimuli in multidimensional space
  • Bioinformatics β€” Visualize genetic distances between populations in two or three dimensions

MDS turns abstract similarity judgments into intuitive spatial representations.


Multidimensional Scaling (MDS) is a family of techniques that transform a matrix of pairwise distances or dissimilarities into a configuration of points in a low-dimensional space. The goal is to preserve the original distance structure as faithfully as possible, yielding a spatial representation that reveals hidden patterns in proximity data.

MDS is particularly valuable when the underlying variables are latent or when direct measurement is infeasible β€” for example, when subjects can judge the similarity between stimuli but cannot articulate the dimensions on which they differ.

Distance and Dissimilarity

Mathematical Preliminaries

Let be an matrix of observed dissimilarities between objects. MDS seeks points (with ) such that the Euclidean distances approximate .

Classical MDS (Principal Coordinates Analysis)

Eigendecomposition Method

Classical MDS (also called Principal Coordinates Analysis, Torgerson, 1952) provides an exact solution when dissimilarities are Euclidean distances:

The quality of representation is assessed by the proportion of variance explained:

Torgerson's Double Centering

Classical MDS can be expressed as a Gram matrix decomposition:

Metric MDS

Stress Function

When the dissimilarities are not Euclidean, or when a general monotonic relationship is desired, metric MDS minimizes a stress function:

Common stress measures include:

Strain (Smallest Space Analysis)

An alternative to stress is the strain function (Lingoes, 1971; Guttman, 1968):

Non-Metric MDS

Ordinal Stress

When only the rank order of dissimilarities is meaningful (ordinal data), non-metric MDS (Kruskal, 1964) finds a monotonic transformation:

The Primary Approach places ties in the dissimilarities at the same distance level. The Secondary Approach places ties at different distances.

Algorithm: SMACOF

The SMACOF (Scaling by Majorizing a Complicated Function) algorithm (de Leeuw, 1977) provides guaranteed convergence to a local minimum:

Shepard Diagram

The Shepard diagram is the primary diagnostic tool for MDS. It plots the original dissimilarities (x-axis) against the configuration distances (y-axis).

PROXSCAL

PROXSCAL (Commandeur & Heiser, 1993) is a general-purpose MDS algorithm that accommodates:

  • Metric, non-metric, and polynomial transformations
  • Individual differences (INDSCAL model)
  • Weighted Euclidean models
  • Multiple dissimilarity matrices

Interpretation and Dimensional Interpretation

Procrustean Rotation

To facilitate interpretation, the MDS configuration can be rotated to match a target configuration:

Property Fitting

External variables can be regressed onto MDS dimensions to label the axes:

Python Implementation

import numpy as np
from sklearn.manifold import MDS
from sklearn.metrics import pairwise_distances
import matplotlib.pyplot as plt

np.random.seed(42)

# Generate synthetic dissimilarity data
n = 30
X_true = np.random.randn(n, 3)
D_true = pairwise_distances(X_true, metric='euclidean')

# --- Classical MDS (sklearn) ---
mds_classical = MDS(n_components=2, dissimilarity='euclidean', random_state=42)
X_classical = mds_classical.fit_transform(D_true)
print("Classical MDS stress:", mds_classical.stress_)

# --- Metric MDS ---
mds_metric = MDS(
    n_components=2,
    metric=True,
    dissimilarity='euclidean',
    random_state=42,
    n_init=10,
    max_iter=300,
)
X_metric = mds_metric.fit_transform(D_true)
print("Metric MDS stress:", mds_metric.stress_)

# --- Non-metric MDS ---
mds_nonmetric = MDS(
    n_components=2,
    metric=False,
    dissimilarity='euclidean',
    random_state=42,
    n_init=10,
    max_iter=300,
)
X_nonmetric = mds_nonmetric.fit_transform(D_true)
print("Non-metric MDS stress:", mds_nonmetric.stress_)

# --- Shepard Diagram ---
def shepard_diagram(D_true, X_mds, title="Shepard Diagram"):
    d_mds = pairwise_distances(X_mds)
    triu_idx = np.triu_indices(n, k=1)

    fig, ax = plt.subplots(figsize=(6, 6))
    ax.scatter(D_true[triu_idx], d_mds[triu_idx], alpha=0.3, s=10)

    # Monotonic line (isotonic regression)
    from scipy.stats import rankdata
    from sklearn.isotonic import IsotonicRegression
    ir = IsotonicRegression()
    d_flat = D_true[triu_idx].reshape(-1)
    m_flat = d_mds[triu_idx].reshape(-1)
    ir.fit(d_flat, m_flat)
    x_mono = np.linspace(d_flat.min(), d_flat.max(), 200)
    ax.plot(x_mono, ir.predict(x_mono), 'r-', linewidth=2, label='Monotonic fit')
    ax.plot([0, d_flat.max()], [0, d_flat.max()], 'k--', alpha=0.5, label='Perfect')
    ax.set_xlabel("Original dissimilarities")
    ax.set_ylabel("MDS distances")
    ax.set_title(title)
    ax.legend()
    plt.tight_layout()
    return fig

# --- Classical MDS via eigendecomposition ---
def classical_mds_eigen(D, m=2):
    n = D.shape[0]
    D2 = D ** 2
    J = np.eye(n) - np.ones((n, n)) / n
    B = -0.5 * J @ D2 @ J

    eigenvalues, eigenvectors = np.linalg.eigh(B)
    idx = np.argsort(eigenvalues)[::-1][:m]
    Lambda_m = np.diag(np.sqrt(np.maximum(eigenvalues[idx], 0)))
    X = eigenvectors[:, idx] @ Lambda_m
    return X, eigenvalues

X_manual, evals = classical_mds_eigen(D_true, m=2)
proportion = np.sum(evals[evals > 0][:2]) / np.sum(evals[evals > 0])
print(f"Classical MDS variance explained: {proportion:.4f}")

# --- Stress computation ---
def compute_stress(D, X, metric=True):
    n = D.shape[0]
    d_mds = pairwise_distances(X)
    if metric:
        return np.sqrt(np.sum((D - d_mds)**2) / np.sum(D**2))
    else:
        from scipy.stats import rankdata
        D_rank = rankdata(D, method='average')
        d_rank = rankdata(d_mds, method='average')
        return np.sqrt(np.sum((D_rank - d_rank)**2) / np.sum(D_rank**2))

stress_manual = compute_stress(D_true, X_manual)
print(f"Manual classical MDS stress: {stress_manual:.4f}")

# --- Individual Differences (INDSCAL) ---
def indscal(K_matrices, m=2):
    n = K_matrices[0].shape[0]
    K = len(K_matrices)
    B_avg = np.zeros((n, n))

    weights = []
    for Dk in K_matrices:
        Dk2 = Dk ** 2
        J = np.eye(n) - np.ones((n, n)) / n
        B_k = -0.5 * J @ Dk2 @ J
        B_avg += B_k

    B_avg /= K
    eigenvalues, eigenvectors = np.linalg.eigh(B_avg)
    idx = np.argsort(eigenvalues)[::-1][:m]
    X_group = eigenvectors[:, idx] @ np.diag(np.sqrt(np.maximum(eigenvalues[idx], 0)))

    for Dk in K_matrices:
        Dk2 = Dk ** 2
        J = np.eye(n) - np.ones((n, n)) / n
        B_k = -0.5 * J @ Dk2 @ J
        w_k = np.diag(X_group.T @ B_k @ X_group) / np.diag(X_group.T @ X_group)
        weights.append(w_k)

    return X_group, np.array(weights)

# Simulate 3 judges
K_matrices = [D_true + 0.3 * np.random.randn(n, n) for _ in range(3)]
K_matrices = [(k + k.T) / 2 for k in K_matrices]  # symmetrize
X_indscal, w_indscal = indscal(K_matrices, m=2)
print("INDSCAL weights:\n", np.round(w_indscal, 3))

Quality Assessment

Applications

Psychology: Mapping perceived similarity between stimuli (e.g., colors, facial expressions, concepts). The spatial configuration reveals the psychological dimensions underlying perception.

Marketing: Product positioning β€” mapping consumer perceptions of brands in a space where distances reflect perceived dissimilarity. Competitive strategies are informed by the proximity structure.

Ecology: Ordination of species communities along environmental gradients. Non-metric MDS (NMDS) is the standard method for community ecology because it handles non-Euclidean ecological distances (Bray-Curtis, Jaccard).

Bioinformatics: Mapping protein structures, gene expression profiles, or drug response patterns where direct Euclidean distance is inappropriate.

Need Expert Statistics Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement