%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
このページで使うデータセットに関しては、使用する時に乱数で作成することにするので、ここで準備しない。
クラスタリングを行うためのデータセットを乱数で作成する。ここで作るデータセットのセントロイドを 5 個とし、生成する特徴量を 2 次元にする。
import sklearn.datasets
X, y = sklearn.datasets.make_blobs(n_samples=200, centers=5, n_features=2, random_state=2020)
plt.scatter(X[:,0], X[:,1], c=y)
plt.show()
乱数でデータセットを作成したので、各サンプルの真のラベルはわかっている。本来の教師なし学習のクラスタリングでは、そのラベルが状態でクラスタリングを行うので、kmeans を行う時は、以下のように特徴量のみを使って学習を進める。とりあえず、k=3 でクラスタリングしてみる。
import sklearn.cluster
kmeans = sklearn.cluster.KMeans(n_clusters=3, random_state=2020)
kmeans.fit(X)
学習結果は次のようにして取得できる。
# セントロイドの座標
print(kmeans.cluster_centers_)
# 各サンプルの値
print(kmeans.labels_)
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax1.scatter(X[:,0], X[:,1], c=y)
ax2 = fig.add_subplot(1, 2, 2)
ax2.scatter(X[:,0], X[:,1], c=kmeans.labels_)
ax2.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], c='red', marker='x')
plt.show()
次に、エルボー法を使って最適な k を見積もってみる。
import sklearn.cluster
sse = []
k_candidates = np.linspace(2, 10).astype(int)
for k in k_candidates:
kmeans = sklearn.cluster.KMeans(n_clusters=k, random_state=0)
kmeans.fit(X)
sse.append(kmeans.inertia_)
plt.plot(k_candidates, sse)
plt.ylabel('SSE')
plt.xlabel('k')
plt.show()
次にシルエット図を描いてみる。
import sklearn.metrics
import matplotlib
def plot_silhoutte(X, y):
cl = np.unique(y)
silhouette_idx = sklearn.metrics.silhouette_samples(X, y, metric='euclidean')
y_upper = 0
y_lower = 0
yticks = []
for class_id, class_label in enumerate(cl):
_silhouette_idx = silhouette_idx[y == class_label]
_silhouette_idx.sort()
y_upper = y_upper + len(_silhouette_idx)
plt.barh(range(y_lower, y_upper), _silhouette_idx, height=1)
yticks.append((y_lower + y_upper) / 2)
y_lower = y_lower + len(_silhouette_idx)
silhouette_idx_mean = np.mean(silhouette_idx)
plt.axvline(silhouette_idx_mean, color='black', linestyle = '--')
plt.yticks(yticks)
plt.ylabel('cluster')
plt.xlabel('silhouette coefficient')
plt.show()
plot_silhoutte(X, y)
import sklearn.cluster
kmeans = sklearn.cluster.KMeans(n_clusters=3, random_state=0)
kmeans.fit(X)
y_pred = kmeans.labels_
plot_silhoutte(X, y_pred)
import sklearn.cluster
kmeans = sklearn.cluster.KMeans(n_clusters=5, random_state=0)
kmeans.fit(X)
y_pred = kmeans.labels_
plot_silhoutte(X, y_pred)
DBSCAN は scikit-learn の DBSCAN
で実行できる。
import sklearn.datasets
import sklearn.cluster
X, y = sklearn.datasets.make_blobs(n_samples=200, centers=5, n_features=2, random_state=2020)
clustering = sklearn.cluster.DBSCAN(eps=2.0, min_samples=3)
clustering.fit(X)
y_pred = clustering.labels_
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax1.scatter(X[:,0], X[:,1], c=y)
ax2 = fig.add_subplot(1, 2, 2)
ax2.scatter(X[:,0], X[:,1], c=clustering.labels_)
plt.show()
DBSCAN を実行すると、ハイパーパラメーターとして探索半径と最小サンプル数を指定する必要がある。これらのパラメーターを変化させて、クラスタリング結果を確認してみよう。
階層的クラスタリングは scipy パッケージを使って実行する。性能が一般的によいとされるウォード法で階層的クラスタリングを行ってみる。
import pandas as pd
import scipy.cluster.hierarchy
import sklearn.datasets
X, y = sklearn.datasets.make_blobs(n_samples=200, centers=5, n_features=2, random_state=2020)
# method = 'ward', 'single', 'complete', 'centroid', 'median', ...
hclust = scipy.cluster.hierarchy.linkage(X, method='ward', metric='euclidean')
scipy.cluster.hierarchy.dendrogram(hclust, labels=y)
plt.show()
import pandas as pd
import scipy.cluster.hierarchy
import sklearn.datasets
X, y = sklearn.datasets.make_blobs(n_samples=200, centers=5, n_features=2, random_state=2020)
# method = 'ward', 'single', 'complete', 'centroid', 'median', ...
hclust = scipy.cluster.hierarchy.linkage(X, method='single', metric='euclidean')
scipy.cluster.hierarchy.dendrogram(hclust, labels=y)
plt.show()
import pandas as pd
import scipy.cluster.hierarchy
import sklearn.datasets
X, y = sklearn.datasets.make_blobs(n_samples=200, centers=5, n_features=2, random_state=2020)
# method = 'ward', 'single', 'complete', 'centroid', 'median', ...
hclust = scipy.cluster.hierarchy.linkage(X, method='complete', metric='euclidean')
scipy.cluster.hierarchy.dendrogram(hclust, labels=y)
plt.show()
y_pred = scipy.cluster.hierarchy.fcluster(hclust, 10, criterion='distance')
print(y_pred)
t-SNE は高次元データを可視化するために使われているアルゴリズムである。数千から数万次元の特徴量を 2 次元にマッピングし、わかりやすく可視化することが可能。ここで、例として MNIST データセットを 2 次元にマッピングしてみる。
import sklearn.datasets
digits = sklearn.datasets.load_digits()
X = digits.data
y = digits.target
print(X.shape)
このデータをそのまま PCA を行い、最初の 2 つの主成分を散布図にすると次のようになる。
import sklearn.decomposition
pca= sklearn.decomposition.PCA(n_components=2)
pca.fit(X)
X_pca = pca.transform(X)
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y)
plt.colorbar()
plt.show()
t-SNE は manifold.TSNE
の関数で実行する。計算量が多いため、実行するのに時間がかかる。また、t-SNE のハイパーパラメーターとして perplexity があるので、このパラメーターを 5〜100 の間で動かして、可視化結果を確認してみよう。
import sklearn.manifold
tsne= sklearn.manifold.TSNE(n_components=2, perplexity=5, random_state=2020)
X_tsne = tsne.fit_transform(X)
plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y)
plt.colorbar()
plt.show()
import sklearn.manifold
tsne= sklearn.manifold.TSNE(n_components=2, perplexity=100, random_state=2020)
X_tsne = tsne.fit_transform(X)
plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y)
plt.colorbar()
plt.show()
t-SNE 変換後の座標軸は embedding_
を介してアクセスすることができる。
import sklearn.manifold
tsne= sklearn.manifold.TSNE(n_components=2, perplexity=50, random_state=2020)
tsne = tsne.fit(X)
X_tnse = tsne.embedding_
plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y)
plt.colorbar()
plt.show()
UMAP は t-SNE と同様に高次元のデータを可視化するために使われるアルゴリズムである。UMAP は scikit-learn に実装されていないため、これを使うためには別途にパッケージのインストールを行う必要がある。
import umap
digits = sklearn.datasets.load_digits()
X = digits.data
y = digits.target
embedding = umap.UMAP(n_neighbors=10).fit_transform(digits.data)
plt.scatter(embedding[:, 0], embedding[:, 1], c=y)
plt.colorbar()
plt.show()
上のコードが正しい使い方ですが、でエラーが発生する場合は、次のようなインポート方法を試してください。
import umap.umap_ as umap
embedding = umap.UMAP(n_neighbors=10).fit_transform(digits.data)
plt.scatter(embedding[:, 0], embedding[:, 1], c=y)
plt.colorbar()
plt.show()