paiza times

paizaがお届けする、テック・キャリア・マネジメント領域における「今必要な情報」を届けるWebメディア

logo

paizaがお届けする、テック・キャリア・マネジメント領域の「今必要な情報」を届けるWebメディア

機械学習初心者向け、Pythonを使ってK-meansでクラスタリングしてみた

f:id:paiza:20170613144753j:plain
Photo by Rene Barrios
秋山です。

機械学習と一言で言っても、そのアルゴリズムにはたくさんの種類があり、「どれがどんな場合に適しているのか」というのは、なかなかわかりづらいと思います。

そこで今回は、初心者向けに「K-means」(k平均法)という手法について説明します。

K-meansがどんなデータに適しているか、どうやってデータが分離されるのか…といったことは、文章だけ読んでも分かりづらいと思いますので、実際にPythonでコードを書いて実行したり、図を出したりして、過程を見ながら説明していきます。

既に機械学習の経験がある人にとっては今さらなことばかりかと思いますが、「機械学習の勉強を始めたい」という人の参考になればと思います。

■K-meansとは

簡単に説明しますと、

  1. まず、各点に対してランダムにどのクラスタに属するかを決定します。
  2. 次に、各クラスタの中心点Vが決定されます。(ランダムに決まったクラスタの中心です)
  3. Vと各点における距離を求め、各点はそれぞれ一番近いクラスタに割り当て直されます。このとき、すべての点が同じクラスタに割り当て直されたら処理は終了し、そうでなければ2に戻ります。

……っというのがK-meansのアルゴリズムです。(※k平均法 - Wikipedia

3.の手順の終了条件は、一般的にはクラスタの割り当て直す数が設定した閾値以下であれば終了…となるように設定することが多いかと思います。

……と、文字だけで説明されても何だかよくわからないかと思いますので、実際にランダムで作ったテストデータのクラスタ割り当てを見て確認してみましょう。

K-meansは、scikit-learnというライブラリで簡単に使うことができます。

インストールは↓これだけでできます。

pip install scikit-learn

また、ライブラリはnumpy,pandas,matplotlibも使います。インストール方法などは、過去に書いたjupyterの記事を参考にしてください。
paiza.hatenablog.com


下記のPythonコードは、 n_samples がサンプル数、 centers がクラスタの個数です。 cluster_std はばらつきを調整しています。 random_state=3 は、ランダムジェネレートのシード値で省略すると毎回違う結果となるので、それを固定しています。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
data,cluster=make_blobs(n_samples=1000,centers=2,cluster_std=2.3, random_state=3)
plt.scatter(data[:,0],data[:,1],c='black',marker='.',s=50)
plt.grid()
plt.show()

上記コードをjupyterで実行すると、このような図が作られます。
f:id:paiza:20170613140852p:plain

cluster には、実際に2クラスタに分かれたデータが入っています。それを表示させるためには以下のようなコードを実行します。

plt.scatter(data[cluster==0,0],data[cluster==0,1],s=50,c='red',marker='.',label='1')
plt.scatter(data[cluster==1,0],data[cluster==1,1],s=50,c='black',marker='.',label='2')
plt.legend()
plt.grid()
plt.show()


上記コードをjupyterで実行すると、このような図が出ます。何となく、右上と左下に集まったデータ群…になっているのがわかりますよね。
f:id:paiza:20170613141106p:plain


それでは、K-meansを使ってクラスタが不明な状態からクラスタ分けを実行してみましょう。

from sklearn.cluster import KMeans
def t(n):
    km = KMeans(n_clusters=2,init='random',n_init=1,max_iter=n,random_state=1)
    cluster = km.fit_predict(X)
    plt.scatter(data[cluster==0,0],data[cluster==0,1],c='red',marker='.',label='1')
    plt.scatter(data[cluster==1,0],data[cluster==1,1],c='black',marker='.',label='2')
    plt.scatter(km.cluster_centers_[:,0],km.cluster_centers_[:,1],marker='X',c='red',label='centroids')
    plt.legend()
    plt.grid()
    plt.show()

KMeans(n_clusters=2,init='random',n_init=1,max_iter=n,random_state=1) というのが、K-meansを行う関数です。

上記の def t(n) では、 max_iter を n として受け取っています。こうすることで、最初に説明した手順の2.と3.の繰り返し回数を指定できます。

また、 random_state=1 では、データを作ったときと同様に、ランダムのシード値を固定しています。


1〜5回それぞれの回数を繰り返した図と、10回繰り返させた図を順に並べると……

t(1)
t(2)
t(3)
t(4)
t(5)
t(10)

回数が多いほど、少~しずついい感じにデータが分離されていってるのがわかるかと思います。


1回
f:id:paiza:20170613143001p:plain


2回
f:id:paiza:20170613143036p:plain


3回
f:id:paiza:20170613143116p:plain


4回
f:id:paiza:20170613143152p:plain


5回
f:id:paiza:20170613143253p:plain


10回
f:id:paiza:20170613143334p:plain

■まとめ

K-meansに限らず、他のアルゴリズムでも似たような感じでコードを書いて実行して結果を見ることで、機械学習への理解が深まるかと思います。

過去に「Word2Vec」「Doc2Vec」を使ってディープラーニングをやってみた記事も書いていますので、「ディープラーニングのほうが興味ある~」という方はこちらもぜひ見てみてください。
paiza.hatenablog.com

■Pythonの講座も公開中!プログラミングが動画で学べるレッスン

paizaは、技術を追い続けることが仕事につながり、スキルのある人がきちんと評価される場を作ることで、日本のITエンジニアの地位向上を目指したいと考えています。

自分のスキルを磨いていきたいと考えている方におすすめなのが「paizaラーニング」。オンラインでプログラミングしながらスキルアップできる入門学習コンテンツです。初心者でも楽しくプログラミングの基本を学ぶことができます。

paizaラーニング

そして、paizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。

paizaのスキルチェック

スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。

paizaのおすすめコンテンツ

CGC codemonster プログラミングゲーム「初恋プログラミング研究会 ~海に行こうよ~」 CGC codemonster プログラミングゲーム「コードモンスター大図鑑 プログラミングでゲットだぜ!」
paiza転職 paiza新卒 EN:TRY paizaラーニング 記事内に記載している情報は、記事公開時点でのものとなります。 Copyright Paiza, Inc, All rights reserved.