LoginSignup
0
1

More than 5 years have passed since last update.

Deeplearning4jのKmeansを使うときに気をつけること

Last updated at Posted at 2017-07-02

結論

deeplearning4jのKmeansを使うときにdistanceFunctioncosinesimilarityを使ってはいけない。

理由

※deeplearning4jは2017/7/2時点で最新版の0.8.0です。

deeplearning4jにはKmeansの関数があります。以下のような形で使います。

KMeansClustering kmc = KMeansClustering.setup(num, iter, distanceFunction);
ClusterSet cs = kmc.applyTo(pointsLst);

ここで、numはクラスタ数、iterは繰り返し回数(10がよく使われる)、destanceFunctionは距離関数(euclideanmanhattancosinesimilarityを指定できる)です。

さて、ここに地雷があります。destanceFunctioncosinesimilarityを指定すると、思ったような結果は出てきません。
※「普通euclideanを指定するだろ」って方は問題なしです。

鋭い方はお気づきでしょうが、cosinesimilarityだけ類似度です。残りの2つは距離です。すなわち、cosinesimilarityは値が大きいほど(MAXは1)類似度が高く、残りの2つは値が小さいほど類似度が高いということです。

deeplearning4jのプログラム的にはこんな感じになっています。ClusterSet.classにて、

    public Pair<Cluster, Double> nearestCluster(Point point) {

        Cluster nearestCluster = null;
        double minDistance = Float.MAX_VALUE;

        double currentDistance;
        for (Cluster cluster : getClusters()) {
            currentDistance = cluster.getDistanceToCenter(point);
            if (currentDistance < minDistance) {
                minDistance = currentDistance;
                nearestCluster = cluster;
            }
        }

        return new Pair<>(nearestCluster, minDistance);

    }

この関数で今あるクラスタと自分の距離を計算し、一番距離が短いクラスタに分類するわけです。すごく真当な処理ですが、cosinesimilarityだけ値の解釈が逆なので、ここでとんでもないことになります。

おわりに

どうしてもcosinesimilarityを使いたい場合は、現状だとextendsクラス作るしかないです。そこだけ例外処理加えてプルリク送ろうかと思いましたが、なんかコード汚いので辞めました。ほっとくのもどうかと思うのですが、どうしましょ。

追記

issuesに登録されていました。
https://github.com/deeplearning4j/deeplearning4j/issues/2361

どうやら「正常な動作」ということで片付いてるようです。たしかに・・・正常な動作ですけど「正しい処理」ではないですよね。使えなくするか、無理やり使うならcosinesimilaritycosinedistanceとして、s[cosinedistance]=1-s[cosinesimilarity]のみ受け付けるようにした方が良いと思いますね。

0
1
0

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
0
1