-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy path__init__.py
More file actions
203 lines (184 loc) · 11.7 KB
/
Copy path__init__.py
File metadata and controls
203 lines (184 loc) · 11.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import pyminicore
from pyminicore import *
from .util import constants
from .util.constants import CSR as csr_tuple, KMCRSV
if hasattr(pyminicore, "SparseMatrixWrapper"):
from pyminicore import SparseMatrixWrapper as smw
import numpy as np
from .util.compute_variance import variance
from .util import hvg
import scipy.sparse as sp
cluster_from_centers = pyminicore.hcluster
def ctrs2sp(centertups, nc):
return sp.vstack([sp.csr_matrix((x[0],[0] * len(x[0]), [0, len(x[0])]), shape=[1, nc]) for x in centertups])
geometric_median = pyminicore.geomed
def hcluster(matrix, centers, *, prior=0., msr=2, weights=None,
eps=1e-10, maxiter=1000, mbsize=-1, ncheckins=-1,
with_rep=False):
"""
def hcluster(matrix, centers, *, prior=0., msr=2, weights=None,
eps=1e-10, maxiter=1000, mbsize=-1, ncheckins=-1):
This is a wrapper function that automatically calls the correct pyminicore hcluster
It uses Expectation Maximization to minimize the cost of the dataset,
but it requires an initial set of centers for an experiment.
To get that initial set, look at kmeanspp for most uses, though you might want to try
greedy_select, which uses farthest-point sampling.
Inputs:
matrix:
This can be scipy.sparse.csr_matrix, minicore.CSparseMatrix,
or minicore.csr_tuple, or a 2-d numpy ndarray.
The dataset to be clustered.
centers:
This can be a dense 2-d numpy array or a list of integers or a numpy array
of an integral type indicating rows to use an initial centers for clustering.
Keyword Arguments:
prior:
Prior/Pseudocount adjustment.
Defaults to 0, although a small adjustment may be made for numerical stability.
Raising this number pushes points closer together for many distances.
msr:
Distance measure. Default is 2 (squared L2). For a full list, see the end of this doc-string.
You may be interested in the KL divergence (5/MKL), Jensen-Shannon Divergence (JSD), TVD, or Hellinger.
Some of these yield imaginary results with negative numbers; minicore expects nonnegative-valued observations.
weights:
None by default; Provide a numpy array of weights for each point to enable weighted clustering
eps:
Tolerance for the k-means convergence algorithm; only actively used for full k-means; (not mini-batch)
maxiter:
Default 1000, maximum number of outer loops to iterate
mbsize:
If this is not defaulted, then minibatch k-means clustering is performed
with the argument as minibatch size. A smaller number provides faster clustering
with lower quality solutions.
ncheckins:
Set ncheckins to determine how many inner loops are taken between outer loop steps in minibatch k-means.
Raising this number may increase or decrease speed.
Returns:
Dictionary with keys --
"asn" - np.array, uint32_t [num samples]
"costs" - np.array, float [num samples]
"initcost" - float, initial cost before clustering
"finalcost" - float, final cost after clustering
"numiter" - int, number of iterations clustering performed
"centers" - final centers:
If the input matrix is dense, this will be a 2-d ndarray of the centers
Otherwise, this will be a tuple for the CSR notation of the centers as ((data, indices, indptr), shape)
You might convert this to a SciPy CSR matrix by:
```
tup, shape = ret["centers"]
smat = scipy.sparse.csr_matrix(tup, shape=shape)
```
#Distance Table -- Numeric ID\tKey\tDescription
0 L1 L1 distance
1 L2 L2 distance
2 SQRL2 Squared L2 Norm
3 JSM Jensen-Shannon Metric, known as S2JSD and the Endres metric, for Poisson and Multinomial models, for which they are equivalent
4 JSD Jensen-Shannon Divergence for Poisson and Multinomial models, for which they are equivalent
5 MKL Multinomial KL divergence
6 HELLINGER Hellinger Distance: sqrt(sum((sqrt(x) - sqrt(y))^2))/2
7 BHATTACHARYYA_METRIC Bhattacharyya metric: sqrt(1 - BhattacharyyaSimilarity(x, y))
8 BHATTACHARYYA_DISTANCE Bhattacharyya distance: -log(dot(sqrt(x) * sqrt(y)))
9 TOTAL_VARIATION_DISTANCE Total Variation Distance: 1/2 sum_{i in D}(|x_i - y_i|)
10 LLR Log-likelihood Ratio under the multinomial model
11 REVERSE_MKL Reverse Multinomial KL divergence
12 UWLLR Unweighted Log-likelihood Ratio. This is effectively the Generalized Jensen-Shannon Divergence with lambda parameter corresponding to the fractional contribution of counts in the first observation. This is symmetric, unlike the G_JSD, because the parameter comes from the counts.
13 ITAKURA_SAITO Itakura-Saito divergence, a Bregman divergence [sum((a / b) - log(a / b) - 1 for a, b in zip(A, B))]
14 REVERSE_ITAKURA_SAITO Reversed Itakura-Saito divergence, a Bregman divergence
15 COSINE_DISTANCE Cosine distance: arccos(\frac{A \cdot B}{|A|_2 |B|_2}) / pi
17 COSINE_SIMILARITY Cosine similarity: \frac{A \cdot B}{|A|_2 |B|_2}
23 SYMMETRIC_ITAKURA_SAITO Symmetrized Itakura-Saito divergence. IS is a [sum((a / b) - log(a / b) - 1 for a, b in zip(A, B))], while SIS is .5 * (IS(a, (a + b) / 2) + IS(b, (a + b) / 2)), analogous to JSD
24 RSYMMETRIC_ITAKURA_SAITO Reversed symmetrized Itakura-Saito divergence. IS is a [sum((a / b) - log(a / b) - 1 for a, b in zip(A, B))], while SIS is .5 * (IS((a + b) / 2, a) + IS((a + b) / 2, b)), analogous to JSD
25 SRLRT Square root of LRT, the log likelihood ratio test; related to the JSM and Generalized JSD
26 SRULRT Square root of UWLLR, unweighted log likelihood ratio test; related to the JSM and Generalized JSD
"""
if isinstance(matrix, sp.csr_matrix) or isinstance(matrix, csr_tuple):
matrix = CSparseMatrix(matrix)
argmat = matrix
return pyminicore.hcluster(argmat, centers=centers, prior=prior, msr=msr, weights=weights, eps=eps,
maxiter=maxiter, mbsize=mbsize, ncheckins=ncheckins,
with_rep=with_rep)
def scluster(matrix, centers, *,
prior=0., msr=2, temp=1.,
maxiter=1000, savepref="", weights=None, mbsize=-1):
"""
This is a wrapper function that automatically calls the correct pyminicore scluster
It uses Expectation Maximization to minimize the cost of the dataset,
but it requires an initial set of centers for an experiment.
To get that initial set, look at kmeanspp for most uses, though you might want to try
greedy_select, which uses farthest-point sampling.
Inputs:
matrix:
This can be scipy.sparse.csr_matrix, minicore.CSparseMatrix,
or minicore.csr_tuple, or a 2-d numpy ndarray.
The dataset to be clustered.
centers:
This can be a dense 2-d numpy array or a list of integers or a numpy array
of an integral type indicating rows to use an initial centers for clustering.
Keyword Arguments:
prior:
Prior/Pseudocount adjustment.
Defaults to 0, although a small adjustment may be made for numerical stability.
Raising this number pushes points closer together for many distances.
msr:
Distance measure. Default is 2 (squared L2). For a full list, see the end of this doc-string.
You may be interested in the KL divergence (5/MKL), Jensen-Shannon Divergence (JSD), TVD, or Hellinger.
Some of these yield imaginary results with negative numbers; minicore expects nonnegative-valued observations.
weights:
None by default; Provide a numpy array of weights for each point to enable weighted clustering
maxiter:
Default 1000, maximum number of outer loops to iterate
savepref:
Default '\"\"'; If non-empty, then costs and assignments are mmap'd to disk
to both reduce memory usage and store final cost/assignments for other analysis.
#Distance Table -- Numeric ID\tKey\tDescription
0 L1 L1 distance
1 L2 L2 distance
2 SQRL2 Squared L2 Norm
3 JSM Jensen-Shannon Metric, known as S2JSD and the Endres metric, for Poisson and Multinomial models, for which they are equivalent
4 JSD Jensen-Shannon Divergence for Poisson and Multinomial models, for which they are equivalent
5 MKL Multinomial KL divergence
6 HELLINGER Hellinger Distance: sqrt(sum((sqrt(x) - sqrt(y))^2))/2
7 BHATTACHARYYA_METRIC Bhattacharyya metric: sqrt(1 - BhattacharyyaSimilarity(x, y))
8 BHATTACHARYYA_DISTANCE Bhattacharyya distance: -log(dot(sqrt(x) * sqrt(y)))
9 TOTAL_VARIATION_DISTANCE Total Variation Distance: 1/2 sum_{i in D}(|x_i - y_i|)
10 LLR Log-likelihood Ratio under the multinomial model
11 REVERSE_MKL Reverse Multinomial KL divergence
12 UWLLR Unweighted Log-likelihood Ratio. This is effectively the Generalized Jensen-Shannon Divergence with lambda parameter corresponding to the fractional contribution of counts in the first observation. This is symmetric, unlike the G_JSD, because the parameter comes from the counts.
13 ITAKURA_SAITO Itakura-Saito divergence, a Bregman divergence [sum((a / b) - log(a / b) - 1 for a, b in zip(A, B))]
14 REVERSE_ITAKURA_SAITO Reversed Itakura-Saito divergence, a Bregman divergence
15 COSINE_DISTANCE Cosine distance: arccos(\frac{A \cdot B}{|A|_2 |B|_2}) / pi
17 COSINE_SIMILARITY Cosine similarity: \frac{A \cdot B}{|A|_2 |B|_2}
23 SYMMETRIC_ITAKURA_SAITO Symmetrized Itakura-Saito divergence. IS is a [sum((a / b) - log(a / b) - 1 for a, b in zip(A, B))], while SIS is .5 * (IS(a, (a + b) / 2) + IS(b, (a + b) / 2)), analogous to JSD
24 RSYMMETRIC_ITAKURA_SAITO Reversed symmetrized Itakura-Saito divergence. IS is a [sum((a / b) - log(a / b) - 1 for a, b in zip(A, B))], while SIS is .5 * (IS((a + b) / 2, a) + IS((a + b) / 2, b)), analogous to JSD
25 SRLRT Square root of LRT, the log likelihood ratio test; related to the JSM and Generalized JSD
26 SRULRT Square root of UWLLR, unweighted log likelihood ratio test; related to the JSM and Generalized JSD
"""
if isinstance(matrix, sp.csr_matrix) or isinstance(matrix, csr_tuple):
matrix = CSparseMatrix(matrix)
return pyminicore.scluster(matrix, centers, msr=msr,
prior=prior, temp=temp, maxiter=maxiter,
savepref=savepref, weights=weights)
# This function provides a single starting point for clustering start-to-finish
def cluster(data, *, msr, k, prior=0., seed=0, nmkc=0,
ntimes=1, lspp=0, use_exponential_skips=False,
n_local_trials=1, weights=None, mbsize=-1, clustereps=1e-4,
temp=-1., cs=False, with_rep=True, outpref="mc.cluster.output",
maxiter=50):
soft = temp > 0. # Enable soft clustering by setting temperature
if isinstance(data, csr_tuple):
mcdata = CSparseMatrix(data)
else:
mcdata = data
ids, asn, costs = pyminicore.kmeanspp(data, msr=msr, k=k,
prior=prior, seed=seed,
ntimes=ntimes, lspp=lspp, expskips=use_exponential_skips,
n_local_trials=n_local_trials, weights=weights)
if soft:
try:
return scluster(mcdata, centers=ids, msr=msr, prior=prior, weights=weights, temp=temp, maxiter=maxiter,
mbn=mbn, savepref=outpref)
except:
raise NotImplementedError("Soft clustering not supported")
else:
return hcluster(data, centers=ids, prior=prior, msr=msr, weights=weights, eps=clustereps, maxiter=maxiter,
with_rep=with_rep, cs=cs)