-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
396c4c7
commit 68ea50b
Showing
11 changed files
with
255 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
try: | ||
from typing import Literal | ||
except ImportError: | ||
from typing_extensions import Literal | ||
from pydantic import conint, Field, PyObject, PrivateAttr | ||
|
||
from semeio.workflows.misfit_preprocessor.hierarchical_config import ( | ||
AbstractClusteringConfig, | ||
) | ||
from semeio.workflows.spearman_correlation_job.cluster_analysis import ( | ||
kmeans_analysis, | ||
) | ||
|
||
|
||
class LimitedKmeansClustering(AbstractClusteringConfig): | ||
""" | ||
The kmeans implementation is backed by sklearn and for a | ||
more detailed description we refer the reader to the | ||
documentation of sklearn.cluster.KMeans | ||
(https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html). | ||
""" | ||
|
||
type: Literal["limited_kmeans"] = "limited_kmeans" | ||
init: Literal["k-means++", "random"] = Field( | ||
"k-means++", | ||
description=("The criterion to use in forming flat clusters. "), | ||
) | ||
n_init: conint(gt=0, strict=True) = Field( | ||
10, | ||
description=( | ||
"Number of time the k-means algorithm will be run with " | ||
"different centroid seeds. The final results will be the " | ||
"best output of n_init consecutive runs in terms of inertia." | ||
), | ||
) | ||
max_iter: conint(gt=0, strict=True) = Field( | ||
300, | ||
description=( | ||
"Maximum number of iterations of the k-means algorithm for a single run." | ||
), | ||
) | ||
random_state: conint(gt=0, strict=True) = Field( | ||
None, | ||
description=( | ||
"Determines random number generation for centroid initialization. " | ||
"Use an int to make the randomness deterministic" | ||
), | ||
) | ||
_cluster_function: PyObject = PrivateAttr(kmeans_analysis) | ||
|
||
|
||
class KmeansClustering(LimitedKmeansClustering): | ||
__doc__ = LimitedKmeansClustering.__doc__ | ||
type: Literal["kmeans"] = "kmeans" | ||
n_clusters: conint(gt=0, strict=True) = Field( | ||
8, | ||
description=( | ||
"The scalar gives the maximum number of clusters to be formed." | ||
"This has a defaulted value for auto_scale " | ||
"and is not configurable for this workflow. " | ||
), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
semeio/workflows/spearman_correlation_job/cluster_analysis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from scipy.cluster.hierarchy import fcluster, linkage | ||
from sklearn.cluster import KMeans | ||
|
||
|
||
def fcluster_analysis( | ||
correlation_matrix, | ||
threshold=1.0, | ||
criterion="inconsistent", | ||
depth=2, | ||
method="single", | ||
metric="euclidean", | ||
): | ||
a = linkage(correlation_matrix, method, metric) | ||
return fcluster(a, threshold, criterion=criterion, depth=depth) | ||
|
||
|
||
def kmeans_analysis( | ||
correlation_matrix, | ||
n_clusters=8, | ||
init="k-means++", | ||
n_init=10, | ||
max_iter=300, | ||
random_state=None, | ||
): | ||
kmeans = KMeans( | ||
init=init, | ||
n_clusters=n_clusters, | ||
n_init=n_init, | ||
max_iter=max_iter, | ||
random_state=random_state, | ||
).fit(correlation_matrix) | ||
return kmeans.labels_ + 1 # Scikit clusters are 0-indexed while scipy is 1-indexed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,6 +53,7 @@ | |
"numpy", | ||
"pandas>0.24", | ||
"pydantic", | ||
"sklearn", | ||
"scipy", | ||
"xlrd<2", | ||
"stea", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
tests/jobs/misfit_preprocessor/unit/test_cluster_functions.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# pylint: disable=unbalanced-tuple-unpacking | ||
from semeio.workflows.spearman_correlation_job.cluster_analysis import ( | ||
kmeans_analysis, | ||
fcluster_analysis, | ||
) | ||
from sklearn.datasets import make_blobs | ||
import pytest | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"func, kwargs", | ||
((fcluster_analysis, {"criterion": "maxclust"}), (kmeans_analysis, {})), | ||
) | ||
def test_same_format(func, kwargs): | ||
# The goal of this test is not to test the actual clustering functions, | ||
# but rather their format. Scipy clusters (labels) are 1-indexed while | ||
# sklearn are 0-indexed. We therefore set up a very simple dataset with | ||
# clearly defined clusters so the result will be the same for all functions. | ||
features, true_labels = make_blobs( | ||
n_samples=200, centers=3, cluster_std=0.1, random_state=42 | ||
) | ||
cluster_result = func(features, 3, **kwargs) | ||
# The clusters are typically the same, but the labels vary so we perform the | ||
# simplest test, just checking that the desired labels are present. | ||
assert set(cluster_result) == {1, 2, 3} |
Oops, something went wrong.