11

私はかなり長い間 scipy の k-meansを使用してきましたが、使いやすさと効率の点で、その機能に満足しています。ただし、今はさまざまな k-means バリアントを調査したいと考えています。より具体的には、いくつかの問題に球状 k-meansを適用したいと考えています。

球形の k-means の優れた Python 実装 (つまり、scipy の k-means に似たもの) を知っていますか? そうでない場合、scipy のソース コードを変更して、k-means アルゴリズムを球形に適合させるのはどれほど難しいでしょうか?

ありがとうございました。

4

3 に答える 3

14

球面 k-means では、中心が球上にあることを保証することを目的としているため、コサイン距離を使用するようにアルゴリズムを調整し、さらに最終結果の重心を正規化する必要があります。

ユークリッド距離を使用する場合、私はアルゴリズムを、反復ごとにクラスターの中心を単位球に投影するものと考えるのを好みます。つまり、各最大化ステップの後に中心を正規化する必要があります。

実際、中心とデータ ポイントの両方が正規化されている場合、余弦距離とユークリッド距離の間には 1 対 1 の関係があります。

|a - b|_2 = 2 * (1 - cos(a,b))

パッケージjasonlaska/sphereclusterは、 scikit- learns を変更k-meansspherical k-means、別の球体クラスタリング アルゴリズムも提供します。

于 2016-08-11T15:47:28.137 に答える
1

( , ) ペアなどlatlon、3D 球体に極座標がある場合は、次のようにします

  1. 座標が ( lat, lon) 度で測定された座標である場合、次のように、これらの点をデカルト座標に変換する関数を作成できます。

    def cartesian_encoder(coord, r_E=6371):
        """Convert lat/lon to cartesian points on Earth's surface.
    
        Input
        -----
            coord : numpy 2darray (size=(N, 2))
            r_E : radius of Earth
    
        Output
        ------
            out : numpy 2darray (size=(N, 3))
        """
        def _to_rad(deg):
            return deg * np.pi / 180.
    
        theta = _to_rad(coord[:, 0])  # lat [radians]
        phi = _to_rad(coord[:, 1])    # lon [radians]
    
        x = r_E * np.cos(phi) * np.cos(theta)
        y = r_E * np.sin(phi) * np.cos(theta)
        z = r_E * np.sin(theta)
    
        return np.concatenate([x.reshape(-1, 1), y.reshape(-1, 1), z.reshape(-1, 1)], axis=1)
    

    座標が既にラジアンになっている場合は、その関数の最初の 5 行を削除するだけです。

  2. sphereclusterpip でパッケージをインストールします。lat( , lon) ペアの行として指定された極データが呼び出さXれ、その中に 10 個のクラスターを見つけたい場合、KMeans クラスタリングの最終的なコードは次のようになります。

    import numpy as np
    import spherecluster
    
    X_cart = cartesian_encoder(X)
    kmeans_labels = SphericalKMeans(10).fit_predict(X_cart)
    
于 2018-01-30T09:28:01.190 に答える