1. k-meansクラスタリングとは?
k-meansクラスタリング(k平均法)は、最も広く使われている教師なし学習アルゴリズムの一つです。 その目的は、与えられたデータセットを、事前に指定した数(k)個の互いに素なグループ(クラスタ)に分割することです。 各クラスタは、そのクラスタに属するデータ点の「中心」(セントロイド)によって特徴づけられます。
教師なし学習なので、正解ラベルは使いません。データの特徴だけを頼りに、似ているもの同士を自動的にグループ分けします。 例えば、顧客データから似たような購買傾向を持つグループを見つけ出す(顧客セグメンテーション)や、画像の色を減らして圧縮する、といった用途で利用されます。
2. k-meansのアルゴリズムの仕組み
k-meansアルゴリズムは、以下のステップを繰り返すことでクラスタリングを行います。
- 初期中心点の選択: データの中からランダムに、あるいは特定の方法でk個の点を「初期」クラスタ中心(セントロイド)として選びます。
- クラスタ割り当て: すべてのデータ点について、最も距離が近い中心点を見つけ、そのデータ点をその中心点が代表するクラスタに割り当てます。
- 中心点の更新: 各クラスタについて、そのクラスタに属するすべてのデータ点の平均ベクトル(重心)を計算し、それを新しいクラスタ中心点とします。
- 繰り返し: ステップ2とステップ3を、クラスタ中心点がほとんど変化しなくなるか、あるいは予め定めた最大反復回数に達するまで繰り返します。
このプロセスにより、各データ点は最終的にいずれか一つのクラスタに属し、各クラスタの中心はそのクラスタ内のデータ点の重心となります。
3. Python (scikit-learn) で試してみよう
Pythonの機械学習ライブラリ scikit-learn
を使えば、k-meansクラスタリングを簡単に実装できます。 ここでは、簡単なサンプルデータで試してみましょう。
make_blobs
で生成したデータに対し、KMeans
を使って3つのクラスタに分類しました。fit
メソッドで学習とクラスタリングが実行され、labels_
属性で各データ点の所属クラスタ番号、cluster_centers_
属性で最終的なクラスタ中心の座標、inertia_
属性でクラスタ内の誤差平方和を取得できます。
4. なぜ初期値が重要なのか?
k-meansアルゴリズムの説明で「初期中心点の選択」というステップがありましたが、実はこの初期中心点の選び方が最終的なクラスタリング結果に大きく影響を与えることがあります。これはk-meansの重要な特性(そして弱点)の一つです。
なぜ影響があるのでしょうか? k-meansは、クラスタ内誤差平方和(イナーシャ)を最小化しようとしますが、アルゴリズムの性質上、必ずしも全体で最も良い解(大域的最適解)を見つけられるとは限りません。選んだ初期値によっては、そこそこ良いけれどもベストではない解(局所的最適解)にたどり着いて、そこで更新が止まってしまうことがあるのです。
運悪く初期値が偏っていたりすると、人間が見れば明らかにおかしいようなクラスタリング結果になってしまうこともあります。したがって、良いクラスタリング結果を得るためには、初期値の選び方が非常に重要になります。
5. 初期値問題への対策
幸いなことに、この初期値問題に対するいくつかの効果的な対策が存在します。
- k-means++ アルゴリズム: これは、初期中心点をより賢く選ぶためのアルゴリズムです。最初の1点はランダムに選びますが、2点目以降は、既に選ばれている中心点からなるべく遠いデータ点を確率的に選びやすくします。これにより、初期中心点が互いに離れて配置されやすくなり、より良い(または最適な)クラスタリング結果を得られる可能性が高まります。 scikit-learnのKMeansでは、これがデフォルトの初期値選択方法 (`init=’k-means++’`) になっています。
- 複数回実行 (`n_init` パラメータ): 異なる初期中心点の組み合わせでk-meansアルゴリズムを複数回実行し、その中で最もイナーシャ(クラスタ内誤差平方和)が小さかった結果を採用するという方法です。単純ですが効果的な方法です。 scikit-learnの
KMeans
クラスでは、n_init
というパラメータで実行回数を指定できます。デフォルトではn_init=10
(バージョンによって異なる可能性あり、最新版を確認) となっており、10回の異なる初期値で実行し、最良の結果を返します。
これらの対策により、初期値に由来する不安定さを大幅に軽減し、より安定して良いクラスタリング結果を得ることができます。
6. scikit-learnでのパラメータ設定
scikit-learnの KMeans
クラスで初期値に関連する主要なパラメータは以下の通りです。
パラメータ | 説明 | デフォルト値 (scikit-learn 1.4時点) | 主な選択肢 |
---|---|---|---|
init | 初期中心点の選択方法を指定します。 | 'k-means++' |
|
n_init | 異なる初期中心でk-meansアルゴリズムを実行する回数を指定します。最終的に最もイナーシャが低い結果が採用されます。 | 10 |
|
random_state | 初期中心点選択やk-means++の際の乱数生成器の状態を固定します。結果の再現性を確保したい場合に整数値を指定します。 | None | 整数値、または None 。 |
例えば、ランダムな初期値で5回実行したい場合は、以下のように指定します。
init='k-means++'
と n_init=10
で十分良い結果が得られます。特別な理由がない限り、これらの設定から始めるのが良いでしょう。 7. まとめ
今回は、教師なし学習の代表的なアルゴリズムであるk-meansクラスタリングについて学びました。
- k-meansはデータをk個のクラスタに分割するシンプルなアルゴリズムです。
- アルゴリズムは、中心点の選択、データ点の割り当て、中心点の更新を繰り返します。
- 初期中心点の選び方によって結果が変わる「初期値依存性」があります。
- k-means++ や 複数回実行 (n_init) によって、初期値問題の影響を軽減できます。
- scikit-learnを使えば簡単に実装でき、パラメータで初期値戦略を制御できます。
k-meansは理解しやすく強力な手法ですが、クラスタの形状が球状であることを仮定していたり、事前にクラスタ数kを決める必要があるなどの特徴もあります。 次のステップでは、他のクラスタリング手法(階層クラスタリング、DBSCANなど)や、クラスタリング結果の評価方法についても学んでいきましょう!