Stackoverflowに関するいくつかの質問でこの問題について言及していますが、具体的な解決策は見つかりませんでした。
コサインの類似性(0と1の間の値)で構成される正方行列があります。たとえば、次のようになります。
| A | B | C | D
A | 1.0 | 0.1 | 0.6 | 0.4
B | 0.1 | 1.0 | 0.1 | 0.2
C | 0.6 | 0.1 | 1.0 | 0.7
D | 0.4 | 0.2 | 0.7 | 1.0
正方行列は任意のサイズにすることができます。クラスター内の要素間の値を最大化するクラスター(数は不明)を取得したい。つまり上記の例では、2つのクラスターを取得する必要があります。
その理由は、CとDの値が最も高く、AとCの値も最も高いためです。
アイテムは1つのクラスターにのみ存在できます。
この問題ではリコールはそれほど重要ではありませんが、精度は非常に重要です。 1)B、2)A、3)C、Dの3つのクラスターを出力できます。ただし、Bが別の要素を持つクラスター内にある場合は、ソリューションを出力することはできません。
対角線(1.0)は私を混乱させると思います。私のデータには、2つ以上の要素のクラスターが少なくとも1つあることが保証されており、精度を犠牲にすることなく、できるだけ多くのクラスターを見つけたいと考えています。
これをPythonに実装する必要があります。
これは、スペクトルクラスタリングを使用して簡単に実行できます。 sklearnのような実装済みの実装を使用することも、自分で実装することもできます。かなり簡単なアルゴリズムです。
これは、python sklearnを使用して実行するコードの一部です。
import numpy as np
from sklearn.cluster import SpectralClustering
mat = np.matrix([[1.,.1,.6,.4],[.1,1.,.1,.2],[.6,.1,1.,.7],[.4,.2,.7,1.]])
SpectralClustering(2).fit_predict(mat)
>>> array([0, 1, 0, 0], dtype=int32)
ご覧のとおり、それはあなたが言及したクラスタリングを返します。
このアルゴリズムは、最大の固有値に対応する入力行列の上位k個の固有ベクトルを取得し、新しい行列でk平均アルゴリズムを実行します。これは、マトリックスに対してこれを行う単純なコードです。
from sklearn.cluster import KMeans
eigen_values, eigen_vectors = np.linalg.eigh(mat)
KMeans(n_clusters=2, init='k-means++').fit_predict(eigen_vectors[:, 2:4])
>>> array([0, 1, 0, 0], dtype=int32)
Sklearnライブラリのアルゴリズムの実装は、私のものとは異なる場合があることに注意してください。私が挙げた例は、最も簡単な方法です。スペクトルクラスタリングアルゴリズムについて詳しく説明しているオンラインの優れたチュートリアルがあります。
アルゴリズムだけでクラスターの数を計算する場合は、密度ベースのクラスター化アルゴリズム[〜#〜] dbscan [〜#〜]のように使用できます。 :
from sklearn.cluster import DBSCAN
DBSCAN(min_samples=1).fit_predict(mat)
array([0, 1, 2, 2])