k-meansクラスタリングで遊ぶ
k-meansがディスられていたので、取り敢えずどんなもんかと実装した。
exp:
#include<srook/k_means/k_means.hpp> int main() { srook::k_mns::k_means km("data",3); // km.set_initial_point(Point{2.0,90.0},Point{5.0,50.0}); // initial centerの独自設定も勿論可能 km.clustering(); // 未設定の場合ベクトルの各min/max内で分布する乱数をinitial centerとする const char* result_file="result"; std::ofstream ofs(result_file); ofs<<km; using namespace std::string_literals; srook::k_mns::ploter pl("output.png"); std::string cmd="plot \""s+std::string(result_file)+"\" index 0,\"\" index 1,\"\" index 2"; try{ pl.output(cmd.c_str()); }catch(const std::runtime_error& exp){ std::cerr<<exp.what()<<std::endl; } }
入力は,
をデリミターとしたテキストデータから行う。出力はgnuplotで入力できる形式で吐き出す。
三つのclusteringの動作確認。initial centerはデータセットのx,yそれぞれのmin,max内で分布される値にしてるけど、割りとよく分類できてるような。 pic.twitter.com/dXSnII5VK8
— roκi (@530506) 2017年5月22日
折角なので、ミッxーマxスのシルエットのようなデータセットを与えて見る事にした。まずは、データセットを作成し、画像として出力しておく。
python3 random_circle.py gnuplot -e "set terminal png; set output \"test.png\"; set datafile separator \",\"; plot \"mouse_data\" index 0"
さて、このデータセットのクラスタリングを行った結果、以下のようになった。
あー、確かに似たような出力になった。データセット:https://t.co/51NPJjfBnh pic.twitter.com/Aged2dtDX1
— roκi (@530506) 2017年5月23日
まぁこんなものだろう。このデータセットでは、initial centerやプロットの精度を上げても特に結果として大きな変化はなかった。まぁこのデータセットで考えればそうだろう。
一応、遊べるように、リポジトリを作ってある。
github.com
また、お手軽に試せるように、gistにフルコードをアップロードしてある。
尚この機能は、SrookCppLibraries からも利用する事ができる。