Autor notebooka: Jakub Nowacki.
Uczenie maszynowe ma wiele algorytmów działających bez nadzoru, czyli bez sklasyfikowanych danych. Służą one do odkrywania różnych wzorców i prawidłowości w danych, lub zmniejszania liczby stopni swobody.
Jest wiele metod klastrowania i mają one różne właściwości, w zależności od problemu. Poniżej ogólna charakterystyka dostępnych algorytmów.
Wygenerujmy najpierw dane do klastrowania.
In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = (10, 8)
np.random.seed(4711)
a = np.random.multivariate_normal([10, 0], [[3, 1], [1, 4]], size=[100,])
b = np.random.multivariate_normal([0, 20], [[3, 1], [1, 4]], size=[50,])
A = pd.DataFrame({
'x': a[:, 0],
'y': a[:, 1],
'label': 0,
})
B = pd.DataFrame({
'x': b[:, 0],
'y': b[:, 1],
'label': 1,
})
X = pd.concat([A, B])
X.head()
Out[1]:
In [2]:
X.describe()
Out[2]:
In [3]:
X.plot.scatter(x='x', y='y', c='label', cmap=plt.cm.Set2);
Algorytm centroidów (K-means) jest jednym z prostszych algorytmów klastrowania, który opiera się na odległościach punktów od centrów klastrów.
O ile zbieżność klastrów odbywa się automatycznie, to sam wybór ilości klastrów jest zdefiniowany przez użytkownika.
In [4]:
from sklearn.cluster import KMeans
features = ['x', 'y']
km = KMeans(n_clusters=2)
km.fit(X[features])
X['predict'] = km.predict(X[features])
X.head()
Out[4]:
In [5]:
ax = X.plot.scatter(x='x', y='y', c='predict', cmap=plt.cm.Set2)
for i, (cx, cy) in enumerate(km.cluster_centers_):
ax.plot(cx, cy, 'X', markersize=20)
Klastrowanie hierarchiczne (Hierarchical clustering) jest metodą klastrowania, która buduję sieć połączeń pomiędzy najbliższymi siebie elementami na podstawie miary odległości.
Klastry | Budowa połączeń |
---|---|
Klastrowanie metodami hierarchicznymi (aglomeracylnymi) jest dostępne jako jedna z metod klastrowania w scikit-learn. Można ją użyć podobnie jak K-means.
In [6]:
from sklearn.cluster import AgglomerativeClustering
cls = AgglomerativeClustering(linkage='ward', n_clusters=2)
cls.fit(X[features])
X['predict'] = cls.labels_
X.head()
Out[6]:
In [7]:
ax = X.plot.scatter(x='x', y='y', c='predict', cmap=plt.cm.Set2)
n_clusters
; co się zmieniło?linkage
; zobacz dokumentację; co się zmieniło?Możemy wykorzystać cechy klastrowania hierarchicznego do budowy dendrogramu. Musimy najpierw zbudować macierz połączeń używając któregoś z algorytmów, w tym przypadku Warda.
In [8]:
from scipy.cluster.hierarchy import dendrogram, linkage
Z = linkage(X[features], 'ward')
Z[:3]
Out[8]:
Po zbudowaniu macieży możemy ją narysować używając Matplotlib i SciPy.
In [9]:
plt.title('Hierarchical Clustering Dendrogram (truncated)')
plt.xlabel('sample index')
plt.ylabel('distance')
dendrogram(
Z,
truncate_mode='lastp',
p=12,
show_leaf_counts=False,
leaf_rotation=90.,
leaf_font_size=12.,
show_contracted=True,
)
plt.show()
n_clusters
; co się zmieniło?linkage
; zobacz dokumentację; co się zmieniło?Principal Component Analysis (PCA) jest metodą zmniejszania stopnia swobody, czyli ilości zmiennych, w danym problemie.
Przekształcenie wykonuje swoisty obrót przestrzeni w taki sposób, aby kolejne wektory składowe były posortowane od największej wariancji do najmniejszej. Nowe wektory rozpinające przestrzeń są formą wektorów własnych macierzy kowariancji.
Dla ilustracji wykonujemy poniżej dekompozycję zbioru irysów używając PCA.
In [10]:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
p = pca.fit_transform(X[['x', 'y']])
p[:10]
Out[10]:
Najpierw narysujmy komponenty w oryginalnym układzie współrzędnych.
In [11]:
pca_score = pca.explained_variance_ratio_
V = pca.components_
x_pca_axis, y_pca_axis = V.T * pca_score / pca_score.min() / 2
x_pca_axis, y_pca_axis
Out[11]:
In [12]:
ax = X.plot.scatter(x='x', y='y', c='predict', cmap=plt.cm.Set2)
ax.arrow(6, 6, x_pca_axis[0], y_pca_axis[0], head_width=0.5, head_length=1) # PCA x
ax.arrow(6, 6, x_pca_axis[1], y_pca_axis[1], head_width=0.5, head_length=1); # PCA y
A tak wygląda obraz w nowym układzie współrzędnych.
In [13]:
plt.scatter(p[:, 0], p[:, 1], c=X['label'], cmap=plt.cm.Set2);