4_unsupervised


Analiza danych i uczenie maszynowe w Python

Autor notebooka: Jakub Nowacki.

Metody bez nadzoru

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.

Klastrowanie

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]:
label x y
0 0 9.211884 -0.151886
1 0 8.889374 -0.339375
2 0 10.768401 2.952446
3 0 8.242133 1.290948
4 0 5.796701 -5.837767

In [2]:
X.describe()


Out[2]:
label x y
count 150.000000 150.000000 150.000000
mean 0.333333 6.751880 6.683081
std 0.472984 4.877784 9.598625
min 0.000000 -3.125396 -5.837767
25% 0.000000 1.427304 -0.535173
50% 0.000000 8.708074 1.298940
75% 1.000000 10.460816 18.693646
max 1.000000 16.363330 24.084572

In [3]:
X.plot.scatter(x='x', y='y', c='label', cmap=plt.cm.Set2);


K-means

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]:
label x y predict
0 0 9.211884 -0.151886 1
1 0 8.889374 -0.339375 1
2 0 10.768401 2.952446 1
3 0 8.242133 1.290948 1
4 0 5.796701 -5.837767 1

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)


Zadanie

  1. Zmień ilość klastrów n_clusters; co się zmieniło?
  2. Zmień algorytm na MiniBatchKMeans; co się zmieniło?
  3. ★ Wygeneruj nowe dane, gdzie klastry są bliżej siebie; co się zmieniło?

Klastrowanie hierarchiczne

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]:
label x y predict
0 0 9.211884 -0.151886 0
1 0 8.889374 -0.339375 0
2 0 10.768401 2.952446 0
3 0 8.242133 1.290948 0
4 0 5.796701 -5.837767 0

In [7]:
ax = X.plot.scatter(x='x', y='y', c='predict', cmap=plt.cm.Set2)


Zadanie

  1. Zmień ilość klastrów n_clusters; co się zmieniło?
  2. Zmień algorytm w parametrze linkage; zobacz dokumentację; co się zmieniło?
  3. ★ Wygeneruj nowe dane, gdzie klastry są bliżej siebie; 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]:
array([[5.20000000e+01, 5.30000000e+01, 4.15105485e-02, 2.00000000e+00],
       [1.40000000e+01, 7.90000000e+01, 5.91375926e-02, 2.00000000e+00],
       [3.30000000e+01, 6.80000000e+01, 7.10677929e-02, 2.00000000e+00]])

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()


Zadanie

  1. Zmień ilość klastrów n_clusters; co się zmieniło?
  2. Zmień algorytm w parametrze linkage; zobacz dokumentację; co się zmieniło?

Principal Component Analysis

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]:
array([[ -7.23084517,  -0.6951744 ],
       [ -7.26261373,  -1.06686677],
       [ -5.08879835,   2.03818602],
       [ -5.51203662,  -0.9557205 ],
       [-10.91318556,  -6.21179381],
       [ -5.29274907,  -2.94484119],
       [ -7.03593023,  -1.82648545],
       [-10.86621083,  -2.95559245],
       [ -7.28666727,  -1.13836019],
       [ -5.1487411 ,   1.60310711]])

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]:
(array([-5.73727207,  0.45209315]), array([12.1449249 ,  0.21356916]))

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);


Zadanie

  1. Wykonaj PCA dla danych irysów.
  2. Poeksperymentuj z liczbą komponentów.
  3. Ile wariancji tłumaczą poszczególne komponenty?