web-dev-qa-db-ja.com

Pythonでk-Meansクラスタリングラベルを最高から最低に設定するにはどうすればよいですか?

私は38のアパートのデータセットと、朝、昼、夕方の電力消費量を持っています。 scikit-learnのk-Means実装を使用してこのデータセットをクラスター化しようとしていますが、興味深い結果が得られています。

最初のクラスタリングの結果: Img

これはすべて非常にうまくいき、4つのクラスターで明らかに各アパートメントに関連付けられた4つのラベル-0、1、2、3を取得します。KMeansメソッドのrandom_stateパラメーターを使用して、シードを修正できます重心はランダムに初期化されるため、一貫して同じアパートメントに起因する同じラベルが表示されます。

ただし、この特定のケースはエネルギー消費に関するものであるため、最高消費者と最低消費者の間の測定可能な分類を実行できます。したがって、ラベル0を最も消費レベルの低いアパートメントに割り当て、ラベル1をもう少し多く消費するアパートメントに割り当てたいと思います。

今のところ、私のラベルは[2 1 3 0]、または["black"、 "green"、 "blue"、 "red"]です。 [0 1 2 3]または["red"、 "green"、 "black"、 "blue"]にしたい。 (シードを固定して)セントロイドの初期化をランダムに保ちながら、どうすればよいですか?

助けてくれてありがとう!

10
Sergio

ルックアップテーブルを使用してラベルを変換することは、目的を達成する簡単な方法です。

まず、モックデータを生成します。

import numpy as np

np.random.seed(1000)

n = 38
X_morning = np.random.uniform(low=.02, high=.18, size=38)
X_afternoon = np.random.uniform(low=.05, high=.20, size=38)
X_night = np.random.uniform(low=.025, high=.175, size=38)
X = np.vstack([X_morning, X_afternoon, X_night]).T

次に、データに対してクラスタリングを実行します。

from sklearn.cluster import KMeans
k = 4
kmeans = KMeans(n_clusters=k, random_state=0).fit(X)

最後に、NumPyの argsort を使用して、次のようなルックアップテーブルを作成します。

idx = np.argsort(kmeans.cluster_centers_.sum(axis=1))
lut = np.zeros_like(idx)
lut[idx] = np.arange(k)

サンプルの実行:

In [70]: kmeans.cluster_centers_.sum(axis=1)
Out[70]: array([ 0.3214523 ,  0.40877735,  0.26911353,  0.25234873])

In [71]: idx
Out[71]: array([3, 2, 0, 1], dtype=int64)

In [72]: lut
Out[72]: array([2, 3, 1, 0], dtype=int64)

In [73]: kmeans.labels_
Out[73]: array([1, 3, 1, ..., 0, 1, 0])

In [74]: lut[kmeans.labels_]
Out[74]: array([3, 0, 3, ..., 2, 3, 2], dtype=int64)

idxは、消費レベルが低いものから高いものの順にクラスターセンターのラベルを示しています。 lut[kmeans.labels_]0/3は、消費レベルが最低/最高のクラスターに属しています。

13
Tonechas