Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

Scikit-Learnを使用したK-Meansクラスタリングの決定的なガイド

概要

K平均クラスタリング は、データインスタンス間の類似性に基づいてデータのクラスターを形成する、最も広く使用されている教師なし機械学習アルゴリズムのXNUMXつです。

このガイドでは、Scikit-Learnを使用して実装する前に、K-Meansアルゴリズムがどのように機能するかを理解するための簡単な例を最初に見ていきます。 次に、K-Meansのクラスター(K)の数を決定する方法について説明し、距離メトリック、分散、およびK-Meansの長所と短所についても説明します。

動機

次の状況を想像してみてください。 ある日、近所を歩いていると、コンビニエンスストアが10店あることに気づき、どの店が似ているのか、近くにあるのではないかと思い始めました。 その質問に答える方法を探しているときに、地図上の座標に基づいて店舗をグループに分割する興味深いアプローチに出くわしました。

たとえば、5つの店舗が西3kmと北XNUMXkmにある場合、次のように割り当てます。 (5, 3) それに座標を付け、グラフで表現します。 この最初のポイントをプロットして、何が起こっているかを視覚化してみましょう。

import matplotlib.pyplot as plt

plt.title("Store With Coordinates (5, 3)")
plt.scatter(x=5, y=3)

これは最初のポイントにすぎないので、店舗をどのように表現できるかを知ることができます。 収集された10の店舗に対してすでに10の座標があるとします。 それらを整理した後 numpy 配列、それらの場所をプロットすることもできます:

import numpy as np

points = np.array([[5, 3], [10, 15], [15, 12], [24, 10], [30, 45], [85, 70], [71, 80], [60, 78], [55, 52],[80, 91]])

xs = points[:,0] 
ys = points[:,1]  

plt.title("10 Stores Coordinates")
plt.scatter(x=xs, y=ys)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

K-Meansアルゴリズムを手動で実装する方法

これで、グラフで10の店舗を見ることができます。主な問題は、近接性に基づいて店舗をさまざまなグループに分割できる方法があるかどうかを見つけることです。 グラフをざっと見るだけで、おそらく気付くでしょう XNUMXつのグループの店舗 – XNUMXつは左下のポイントで、もうXNUMXつは右上のポイントです。 おそらく、真ん中のXNUMXつのポイントを別々のグループとして区別することもできます。したがって、 XNUMXつの異なるグループ.

このセクションでは、ポイントを手動でクラスタリングするプロセスについて説明します。ポイントを指定された数のグループに分割します。 そうすれば、基本的にすべてのステップを慎重に検討します。 K-Meansクラスタリングアルゴリズム。 このセクションの終わりまでに、K-Meansクラスタリング中に実行されるすべてのステップを直感的かつ実用的に理解できるようになります。 その後、Scikit-Learnに委任します。

ポイントのグループがXNUMXつまたはXNUMXつあるかどうかを判断する最良の方法は何でしょうか? 簡単な方法のXNUMXつは、グループの数をXNUMXつ(たとえばXNUMXつ)選択し、その選択に基づいてポイントをグループ化することです。

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

あると決めたとしましょう 2つのグループ 当店の(ポイント)。 ここで、どのポイントがどのグループに属しているかを理解する方法を見つける必要があります。 これは、表すXNUMXつのポイントを選択することで実行できます。 グループ1 とXNUMXつを表す グループ2。 これらのポイントは、他のすべてのポイントから各グループまでの距離を測定する際の参照として使用されます。

そのように、ポイントを言う (5, 3) 最終的にグループ1に属し、ポイント (79, 60) グループ2に。新しいポイントを割り当てようとするとき (6, 3) グループに対しては、これらXNUMX点までの距離を測定する必要があります。 ポイントの場合 (6, 3) is クローザー (5, 3)、したがって、それはそのポイントによって表されるグループに属します– グループ1。 このようにして、すべてのポイントを対応するグループに簡単にグループ化できます。

この例では、グループの数を決定することに加えて(クラスタ)–私たちはまたいくつかのポイントを選択しています 参照 各グループの新しいポイントの距離の。

それが私たちの店の類似点を理解するための一般的な考え方です。 それを実践しましょう–最初にXNUMXつの参照点を選択できます ランダム。 の基準点 グループ1 なります (5, 3) との基準点 グループ2 なります (10, 15)。 両方のポイントを選択できます numpy 配列による [0] および [1] インデックスを作成して保存します g1 (グループ1)および g2 (グループ2)変数:

g1 = points[0]
g2 = points[1]

これを行った後、他のすべてのポイントからそれらの参照ポイントまでの距離を計算する必要があります。 これは重要な問題を提起します-その距離をどのように測定するか。 基本的に任意の距離測度を使用できますが、このガイドでは、ユークリッド距離_を使用します。

ユークリッド距離の測定がピタゴラスの定理に基づいていることを知っておくと便利です。

$$
c ^ 2 = a ^ 2 + b ^ 2
$$

平面内の点に適合した場合– (a1, b1) および (a2, b2)、前の式は次のようになります。

$$
c ^ 2 =(a2-a1)^ 2 +(b2-b1)^ 2
$$

距離はの平方根になります c、したがって、式を次のように書くこともできます。

$$
euclidean_ {dist} = sqrt [2] [(a2 – a1)^ 2 +(b2 – b1)^ 2)]
$$

注: 多次元点のユークリッド距離式を一般化することもできます。 たとえば、XNUMX次元空間では、点にはXNUMXつの座標があります。この式は、次のようにそれを反映しています。
$$
euclidean_ {dist} = sqrt [2] [(a2 – a1)^ 2 +(b2 – b1)^ 2 +(c2 – c1)^ 2)]
$$
私たちが操作している空間の次元の数に関係なく、同じ原則に従います。

これまで、グループを表すポイントを選択し、距離を計算する方法を知っています。 それでは、収集した各ストアポイントをグループに割り当てて、距離とグループをまとめましょう。

それをよりよく視覚化するために、XNUMXつのリストを宣言します。 最初のグループのポイントを保存する最初のもの– points_in_g1。 グループ2からのポイントを保存するXNUMX番目のもの– points_in_g2、そして最後のもの– groupラベル どちらかとしてのポイント 1 (グループ1に属する)または 2 (グループ2に属する):

points_in_g1 = []
points_in_g2 = []
group = []

これで、ポイントを反復処理して、ポイントと各グループ参照との間のユークリッド距離を計算できます。 各ポイントは クローザー XNUMXつのグループのいずれかに–どちらのグループに最も近いかに基づいて、各ポイントを対応するリストに割り当て、さらに追加します 1 or 2 group リスト:

for p in points:
    x1, y1 = p[0], p[1]
    euclidean_distance_g1 = np.sqrt((g1[0] - x1)**2 + (g1[1] - y1)**2)
    euclidean_distance_g2 = np.sqrt((g2[0] - x1)**2 + (g2[1] - y1)**2)
    if euclidean_distance_g1 < euclidean_distance_g2:
        points_in_g1.append(p)
        group.append('1')
    else:
        points_in_g2.append(p)
        group.append('2')

この反復の結果を見て、何が起こったかを見てみましょう。

print(f'points_in_g1:{points_in_g1}n 
npoints_in_g2:{points_in_g2}n 
ngroup:{group}')

結果は次のとおりです。

points_in_g1:[array([5, 3])]
 
points_in_g2:[array([10, 15]), array([15, 12]), 
              array([24, 10]), array([30, 45]), 
              array([85, 70]), array([71, 80]),
              array([60, 78]), array([55, 52]), 
              array([80, 91])]
 
group:[1, 2, 2, 2, 2, 2, 2, 2, 2, 2] 

Seabornを使用して、割り当てられたグループに基づいて異なる色でクラスタリング結果をプロットすることもできます。 scatterplot() group として hue 引数:

import seaborn as sns

sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

最初のポイントのみがグループ1に割り当てられ、他のすべてのポイントがグループ2に割り当てられていることがはっきりとわかります。その結果は、最初に想定していたものとは異なります。 結果と当初の期待の違いを考えると、それを変える方法はありますか? あるようです!

XNUMXつのアプローチは、プロセスを繰り返し、グループの参照となるさまざまなポイントを選択することです。 これにより、私たちの結果が、うまくいけば、私たちが最初に想像したものとより一致するように変わるでしょう。 今回は、以前のようにランダムに選択するのではなく、 意味する すでにグループ化されたすべてのポイントの。 そうすれば、これらの新しいポイントを対応するグループの中央に配置できます。

たとえば、XNUMX番目のグループにポイントしかない場合 (10, 15), (30, 45)。 新しい 中央の ポイントは (10 + 30)/2 および (15+45)/2 –これは等しい (20, 30).

結果をリストに入れているので、最初に結果を次のように変換できます。 numpy 配列、それらのxs、ysを選択してから、 意味する:

g1_center = [np.array(points_in_g1)[:, 0].mean(), np.array(points_in_g1)[:, 1].mean()]
g2_center = [np.array(points_in_g2)[:, 0].mean(), np.array(points_in_g2)[:, 1].mean()]
g1_center, g2_center

アドバイス: 使ってみる numpy 可能な限りNumPy配列。 これらは、パフォーマンスを向上させ、多くの線形代数演算を簡素化するように最適化されています。 線形代数の問題を解こうとしているときはいつでも、必ず見てください。 numpy あるかどうかを確認するためのドキュメント numpy あなたの問題を解決するために設計された方法。 チャンスはあるということです!

新しい中心点でプロセスを繰り返すのを助けるために、前のコードを関数に変換して実行し、点のグループ化方法に変更があったかどうかを確認しましょう。

def assigns_points_to_two_groups(g1_center, g2_center):
    points_in_g1 = []
    points_in_g2 = []
    group = []

    for p in points:
        x1, y1 = p[0], p[1]
        euclidean_distance_g1 = np.sqrt((g1_center[0] - x1)**2 + (g1_center[1] - y1)**2)
        euclidean_distance_g2 = np.sqrt((g2_center[0] - x1)**2 + (g2_center[1] - y1)**2)
        if euclidean_distance_g1 < euclidean_distance_g2:
            points_in_g1.append(p)
            group.append(1)
        else:
            points_in_g2.append(p)
            group.append(2)
    return points_in_g1, points_in_g2, group

注: 同じコードを何度も繰り返していることに気付いた場合は、そのコードを別の関数にラップする必要があります。 コードを関数に編成することは、特にテストを容易にするため、ベストプラクティスと見なされます。 関数のない完全なコードよりも、コードの一部をテストして分離する方が簡単です。

関数を呼び出して、その結果をに保存しましょう points_in_g1, points_in_g2, group 変数:

points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
points_in_g1, points_in_g2, group

また、グループの分割を視覚化するために、色付きの点で散布図をプロットします。

sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

ポイントのクラスタリングは 良くなって。 しかし、それでも、グラフの中央には、両方のグループへの近接性を考慮したときにどちらかのグループに割り当てることができるXNUMXつのポイントがあります。 これまでに開発したアルゴリズムは、これらのポイントの両方をXNUMX番目のグループに割り当てます。

これは、XとYを使用して、XNUMXつの新しい中心点を作成することで、おそらくもう一度プロセスを繰り返すことができることを意味します。 (図心) 私たちのグループに、距離に基づいてそれらを再割り当てします。

図心を更新する関数も作成しましょう。 プロセス全体を、その関数の複数の呼び出しに減らすことができるようになりました。

def updates_centroids(points_in_g1, points_in_g2):
    g1_center = np.array(points_in_g1)[:, 0].mean(), np.array(points_in_g1)[:, 1].mean()
    g2_center = np.array(points_in_g2)[:, 0].mean(), np.array(points_in_g2)[:, 1].mean()
    return g1_center, g2_center

g1_center, g2_center = updates_centroids(points_in_g1, points_in_g2)
points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

このXNUMX回目の反復の後、各ポイントが異なるクラスターに属していることに注意してください。 結果は良くなっているようです。もう一度やりましょう。 今行く XNUMX回目の反復 私たちの方法の:

g1_center, g2_center = updates_centroids(points_in_g1, points_in_g2)
points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

今回でXNUMX回目 同じ結果 前のものと同じように。 したがって、ポイントはグループを変更しないようです。結果は、ある種の安定性に達しました。変更できない状態になっている、または 収束。 それに加えて、2つのグループで想定したのとまったく同じ結果が得られました。 この到達した分割が理にかなっているかどうかもわかります。

これまでに行ったことを簡単に要約してみましょう。 10店舗を地理的にXNUMXつのセクションに分割しました。XNUMXつは南西部の下部にあり、もうXNUMXつは北東部にあります。 すでに持っているもの以外に、収益、XNUMX日の顧客数など、より多くのデータを収集することは興味深い場合があります。 そうすることで、より豊富な分析を実行し、より興味深い結果を生成できる可能性があります。

このようなクラスタリング調査は、すでに確立されているブランドが新しい店舗を開くためにエリアを選択したい場合に実行できます。 その場合、場所以外にも考慮される変数がたくさんあります。

これはすべて、K-Meansアルゴリズムと何の関係がありますか?

これらの手順を実行しているときに、K-Meansアルゴリズムと何の関係があるのか​​疑問に思われたかもしれません。 これまでに行ってきたプロセスは K-Meansアルゴリズム。 つまり、グループ/クラスターの数を決定し、初期点をランダムに選択し、クラスターが収束するまで各反復で重心を更新しました。 基本的に、アルゴリズム全体を手作業で実行しました。各ステップを慎重に実行します。

  K K-Meansでは クラスターの数 反復プロセスを開始する前に設定する必要があります。 私たちの場合には K = 2。 この特性は時々見られます 階層的クラスタリングなど、事前に固定数のクラスターを持つ必要のない他のクラスタリング方法があることを考慮してください。

平均法を使用しているため、K-meansも次のようになります。 外れ値と極値に敏感 –それらは変動性を高め、重心がその役割を果たすのを難しくします。 だから、実行する必要性を意識してください 極値と外れ値分析 K-Meansアルゴリズムを使用してクラスタリングを実行する前。

また、ポイントが直線部分にセグメント化されていることに注意してください。クラスターを作成するときに曲線はありません。 これは、K-Meansアルゴリズムの欠点にもなり得ます。

注: より柔軟で楕円やその他の形状に適応できるようにする必要がある場合は、 一般化されたK-meansガウス混合モデル。 このモデルは、楕円形のセグメンテーションクラスターに適応できます。

K-Meansにも多くの 利点! それは上手く機能します 大規模なデータセット 一部のタイプの階層的クラスタリングアルゴリズムを使用している場合、これは処理が困難になる可能性があります。 また 収束を保証します、そして簡単にできます 一般化する および 適応する。 それに加えて、それはおそらく最も使用されているクラスタリングアルゴリズムです。

K-Meansアルゴリズムで実行されるすべての手順を完了し、そのすべての長所と短所を理解したので、Scikit-Learnライブラリを使用して最終的にK-Meansを実装できます。

を使用してK-Meansアルゴリズムを実装する方法 scikit-Learn

結果を再確認するために、このプロセスをもう一度実行しますが、ここでは3行のコードを使用します。 sklearn:

from sklearn.cluster import KMeans


kmeans = KMeans(n_clusters=2, random_state=42) 
kmeans.fit(points)
kmeans.labels_

ここでは、ラベルは以前のグループと同じです。 結果を簡単にプロットしてみましょう。

sns.scatterplot(x = points[:,0], y = points[:,1], hue=kmeans.labels_)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

結果のプロットは、前のセクションのプロットと同じです。

ベストプラクティス、業界で認められた標準、および含まれているチートシートを含む、Gitを学習するための実践的で実用的なガイドを確認してください。 グーグルGitコマンドを停止し、実際に 学ぶ それ!

注: Scikit-Learnを使用してK-Meansアルゴリズムをどのように実行したかを見るだけで、これは簡単で、あまり心配する必要がないという印象を与えるかもしれません。 K-Meansアルゴリズムを段階的に説明したときに、前のセクションで説明したすべてのステップを3行のコードで実行します。 しかし、 悪魔は細部に宿る この場合! アルゴリズムのすべての手順と制限を理解していない場合、K-Meansアルゴリズムが予期しない結果をもたらす状況に直面する可能性があります。

Scikit-Learnを使用すると、K-Meansを初期化して、収束を高速化することもできます。 init='k-means++' 口論。 大まかに言えば、 K-Means ++ まだ選択します k 初期クラスターは、一様分布に従ってランダムに中心になります。 次に、後続の各クラスター中心は、距離測度だけを計算するのではなく、確率を使用して、残りのデータポイントから選択されます。 確率を使用するとアルゴリズムが高速化され、非常に大きなデータセットを処理する場合に役立ちます。

エルボー法–最適なグループ数の選択

ここまでは順調ですね! ポイントと重心の間のユークリッド距離に基づいて、10個のストアをクラスター化しました。 しかし、グラフの中央にある、クラスター化が少し難しいXNUMXつのポイントについてはどうでしょうか。 彼らも別のグループを形成できませんでしたか? 私たちは実際に選択して間違いを犯しましたか K = 2 グループ? 多分私たちは実際に持っていた K = 3 グループ? XNUMXつ以上のグループがあり、それを認識していない可能性もあります。

ここで尋ねられている質問は K-Meansのグループ数(K)を決定する方法。 その質問に答えるには、Kの異なる値に対して「より良い」クラスターがあるかどうかを理解する必要があります。

それを見つける素朴な方法は、異なる値を持つポイントをクラスタリングすることです。 K、そう、のために K = 2、K = 3、K=4など:

for number_of_clusters in range(1, 11): 
    kmeans = KMeans(n_clusters = number_of_clusters, random_state = 42)
    kmeans.fit(points) 

しかし、異なるためのクラスタリングポイント Ks 一人で 十分ではありません の理想的な値を選択したかどうかを理解する K。 それぞれのクラスタリング品質を評価する方法が必要です K 選択しました。

手動で計算する Cluster Sum of Squares(WCSS)内

これは、クラスター化されたポイントが互いにどれだけ近いかを測定するための理想的な場所です。 それは本質的にどれくらいを説明します 分散 単一のクラスター内にあります。 この対策はと呼ばれます クラスターの二乗和内または WCSS 略して。 WCSSが小さいほど、ポイントが近くなるため、より整形式のクラスターになります。 WCSS式は、任意の数のクラスターに使用できます。

$$
WCSS = sum(Pi_1 – Centroid_1)^ 2 + cdots + sum(Pi_n – Centroid_n)^ 2
$$

注: このガイドでは、 ユークリッド距離 重心を取得するために使用しますが、マンハッタンなどの他の距離測度も使用できます。

これで、XNUMXつのクラスターを選択したと想定し、WCSSの実装を試みて、WCSSとは何かおよびその使用方法をよりよく理解できるようになりました。 式が示すように、すべてのクラスターポイントと重心の間の差のXNUMX乗を合計する必要があります。 したがって、最初のグループからの最初のポイントが (5, 3) 最初のグループの最後の重心(収束後)は (16.8, 17.0)、WCSSは次のようになります。

$$
WCSS = sum((5,3)–(16.8、17.0))^ 2
$$

$$
WCSS = sum((5-16.8)+(3-17.0))^ 2
$$

$$
WCSS = sum((-11.8)+(-14.0))^ 2
$$

$$
WCSS = sum((-25.8))^ 2
$$

$$
WCSS = 335.24
$$

この例は、クラスターからXNUMXつのポイントのWCSSを計算する方法を示しています。 ただし、クラスターには通常複数のポイントが含まれているため、WCSSを計算する際にはそれらすべてを考慮する必要があります。 これを行うには、点と重心のクラスターを受け取り、平方和を返す関数を定義します。

def sum_of_squares(cluster, centroid):
    squares = []
    for p in cluster:
        squares.append((p - centroid)**2)
        ss = np.array(squares).sum()
    return ss

これで、各クラスターの二乗和を取得できます。

g1 = sum_of_squares(points_in_g1, g1_center)
g2 = sum_of_squares(points_in_g2, g2_center)

そして、結果を合計して合計を求めます WCSS:

g1 + g2

この結果:

2964.3999999999996

だから、私たちの場合、 K が2に等しい場合、WCSSの合計は 2964.39。 これで、Kを切り替えて、それらすべてのWCSSを計算できます。 そうすれば、私たちは何についての洞察を得ることができます K クラスタリングを最高のパフォーマンスにすることを選択する必要があります。

計算する WCSS 使い方 scikit-Learn

幸い、それぞれのWCSSを手動で計算する必要はありません。 K。 指定された数のクラスターに対してK-Meansクラスタリングを実行した後、を使用してWCSSを取得できます。 inertia_ 属性。 これで、K-Meansに戻ることができます for ループし、それを使用してクラスターの数を切り替え、対応するWCSS値を一覧表示します。

wcss = [] 
for number_of_clusters in range(1, 11): 
    kmeans = KMeans(n_clusters = number_of_clusters, random_state = 42)
    kmeans.fit(points) 
    wcss.append(kmeans.inertia_)
wcss

リストのXNUMX番目の値は、以前に計算したものとまったく同じであることに注意してください。 K = 2:

[18272.9, # For k=1 
 2964.3999999999996, # For k=2
 1198.75, # For k=3
 861.75,
 570.5,
 337.5,
 175.83333333333334,
 79.5,
 17.0,
 0.0]

これらの結果を視覚化するために、 Ks WCSS値とともに:

ks = [1, 2, 3, 4, 5 , 6 , 7 , 8, 9, 10]
plt.plot(ks, wcss)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

プロットに中断がある場合 x = 2、ラインの低いポイント、そしてさらに低いポイント x = 3。 それが私たちに思い出させることに注意してください ひじの形。 WCSSとともにKをプロットすることにより、 エルボー法 Kの数を選択します。 そしてその 選択したKは正確に最も低いエルボーポイントです、だから、それは 3 2、 私たちの場合には:

ks = [1, 2, 3, 4, 5 , 6 , 7 , 8, 9, 10]
plt.plot(ks, wcss);
plt.axvline(3, linestyle='--', color='r')

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

K-Meansクラスターアルゴリズムを再度実行して、データがどのように表示されるかを確認できます。 XNUMXつのクラスター:

kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(points)
sns.scatterplot(x = points[:,0], y = points[:,1], hue=kmeans.labels_)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

すでにXNUMXつのクラスターに満足していましたが、エルボー法によれば、XNUMXつのクラスターの方がデータに適しています。 この場合、XNUMX種類ではなくXNUMX種類の店舗があります。 エルボー方式を採用する前は、南西部と北東部の店舗群を考えていましたが、現在は中央にも店舗があります。 近くでの競争が少ないので、別の店舗を開くのに適した場所かもしれません。

代替クラスター品質測定

クラスターの品質を評価するときに使用できる他の測定値もあります。

  • シルエットスコア –クラスター内のポイント間の距離だけでなく、クラスター自体の間の距離も分析します
  • クラスター間二乗和 (BCSS) –WCSSを補完するメトリック
  • 二乗和エラー (SSE)
  • 最大半径 –ポイントからその図心までの最大距離を測定します
  • 平均半径 –ポイントからその重心までの最大距離の合計をクラスターの数で割ったもの。

問題によっては、最も広く使用されているメトリックよりもいくつかの選択肢の方が適用できる可能性があるため、実験してそれぞれを理解することをお勧めします。 (WCSSとシルエットスコア).

最終的に、多くのデータサイエンスアルゴリズムと同様に、各クラスター内の分散を減らし、異なるクラスター間の分散を最大化する必要があります。 したがって、より定義された分離可能なクラスターがあります。

別のデータセットにK-Meansを適用する

別のデータセットで学んだことを使用してみましょう。 今回は、似たようなワインのグループを探します。

注: データセットをダウンロードできます こちら.

インポートから始めます pandas を読む wine-clustering CSV (カンマ区切り値) ファイルに Dataframe 構造:

import pandas as pd

df = pd.read_csv('wine-clustering.csv')

ロードした後、データの最初のXNUMXつのレコードを確認してみましょう。 head() 方法:

df.head()

この結果:

	Alcohol 	Malic_Acid 	Ash 	Ash_Alcanity 	Magnesium 	Total_Phenols 	Flavanoids 	Nonflavanoid_Phenols 	Proanthocyanins 	Color_Intensity 	Hue 	OD280 	Proline
0 	14.23 		1.71 		2.43 	15.6 			127 		2.80 			3.06 		0.28 					2.29 				5.64 				1.04 	3.92 	1065
1 	13.20 		1.78 		2.14 	11.2 			100 		2.65 			2.76 		0.26 					1.28 				4.38 				1.05 	3.40 	1050
2 	13.16 		2.36 		2.67 	18.6 			101 		2.80 			3.24 		0.30 					2.81 				5.68 				1.03 	3.17 	1185
3 	14.37 		1.95 		2.50 	16.8 			113 		3.85 			3.49 		0.24 					2.18 				7.80 				0.86 	3.45 	1480
4 	13.24 		2.59 		2.87 	21.0 			118 		2.80 			2.69 		0.39 					1.82 				4.32 				1.04 	2.93 	735

ワインに含まれる物質の多くの測定値があります。 ここでも、カテゴリ列はすべて数値であるため、変換する必要はありません。 それでは、記述統計を見てみましょう。 describe() 方法:

df.describe().T 

記述テーブル:

 						count 	mean 		std 		min 	25% 	50% 	75% 		max
Alcohol 				178.0 	13.000618 	0.811827 	11.03 	12.3625 13.050 	13.6775 	14.83
Malic_Acid 				178.0 	2.336348 	1.117146 	0.74 	1.6025 	1.865 	3.0825 		5.80
Ash 					178.0 	2.366517 	0.274344 	1.36 	2.2100 	2.360 	2.5575 		3.23
Ash_Alcanity 			178.0 	19.494944 	3.339564 	10.60 	17.2000 19.500 	21.5000 	30.00
Magnesium 				178.0 	99.741573 	14.282484 	70.00 	88.0000 98.000 	107.0000 	162.00
Total_Phenols 			178.0 	2.295112 	0.625851 	0.98 	1.7425 	2.355 	2.8000 		3.88
Flavanoids 				178.0 	2.029270 	0.998859 	0.34 	1.2050 	2.135 	2.8750 		5.08
Nonflavanoid_Phenols 	178.0 	0.361854 	0.124453 	0.13 	0.2700 	0.340 	0.4375 		0.66
Proanthocyanins 		178.0 	1.590899 	0.572359 	0.41 	1.2500 	1.555 	1.9500 		3.58
Color_Intensity 		178.0 	5.058090 	2.318286 	1.28 	3.2200 	4.690 	6.2000 		13.00
Hue 					178.0 	0.957449 	0.228572 	0.48 	0.7825 	0.965 	1.1200 		1.71
OD280 					178.0 	2.611685 	0.709990 	1.27 	1.9375 	2.780 	3.1700 		4.00
Proline 				178.0 	746.893258 	314.907474 	278.00 	500.500 673.500 985.0000 	1680.00

表を見ると、いくつかあることが明らかです。 データの変動性 –などの一部の列 Alchool もっとあります、そして他の人のために、 Malic_Acid、 以下。 これで、あるかどうかを確認できます nullまたは NaN データセットの値:

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 178 entries, 0 to 177
Data columns (total 13 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   Alcohol               178 non-null    float64
 1   Malic_Acid            178 non-null    float64
 2   Ash                   178 non-null    float64
 3   Ash_Alcanity          178 non-null    float64
 4   Magnesium             178 non-null    int64  
 5   Total_Phenols         178 non-null    float64
 6   Flavanoids            178 non-null    float64
 7   Nonflavanoid_Phenols  178 non-null    float64
 8   Proanthocyanins       178 non-null    float64
 9   Color_Intensity       178 non-null    float64
 10  Hue                   178 non-null    float64
 11  OD280                 178 non-null    float64
 12  Proline               178 non-null    int64  
dtypes: float64(11), int64(2)
memory usage: 18.2 KB

データセットに空の値がないことを考えると、データを削除したり入力したりする必要はありません。 Seabornを使用できます pairplot() データ分布を確認し、データセットがクラスタリングに役立つ列のペアを形成しているかどうかを確認するには、次のようにします。

sns.pairplot(df)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

ペアプロットを見ると、XNUMXつの列がクラスタリングの目的で有望であるように見えます– Alcohol および OD280 (これはワインのタンパク質濃度を決定するための方法です)。 それらの3つを組み合わせたプロットにはXNUMXつの異なるクラスターがあるようです。

相関しているように見える他の列もあります。 最も注目すべきは Alcohol および Total_Phenols, Alcohol および Flavanoids。 それらは、ペアプロットで観察できる優れた線形関係を持っています。

私たちの焦点はK-Meansによるクラスタリングであるため、たとえば、XNUMX組の列を選択しましょう。 Alcohol および OD280、このデータセットのエルボーメソッドをテストします。

注: データセットのより多くの列を使用する場合は、3次元でプロットするか、データを次のように縮小する必要があります。 主成分(PCAの使用)。 これは有効でより一般的なアプローチです。説明の量に基づいて主成分を選択するようにしてください。データの次元を減らすと、情報が失われることに注意してください。したがって、プロットは 近似 実際のデータではなく、実際のデータです。

これらのXNUMXつの列を軸に設定して散布図をプロットし、グループに分割するポイントを詳しく見てみましょう。

sns.scatterplot(data=df, x='OD280', y='Alcohol')

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

これで、列を定義し、elbowメソッドを使用してクラスターの数を決定できます。 また、アルゴリズムを開始します kmeans++ より迅速に収束することを確認するためだけに:

values = df[['OD280', 'Alcohol']]

wcss_wine = [] 
for i in range(1, 11): 
    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
    kmeans.fit(values) 
    wcss_wine.append(kmeans.inertia_)

WCSSを計算したので、結果をプロットできます。

clusters_wine = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plt.plot(clusters_wine, wcss_wine)
plt.axvline(3, linestyle='--', color='r')

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

エルボー法によると、ここには3つのクラスターが必要です。 最後のステップとして、ポイントを3つのクラスターにクラスター化し、色で識別されるクラスターをプロットしてみましょう。

kmeans_wine = KMeans(n_clusters=3, random_state=42)
kmeans_wine.fit(values)
sns.scatterplot(x = values['OD280'], y = values['Alcohol'], hue=kmeans_wine.labels_)

Scikit-Learn PlatoBlockchain Data Intelligence を使用した K-Means クラスタリングの決定版ガイド。垂直検索。あい。

クラスターを見ることができます 0, 1, 2 グラフで。 私たちの分析に基づいて、 グループ0 タンパク質含有量が高く、アルコール度数が低いワインがあります。 グループ1 アルコール度数が高く、タンパク質が少ないワインがあり、 グループ2 ワインには高タンパクと高アルコールの両方が含まれています。

これは非常に興味深いデータセットであり、正規化とPCAの後にデータをクラスター化することによって、また結果を解釈して新しい接続を見つけることによって、分析をさらに進めることをお勧めします。

まとめ

K平均 クラスタリングは、データクラスタリングのためのシンプルでありながら非常に効果的な教師なし機械学習アルゴリズムです。 データポイント間のユークリッド距離に基づいてデータをクラスター化します。 K-Meansクラスタリングアルゴリズムには、テキストドキュメント、画像、ビデオなどをグループ化するための多くの用途があります。

タイムスタンプ:

より多くの スタックアバス