Rokiのチラ裏

学生による学習のログ

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で入力できる形式で吐き出す。

折角なので、ミッxーマxスのシルエットのようなデータセットを与えて見る事にした。まずは、データセットを作成し、画像として出力しておく。

python3 random_circle.py
gnuplot -e "set terminal png; set output \"test.png\"; set datafile separator \",\"; plot \"mouse_data\" index 0"

さて、このデータセットクラスタリングを行った結果、以下のようになった。

まぁこんなものだろう。このデータセットでは、initial centerやプロットの精度を上げても特に結果として大きな変化はなかった。まぁこのデータセットで考えればそうだろう。
一応、遊べるように、リポジトリを作ってある。 github.com また、お手軽に試せるように、gistにフルコードをアップロードしてある。 尚この機能は、SrookCppLibraries からも利用する事ができる。