K-최근접이웃: 게으른 분류기
K-최근접 이웃(KNN) 가장 직관적인 기계 학습 알고리즘 중 하나입니다. 새로운 점을 분류하려면 i를 보세요 K개의 가장 가까운 지점 훈련 데이터 세트 e에서 다수 클래스를 할당합니다. 훈련 중에는 명시적인 모델을 구축하지 않습니다(이것이 바로 모델이라고 불리는 이유입니다). 게으른 학습자): 모든 계산 작업은 예측 시점에 발생합니다. 알고리즘은 특징 공간에서 이웃을 검색해야 합니다.
KNN의 단순성은 강점과 약점입니다. 이해하고 구현하기 쉽습니다. 하지만 각 훈련 지점으로부터의 거리를 계산해야 하기 때문에 대규모 데이터 세트에서는 속도가 느려집니다. 새로운 예측. KD-Tree 및 Ball Tree와 같은 데이터 구조는 이 문제를 완화하지만 제거하지는 않습니다. 완전히.
이 기사에서 배울 내용
- KNN 작동 방식 및 거리 측정법
- K의 최적값을 선택하는 방법
- K-평균: 가장 널리 사용되는 클러스터링
- DBSCAN: 밀도 기반 클러스터링
- 레이블 없는 클러스터링을 평가하는 방법
- 실루엣 점수 및 팔꿈치 방법
거리 측정법
KNN은 다음 개념을 기반으로 합니다. 거리 특징 공간의 점 사이. 선택 측정항목이 결과에 큰 영향을 미칩니다. 거기 유클리드 거리 거기 있어요 가장 일반적인 것은 n차원 공간에서 두 점 사이의 직선입니다. 거기 맨해튼의 거리 절대 차이의 합을 계산합니다(예: 거리 그리드를 걷는 경우). 거기 거리 민코프스키 이는 매개변수 p에 의해 제어되는 처음 두 가지의 일반화입니다.
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
import numpy as np
# Dataset
wine = load_wine()
X, y = wine.data, wine.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Trovare il K ottimale
k_range = range(1, 31)
cv_scores = []
for k in k_range:
pipeline = Pipeline([
('scaler', StandardScaler()),
('knn', KNeighborsClassifier(n_neighbors=k))
])
scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring='accuracy')
cv_scores.append(scores.mean())
best_k = k_range[np.argmax(cv_scores)]
print(f"Miglior K: {best_k} con accuracy: {max(cv_scores):.3f}")
# Modello finale con il K ottimale
final_pipeline = Pipeline([
('scaler', StandardScaler()),
('knn', KNeighborsClassifier(n_neighbors=best_k, weights='distance'))
])
final_pipeline.fit(X_train, y_train)
test_accuracy = final_pipeline.score(X_test, y_test)
print(f"Test accuracy con K={best_k}: {test_accuracy:.3f}")
K-평균 클러스터링
K-평균 가장 많이 사용되는 클러스터링 알고리즘입니다. 데이터를 다음으로 분할합니다. K 클러스터여기서 각 클러스터는 자체적으로 정의됩니다. 중심 (요점 중간). 알고리즘은 각 점을 가장 가까운 중심에 할당하고 i를 다시 계산하는 두 단계를 번갈아 가며 수행합니다. 할당된 포인트의 평균인 중심입니다. 수렴할 때까지 반복됩니다.
K-평균은 비슷한 크기의 구형 클러스터와 잘 작동하지만 중요한 제한 사항이 있습니다. K를 미리 지정하면 중심 초기화에 민감합니다(부분적으로 고정됨). K-Means++에서) 불규칙한 모양이나 크기가 다른 클러스터를 잘 처리하지 못합니다.
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
import numpy as np
# Dati di esempio: segmentazione clienti
np.random.seed(42)
# 3 gruppi naturali di clienti
group1 = np.random.randn(100, 2) * 0.5 + [2, 2] # Budget
group2 = np.random.randn(100, 2) * 0.8 + [7, 7] # Premium
group3 = np.random.randn(100, 2) * 0.6 + [2, 8] # Frequenti
X = np.vstack([group1, group2, group3])
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Elbow method: trovare il K ottimale
inertias = []
silhouettes = []
K_range = range(2, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_scaled)
inertias.append(kmeans.inertia_)
silhouettes.append(silhouette_score(X_scaled, labels))
# Risultati
for k, inertia, sil in zip(K_range, inertias, silhouettes):
marker = " <-- ottimale" if k == 3 else ""
print(f"K={k}: Inertia={inertia:.1f}, Silhouette={sil:.3f}{marker}")
# Modello finale
kmeans_final = KMeans(n_clusters=3, random_state=42, n_init=10)
clusters = kmeans_final.fit_predict(X_scaled)
print(f"\nDistribuzione cluster: {np.bincount(clusters)}")
DBSCAN: 밀도 기반 클러스터링
DBSCAN(노이즈가 있는 애플리케이션의 밀도 기반 공간 클러스터링) 그것은 알고리즘이다 클러스터 수를 미리 지정할 필요가 없는 클러스터링입니다. 클러스터를 다음으로 식별 저밀도 영역으로 구분된 밀집 영역. 두 가지 매개변수가 동작을 제어합니다. EPS (근접 반경) e min_samples (최소 포인트 수 클러스터를 형성합니다).
DBSCAN은 포인트를 세 가지 범주로 분류합니다. 핵심 포인트 (적어도 min_samples이(가) 내에 닫혀 있어야 합니다. 엡), 국경점 (핵심 지점에 가깝지만 적절한 이웃이 거의 없음) e 소음 포인트 (핵심도 경계도 아님). K-평균과 달리 DBSCAN은 임의 모양의 클러스터를 처리하고 이상값을 자동으로 식별합니다.
from sklearn.cluster import DBSCAN, AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
from sklearn.datasets import make_moons
import numpy as np
# Dataset con cluster non sferici (mezzalune)
X, y_true = make_moons(n_samples=300, noise=0.1, random_state=42)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# DBSCAN
dbscan = DBSCAN(eps=0.3, min_samples=10)
labels_dbscan = dbscan.fit_predict(X_scaled)
n_clusters = len(set(labels_dbscan)) - (1 if -1 in labels_dbscan else 0)
n_noise = list(labels_dbscan).count(-1)
print(f"DBSCAN: {n_clusters} cluster, {n_noise} punti rumore")
if n_clusters > 1:
mask = labels_dbscan != -1
sil = silhouette_score(X_scaled[mask], labels_dbscan[mask])
print(f" Silhouette (escluso rumore): {sil:.3f}")
# Clustering Gerarchico (Agglomerativo)
agg = AgglomerativeClustering(n_clusters=2, linkage='ward')
labels_agg = agg.fit_predict(X_scaled)
sil_agg = silhouette_score(X_scaled, labels_agg)
print(f"\nHierarchical (Ward): Silhouette = {sil_agg:.3f}")
# K-Means per confronto (fatica con mezzalune)
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=2, random_state=42, n_init=10)
labels_km = kmeans.fit_predict(X_scaled)
sil_km = silhouette_score(X_scaled, labels_km)
print(f"K-Means: Silhouette = {sil_km:.3f}")
클러스터링 평가 지표
군집화를 평가하는 것은 감독된 분류보다 더 어렵습니다. 참조 라벨이 없습니다. 그만큼 실루엣 점수 각 포인트의 양을 측정합니다. 이웃 클러스터와 비교하여 클러스터와 유사함: 범위는 -1(잘못된 할당)부터 1(밀도 클러스터)까지입니다. 그리고 잘 분리됨) 그만큼 데이비스-볼딘 지수 클러스터 간의 평균 유사성을 측정합니다. 낮을수록 좋습니다. 그만큼 칼린스키-하라바즈 지수 간의 관계를 측정합니다. 클러스터 간 및 클러스터 내 분산: 높을수록 좋습니다.
KNN 대 K-평균: 혼동하지 마십시오! KNN은 알고리즘이다 감독 분류/회귀용(레이블 사용) K-평균은 알고리즘입니다 감독되지 않은 클러스터링(레이블을 사용하지 않음) 그들이 공유하는 유일한 것은 문자 K입니다.
각 알고리즘을 사용하는 경우
KNN: 중소 규모 데이터 세트의 분류 문제와 특징과 목표는 지역적이며 비선형적입니다. K-평균: 클러스터로 분할하는 경우 구형이고 균형이 잡혀 있습니다. DBSCAN: 군집의 모양이 불규칙할 때 이상값이 있음 중요하거나 클러스터 수를 알 수 없습니다. 계층적: 이해가 필요할 때 그룹화 계층 구조와 데이터 세트가 너무 크지 않습니다.
핵심 사항
- KNN은 K개의 가장 가까운 이웃을 기반으로 분류합니다. 간단하지만 대규모 데이터 세트에서는 느립니다.
- K 선택은 교차 검증을 통해 이루어집니다. K가 너무 낮으면 과적합이 발생하고 너무 높으면 과소적합이 발생합니다.
- K-평균은 중심이 있는 K개 클러스터로 분할됩니다. 알려진 K가 필요하며 구형 클러스터에서 작동합니다.
- DBSCAN은 밀도를 기준으로 임의 모양의 클러스터를 찾고 이상값을 식별합니다.
- Silhouette Score는 클러스터링 품질을 평가하는 데 가장 많이 사용되는 측정항목입니다.
- 모든 거리 기반 알고리즘에는 기능 스케일링이 필수적입니다.







