【k-means法】機械学習手法であるk-means法を実践してみた

はじめに

こんにちは、がんがんです。
今回は機械学習手法であるk-means法について実践してみたので、その備忘録です。

k-means法とは

k-means法は機械学習手法の1つです。昔から使われている教師なし学習の手法です。
詳細は以下がとてもきれいにまとめられていますので参考にどうぞ。

www.hellocybernetics.tech

実験

オリジナルデータのプロット

まずはIrisのオリジナルデータをプロットしていきます。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from sklearn import datasets
from sklearn.model_selection import train_test_split 
from sklearn.preprocessing import StandardScaler

"""
	Irisのデータセットを表示
"""
def iris_data():
	#  data import
	iris = datasets.load_iris()
	names = iris.target_names
	data1 = 1
	data2 = 2
	data3 = 3
	
	X = iris.data[:, [data1,data2,data3]]
	y = iris.target
	
	print("Class labels:{}".format(np.unique(y)))
	
	#  Split the data
	X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=0 )
	
	sc = StandardScaler()
	sc.fit(X_train)
	X_train_std = sc.transform(X_train)
	X_test_std = sc.transform(X_test)
	
	#  data plot
	fig = plt.figure()
	ax = Axes3D(fig)
	ax1 = ax.scatter3D(np.ravel(X[y==0,0]), np.ravel(X[y==0,1]), np.ravel(X[y==0,2]), c="b", marker="o")
	ax2 = ax.scatter3D(np.ravel(X[y==1,0]), np.ravel(X[y==1,1]), np.ravel(X[y==1,2]), c="r", marker="o")
	ax3 = ax.scatter3D(np.ravel(X[y==2,0]), np.ravel(X[y==2,1]), np.ravel(X[y==2,2]), c="y", marker="o")
	ax.set_xlabel(iris.feature_names[data1])
	ax.set_ylabel(iris.feature_names[data2])
	ax.set_zlabel(iris.feature_names[data3])
	
	plt.legend( (ax1, ax2, ax3),
				(names[0], names[1], names[2]),
				scatterpoints=1,
				loc="upper left",
				ncol=3,
				fontsize=8)
	plt.show()

きちんと3種類が表示されています。
f:id:gangannikki:20181116191621p:plain

k-means法を用いてクラスタリング

次にk-means法を用いてクラスタリングをしていきます。

"""
	k-means法を用いてクラスタリング
"""
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from sklearn import datasets
from sklearn.model_selection import train_test_split 
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans

def k_means():
	#  data import
	iris = datasets.load_iris()
	names = iris.target_names
	data1 = 1
	data2 = 2
	data3 = 3
	
	X = iris.data[:, [data1,data2,data3]]
	y = iris.target
	
	print("Class labels:{}".format(np.unique(y)))
	
	#  Split the data
	X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=0 )
	
	sc = StandardScaler()
	sc.fit(X_train)
	X_train_std = sc.transform(X_train)
	X_test_std = sc.transform(X_test)

	#  k-means
	km = KMeans(n_clusters=3,
				init="random",
				n_init=10,
				max_iter=300,
				tol=1e-04,
				random_state=0
	)
	y_km = km.fit_predict(X)
	
	#  Predicted data plot
	fig = plt.figure()
	ax = Axes3D(fig)
	ax_km1=ax.scatter3D(np.ravel(X[y_km==0,0]), np.ravel(X[y_km==0,1]), np.ravel(X[y_km==0,2]), c="y", marker="x")
	ax_km2=ax.scatter3D(np.ravel(X[y_km==1,0]), np.ravel(X[y_km==1,1]), np.ravel(X[y_km==1,2]), c="r", marker="x")
	ax_km3=ax.scatter3D(np.ravel(X[y_km==2,0]), np.ravel(X[y_km==2,1]), np.ravel(X[y_km==2,2]), c="b", marker="x")
	ax_km4=ax.scatter3D(km.cluster_centers_[:, 0], km.cluster_centers_[:, 1],km.cluster_centers_[:, 2], c="k", marker="o")
	ax.set_xlabel(iris.feature_names[data1])
	ax.set_ylabel(iris.feature_names[data2])
	ax.set_zlabel(iris.feature_names[data3])
	plt.legend( (ax_km1, ax_km2, ax_km3, ax_km4),
				(names[0], names[1], names[2], "Centroid"),
				scatterpoints=1,
				loc="upper left",
				ncol=3,
				fontsize=8)
	plt.show()

きちんと3種類に分けることができています。
f:id:gangannikki:20181116191800p:plain

まとめ

今回はk-means法を試してみました。k-means自体は1行で書くことができ、とても簡単です。
機械学習法であるランダムフォレストなども興味があるため、後々やっていきます。