6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pyclusteringのxmeansの一部をsklearn風にラッパーする

Last updated at Posted at 2019-06-07

#動機
k-means法では最初にクラスタ数を決めなければいけないが、x-means法なら自動的に決めてくれる(最適なクラスタ数かどうかはわからないが)。そこでpyclusteringのxmeansを見つけたが使い方がsklearnのスタイルと違ったため使いづらかった。そこで今回はpyclusteringのxmeans.fitについてsklearn風にラッパーしたいと思う。

#問題点
sklearnのk-meansとpyclusteringのx-meansの大きな違いはskleranでいうlabel_の配列の返し方が違うところだ。例えば標本として samples = [a,b,c,d]があり(a,b,c,d) = (0,1,0,1)でクラスタリングされたとする。
skleranのlabel_は[0,1,0,1]と標本配列と同じ順番にクラスタ番号の配列を返す。
pyclusteringでいうところのlabel_(正確にはxmeans.xmeans().getcluster())は[[0,2],[1,3]]と標本配列のインデックスがクラスタ番号順に分類され、その配列を返す。
(国語力が足りない....)
今回はそれを解決する。

#コード

import pyclustering
from pyclustering.cluster import xmeans
import numpy as np


class XMeans:
    def fit(self,features):
        '''pyclusteringのxmeansで計算'''
        initializer = xmeans.kmeans_plusplus_initializer(data=features,amount_centers=2)
        initial_centers = initializer.initialize()
        xm = xmeans.xmeans(data=features,initial_centers=initial_centers)
        xm.process()

        """
        分類が出力される
        しかしこの出力の仕方がscikit-learnとは違うので厄介
        """
        clusters = xm.get_clusters()
        '''一次元配列flat_labelを用意'''
        flat_label = np.array([])
        '''sklearnでいうlabel_の大きさを調べる'''
        for cluster in clusters:
            flat_label = np.append(flat_label,cluster)
        '''正規のlabelを代入するための配列を確保'''
        labels = np.zeros((1,flat_label.size))
        '''
        pyclusteringのclustersはクラスター数次元配列があり、標本の名前がクラスターに分類され配列として返す。
        一方でsklearnのlabel_は標本と同様の順番に、その標本が属するクラスターの番号を配列で返す。
        下記のコードはその変換を行っている
        '''
        for n,n_th_cluster in enumerate(clusters):
            for img_num in n_th_cluster:
                labels[0][img_num] = n

        
        '''このままのラベルだと[[a........z]]の二重括弧になる。
        それはsklearnの仕様に沿わない。[a........z]の一重括弧にする。
        '''

        self.labels_ = labels[0]
        return self

2020/05/30 コードを一部修正
@physicalcottonさんのご指摘によりコードを一部修正しました。@physicalcottonさん、ご指摘ありがとうございます。
#まとめ
個人的にこのコードはまだまだ改善の余地があると思っている。もしよければ改善点を申し付けていただいたらありがたい。

6
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?