Machine Learning Academy · Pelajaran

Metrik Jarak: Euclid, Manhattan dan Minkowski

Pelajar akan membandingkan metrik jarak, memahami bila jarak Manhattan mengatasi jarak Euclid, dan menghantar metrik tersuai kepada KNeighborsClassifier.

Pelajaran 3 daripada 413 langkah

Metrik Jarak: Euclid, Manhattan dan Minkowski ialah pelajaran Machine Learning Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Machine Learning Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.

Sebab Metrik Jarak Penting dalam KNN

KNN mentakrifkan jiran terdekat menggunakan metrik jarak — fungsi matematik yang mengukur sejauh mana jarak antara dua titik dalam ruang ciri. Pemilihan metrik secara langsung mempengaruhi jiran yang dipilih dan seterusnya perkara yang diramalkan oleh model. Metrik yang berbeza membuat andaian yang berbeza tentang geometri data. Jarak Euclidean menganggap pergerakan menyerong adalah sah; jarak Manhattan hanya membenarkan pergerakan yang selari dengan paksi; kesamaan kosinus mengabaikan magnitud dan menumpukan pada arah. Tiada satu metrik yang terbaik secara universal — pilihan yang tepat bergantung pada struktur masalah.

import numpy as np

A = np.array([0, 0])
B = np.array([3, 4])

# Euclidean: straight-line distance
euclidean = np.sqrt(np.sum((A - B)**2))
print('Euclidean:', euclidean)  # 5.0

# Manhattan: sum of absolute differences
manhattan = np.sum(np.abs(A - B))
print('Manhattan:', manhattan)  # 7

# Chebyshev: maximum single-axis difference
chebyshev = np.max(np.abs(A - B))
print('Chebyshev:', chebyshev)  # 4

Jarak Euclidean: Norma L2

Jarak Euclidean (juga dipanggil jarak L2 atau norma L2) mengukur jarak garis lurus antara dua titik. Dalam 2D, ia mengikut teorem Pythagoras: sqrt(dx^2 + dy^2). Dalam n dimensi: sqrt(sum of squared differences). Ini ialah metrik yang paling intuitif dan merupakan metrik lalai dalam KNeighborsClassifier. Jarak Euclidean berfungsi dengan baik apabila ciri bersifat berterusan, berada pada skala yang serupa dan tanggapan tentang kedekatan menyerong mempunyai makna fizikal — contohnya, koordinat geografi atau bacaan penderia.

import numpy as np

def euclidean(a, b):
    return np.sqrt(np.sum((np.array(a) - np.array(b))**2))

# 2D example
print('2D:', euclidean([0, 0], [3, 4]))  # 5.0

# 3D example
print('3D:', euclidean([1, 2, 3], [4, 6, 3]).round(2))  # 5.0

# Using scipy for efficiency
from scipy.spatial.distance import euclidean as sp_euclidean
print('scipy:', sp_euclidean([0, 0], [3, 4]))

Jarak Manhattan: Norma L1

Jarak Manhattan (norma L1, jarak blok bandar, jarak teksi) menjumlahkan perbezaan mutlak sepanjang setiap paksi: sum(|a_i - b_i|). Namanya berasal daripada susun atur grid jalan Manhattan — anda hanya boleh bergerak sepanjang blok, bukan secara menyerong. Jarak Manhattan lebih teguh terhadap pencilan berbanding Euclidean kerana ia menggunakan nilai mutlak dan bukannya kuasa dua. Jarak ini sering diutamakan untuk data berdimensi tinggi serta ciri yang mewakili kiraan, penilaian atau kuantiti lain yang pergerakan menyerongnya tidak bermakna secara fizikal.

import numpy as np

def manhattan(a, b):
    return np.sum(np.abs(np.array(a) - np.array(b)))

print('Manhattan (0,0)-(3,4):', manhattan([0,0], [3,4]))  # 7
print('Euclidean (0,0)-(3,4):', np.linalg.norm([3,4]))    # 5.0

# Manhattan treats 3+4=7 units of travel
# Euclidean takes the diagonal shortcut = 5.0
# In a grid city, only Manhattan is physically achievable

from scipy.spatial.distance import cityblock
print('scipy cityblock:', cityblock([0,0], [3,4]))

Jarak Minkowski: Mengumumkan L1 dan L2

Jarak Minkowski ialah generalisasi yang menyatukan Euclidean dan Manhattan di bawah satu formula: (sum(|a_i - b_i|^p))^(1/p). Apabila p=1, ia bersamaan dengan jarak Manhattan. Apabila p=2, ia bersamaan dengan jarak Euclidean. Apabila p → infinity, ia menghampiri jarak Chebyshev (perbezaan maksimum pada satu paksi). Dalam scikit-learn, KNeighborsClassifier menggunakan Minkowski dengan p=2 secara lalai. Anda boleh meneroka nilai p lain sebagai hiperparameter — walaupun nilai p selain 1 dan 2 jarang digunakan dalam amalan.

import numpy as np

def minkowski(a, b, p):
    a, b = np.array(a), np.array(b)
    return np.sum(np.abs(a - b)**p)**(1/p)

a, b = [0, 0], [3, 4]

for p in [1, 2, 3, 10, 100]:
    d = minkowski(a, b, p)
    print(f'p={p}: {d:.4f}')

# p=1  -> 7.0 (Manhattan)
# p=2  -> 5.0 (Euclidean)
# p->inf -> 4.0 (Chebyshev = max(3,4))

Menghantar Metrik kepada KNeighborsClassifier

Scikit-learn membolehkan anda menentukan metrik jarak melalui parameter metric. Pilihan rentetan yang lazim termasuk 'euclidean', 'manhattan', 'minkowski' (dengan parameter p tambahan), 'chebyshev' dan 'cosine'. Anda juga boleh menghantar fungsi Python boleh panggil sebagai metrik tersuai. Apabila menggunakan metrik bukan piawai, tetapkan algorithm='ball_tree' atau algorithm='kd_tree' untuk carian jiran yang cekap, atau algorithm='brute' untuk carian menyeluruh yang dijamin betul tetapi lebih perlahan.

from sklearn.neighbors import KNeighborsClassifier

# Euclidean (default)
knn_l2 = KNeighborsClassifier(n_neighbors=5, metric='euclidean')

# Manhattan
knn_l1 = KNeighborsClassifier(n_neighbors=5, metric='manhattan')

# Minkowski with p=1.5
knn_mk = KNeighborsClassifier(n_neighbors=5, metric='minkowski', p=1.5)

# Chebyshev
knn_ch = KNeighborsClassifier(n_neighbors=5, metric='chebyshev')

# Cosine similarity (for text/angle-based)
knn_cos = KNeighborsClassifier(n_neighbors=5, metric='cosine',
                                algorithm='brute')

Euclidean berbanding Manhattan: Perbandingan Praktikal

Apabila Euclidean dan Manhattan dibandingkan secara empirikal, perbezaannya paling jelas apabila terdapat ciri pencilan. Euclidean mengkuasa duakan perbezaan, menyebabkan satu penyimpangan besar mendominasi jumlah jarak. Manhattan menjumlahkan nilai mutlak, lalu melayan semua penyimpangan secara berkadar. Dalam amalan, bagi data imej atau ukuran fizikal berterusan, Euclidean sering memberikan hasil terbaik. Bagi data jarang berdimensi tinggi (teks, penilaian pengguna-item, kiraan), Manhattan biasanya lebih stabil kerana tidak memperbesarkan kesan mana-mana satu dimensi.

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_wine

X, y = load_wine(return_X_y=True)

for metric in ['euclidean', 'manhattan', 'chebyshev']:
    pipe = Pipeline([
        ('sc', StandardScaler()),
        ('knn', KNeighborsClassifier(n_neighbors=5, metric=metric))
    ])
    score = cross_val_score(pipe, X, y, cv=10).mean()
    print(f'{metric:12}: {score:.3f}')

Kesamaan Kosinus untuk Data Teks

Persamaan kosinus mengukur sudut antara dua vektor, bukannya magnitudnya. Dua dokumen dianggap serupa jika kedua-duanya menghala ke arah yang sama dalam ruang ciri, tanpa mengira panjang dokumen. Jarak kosinus = 1 - persamaan kosinus. Metrik ini ialah pilihan utama untuk pengelasan teks dengan vektor TF-IDF, apabila dua dokumen boleh mempunyai panjang yang sangat berbeza tetapi menggunakan kosa kata yang sama dalam perkadaran yang serupa. Perhatikan bahawa jarak kosinus bukan metrik sebenar (melanggar ketaksamaan segi tiga), tetapi berfungsi dengan baik dalam amalan untuk KNN pada teks.

import numpy as np

def cosine_distance(a, b):
    a, b = np.array(a, dtype=float), np.array(b, dtype=float)
    cos_sim = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
    return 1 - cos_sim

# Long and short documents with same topic should be close
doc1 = [2, 1, 0, 3]  # counts of words: 'python', 'ml', 'java', 'data'
doc2 = [4, 2, 0, 6]  # same proportions, longer document
doc3 = [0, 0, 5, 1]  # different topic

print('doc1 vs doc2 (same topic):', cosine_distance(doc1, doc2).round(3))  # near 0
print('doc1 vs doc3 (diff topic):', cosine_distance(doc1, doc3).round(3))  # larger

Jarak Hamming untuk Ciri Kategori dan Binari

Jarak Hamming mengira bilangan kedudukan yang berbeza antara dua vektor. Jarak ini sesuai untuk ciri binari atau kategori yang tidak mempunyai maksud perbezaan magnitud. Sebagai contoh, apabila membandingkan dua rekod pesakit yang dikodkan sebagai vektor simptom binari (1=hadir, 0=tiada), jarak Hamming mengira bilangan simptom yang berbeza. Dalam scikit-learn, hantarkan metric='hamming' kepada KNeighborsClassifier. Jarak Hamming juga digunakan untuk membandingkan jujukan DNA, mengesan ralat dalam kod binari dan mengenal pasti cap jari genetik.

import numpy as np

def hamming(a, b):
    a, b = np.array(a), np.array(b)
    return np.sum(a != b) / len(a)

# Binary symptom vectors: [fever, cough, headache, fatigue]
patient1 = [1, 1, 0, 1]
patient2 = [1, 1, 1, 1]  # only headache differs
patient3 = [0, 0, 1, 0]  # very different

print('p1 vs p2:', hamming(patient1, patient2))  # 0.25
print('p1 vs p3:', hamming(patient1, patient3))  # 0.75

# sklearn usage
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3, metric='hamming')

Kesan Dimensi dan Jarak

Apabila bilangan ciri (dimensi) bertambah, semua kaedah berasaskan jarak mengalami kesan dimensi: dalam dimensi yang tinggi, jarak antara mana-mana dua titik rawak menghampiri nilai yang sama, menyebabkan semua titik kelihatan sama jauhnya. Apabila jarak tidak lagi dapat dibezakan, konsep "jiran terdekat" kehilangan makna. Inilah sebabnya KNN biasanya memberikan prestasi terbaik pada set data yang mempunyai kurang daripada 20-50 ciri dan sebab pengurangan dimensi (PCA, pemilihan ciri) sering dilakukan sebelum KNN dalam keadaan berdimensi tinggi.

import numpy as np

np.random.seed(42)

for d in [2, 10, 50, 100, 500]:
    # Random points in d-dimensional unit hypercube
    X = np.random.rand(1000, d)
    query = np.random.rand(d)
    dists = np.linalg.norm(X - query, axis=1)
    # High-dimensional: max/min ratio -> 1 (all distances similar)
    ratio = dists.max() / dists.min()
    print(f'd={d:3}: min={dists.min():.2f}, max={dists.max():.2f}, ratio={ratio:.2f}')

# As d grows, ratio approaches 1: distances become indistinguishable

Memilih Metrik: Panduan Praktikal

Berikut ialah panduan membuat keputusan untuk memilih metrik jarak: gunakan Euclidean (L2) untuk ciri berterusan pada skala yang serupa (selepas StandardScaler); gunakan Manhattan (L1) untuk data yang jarang atau berdimensi tinggi dan apabila keteguhan terhadap pencilan diperlukan; gunakan Cosine untuk vektor teks/TF-IDF apabila magnitud tidak sepatutnya penting; gunakan Hamming untuk ciri binari atau kategori; gunakan Minkowski dengan p tersuai hanya jika pengetahuan domain mencadangkan geometri tertentu. Dalam amalan, cuba Euclidean dan Manhattan dahulu menggunakan pengesahan silang dan pilih yang memberikan hasil terbaik.

def recommend_metric(data_type, is_sparse, has_outliers):
    if data_type == 'text':
        return 'cosine'
    elif data_type == 'binary' or data_type == 'categorical':
        return 'hamming'
    elif is_sparse or has_outliers:
        return 'manhattan'
    else:
        return 'euclidean'  # default, safe choice

print(recommend_metric('text', False, False))       # cosine
print(recommend_metric('binary', False, False))     # hamming
print(recommend_metric('continuous', True, False))  # manhattan
print(recommend_metric('continuous', False, False)) # euclidean

Menyertakan Metrik dalam Carian Grid

Anda boleh menyertakan parameter metric dalam GridSearchCV untuk mencari gabungan terbaik bagi k dan metrik jarak secara serentak. Ini mengelakkan percubaan dan kesilapan secara manual merentas metrik. Apabila mencari merentas metrik yang memerlukan parameter tambahan (seperti p bagi Minkowski), sertakan parameter tersebut dalam grid parameter juga. Metrik terbaik bergantung pada data dan selalunya tidak dapat ditentukan melalui pengetahuan domain sahaja — membiarkan pengesahan silang membuat keputusan ialah pendekatan yang berprinsip dan praktikal.

from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

pipe = Pipeline([('sc', StandardScaler()), ('knn', KNeighborsClassifier())])

param_grid = [
    {'knn__n_neighbors': [3, 5, 7, 11],
     'knn__metric': ['euclidean', 'manhattan'],
     'knn__weights': ['uniform', 'distance']},
    {'knn__n_neighbors': [3, 5, 7],
     'knn__metric': ['minkowski'],
     'knn__p': [1, 1.5, 2, 3]}
]

grid = GridSearchCV(pipe, param_grid, cv=10, scoring='accuracy', n_jobs=-1)
grid.fit(X_train, y_train)
print('Best params:', grid.best_params_)

Semakan Pantas

Uji pemahaman anda tentang konsep Pembelajaran Mesin dengan Python daripada pelajaran ini.

Ringkasan Pelajaran

Dalam pelajaran ini, anda telah mempelajari: perbezaan matematik antara jarak Euclidean, Manhattan dan Minkowski serta masa yang sesuai untuk menggunakan setiap satunya, persamaan kosinus untuk data teks dan Hamming untuk ciri binari, serta kesan dimensi yang menyebabkan semua jarak menghampiri nilai yang sama dalam ruang berdimensi tinggi. Seterusnya, kita akan meneroka KNN untuk tugasan regresi dan batas kebolehskalaannya pada set data yang besar.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
30
Pelajaran
120

Soalan Lazim

Adakah pelajaran “Metrik Jarak: Euclid, Manhattan dan Minkowski” percuma?

Ya — teks penuh “Metrik Jarak: Euclid, Manhattan dan Minkowski” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Machine Learning Academy, tingkat taraf kepada CoddyKit PRO. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Metrik Jarak: Euclid, Manhattan dan Minkowski”?

Pelajar akan membandingkan metrik jarak, memahami bila jarak Manhattan mengatasi jarak Euclid, dan menghantar metrik tersuai kepada KNeighborsClassifier. Anda berlatih Machine Learning Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Machine Learning Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Machine Learning Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Metrik Jarak: Euclid, Manhattan dan Minkowski” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Machine Learning Academy ini?

Ya. Setiap pelajaran Machine Learning Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Cara KNN Berfungsi: Jarak, Jiran dan Undian
  2. Memilih k: Kaedah Siku dan Lengkung Pengesahan
  3. Metrik Jarak: Euclid, Manhattan dan Minkowski
  4. KNN untuk Regresi dan Had Kebolehskalaannya
← Kembali ke Machine Learning Academy