我正在尝试使用 sklearn.cluster.OPTICS 对已计算的相似度(距离)矩阵进行聚类,并填充归一化余弦距离(0.0到1.0)
但是但是,无论我给 max_eps 和 eps 做什么,我都不会出现任何集群。
稍后,我将需要在超过129'000 x 129'000项的相似性矩阵上运行OPTICS,希望依靠Dask来保持较低的内存占用。
我正在提取少量单词的快速文本向量(每个向量300个维),并使用dask距离从向量创建相似矩阵。
结果是一个矩阵,如下所示:
import { Component, ChangeDetectorRef } from '@angular/core';
constructor(.., private cdr: ChangeDetectorRef){}
this.myValueSubscription = this.myService.getValue().subscribe(value => {
this.myValue = value;
alert("myValue : " + this.myValue);
this.cdr.detectChanges(); // <= ADDED
})
例如,我可以使用0.8的阈值进行聚类
function transferArchive() {
//TAB 1
//Target Range - Tab 1, Range 1
var sss = SpreadsheetApp.getActiveSpreadsheet();
var ss = sss.getSheetByName('Front Sheet');
var range = ss.getRange('B4:E');
var data = range.getValues();
//Destination Range - Tab 1, Range 1
var tss = SpreadsheetApp.getActiveSpreadsheet();
var ts = tss.getSheetByName('Printed POs');
ts.getRange(lastRow(ts, 1), 2, data.length, data[0].length).setValues(data);
}
function lastRow(sheet, colNum) {
var v = sheet.getRange(1, colNum, sheet.getLastRow()).getValues(),
l = v.length,
r;
while (l > 0) {
if (v[l] && v[l][0].toString().length > 0) {
r = (l + 2);
break;
} else {
l--;
}
}
return r ? r : 1;
}
可打印
sim == [[0. 0.56742118 0.42776633 0.42344265 0.84878847 0.87984235
0.87468601 0.95224451 0.89341788 0.80922083]
[0.56742118 0. 0.59779273 0.62900345 0.83004028 0.87549904
0.887784 0.8591598 0.80752158 0.80960947]
[0.42776633 0.59779273 0. 0.45120935 0.79292425 0.78556189
0.82378645 0.93107747 0.83290157 0.85349163]
[0.42344265 0.62900345 0.45120935 0. 0.81379353 0.83985011
0.8441614 0.89824009 0.77074847 0.81297649]
[0.84878847 0.83004028 0.79292425 0.81379353 0. 0.15328565
0.36656755 0.79393195 0.76615941 0.83415538]
[0.87984235 0.87549904 0.78556189 0.83985011 0.15328565 0.
0.36000894 0.7792588 0.77379052 0.83737352]
[0.87468601 0.887784 0.82378645 0.8441614 0.36656755 0.36000894
0. 0.82404421 0.86144969 0.87628284]
[0.95224451 0.8591598 0.93107747 0.89824009 0.79393195 0.7792588
0.82404421 0. 0.521453 0.5784272 ]
[0.89341788 0.80752158 0.83290157 0.77074847 0.76615941 0.77379052
0.86144969 0.521453 0. 0.629014 ]
[0.80922083 0.80960947 0.85349163 0.81297649 0.83415538 0.83737352
0.87628284 0.5784272 0.629014 0. ]]
但是我期望会有几个集群。
我为OPTICS中所有受支持的参数尝试了许多不同的值,但没有能够产生任何可用的甚至比一个集群更多的集群。
我正在使用以下版本:
from dask import array as da
import dask_distance
import logging
import numpy as np
from sklearn.cluster import OPTICS
from collections import defaultdict
log = logging.warning
np.set_printoptions(suppress=True)
if __name__ == "__main__":
array = np.load("vectors.npy")
vectors = da.from_array(array)
sim = dask_distance.cosine(vectors, vectors)
sim = sim.clip(0.0, 1.0)
m = np.max(sim)
c = OPTICS(eps=-1, cluster_method="dbscan", metric="precomputed", algorithm="brute")
clusters = c.fit(sim)
words = [
"icecream",
"cake",
"cream",
"ice",
"dog",
"cat",
"animal",
"car",
"truck",
"bus",
]
cs = defaultdict(list)
for index, c in enumerate(clusters.labels_):
cs[c].append(words[index])
for v in cs.values():
log(v)
log(clusters.labels_)
这是使用sklearn DBSCAN的外观
['icecream', 'cake', 'cream', 'ice', 'dog', 'cat', 'animal', 'car', 'truck', 'bus']
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
收益
python -V
Python 3.7.3
sklearn.__version__
'0.21.3'
dask.__version__
'2.3.0'
numpy.__version__
'1.17.0'
这是非常正确的,但是具有更大的内存占用空间(OPTICS显然只需要计算矩阵的一半)
答案 0 :(得分:1)
您是否尝试估计129000x129000矩阵需要多少内存-计算和使用该内存需要多长时间?!?我强烈怀疑,在此方面,dask在此方面是否会有所帮助。首先,您需要使用某种索引方法来避免任何O(n²)成本。用k个节点将O(n²)切成k的倍数,只会使您无法扩展到足够的规模。
使用"precomputed"
时,您已经计算了完整距离矩阵。现在,无论是OPTICS还是DBSCAN都不会再次对其进行计算(也不是DBSCAN的下半部分),它们只会在这个巨大的巨大矩阵上进行迭代,因为它们无法对此做出任何假设:甚至不是对称的。
您为什么认为eps=-1
是正确的? min_samples
与OPTICS怎么样?如果您没有选择相同的参数,那么您当然不会获得类似的OPTICS和DBSCAN结果。
OPTICS使用您的参数找到的结果是正确的。在eps=-1
上,没有点是邻居,并且在min_samples=5
下没有簇,所有点都应标记为-1。