私は線形代数のビットでそれを行う方法を考え出しました。
最初に、試行行列は、各数に対応する合計に分解されます(実装では不要ですが、数は数学的に式を定式化するためには1から始まる必要があります)。
ある:
trial 0 trial 1 trial 2 trial 3
index 0 0 1 0 0
index 1 0 1 1 0
index 2 2 0 2 0
index 3 1 2 2 1
は、以下のように分解される(インクリメント)
trial 0 trial 1 trial 2 trial 3
index 0 1 2 1 1
index 1 1 2 2 1
index 2 3 1 3 1
index 3 2 3 3 2
、次のようになる。
T = 1 0 1 1 + 2 * 0 1 0 0 + 3 * 0 0 0 0
1 0 0 1 0 1 1 0 0 0 0 0
0 1 0 1 0 0 0 0 1 0 1 0
0 0 0 0 1 0 0 1 0 1 1 0
そして各(正規化)成分行列が乗算されますその転置によって合計される:
C1*C1.T/1 + C2*C2.T/2 + C3*C3.T/3
ここで、Ci
は、クラスタ番号i
に対応するT
のマトリックス成分です。
この合計は、結果の共起行列です。以下は、上記の例の実装と結果である:
test = pd.DataFrame(np.array([[0, 1, 0, 0],
[0, 1, 1, 0],
[2, 0, 2, 0],
[1, 2, 2, 1]]),
columns = ['trial 1', 'trial 2', 'trial 3', 'trial 4'])
test_val = test.values
# Base matrix that will be added to.
curr_mat = np.zeros((test_val.shape[0], test_val.shape[0]))
# Max index of matrix components (i.e. max_val + 1 is number of clusters/matrix components)
max_val = np.max(test_val)
for n_clus in range(max_val + 1):
# Extract component matrix corresponding to current iteration.
clus_mem = (test_val == n_clus).astype(int)
curr_mat += np.dot(clus_mem, clus_mem.T)
res = pd.DataFrame(curr_mat, index=test.index, columns=test.index)
結果で:
index 0 index 1 index 2 index 3
index 0 4 3 1 0
index 1 3 4 1 0
index 2 1 1 4 1
index 3 0 0 1 4
は、残念ながら、私はfor
ループを使用する必要がありましたが、反復回数は現在のクラスタの数だけありますnumpyの効率的な配列操作を利用しています。
インデックス0とインデックス1はどのように3回共起するのですか? –
@coldspeedこれらは同じクラスタに3回割り当てられます(trial0のcluster0に割り当てられ、trial1のcluster1とtrial3のcluster0に割り当てられます) – duncster94