7 | """
8 |
9 | class ClusteringError(Exception):
10 | """
11 | Base Class for clustering errors.
12 | """
13 |
14 | class EmptyClusteringError(ClusteringError):
15 | """
16 | Raised when the clustering does not contain elements.
17 | """
18 | def __str__(self):
19 | return 'Clustering must have one or more elements in one or more clusters.'
20 |
21 |
22 | class InvalidElementError(ClusteringError):
23 | """
24 | Raised when an element is None or np.nan.
25 | """
26 | def __str__(self):
27 | return 'Elements cannot be None or NaN.'
28 |
29 | class InvalidClusterError(ClusteringError):
30 | """
31 | Raised when an element is None or np.nan.
32 | """
33 | def __str__(self):
34 | return 'Clusters cannot be None or NaN.'
35 |
36 | class EmptyClusterError(ClusteringError):
37 | """
38 | Raised when a clustering has empty clusters.
39 | """
40 |
41 | def __init__(self, n_emptys = None, empty_list = None):
42 | self.n_emptys = n_emptys
43 | self.empty_list = empty_list
44 |
45 | def __str__(self):
46 | if self.empty_list:
47 | return 'The following clusters contain 0 elements:\n{}'.format(self.empty_list)
48 | elif self.n_emptys:
49 | return 'There are {} clusters with 0 elements.'.format(self.n_emptys)
50 | else:
51 | return 'EmptyClusterError'
52 |
53 | class UnassignedElementError(ClusteringError):
54 | """
55 | Raised when elements are not assigned to clusters.
56 | """
57 |
58 | def __init__(self, n_unassigned = None, unassigned_list = None):
59 | self.n_unassigned = n_unassigned
60 | self.unassigned_list = unassigned_list
61 |
62 | def __str__(self):
63 | if self.unassigned_list:
64 | return 'The following elements were not assigned a cluster:\n{}'.format(self.unassigned_list)
65 | elif self.n_unassigned:
66 | return 'There are {} elements unassigned to a cluster.'.format(self.n_unassigned)
67 | else:
68 | return 'UnassignedElementError'
69 |
70 |
71 |
72 | class ClusteringSimilarityError(Exception):
73 | """
74 | Base Class for clustering similarity errors.
75 | """
76 | def __str__(self):
77 | return 'The element sets must be the same for both clusterings.'
78 |
79 |
80 |
--------------------------------------------------------------------------------
/docs/html/_static/fonts/source-serif-pro/source-serif-pro.css:
--------------------------------------------------------------------------------
1 | @font-face{
2 | font-family: 'Source Serif Pro';
3 | font-weight: 200;
4 | font-style: normal;
5 | font-stretch: normal;
6 | src: url('EOT/SourceSerifPro-ExtraLight.eot') format('embedded-opentype'),
7 | url('WOFF/OTF/SourceSerifPro-ExtraLight.otf.woff') format('woff'),
8 | url('OTF/SourceSerifPro-ExtraLight.otf') format('opentype'),
9 | url('TTF/SourceSerifPro-ExtraLight.ttf') format('truetype');
10 | }
11 |
12 | @font-face{
13 | font-family: 'Source Serif Pro';
14 | font-weight: 300;
15 | font-style: normal;
16 | font-stretch: normal;
17 | src: url('EOT/SourceSerifPro-Light.eot') format('embedded-opentype'),
18 | url('WOFF/OTF/SourceSerifPro-Light.otf.woff') format('woff'),
19 | url('OTF/SourceSerifPro-Light.otf') format('opentype'),
20 | url('TTF/SourceSerifPro-Light.ttf') format('truetype');
21 | }
22 |
23 | @font-face{
24 | font-family: 'Source Serif Pro';
25 | font-weight: 400;
26 | font-style: normal;
27 | font-stretch: normal;
28 | src: url('EOT/SourceSerifPro-Regular.eot') format('embedded-opentype'),
29 | url('WOFF/OTF/SourceSerifPro-Regular.otf.woff') format('woff'),
30 | url('OTF/SourceSerifPro-Regular.otf') format('opentype'),
31 | url('TTF/SourceSerifPro-Regular.ttf') format('truetype');
32 | }
33 |
34 | @font-face{
35 | font-family: 'Source Serif Pro';
36 | font-weight: 600;
37 | font-style: normal;
38 | font-stretch: normal;
39 | src: url('EOT/SourceSerifPro-Semibold.eot') format('embedded-opentype'),
40 | url('WOFF/OTF/SourceSerifPro-Semibold.otf.woff') format('woff'),
41 | url('OTF/SourceSerifPro-Semibold.otf') format('opentype'),
42 | url('TTF/SourceSerifPro-Semibold.ttf') format('truetype');
43 | }
44 |
45 | @font-face{
46 | font-family: 'Source Serif Pro';
47 | font-weight: 700;
48 | font-style: normal;
49 | font-stretch: normal;
50 | src: url('EOT/SourceSerifPro-Bold.eot') format('embedded-opentype'),
51 | url('WOFF/OTF/SourceSerifPro-Bold.otf.woff') format('woff'),
52 | url('OTF/SourceSerifPro-Bold.otf') format('opentype'),
53 | url('TTF/SourceSerifPro-Bold.ttf') format('truetype');
54 | }
55 |
56 | @font-face{
57 | font-family: 'Source Serif Pro';
58 | font-weight: 900;
59 | font-style: normal;
60 | font-stretch: normal;
61 | src: url('EOT/SourceSerifPro-Black.eot') format('embedded-opentype'),
62 | url('WOFF/OTF/SourceSerifPro-Black.otf.woff') format('woff'),
63 | url('OTF/SourceSerifPro-Black.otf') format('opentype'),
64 | url('TTF/SourceSerifPro-Black.ttf') format('truetype');
65 | }
66 |
--------------------------------------------------------------------------------
/tests/test_ppr_implemenation.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # These tests were designed by Jisung Yoon - jisung.yoon@postech.ac.kr
4 | # Note that the implementation code use threshold as 0.0001, so we use a significant level as 3.
5 | # If reduce the threshold, then results will be more precise, but takes some time.
6 | # Also, prpack is kind of approximated method.
7 |
8 | import json
9 | import time
10 |
11 | from numpy.testing import assert_approx_equal
12 |
13 | import clusim.sim as sim
14 | from clusim.clustering import Clustering
15 |
16 | def test_simple_example():
17 | c1_elm2clu_dict = {0: [0, 1], 1: [1, 2], 2: [1, 3], 3: [0], 4: [2], 5: [1]}
18 | c2_elm2clu_dict = {0: [0], 1: [1], 2: [1], 3: [0, 3], 4: [2, 4], 5: [2]}
19 |
20 | c1 = Clustering(elm2clu_dict=c1_elm2clu_dict)
21 | c2 = Clustering(elm2clu_dict=c2_elm2clu_dict)
22 |
23 | sim_ppr_pack = sim.element_sim(
24 | c1,
25 | c2,
26 | alpha=0.9,
27 | r=1.0,
28 | r2=None,
29 | rescale_path_type="max",
30 | ppr_implementation="prpack",
31 | )
32 | sim_ppr_power_iteration = sim.element_sim(
33 | c1,
34 | c2,
35 | alpha=0.9,
36 | r=1.0,
37 | r2=None,
38 | rescale_path_type="max",
39 | ppr_implementation="power_iteration",
40 | )
41 |
42 | assert_approx_equal(sim_ppr_pack, sim_ppr_power_iteration, significant=3)
43 |
44 |
45 | def test_real_example_on_overlapping_community():
46 | ground_truth_community = json.load(
47 | open("ground_truth_community_Philosophy.json", "r")
48 | )
49 | detected_community = json.load(open("detected_community_Philosophy.json", "r"))
50 |
51 | c1 = Clustering(elm2clu_dict=ground_truth_community)
52 | c2 = Clustering(elm2clu_dict=detected_community)
53 |
54 | start = time.time()
55 | sim_ppr_pack = sim.element_sim(
56 | c1,
57 | c2,
58 | alpha=0.9,
59 | r=1.0,
60 | r2=None,
61 | rescale_path_type="max",
62 | ppr_implementation="prpack",
63 | )
64 | end = time.time()
65 | print("prpack elapsed time: {}s".format(end - start))
66 | start = time.time()
67 | sim_ppr_power_iteration = sim.element_sim(
68 | c1,
69 | c2,
70 | alpha=0.9,
71 | r=1.0,
72 | r2=None,
73 | rescale_path_type="max",
74 | ppr_implementation="power_iteration",
75 | )
76 | end = time.time()
77 | print("power iteration elapsed time: {}s".format(end - start))
78 |
79 | assert_approx_equal(sim_ppr_pack, sim_ppr_power_iteration, significant=3)
80 |
81 |
82 | if __name__ == "__main__":
83 |
84 | test_simple_example()
85 | test_real_example_on_overlapping_community()
86 |
--------------------------------------------------------------------------------
/paper.bib:
--------------------------------------------------------------------------------
1 |
2 | @article{Hubert1985adjrand,
3 | author = {Hubert, Lawrence and Arabie, Phipps},
4 | title = {{Comparing partitions}},
5 | journal = {Journal of Classification},
6 | year = {1985},
7 | volume = {2},
8 | number = {1},
9 | pages = {193--218},
10 | month = {dec},
11 | doi = {10.1007/BF01908075}
12 | }
13 |
14 | @article{Jain1999clustering,
15 | author = {Jain, Anil K. and Murty, M. Narasimha and Flynn, Patrick J.},
16 | title = {Data clustering: a review},
17 | journal = {ACM Computing Surveys (CSUR)},
18 | uuid = {D16B9D09-A1A3-4009-AF70-7E05674A9DEF},
19 | volume = {31},
20 | number = {3},
21 | pages = {264-323},
22 | publisher = {Acm},
23 | year = {1999},
24 | doi = {10.1145/331499.331504}
25 | }
26 |
27 | @article{deSouto2008geneclustering,
28 | author = {de Souto, Marcilio CP and Costa, Ivan G. and de Araujo, Daniel SA and Ludermir, Teresa B. and Schliep, Alexander},
29 | title = {Clustering cancer gene expression data: a comparative study},
30 | journal = {BMC Bioinformatics},
31 | uuid = {392D1EB3-675F-4D8B-869A-38F4820DB9A3},
32 | volume = {9},
33 | number = {1},
34 | pages = {1},
35 | year = {2008},
36 | doi = {10.1186/1471-2105-9-497}
37 | }
38 |
39 | @inproceedings{Vinh2009nmicorrection,
40 | author = {Vinh, Nguyen Xuan and Epps, Julien and Bailey, James},
41 | booktitle = {Proceedings of the 26th Annual International Conference on Machine Learning},
42 | title = {Information theoretic measures for clusterings comparison: is a correction for chance necessary?},
43 | uuid = {B53F7F88-E5B1-474F-80D7-6D9EF6C28A0E},
44 | pages = {1073-1080},
45 | organization = {ACM},
46 | year = {2009},
47 | doi = {10.1145/1553374.1553511}
48 | }
49 |
50 | @article{Gates2017impact,
51 | title={The Impact of Random Models on Clustering Similarity},
52 | volume={18},
53 | number={87},
54 | journal={Journal of Machine Learning Research},
55 | author={Gates, Alexander J. and Ahn, Yong-Yeol},
56 | year={2017},
57 | pages={1-28},
58 | doi = {10.1101/196840}
59 | }
60 |
61 | @misc{Gates2018element,
62 | title={On comparing clusterings: an element-centric framework unifies overlaps and hierarchy},
63 | author={Gates, Alexander J. and Wood, Ian B. and Hetrick, William P. and Ahn, Yong-Yeol},
64 | year={2018},
65 | archivePrefix = "arXiv",
66 | note = {arXiv:1706.06136}
67 | }
68 |
69 | @article{scikitlearn,
70 | title={Scikit-learn: Machine Learning in {P}ython},
71 | author={Pedregosa, F. and Varoquaux, G. and Gramfort, A. and Michel, V.
72 | and Thirion, B. and Grisel, O. and Blondel, M. and Prettenhofer, P.
73 | and Weiss, R. and Dubourg, V. and Vanderplas, J. and Passos, A. and
74 | Cournapeau, D. and Brucher, M. and Perrot, M. and Duchesnay, E.},
75 | journal={Journal of Machine Learning Research},
76 | volume={12},
77 | pages={2825--2830},
78 | year={2011}
79 | }
80 |
81 | @article{Sukumaran2010dendropy,
82 | author = {Sukumaran, J. and Holder, Mark T.},
83 | title = {DendroPy: A Python library for phylogenetic computing},
84 | journal = {Bioinformatics},
85 | year = {2010},
86 | volume = {26},
87 | pages = {1569-1571},
88 | doi = {10.1093/bioinformatics/btq228}
89 | }
90 |
--------------------------------------------------------------------------------
/examples/CluSim Examples - basic element-centric similarity.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from clusim.clustering import Clustering, print_clustering\n",
10 | "import clusim.sim as sim"
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 6,
16 | "metadata": {},
17 | "outputs": [
18 | {
19 | "name": "stdout",
20 | "output_type": "stream",
21 | "text": [
22 | "01|23|45\n",
23 | "0|123|45\n",
24 | "Element-centric Similarity: 0.6944444444444443\n",
25 | "Element-centric Similarity for each element:\n",
26 | "[0.5 0.33333333 0.66666667 0.66666667 1. 1. ]\n",
27 | "[0.5 0.33333333 0.66666667 0.66666667 1. 1. ] {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5}\n",
28 | "\n",
29 | "012|23|45\n",
30 | "Element-centric Similarity: 0.7017543859649121\n",
31 | "Element-centric Similarity for each element:\n",
32 | "[0.45614035 0.45614035 0.61403509 0.68421053 1. 1. ]\n"
33 | ]
34 | }
35 | ],
36 | "source": [
37 | "# Element-centeric Clustering Similarity\n",
38 | "\n",
39 | "# first consider the case of two partitions (no overlap or hierarchy)\n",
40 | "clustering1 = Clustering(elm2clu_dict = {0:[0], 1:[0], 2:[1], 3:[1], 4:[2], 5:[2]})\n",
41 | "clustering2 = Clustering(elm2clu_dict = {0:[0], 1:[1], 2:[1], 3:[1], 4:[2], 5:[2]})\n",
42 | "\n",
43 | "print_clustering(clustering1)\n",
44 | "print_clustering(clustering2)\n",
45 | "print(\"Element-centric Similarity:\", sim.element_sim(clustering1, clustering2, alpha = 0.9) )\n",
46 | "print(\"Element-centric Similarity for each element:\")\n",
47 | "elementScores, relabeled_elements = sim.element_sim_elscore(clustering1, clustering2, alpha = 0.9) \n",
48 | "print(elementScores)\n",
49 | "print(elementScores, relabeled_elements)\n",
50 | "print()\n",
51 | "# now lets conisder an example with overlap\n",
52 | "clustering3 = Clustering(elm2clu_dict = {0:[0], 1:[0], 2:[0,1], 3:[1], 4:[2], 5:[2]})\n",
53 | "print_clustering(clustering3)\n",
54 | "print(\"Element-centric Similarity:\", sim.element_sim(clustering1, clustering3, alpha = 0.9))\n",
55 | "print(\"Element-centric Similarity for each element:\")\n",
56 | "elementScores, relabeled_elements = sim.element_sim_elscore(clustering1, clustering3, alpha = 0.9)\n",
57 | "print(elementScores)"
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {},
64 | "outputs": [],
65 | "source": []
66 | }
67 | ],
68 | "metadata": {
69 | "kernelspec": {
70 | "display_name": "Python 3 (ipykernel)",
71 | "language": "python",
72 | "name": "python3"
73 | },
74 | "language_info": {
75 | "codemirror_mode": {
76 | "name": "ipython",
77 | "version": 3
78 | },
79 | "file_extension": ".py",
80 | "mimetype": "text/x-python",
81 | "name": "python",
82 | "nbconvert_exporter": "python",
83 | "pygments_lexer": "ipython3",
84 | "version": "3.10.12"
85 | }
86 | },
87 | "nbformat": 4,
88 | "nbformat_minor": 2
89 | }
90 |
--------------------------------------------------------------------------------
/docs/html/_modules/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Overview: module code — clusim 0.4 documentation
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
All modules for which code is available
37 |
42 |
43 |
44 |
45 |
46 |
60 |
61 |
62 |
74 |
78 |
79 |
--------------------------------------------------------------------------------
/docs/html/search.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Search — clusim 0.4 documentation
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
Search
42 |
43 |
44 |
45 | Please activate JavaScript to enable the search
46 | functionality.
47 |
48 |
49 |
50 | Searching for multiple words only shows matches that contain
51 | all words.
52 |
53 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
70 |
71 |
72 |
84 |
88 |
89 |
--------------------------------------------------------------------------------
/examples/CluSim Examples - apply all similarity measures.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "import clusim.clugen as clugen\n",
10 | "import clusim.sim as sim\n",
11 | "from clusim.clustering import print_clustering"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 2,
17 | "metadata": {},
18 | "outputs": [
19 | {
20 | "name": "stdout",
21 | "output_type": "stream",
22 | "text": [
23 | "08|17|92|3|456\n",
24 | "0|1|8245|936|7\n",
25 | " jaccard_index 0.07142857142857142\n",
26 | " rand_index 0.7111111111111111\n",
27 | " adjrand_index -0.03174603174603155\n",
28 | " fowlkes_mallows_index 0.13608276348795434\n",
29 | " fmeasure 0.13333333333333333\n",
30 | " purity_index 0.6000000000000001\n",
31 | " classification_error 0.3999999999999999\n",
32 | " czekanowski_index 0.13333333333333333\n",
33 | " dice_index 0.13333333333333333\n",
34 | " sorensen_index 0.13333333333333333\n",
35 | " rogers_tanimoto_index 0.5517241379310345\n",
36 | " southwood_index 0.07692307692307693\n",
37 | " pearson_correlation -0.00011870845204178538\n",
38 | " corrected_chance -0.022401678740658508\n",
39 | " sample_expected_sim 0.07142857142857142\n",
40 | " nmi 0.5455316486635409\n",
41 | " mi 1.1709505944546694\n",
42 | " adj_mi -0.03700743364585456\n",
43 | " rmi -0.09728645468898911\n",
44 | " vi 1.9509775004326926\n",
45 | " geometric_accuracy 0.6\n",
46 | " overlap_quality -0.0\n",
47 | " onmi 0.4934700561224017\n",
48 | " omega_index -0.03174603174603155\n"
49 | ]
50 | }
51 | ],
52 | "source": [
53 | "c1 = clugen.make_random_clustering(n_elements = 10, n_clusters = 2)\n",
54 | "c2 = clugen.make_random_clustering(n_elements = 10, n_clusters = 5)\n",
55 | "\n",
56 | "print_clustering(c1)\n",
57 | "print_clustering(c2)\n",
58 | "\n",
59 | "row_format2 =\"{:>25}\" * (2)\n",
60 | "for simfunc in sim.available_similarity_measures:\n",
61 | " print(row_format2.format(simfunc, eval('sim.' + simfunc+'(c1, c2)')))"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": null,
67 | "metadata": {},
68 | "outputs": [],
69 | "source": []
70 | }
71 | ],
72 | "metadata": {
73 | "kernelspec": {
74 | "display_name": "Python 3 (ipykernel)",
75 | "language": "python",
76 | "name": "python3"
77 | },
78 | "language_info": {
79 | "codemirror_mode": {
80 | "name": "ipython",
81 | "version": 3
82 | },
83 | "file_extension": ".py",
84 | "mimetype": "text/x-python",
85 | "name": "python",
86 | "nbconvert_exporter": "python",
87 | "pygments_lexer": "ipython3",
88 | "version": "3.10.12"
89 | }
90 | },
91 | "nbformat": 4,
92 | "nbformat_minor": 2
93 | }
94 |
--------------------------------------------------------------------------------
/examples/CluSim Examples - NMI adjustment and normalization.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "import clusim.sim as sim\n",
10 | "import clusim.clugen as clugen\n",
11 | "from clusim.clustering import print_clustering"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 2,
17 | "metadata": {},
18 | "outputs": [
19 | {
20 | "name": "stdout",
21 | "output_type": "stream",
22 | "text": [
23 | "0125|37|84|96\n",
24 | "012|9357|84|6\n",
25 | " sum 0.7015919313018382\n",
26 | " max 0.6878135027027825\n",
27 | " min 0.715933669146816\n",
28 | " sqrt 0.7017327444823468\n"
29 | ]
30 | }
31 | ],
32 | "source": [
33 | "# Adjusted Mutual Information for different random models\\n\",\n",
34 | "c1 = clugen.make_random_clustering(n_elements = 10, n_clusters = 2)\n",
35 | "c2 = clugen.make_random_clustering(n_elements = 10, n_clusters = 5)\n",
36 | "\n",
37 | "print_clustering(c1)\n",
38 | "print_clustering(c2)\n",
39 | "\n",
40 | "row_format2 = \"{:>25}\"*2\n",
41 | "for ntype in ['sum', 'max', 'min', 'sqrt']:\n",
42 | " print(row_format2.format(ntype, str(sim.nmi(c1, c2, norm_type = ntype))))"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 3,
48 | "metadata": {},
49 | "outputs": [
50 | {
51 | "name": "stdout",
52 | "output_type": "stream",
53 | "text": [
54 | "02378|156|94\n",
55 | "026|19|34|57|8\n",
56 | " perm -0.148000236069058\n",
57 | " perm1 -0.148000236069058\n",
58 | " num -0.0997416150535352\n",
59 | " num1 -0.120532494782882\n",
60 | " all -0.241995583076721\n",
61 | " all1 -0.295381261557531\n"
62 | ]
63 | }
64 | ],
65 | "source": [
66 | "# Adjusted Mutual Information for different random models\\n\",\n",
67 | "c1 = clugen.make_random_clustering(n_elements = 10, n_clusters = 2)\n",
68 | "c2 = clugen.make_random_clustering(n_elements = 10, n_clusters = 5)\n",
69 | "\n",
70 | "print_clustering(c1)\n",
71 | "print_clustering(c2)\n",
72 | "\n",
73 | "row_format2 = \"{:>25}\"*2\n",
74 | "for rdm in sim.available_random_models:\n",
75 | " print(row_format2.format(rdm, str(sim.adj_mi(c1, c2, random_model = rdm))))"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {},
82 | "outputs": [],
83 | "source": []
84 | }
85 | ],
86 | "metadata": {
87 | "kernelspec": {
88 | "display_name": "Python 3 (ipykernel)",
89 | "language": "python",
90 | "name": "python3"
91 | },
92 | "language_info": {
93 | "codemirror_mode": {
94 | "name": "ipython",
95 | "version": 3
96 | },
97 | "file_extension": ".py",
98 | "mimetype": "text/x-python",
99 | "name": "python",
100 | "nbconvert_exporter": "python",
101 | "pygments_lexer": "ipython3",
102 | "version": "3.10.12"
103 | }
104 | },
105 | "nbformat": 4,
106 | "nbformat_minor": 2
107 | }
108 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue,
4 | email, or any other method with the owners of this repository before making a change.
5 |
6 | Please note we have a code of conduct, please follow it in all your interactions with the project.
7 |
8 | ## Pull Request Process
9 |
10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a
11 | build.
12 | 2. Update the README.md with details of changes to the interface, this includes new environment
13 | variables, exposed ports, useful file locations and container parameters.
14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this
15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
17 | do not have permission to do that, you may request the second reviewer to merge it for you.
18 |
19 | ## Code of Conduct
20 |
21 | ### Our Pledge
22 |
23 | In the interest of fostering an open and welcoming environment, we as
24 | contributors and maintainers pledge to making participation in our project and
25 | our community a harassment-free experience for everyone, regardless of age, body
26 | size, disability, ethnicity, gender identity and expression, level of experience,
27 | nationality, personal appearance, race, religion, or sexual identity and
28 | orientation.
29 |
30 | ### Our Standards
31 |
32 | Examples of behavior that contributes to creating a positive environment
33 | include:
34 |
35 | * Using welcoming and inclusive language
36 | * Being respectful of differing viewpoints and experiences
37 | * Gracefully accepting constructive criticism
38 | * Focusing on what is best for the community
39 | * Showing empathy towards other community members
40 |
41 | Examples of unacceptable behavior by participants include:
42 |
43 | * The use of sexualized language or imagery and unwelcome sexual attention or
44 | advances
45 | * Trolling, insulting/derogatory comments, and personal or political attacks
46 | * Public or private harassment
47 | * Publishing others' private information, such as a physical or electronic
48 | address, without explicit permission
49 | * Other conduct which could reasonably be considered inappropriate in a
50 | professional setting
51 |
52 | ### Our Responsibilities
53 |
54 | Project maintainers are responsible for clarifying the standards of acceptable
55 | behavior and are expected to take appropriate and fair corrective action in
56 | response to any instances of unacceptable behavior.
57 |
58 | Project maintainers have the right and responsibility to remove, edit, or
59 | reject comments, commits, code, wiki edits, issues, and other contributions
60 | that are not aligned to this Code of Conduct, or to ban temporarily or
61 | permanently any contributor for other behaviors that they deem inappropriate,
62 | threatening, offensive, or harmful.
63 |
64 | ### Scope
65 |
66 | This Code of Conduct applies both within project spaces and in public spaces
67 | when an individual is representing the project or its community. Examples of
68 | representing a project or community include using an official project e-mail
69 | address, posting via an official social media account, or acting as an appointed
70 | representative at an online or offline event. Representation of a project may be
71 | further defined and clarified by project maintainers.
72 |
73 | ### Enforcement
74 |
75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
76 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
77 | complaints will be reviewed and investigated and will result in a response that
78 | is deemed necessary and appropriate to the circumstances. The project team is
79 | obligated to maintain confidentiality with regard to the reporter of an incident.
80 | Further details of specific enforcement policies may be posted separately.
81 |
82 | Project maintainers who do not follow or enforce the Code of Conduct in good
83 | faith may face temporary or permanent repercussions as determined by other
84 | members of the project's leadership.
85 |
86 | ### Attribution
87 |
88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
89 | available at [http://contributor-covenant.org/version/1/4][version]
90 |
91 | [homepage]: http://contributor-covenant.org
92 | [version]: http://contributor-covenant.org/version/1/4/
--------------------------------------------------------------------------------
/docs/html/y.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | <no title> — clusim 0.4 documentation
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
42 |
43 |
44 |
47 |
48 |
71 |
72 |
73 |
74 |
75 |
76 | Docs
77 |
78 | <no title>
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
103 |
108 |
109 |
112 |
113 |
--------------------------------------------------------------------------------
/docs/html/_static/fonts/source-serif-pro/ReadMe.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Read Me File for Adobe® OpenType® Fonts
5 |
6 |
7 |
8 | Adobe® OpenType® Fonts
10 | Thank
11 | you for licensing Adobe OpenType fonts. In order to ensure that you
12 | have the most up-to-date product information, Adobe has posted an OpenType
14 | Read Me file on the Adobe web site that contains information such
15 | as minimum system requirements, technical support contact information
16 | and software installation notes. We have also posted an OpenType
18 | User's Guide in PDF format on the Adobe web site that can be
19 | viewed online and downloaded to your computer. If you have
20 | licensed an Adobe OpenType Pro font, there may be additional PDF
21 | documents, such as a specimen book, a glyph complement showing, and a
22 | typeface-specific Read Me file, available on the typefaces
23 | product pages on the Adobe web site. These additional files may be
24 | viewed online or downloaded to your computer.
To get you started
25 | quickly, below are links to localized installation instructions for
26 | your fonts.
27 |
28 |
Installation Instructions
29 | English
30 | Instructions for installing this font can be found online at http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
32 | French / Français
33 | Le mode d'installation de cette police de caractère se trouve en
34 | ligne à http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
36 | German / Deutsch
37 | Die Anweisungen zur Installation dieser Schriftart finden Sie online
38 | unter http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
40 | Italian / Italiano
41 | Le istruzioni per l'installazione di questo font sono disponibili
42 | online all'indirizzo http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
44 | Spanish / Español
45 | Las instrucciones para instalar esta fuente se pueden encontrar
46 | online en http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
48 | Dutch / Hollands
49 | De instructies voor de installatie van dit lettertype vindt u op http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
51 | Swedish / Svenska
52 | Anvisningar för hur det här teckensnittet installeras finns
53 | online på http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
55 | Norwegian / Norsk
56 | Instruksjoner for installering av skrifttypen finnes online på
57 | http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
59 | Finnish / Suomi
60 | Ohjeet tämän fontin asentamiseen löytyvät
61 | osoitteesta http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
63 | Danish / Dansk
64 | Du finder en vejledning i installation af denne skrifttype online
65 | på adressen http://www.adobe.com/type/browser/fontinstall/instructions_main.html .
67 | Japanese / 日本語
68 | このフォントをインストールする手順は、オンラインで http://www.adobe.com/type/browser/fontinstall/instructions_main.html
70 | を参照してください。
71 |
72 |
73 |
--------------------------------------------------------------------------------
/docs/html/_static/pygments.css:
--------------------------------------------------------------------------------
1 | .highlight .hll { background-color: #ffffcc }
2 | .highlight { background: #eeffcc; }
3 | .highlight .c { color: #408090; font-style: italic } /* Comment */
4 | .highlight .err { border: 1px solid #FF0000 } /* Error */
5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */
6 | .highlight .o { color: #666666 } /* Operator */
7 | .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
8 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
9 | .highlight .cp { color: #007020 } /* Comment.Preproc */
10 | .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
11 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
12 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */
14 | .highlight .ge { font-style: italic } /* Generic.Emph */
15 | .highlight .gr { color: #FF0000 } /* Generic.Error */
16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */
18 | .highlight .go { color: #333333 } /* Generic.Output */
19 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
20 | .highlight .gs { font-weight: bold } /* Generic.Strong */
21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */
23 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
24 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
25 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
26 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */
27 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
28 | .highlight .kt { color: #902000 } /* Keyword.Type */
29 | .highlight .m { color: #208050 } /* Literal.Number */
30 | .highlight .s { color: #4070a0 } /* Literal.String */
31 | .highlight .na { color: #4070a0 } /* Name.Attribute */
32 | .highlight .nb { color: #007020 } /* Name.Builtin */
33 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
34 | .highlight .no { color: #60add5 } /* Name.Constant */
35 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
36 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
37 | .highlight .ne { color: #007020 } /* Name.Exception */
38 | .highlight .nf { color: #06287e } /* Name.Function */
39 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
40 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
41 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
42 | .highlight .nv { color: #bb60d5 } /* Name.Variable */
43 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
45 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */
46 | .highlight .mf { color: #208050 } /* Literal.Number.Float */
47 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */
48 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */
49 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */
50 | .highlight .sa { color: #4070a0 } /* Literal.String.Affix */
51 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
52 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */
53 | .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
54 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
55 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */
56 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
57 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
58 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
59 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */
60 | .highlight .sr { color: #235388 } /* Literal.String.Regex */
61 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */
62 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */
63 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
64 | .highlight .fm { color: #06287e } /* Name.Function.Magic */
65 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
66 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
67 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
68 | .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
69 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/docs/html/_static/fonts/source-serif-pro/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 |
5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6 |
7 |
8 | -----------------------------------------------------------
9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 |
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 |
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded,
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 |
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 |
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 |
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 |
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 |
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 |
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 |
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 |
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 |
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 |
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 |
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 |
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 |
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 |
--------------------------------------------------------------------------------
/docs/html/py-modindex.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Python Module Index — clusim 0.4 documentation
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
Python Module Index
41 |
42 |
45 |
46 |
47 |
48 |
49 | c
50 |
51 |
52 |
53 | clugen
54 | A set of functions to generate Clusterings and random Clusterings
55 |
56 |
58 |
59 | clusim
60 |
61 |
62 |
63 |
64 | clusim.clugen
65 |
66 |
67 |
68 |
69 | clusim.clusimelement
70 |
71 |
72 |
73 |
74 | clusim.clustering
75 |
76 |
77 |
78 |
79 | clusimelement
80 | Element-centric Clustering Similarity
81 |
82 |
83 |
84 | clustering
85 | The main Clustering class
86 |
87 |
88 |
89 |
90 |
91 |
92 |
106 |
107 |
108 |
120 |
124 |
125 |
--------------------------------------------------------------------------------
/tests/test_sim.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Tests for ``sim.py``
4 | # These tests were hand calculated by Alexander J. Gates: ajgates42@gmail.com
5 | #
6 |
7 | from clusim.clustering import Clustering
8 | import clusim.sim as sim
9 | from clusim.dag import DAG
10 | from numpy.testing import assert_approx_equal
11 |
12 |
13 | def test_comparison_example():
14 | c1_elm2clu_dict = {0: [0], 1: [1], 2: [1], 3: [0], 4: [2], 5: [1]}
15 | c2_elm2clu_dict = {0: [0], 1: [1], 2: [1], 3: [0], 4: [2], 5: [2]}
16 |
17 | c1 = Clustering(elm2clu_dict=c1_elm2clu_dict)
18 | c2 = Clustering(elm2clu_dict=c2_elm2clu_dict)
19 |
20 | N11, N10, N01, N00 = sim.count_pairwise_cooccurence(c1, c2)
21 |
22 | assert N11 == 2
23 | assert N10 == 2
24 | assert N01 == 1
25 | assert N00 == 10
26 |
27 | known_sim_values = {
28 | 'jaccard_index': 0.4,
29 | 'rand_index': 0.8,
30 | 'fowlkes_mallows_index': 0.5773502691896258,
31 | 'rogers_tanimoto_index': 2./3.,
32 | 'southwood_index': 2./3.,
33 | 'czekanowski_index': 0.5714285714285714,
34 | 'dice_index': 0.5714285714285714,
35 | 'sorensen_index': 0.5714285714285714,
36 | 'pearson_correlation': 0.011363636363636364,
37 | 'classification_error': 0.16666666666666674,
38 | 'purity_index': 0.8333333333333333,
39 | 'fmeasure': 0.5714285714285714,
40 | 'nmi': 0.7396673768007593,
41 | 'vi': 0.792481250360578,
42 | 'geometric_accuracy': 0.8333333333333334,
43 | 'overlap_quality': -0.0,
44 | 'onmi': 0.7449589906475155,
45 | 'omega_index': 0.44444444444444453}
46 |
47 | for simfunc in sim.available_similarity_measures:
48 | simvalue = eval('sim.' + simfunc+'(c1, c2)')
49 | assert simvalue == known_sim_values[simfunc],\
50 | "Similarity Measure {} does not match. {} != {}".format(
51 | simfunc, simvalue, known_sim_values[simfunc])
52 |
53 |
54 | def test_model_example():
55 | c1_elm2clu_dict = {0: [0], 1: [1], 2: [1], 3: [0]}
56 | c2_elm2clu_dict = {0: [0], 1: [1], 2: [1], 3: [1]}
57 |
58 | c1 = Clustering(elm2clu_dict=c1_elm2clu_dict)
59 | c2 = Clustering(elm2clu_dict=c2_elm2clu_dict)
60 |
61 | known_rand_values = {'perm': 0.5, 'perm1': 0.5, 'num': 0.510204081632653,
62 | 'num1': 0.5, 'all': 0.555555555555556, 'all1': 0.5}
63 |
64 | known_mi_values = {'perm': 0.311278124459133, 'perm1': 0.311278124459133,
65 | 'num': 0.309927805548467, 'num1': 0.301825892084476,
66 | 'all': 0.611635721962606, 'all1': 0.419448541053684}
67 |
68 | for rdm in sim.available_random_models:
69 | exp_rand_value = sim.expected_rand_index(
70 | n_elements=c1.n_elements,
71 | n_clusters1=c1.n_clusters,
72 | n_clusters2=c2.n_clusters,
73 | clu_size_seq1=c1.clu_size_seq,
74 | clu_size_seq2=c2.clu_size_seq,
75 | random_model=rdm)
76 | assert_approx_equal(
77 | exp_rand_value, known_rand_values[rdm], 10**(-10),
78 | "Expected Rand Index with {} Random Model does not match."
79 | "{} != {}".format(rdm, exp_rand_value, known_rand_values[rdm]))
80 |
81 | exp_mi_value = float(sim.expected_mi(n_elements=c1.n_elements,
82 | n_clusters1=c1.n_clusters,
83 | n_clusters2=c2.n_clusters,
84 | clu_size_seq1=c1.clu_size_seq,
85 | clu_size_seq2=c2.clu_size_seq,
86 | random_model=rdm,
87 | logbase=2.))
88 | assert_approx_equal(
89 | exp_mi_value, known_mi_values[rdm], 10**(-10),
90 | "Expected MI with {} Random Model does not match."
91 | "{} != {}".format(rdm, exp_mi_value, known_mi_values[rdm]))
92 |
93 | def test_elementsim_example():
94 |
95 | # taken from Fig 3 of Gates et al (2018) Scientific Reports
96 |
97 | # overlapping clustering
98 | c1_elm2clu_dict = {0:[0], 1:[0], 2:[0], 3:[3], 4:['.3'], 5:['.3', '.9'], 6:['.9']}
99 |
100 | # hierarchical clustering
101 | c2_elm2clu_dict = {0:[1], 1:[1], 2:[2], 3:[5], 4:[5], 5:[6, 8], 6:[9]}
102 | c2_dag = DAG()
103 | c2_dag.add_edges_from([(0,1), (0,2), (3,4), (4,5), (4,6), (3,7), (7,8), (7,9)])
104 |
105 | c1 = Clustering(elm2clu_dict = c1_elm2clu_dict)
106 | c2 = Clustering(elm2clu_dict = c2_elm2clu_dict, hier_graph = c2_dag)
107 |
108 | known_elsim = [0.92875658, 0.92875658, 0.85751315, 0.25717544, 0.74282456, 0.82083876, 0.80767074]
109 |
110 | elsim, ellabels = sim.element_sim_elscore(c1, c2, alpha = 0.9, r = 1., r2 = None, rescale_path_type = 'max')
111 |
112 | for i in range(7):
113 | assert_approx_equal(elsim[i], known_elsim[i], 10**(-10), "Element-centric similarity for element %s does not match. %s != %s" % (i, elsim[i], known_elsim[i]) )
114 |
115 |
116 | if __name__ == "__main__":
117 |
118 | test_comparison_example()
119 |
120 | test_model_example()
121 |
122 | test_elementsim_example()
123 |
124 |
--------------------------------------------------------------------------------
/docs/html/_static/nature.css:
--------------------------------------------------------------------------------
1 | /*
2 | * nature.css_t
3 | * ~~~~~~~~~~~~
4 | *
5 | * Sphinx stylesheet -- nature theme.
6 | *
7 | * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | @import url("basic.css");
13 |
14 | /* -- page layout ----------------------------------------------------------- */
15 |
16 | body {
17 | font-family: Arial, sans-serif;
18 | font-size: 100%;
19 | background-color: #fff;
20 | color: #555;
21 | margin: 0;
22 | padding: 0;
23 | }
24 |
25 | div.documentwrapper {
26 | float: left;
27 | width: 100%;
28 | }
29 |
30 | div.bodywrapper {
31 | margin: 0 0 0 230px;
32 | }
33 |
34 | hr {
35 | border: 1px solid #B1B4B6;
36 | }
37 |
38 | div.document {
39 | background-color: #eee;
40 | }
41 |
42 | div.body {
43 | background-color: #ffffff;
44 | color: #3E4349;
45 | padding: 0 30px 30px 30px;
46 | font-size: 0.9em;
47 | }
48 |
49 | div.footer {
50 | color: #555;
51 | width: 100%;
52 | padding: 13px 0;
53 | text-align: center;
54 | font-size: 75%;
55 | }
56 |
57 | div.footer a {
58 | color: #444;
59 | text-decoration: underline;
60 | }
61 |
62 | div.related {
63 | background-color: #6BA81E;
64 | line-height: 32px;
65 | color: #fff;
66 | text-shadow: 0px 1px 0 #444;
67 | font-size: 0.9em;
68 | }
69 |
70 | div.related a {
71 | color: #E2F3CC;
72 | }
73 |
74 | div.sphinxsidebar {
75 | font-size: 0.75em;
76 | line-height: 1.5em;
77 | }
78 |
79 | div.sphinxsidebarwrapper{
80 | padding: 20px 0;
81 | }
82 |
83 | div.sphinxsidebar h3,
84 | div.sphinxsidebar h4 {
85 | font-family: Arial, sans-serif;
86 | color: #222;
87 | font-size: 1.2em;
88 | font-weight: normal;
89 | margin: 0;
90 | padding: 5px 10px;
91 | background-color: #ddd;
92 | text-shadow: 1px 1px 0 white
93 | }
94 |
95 | div.sphinxsidebar h4{
96 | font-size: 1.1em;
97 | }
98 |
99 | div.sphinxsidebar h3 a {
100 | color: #444;
101 | }
102 |
103 |
104 | div.sphinxsidebar p {
105 | color: #888;
106 | padding: 5px 20px;
107 | }
108 |
109 | div.sphinxsidebar p.topless {
110 | }
111 |
112 | div.sphinxsidebar ul {
113 | margin: 10px 20px;
114 | padding: 0;
115 | color: #000;
116 | }
117 |
118 | div.sphinxsidebar a {
119 | color: #444;
120 | }
121 |
122 | div.sphinxsidebar input {
123 | border: 1px solid #ccc;
124 | font-family: sans-serif;
125 | font-size: 1em;
126 | }
127 |
128 | div.sphinxsidebar .searchformwrapper {
129 | margin-left: 20px;
130 | margin-right: 20px;
131 | }
132 |
133 | /* -- body styles ----------------------------------------------------------- */
134 |
135 | a {
136 | color: #005B81;
137 | text-decoration: none;
138 | }
139 |
140 | a:hover {
141 | color: #E32E00;
142 | text-decoration: underline;
143 | }
144 |
145 | div.body h1,
146 | div.body h2,
147 | div.body h3,
148 | div.body h4,
149 | div.body h5,
150 | div.body h6 {
151 | font-family: Arial, sans-serif;
152 | background-color: #BED4EB;
153 | font-weight: normal;
154 | color: #212224;
155 | margin: 30px 0px 10px 0px;
156 | padding: 5px 0 5px 10px;
157 | text-shadow: 0px 1px 0 white
158 | }
159 |
160 | div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }
161 | div.body h2 { font-size: 150%; background-color: #C8D5E3; }
162 | div.body h3 { font-size: 120%; background-color: #D8DEE3; }
163 | div.body h4 { font-size: 110%; background-color: #D8DEE3; }
164 | div.body h5 { font-size: 100%; background-color: #D8DEE3; }
165 | div.body h6 { font-size: 100%; background-color: #D8DEE3; }
166 |
167 | a.headerlink {
168 | color: #c60f0f;
169 | font-size: 0.8em;
170 | padding: 0 4px 0 4px;
171 | text-decoration: none;
172 | }
173 |
174 | a.headerlink:hover {
175 | background-color: #c60f0f;
176 | color: white;
177 | }
178 |
179 | div.body p, div.body dd, div.body li {
180 | line-height: 1.5em;
181 | }
182 |
183 | div.admonition p.admonition-title + p {
184 | display: inline;
185 | }
186 |
187 | div.highlight{
188 | background-color: white;
189 | }
190 |
191 | div.note {
192 | background-color: #eee;
193 | border: 1px solid #ccc;
194 | }
195 |
196 | div.seealso {
197 | background-color: #ffc;
198 | border: 1px solid #ff6;
199 | }
200 |
201 | div.topic {
202 | background-color: #eee;
203 | }
204 |
205 | div.warning {
206 | background-color: #ffe4e4;
207 | border: 1px solid #f66;
208 | }
209 |
210 | p.admonition-title {
211 | display: inline;
212 | }
213 |
214 | p.admonition-title:after {
215 | content: ":";
216 | }
217 |
218 | pre {
219 | padding: 10px;
220 | background-color: White;
221 | color: #222;
222 | line-height: 1.2em;
223 | border: 1px solid #C6C9CB;
224 | font-size: 1.1em;
225 | margin: 1.5em 0 1.5em 0;
226 | -webkit-box-shadow: 1px 1px 1px #d8d8d8;
227 | -moz-box-shadow: 1px 1px 1px #d8d8d8;
228 | }
229 |
230 | code {
231 | background-color: #ecf0f3;
232 | color: #222;
233 | /* padding: 1px 2px; */
234 | font-size: 1.1em;
235 | font-family: monospace;
236 | }
237 |
238 | .viewcode-back {
239 | font-family: Arial, sans-serif;
240 | }
241 |
242 | div.viewcode-block:target {
243 | background-color: #f4debf;
244 | border-top: 1px solid #ac9;
245 | border-bottom: 1px solid #ac9;
246 | }
247 |
248 | div.code-block-caption {
249 | background-color: #ddd;
250 | color: #222;
251 | border: 1px solid #C6C9CB;
252 | }
--------------------------------------------------------------------------------
/docs/html/_static/fonts/open-sans/stylesheet.css:
--------------------------------------------------------------------------------
1 | /***** Font Definition for Open Sans. This stylesheet comes from qrohlf.com/posts/better-opensans *****/
2 |
3 | /* Regular */
4 | @font-face {
5 | font-family: 'Open Sans';
6 |
7 | src: url('fonts/OpenSans-Regular-webfont.eot');
8 | src: url('fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
9 | url('fonts/OpenSans-Regular-webfont.woff') format('woff'),
10 | url('fonts/OpenSans-Regular-webfont.ttf') format('truetype'),
11 | url('fonts/OpenSans-Regular-webfont.svg#OpenSansRegular') format('svg');
12 | font-weight: normal;
13 | font-weight: 400;
14 | font-style: normal;
15 |
16 | }
17 |
18 | /* Italic */
19 | @font-face {
20 | font-family: 'Open Sans';
21 | src: url('fonts/OpenSans-Italic-webfont.eot');
22 | src: url('fonts/OpenSans-Italic-webfont.eot?#iefix') format('embedded-opentype'),
23 | url('fonts/OpenSans-Italic-webfont.woff') format('woff'),
24 | url('fonts/OpenSans-Italic-webfont.ttf') format('truetype'),
25 | url('fonts/OpenSans-Italic-webfont.svg#OpenSansItalic') format('svg');
26 | font-weight: normal;
27 | font-weight: 400;
28 | font-style: italic;
29 |
30 | }
31 |
32 | /* Light */
33 | @font-face {
34 | font-family: 'Open Sans';
35 | src: url('fonts/OpenSans-Light-webfont.eot');
36 | src: url('fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
37 | url('fonts/OpenSans-Light-webfont.woff') format('woff'),
38 | url('fonts/OpenSans-Light-webfont.ttf') format('truetype'),
39 | url('fonts/OpenSans-Light-webfont.svg#OpenSansLight') format('svg');
40 | font-weight: 200;
41 | font-style: normal;
42 |
43 | }
44 |
45 | /* Light Italic */
46 | @font-face {
47 | font-family: 'Open Sans';
48 | src: url('fonts/OpenSans-LightItalic-webfont.eot');
49 | src: url('fonts/OpenSans-LightItalic-webfont.eot?#iefix') format('embedded-opentype'),
50 | url('fonts/OpenSans-LightItalic-webfont.woff') format('woff'),
51 | url('fonts/OpenSans-LightItalic-webfont.ttf') format('truetype'),
52 | url('fonts/OpenSans-LightItalic-webfont.svg#OpenSansLightItalic') format('svg');
53 | font-weight: 200;
54 | font-style: italic;
55 |
56 | }
57 |
58 | /* Semibold */
59 | @font-face {
60 | font-family: 'Open Sans';
61 | src: url('fonts/OpenSans-Semibold-webfont.eot');
62 | src: url('fonts/OpenSans-Semibold-webfont.eot?#iefix') format('embedded-opentype'),
63 | url('fonts/OpenSans-Semibold-webfont.woff') format('woff'),
64 | url('fonts/OpenSans-Semibold-webfont.ttf') format('truetype'),
65 | url('fonts/OpenSans-Semibold-webfont.svg#OpenSansSemibold') format('svg');
66 | font-weight: 500;
67 | font-style: normal;
68 |
69 | }
70 |
71 | /* Semibold Italic */
72 | @font-face {
73 | font-family: 'Open Sans';
74 | src: url('fonts/OpenSans-SemiboldItalic-webfont.eot');
75 | src: url('fonts/OpenSans-SemiboldItalic-webfont.eot?#iefix') format('embedded-opentype'),
76 | url('fonts/OpenSans-SemiboldItalic-webfont.woff') format('woff'),
77 | url('fonts/OpenSans-SemiboldItalic-webfont.ttf') format('truetype'),
78 | url('fonts/OpenSans-SemiboldItalic-webfont.svg#OpenSansSemiboldItalic') format('svg');
79 | font-weight: 500;
80 | font-style: italic;
81 |
82 | }
83 |
84 | /* Bold */
85 | @font-face {
86 | font-family: 'Open Sans';
87 | src: url('fonts/OpenSans-Bold-webfont.eot');
88 | src: url('fonts/OpenSans-Bold-webfont.eot?#iefix') format('embedded-opentype'),
89 | url('fonts/OpenSans-Bold-webfont.woff') format('woff'),
90 | url('fonts/OpenSans-Bold-webfont.ttf') format('truetype'),
91 | url('fonts/OpenSans-Bold-webfont.svg#OpenSansBold') format('svg');
92 | font-weight: bold;
93 | font-weight: 700;
94 | font-style: normal;
95 |
96 | }
97 |
98 | /* Bold Italic */
99 | @font-face {
100 | font-family: 'Open Sans';
101 | src: url('fonts/OpenSans-BoldItalic-webfont.eot');
102 | src: url('fonts/OpenSans-BoldItalic-webfont.eot?#iefix') format('embedded-opentype'),
103 | url('fonts/OpenSans-BoldItalic-webfont.woff') format('woff'),
104 | url('fonts/OpenSans-BoldItalic-webfont.ttf') format('truetype'),
105 | url('fonts/OpenSans-BoldItalic-webfont.svg#OpenSansBoldItalic') format('svg');
106 | font-weight: bold;
107 | font-weight: 700;
108 | font-style: italic;
109 |
110 | }
111 |
112 | /* Extra Bold */
113 | @font-face {
114 | font-family: 'Open Sans';
115 | src: url('fonts/OpenSans-ExtraBold-webfont.eot');
116 | src: url('fonts/OpenSans-ExtraBold-webfont.eot?#iefix') format('embedded-opentype'),
117 | url('fonts/OpenSans-ExtraBold-webfont.woff') format('woff'),
118 | url('fonts/OpenSans-ExtraBold-webfont.ttf') format('truetype'),
119 | url('fonts/OpenSans-ExtraBold-webfont.svg#OpenSansExtrabold') format('svg');
120 | font-weight: 900;
121 | font-style: normal;
122 |
123 | }
124 |
125 | /* Extra Bold Italic */
126 | @font-face {
127 | font-family: 'Open Sans';
128 | src: url('fonts/OpenSans-ExtraBoldItalic-webfont.eot');
129 | src: url('fonts/OpenSans-ExtraBoldItalic-webfont.eot?#iefix') format('embedded-opentype'),
130 | url('fonts/OpenSans-ExtraBoldItalic-webfont.woff') format('woff'),
131 | url('fonts/OpenSans-ExtraBoldItalic-webfont.ttf') format('truetype'),
132 | url('fonts/OpenSans-ExtraBoldItalic-webfont.svg#OpenSansExtraboldItalic') format('svg');
133 | font-weight: 900;
134 | font-style: italic;
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/docs/clusim.rst:
--------------------------------------------------------------------------------
1 | .. CluSim documentation master file, created by
2 | sphinx-quickstart on Thu Aug 23 00:00:27 2018.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to CluSim's documentation!
7 |
8 | .. toctree::
9 | :maxdepth: 2
10 | :caption: Contents:
11 | :glob:
12 |
13 |
14 | Installation
15 | ===================
16 | This package is available in PyPI. Just run the following command on terminal to install.
17 |
18 | >>> pip install clusim
19 |
20 | You can also source the code directly from the github [project page](https://github.com/Hoosier-Clusters/clusim).
21 |
22 |
23 | Usage
24 | ===================
25 |
26 | A first comparison
27 | --------------------------
28 | We start by importing the required modules
29 |
30 | >>> from clusim.clustering import Clustering, print_clustering
31 | >>> import clusim.sim as sim
32 |
33 | The simplest way to make a Clustering is to use an elm2clu_dict which maps each element.
34 |
35 | >>> c1 = Clustering(elm2clu_dict = {0:[0], 1:[0], 2:[1], 3:[1], 4:[2], 5:[2]})
36 | >>> c2 = Clustering(elm2clu_dict = {0:[0], 1:[1], 2:[1], 3:[1], 4:[2], 5:[2]})
37 |
38 | >>> print_clustering(c1)
39 | >>> 01|23|45
40 | >>> print_clustering(c2)
41 | >>> 0|123|45
42 |
43 | Finally, the similarity of the two Clusterings can be found using the Jaccard Index.
44 |
45 | >>> sim.jaccard_index(c1, c2)
46 | >>> 0.4
47 |
48 | Basics of element-centric similarity
49 | --------------------------------------
50 | >>> from clusim.clustering import Clustering, print_clustering
51 | >>> import clusim.sim as sim
52 |
53 | >>> c1 = Clustering(elm2clu_dict = {0:[0], 1:[0], 2:[1], 3:[1], 4:[2], 5:[2]})
54 | >>> c2 = Clustering(elm2clu_dict = {0:[0], 1:[1], 2:[1], 3:[1], 4:[1], 5:[2]})
55 |
56 | The basic element-centric similarity score with a fixed alpha:
57 |
58 | >>> sim.element_sim(c1, c2, alpha = 0.9)
59 | >>> 0.6944444444444443
60 |
61 | We can also get the element scores. Note that since non-numberic elements are allowed, the element scores also returns a dict which maps the elements to the index in the elementScore array.
62 |
63 | >>> elementScores, relabeled_elements = sim.element_sim_elscore(c1, c2, alpha = 0.9)
64 | >>> print(elementScores)
65 | >>> [0.5 0.33333333 0.66666667 0.66666667 1. 1. ]
66 |
67 | The above element-centric similarity scores can be (roughly) interpreted as follows:
68 | 1. cluster 2 has the same memberships between the clusterings, so elements 4 and 5 have an element-centric similarity of 1.0
69 | 2. cluster 0 has one element difference between the clusterings (element 1 moved from cluster 0 to cluster 1), so element 0 has an element-centric similarity of 1/2
70 | 3. cluster 1 has one element difference between the clusterings (element 1 moved from cluster 0 to cluster 1), so elements 2 and 3 have an element-centric similarity of 2/3
71 | 4. element 1 moved from cluster 0 to cluster 1 so it has an element-centric similarity of 1/3
72 |
73 |
74 | Additional CluSim examples
75 | --------------------------------------
76 | Many more examples can be found in the jupyter notebooks included with the package:
77 | 1. `Using Similarity Measures `_
78 | 2. `Adjusting The Rand Index for different random models `_
79 | 3. `Adjusting Normalized Mutual Information `_
80 | 4. `Basics of Elementcentric Similarity `_
81 | 5. `Valid Clusterings `_
82 | 6. `Application with SciKit Learn `_
83 | 7. `Application with Hierarchical Clustering `_
84 |
85 |
86 | The “Clustering”
87 | =================
88 | .. autoclass:: clusim.clustering.Clustering
89 | :members:
90 |
91 | .. autoclass:: clusim.clusteringerror
92 | :members:
93 |
94 | .. automodule:: clusim.clustering
95 | :members:
96 |
97 |
98 | Clustering Generation
99 | ======================
100 | .. automodule:: clusim.clugen
101 | :members:
102 |
103 |
104 | Clustering Similarity
105 | ======================
106 | The different clustering similarity measures available.
107 |
108 |
109 | Pairwise Counting Measures
110 | --------------------------
111 | .. autofunction:: clusim.sim.contingency_table
112 |
113 | .. autofunction:: clusim.sim.count_pairwise_cooccurence
114 | .. autofunction:: clusim.sim.jaccard_index
115 | .. autofunction:: clusim.sim.rand_index
116 | .. autofunction:: clusim.sim.fowlkes_mallows_index
117 | .. autofunction:: clusim.sim.fmeasure
118 | .. autofunction:: clusim.sim.purity_index
119 | .. autofunction:: clusim.sim.classification_error
120 | .. autofunction:: clusim.sim.czekanowski_index
121 | .. autofunction:: clusim.sim.dice_index
122 | .. autofunction:: clusim.sim.sorensen_index
123 | .. autofunction:: clusim.sim.rogers_tanimoto_index
124 | .. autofunction:: clusim.sim.southwood_index
125 | .. autofunction:: clusim.sim.pearson_correlation
126 |
127 |
128 | Information Theoretic Measures
129 | ------------------------------
130 | .. autofunction:: clusim.sim.mi
131 | .. autofunction:: clusim.sim.nmi
132 | .. autofunction:: clusim.sim.vi
133 | .. autofunction:: clusim.sim.rmi
134 |
135 | Correction for Chance
136 | ------------------------------
137 | .. autofunction:: clusim.sim.corrected_chance
138 | .. autofunction:: clusim.sim.sample_expected_sim
139 | .. autofunction:: clusim.sim.expected_rand_index
140 | .. autofunction:: clusim.sim.adjrand_index
141 | .. autofunction:: clusim.sim.adj_mi
142 | .. autofunction:: clusim.sim.expected_mi
143 |
144 |
145 | Overlapping Clustering Similarity
146 | ----------------------------------
147 | .. autofunction:: clusim.sim.onmi
148 | .. autofunction:: clusim.sim.omega_index
149 | .. autofunction:: clusim.sim.geometric_accuracy
150 | .. autofunction:: clusim.sim.overlap_quality
151 |
152 |
153 | Element-centric Clustering Similarity
154 | ======================================
155 | .. automodule:: clusim.clusimelement
156 | :members:
157 |
158 |
159 | References
160 | ===========
161 | .. bibliography:: clusimref.bib
162 |
--------------------------------------------------------------------------------
/docs/html/_sources/clusim.rst.txt:
--------------------------------------------------------------------------------
1 | .. CluSim documentation master file, created by
2 | sphinx-quickstart on Thu Aug 23 00:00:27 2018.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to CluSim's documentation!
7 |
8 | .. toctree::
9 | :maxdepth: 2
10 | :caption: Contents:
11 | :glob:
12 |
13 |
14 | Installation
15 | ===================
16 | This package is available in PyPI. Just run the following command on terminal to install.
17 |
18 | >>> pip install clusim
19 |
20 | You can also source the code directly from the github [project page](https://github.com/Hoosier-Clusters/clusim).
21 |
22 |
23 | Usage
24 | ===================
25 |
26 | A first comparison
27 | --------------------------
28 | We start by importing the required modules
29 |
30 | >>> from clusim.clustering import Clustering, print_clustering
31 | >>> import clusim.sim as sim
32 |
33 | The simplest way to make a Clustering is to use an elm2clu_dict which maps each element.
34 |
35 | >>> c1 = Clustering(elm2clu_dict = {0:[0], 1:[0], 2:[1], 3:[1], 4:[2], 5:[2]})
36 | >>> c2 = Clustering(elm2clu_dict = {0:[0], 1:[1], 2:[1], 3:[1], 4:[2], 5:[2]})
37 |
38 | >>> print_clustering(c1)
39 | >>> 01|23|45
40 | >>> print_clustering(c2)
41 | >>> 0|123|45
42 |
43 | Finally, the similarity of the two Clusterings can be found using the Jaccard Index.
44 |
45 | >>> sim.jaccard_index(c1, c2)
46 | >>> 0.4
47 |
48 | Basics of element-centric similarity
49 | --------------------------------------
50 | >>> from clusim.clustering import Clustering, print_clustering
51 | >>> import clusim.sim as sim
52 |
53 | >>> c1 = Clustering(elm2clu_dict = {0:[0], 1:[0], 2:[1], 3:[1], 4:[2], 5:[2]})
54 | >>> c2 = Clustering(elm2clu_dict = {0:[0], 1:[1], 2:[1], 3:[1], 4:[1], 5:[2]})
55 |
56 | The basic element-centric similarity score with a fixed alpha:
57 |
58 | >>> sim.element_sim(c1, c2, alpha = 0.9)
59 | >>> 0.6944444444444443
60 |
61 | We can also get the element scores. Note that since non-numberic elements are allowed, the element scores also returns a dict which maps the elements to the index in the elementScore array.
62 |
63 | >>> elementScores, relabeled_elements = sim.element_sim_elscore(c1, c2, alpha = 0.9)
64 | >>> print(elementScores)
65 | >>> [0.5 0.33333333 0.66666667 0.66666667 1. 1. ]
66 |
67 | The above element-centric similarity scores can be (roughly) interpreted as follows:
68 | 1. cluster 2 has the same memberships between the clusterings, so elements 4 and 5 have an element-centric similarity of 1.0
69 | 2. cluster 0 has one element difference between the clusterings (element 1 moved from cluster 0 to cluster 1), so element 0 has an element-centric similarity of 1/2
70 | 3. cluster 1 has one element difference between the clusterings (element 1 moved from cluster 0 to cluster 1), so elements 2 and 3 have an element-centric similarity of 2/3
71 | 4. element 1 moved from cluster 0 to cluster 1 so it has an element-centric similarity of 1/3
72 |
73 |
74 | Additional CluSim examples
75 | --------------------------------------
76 | Many more examples can be found in the jupyter notebooks included with the package:
77 | 1. `Using Similarity Measures `_
78 | 2. `Adjusting The Rand Index for different random models `_
79 | 3. `Adjusting Normalized Mutual Information `_
80 | 4. `Basics of Elementcentric Similarity `_
81 | 5. `Valid Clusterings `_
82 | 6. `Application with SciKit Learn `_
83 | 7. `Application with Hierarchical Clustering `_
84 |
85 |
86 | The “Clustering”
87 | =================
88 | .. autoclass:: clusim.clustering.Clustering
89 | :members:
90 |
91 | .. autoclass:: clusim.clusteringerror
92 | :members:
93 |
94 | .. automodule:: clusim.clustering
95 | :members:
96 |
97 |
98 | Clustering Generation
99 | ======================
100 | .. automodule:: clusim.clugen
101 | :members:
102 |
103 |
104 | Clustering Similarity
105 | ======================
106 | The different clustering similarity measures available.
107 |
108 |
109 | Pairwise Counting Measures
110 | --------------------------
111 | .. autofunction:: clusim.sim.contingency_table
112 |
113 | .. autofunction:: clusim.sim.count_pairwise_cooccurence
114 | .. autofunction:: clusim.sim.jaccard_index
115 | .. autofunction:: clusim.sim.rand_index
116 | .. autofunction:: clusim.sim.fowlkes_mallows_index
117 | .. autofunction:: clusim.sim.fmeasure
118 | .. autofunction:: clusim.sim.purity_index
119 | .. autofunction:: clusim.sim.classification_error
120 | .. autofunction:: clusim.sim.czekanowski_index
121 | .. autofunction:: clusim.sim.dice_index
122 | .. autofunction:: clusim.sim.sorensen_index
123 | .. autofunction:: clusim.sim.rogers_tanimoto_index
124 | .. autofunction:: clusim.sim.southwood_index
125 | .. autofunction:: clusim.sim.pearson_correlation
126 |
127 |
128 | Information Theoretic Measures
129 | ------------------------------
130 | .. autofunction:: clusim.sim.mi
131 | .. autofunction:: clusim.sim.nmi
132 | .. autofunction:: clusim.sim.vi
133 | .. autofunction:: clusim.sim.rmi
134 |
135 | Correction for Chance
136 | ------------------------------
137 | .. autofunction:: clusim.sim.corrected_chance
138 | .. autofunction:: clusim.sim.sample_expected_sim
139 | .. autofunction:: clusim.sim.expected_rand_index
140 | .. autofunction:: clusim.sim.adjrand_index
141 | .. autofunction:: clusim.sim.adj_mi
142 | .. autofunction:: clusim.sim.expected_mi
143 |
144 |
145 | Overlapping Clustering Similarity
146 | ----------------------------------
147 | .. autofunction:: clusim.sim.onmi
148 | .. autofunction:: clusim.sim.omega_index
149 | .. autofunction:: clusim.sim.geometric_accuracy
150 | .. autofunction:: clusim.sim.overlap_quality
151 |
152 |
153 | Element-centric Clustering Similarity
154 | ======================================
155 | .. automodule:: clusim.clusimelement
156 | :members:
157 |
158 |
159 | References
160 | ===========
161 | .. bibliography:: clusimref.bib
162 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Configuration file for the Sphinx documentation builder.
4 | #
5 | # This file does only contain a selection of the most common options. For a
6 | # full list see the documentation:
7 | # http://www.sphinx-doc.org/en/master/config
8 |
9 | # -- Path setup --------------------------------------------------------------
10 |
11 | # If extensions (or modules to document with autodoc) are in another directory,
12 | # add these directories to sys.path here. If the directory is relative to the
13 | # documentation root, use os.path.abspath to make it absolute, like shown here.
14 | #
15 |
16 | import os
17 | import sys
18 | sys.path.insert(0, os.path.abspath('../clusim'))
19 | from clusim import __version__, __release__, __author__, __description__
20 |
21 | # The short X.Y version
22 | version = ''
23 | # The full version, including alpha/beta/rc tags
24 | release = ''
25 |
26 |
27 | # -- General configuration ---------------------------------------------------
28 |
29 | # If your documentation needs a minimal Sphinx version, state it here.
30 | #
31 | # needs_sphinx = '1.0'
32 |
33 | # Add any Sphinx extension module names here, as strings. They can be
34 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
35 | # ones.
36 | extensions = ['sphinx.ext.autodoc',
37 | 'sphinx.ext.doctest',
38 | 'sphinx.ext.viewcode',
39 | 'sphinx.ext.intersphinx',
40 | 'sphinx.ext.todo',
41 | 'sphinx.ext.coverage',
42 | 'sphinx.ext.autosummary',
43 | 'sphinx.ext.githubpages',
44 | 'sphinx.ext.napoleon',
45 | 'numpydoc',
46 | 'sphinxcontrib.bibtex']
47 |
48 | # Add any paths that contain templates here, relative to this directory.
49 | templates_path = ['_templates']
50 |
51 | # The suffix(es) of source filenames.
52 | # You can specify multiple suffix as a list of string:
53 | #
54 | # source_suffix = ['.rst', '.md']
55 | source_suffix = '.rst'
56 |
57 | # The master toctree document.
58 | master_doc = 'clusim'
59 |
60 | # General information about the project.
61 | project = u'clusim'
62 | copyright = u'2017, Alexander Gates and Yong-Yeol Ahn'
63 | author = __author__
64 |
65 | # The version info for the project you're documenting, acts as replacement for
66 | # |version| and |release|, also used in various other places throughout the
67 | # built documents.
68 | #
69 | # The short X.Y version.
70 | version = __version__
71 | # The full version, including alpha/beta/rc tags.
72 | release = __release__
73 |
74 |
75 | # The language for content autogenerated by Sphinx. Refer to documentation
76 | # for a list of supported languages.
77 | #
78 | # This is also used if you do content translation via gettext catalogs.
79 | # Usually you set "language" from the command line for these cases.
80 | language = None
81 |
82 | # List of patterns, relative to source directory, that match files and
83 | # directories to ignore when looking for source files.
84 | # This pattern also affects html_static_path and html_extra_path .
85 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**.ipynb_checkpoints']
86 |
87 | # The name of the Pygments (syntax highlighting) style to use.
88 | pygments_style = 'sphinx'
89 |
90 |
91 | # -- Options for HTML output -------------------------------------------------
92 |
93 | # The theme to use for HTML and HTML Help pages. See the documentation for
94 | # a list of builtin themes.
95 | #
96 | #html_theme = 'alabaster'
97 | #import guzzle_sphinx_theme
98 |
99 | #html_theme_path = guzzle_sphinx_theme.html_theme_path()
100 | #html_theme = 'guzzle_sphinx_theme'
101 | html_theme = 'nature'
102 |
103 | # Register the theme as an extension to generate a sitemap.xml
104 | #extensions.append("guzzle_sphinx_theme")
105 |
106 | # Guzzle theme options (see theme.conf for more information)
107 | #html_theme_options = {
108 | # Set the name of the project to appear in the sidebar
109 | # "project_nav_name": "CluSim",
110 |
111 | # Set you GA account ID to enable tracking
112 | #"google_analytics_account": "my_ga_account",
113 | #}
114 |
115 | # Theme options are theme-specific and customize the look and feel of a theme
116 | # further. For a list of options available for each theme, see the
117 | # documentation.
118 | #
119 | # html_theme_options = {}
120 |
121 | # Add any paths that contain custom static files (such as style sheets) here,
122 | # relative to this directory. They are copied after the builtin static files,
123 | # so a file named "default.css" will overwrite the builtin "default.css".
124 | html_static_path = []
125 |
126 | # Custom sidebar templates, must be a dictionary that maps document names
127 | # to template names.
128 | #
129 | # The default sidebars (for documents that don't match any pattern) are
130 | # defined by theme itself. Builtin themes are using these templates by
131 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
132 | # 'searchbox.html']``.
133 | #
134 | # html_sidebars = {}
135 |
136 |
137 | # -- Options for HTMLHelp output ---------------------------------------------
138 |
139 | # Output file base name for HTML help builder.
140 | htmlhelp_basename = 'CluSimdoc'
141 |
142 |
143 | # -- Options for LaTeX output ------------------------------------------------
144 |
145 | latex_elements = {
146 | # The paper size ('letterpaper' or 'a4paper').
147 | #
148 | # 'papersize': 'letterpaper',
149 |
150 | # The font size ('10pt', '11pt' or '12pt').
151 | #
152 | # 'pointsize': '10pt',
153 |
154 | # Additional stuff for the LaTeX preamble.
155 | #
156 | # 'preamble': '',
157 |
158 | # Latex figure (float) alignment
159 | #
160 | # 'figure_align': 'htbp',
161 | }
162 |
163 | # Grouping the document tree into LaTeX files. List of tuples
164 | # (source start file, target name, title,
165 | # author, documentclass [howto, manual, or own class]).
166 | latex_documents = [
167 | (master_doc, 'CluSim.tex', 'CluSim Documentation',
168 | 'Alexander J Gates and Yong-Yeol Ahn', 'manual'),
169 | ]
170 |
171 |
172 | # -- Options for manual page output ------------------------------------------
173 |
174 | # One entry per manual page. List of tuples
175 | # (source start file, name, description, authors, manual section).
176 | man_pages = [
177 | (master_doc, 'clusim', 'CluSim Documentation',
178 | [author], 1)
179 | ]
180 |
181 |
182 | # -- Options for Texinfo output ----------------------------------------------
183 |
184 | # Grouping the document tree into Texinfo files. List of tuples
185 | # (source start file, target name, title, author,
186 | # dir menu entry, description, category)
187 | texinfo_documents = [
188 | (master_doc, 'clusim', u'clusim Documentation',
189 | author, 'clusim', __description__)
190 | ]
191 |
192 | # -- Extension configuration -------------------------------------------------
193 | autodoc_member_order = 'bysource'
194 |
--------------------------------------------------------------------------------
/paper.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'CluSim: a python package for calculating clustering similarity'
3 | tags:
4 | - Python
5 | - clustering
6 | - network communities
7 | - clustering similarity
8 | authors:
9 | - name: Alexander J. Gates
10 | orcid: 0000-0003-0099-7480
11 | affiliation: 1 # (Multiple affiliations must be quoted)
12 | - name: Yong-Yeol Ahn
13 | orcid: 0000-0002-4352-4301
14 | affiliation: "2,3"
15 | affiliations:
16 | - name: Department of Physics, Northeastern University, Boston, 02115, USA
17 | index: 1
18 | - name: Department of Informatics, Indiana University, Bloomington, 47408, USA
19 | index: 2
20 | - name: Program in Cognitive Science, Indiana University, Bloomington, 47408, USA
21 | index: 3
22 | date: 13 March 2019
23 | bibliography: paper.bib
24 | ---
25 |
26 | # Summary
27 |
28 | Clustering is a primary method to reveal the structure of data [@Jain1999clustering]. To understand, evaluate, and leverage data clusterings, we need to quantitatively compare them. Clustering comparison is the basis for method evaluation, consensus clustering, and tracking the temporal evolution of clusters, among many other tasks. For instance, the evaluation of a clustering method is usually achieved by comparing the method's result to a planted reference clustering, assuming that the more similar the method's solution is to the reference clustering, the better the method. Despite the importance of clustering comparison, no consensus has been reached for a standardized assessment; each similarity measure rewards and penalizes different criteria, sometimes producing contradictory conclusions.
29 |
30 | Clustering similarity measures can be classified based on the cluster types: i) *partitions* that group elements into non-overlapping clusters, ii) *hierarchical clusterings* that group elements into a nested series of partitions (a.k.a. dendrogram), or iii) *overlapping clusterings* with elements belonging to multiple clusters. One approach to aid with the interpretation of the similarity score establishes a baseline in the context of a random ensemble of clusterings. Such a correction procedure requires two choices: *a model for random clusterings* and *how clusterings are drawn from the random model*. With few exceptions, similarity measures are only designed to compare clusterings of the same type, and the decisions required for the correction procedure are usually ignored or relegated to the status of technical trivialities [@Gates2017impact].
31 |
32 | Here, we introduce *CluSim*, a python package providing a unified library of over 20 clustering similarity measures for partitions, dendrograms, and overlapping clusterings. To our knowledge, this package constitutes the first collection of clustering similarity measures for all three clustering types and extended access to random models of clusterings [@Gates2018element]. We illustrate the use of the package through two examples: an evaluation of measure behavior with variation in 3 clustering properties (membership, cluster sizes, and number of clusters) and a clustering comparison of Gene Expression data in the context of different random models.
33 |
34 | # Examples
35 |
36 | The basic class in the *CluSim* package is a *Clustering*, or an assignment of labeled elements (i.e. data points or network vertices) into clusters (the groups). *Hierarchical Clusterings* also contain a dendrogram, or more generally an acyclic graph, capturing the nested structure of the clusters. In *CluSim*, a *Clustering* can be instantiated from 7 different common formats, including full support for *scipy*, *scikit-learn*, and *dendropy* clustering formats [@scikitlearn; @Sukumaran2010dendropy].
37 |
38 | *CluSim* provides more than 20 clustering similarity and distance measures for the comparison between two *Clusterings*. All similarity measures produce a score in the range $[0,1]$, where $1$ indicates identical clusterings and $0$ indicates maximally dissimilar clusterings. See the online documentation for a detailed list and mathematical definitions of these similarity measures.
39 |
40 | The clustering similarity measures presented here differ in how each evaluates the trade-offs between variation in three primary characteristics of clusterings: the grouping of elements into clusters, the number of clusters, and the size distribution of those clusters [@Gates2018element]. To illustrate these trade-offs, we present three simple examples in Fig. 1. In the first example, 1,024 elements are grouped into 32 clusters of equal size and compared against a similar clustering with a fraction of the elements randomly exchanged between the clusters, keeping the same cluster sizes. As seen in Fig. 1**a**), all similarity measures decrease as the fraction of shuffled elements increases, but the measures differ on whether they can differentiate between clusterings that are completely random, or if there is a discontinuous jump in the similarity value. In the second example, 1,024 elements are grouped into 32 clusters of equal size and compared against a similar clustering with increasing cluster size skew-ness. As seen in Fig. 1**b**), some similarity measures decrease as the fraction cluster size heterogeneity increases, while others increase. Finally, in the third example, 1,024 elements are grouped into 8 clusters of equal size and compared against a similar clustering with an increasing number of equal-sized clusters. As seen in Fig. 1**c**), most similarity measures decrease as the number of clusters increases, but the normalized mutual information increases. For more details and an extended interpretation of these experiments, see the analysis in Gates et al (2019) [@Gates2018element]. Ultimately, the practitioner should choose a clustering similarity measure that is sensitive to the relevant features of the clusterings for the problem at hand.
41 |
42 | 
43 |
44 |
45 |
46 | To facilitate comparisons within a set of clusterings, it is often argued to consider clustering similarity in the context of a random baseline [@Hubert1985adjrand; @Vinh2009nmicorrection; @Gates2017impact]. The *CluSim* package provides both analytic and statistical sampling methods for calculating such a correction for chance. Analytic solutions are available for the Rand index and Normalized Mutual Information using five random models: the permutation model, both one-sided and two-sided models for clusterings with a fixed number of clusters, and both one-sided and two-sided models for all random clusterings. See Gates \& Ahn (2017) [@Gates2017impact] for detailed derivations and explanations of the differences between clustering random models. For all other similarity measures, the correction for chance is estimated by randomly sampling the random ensemble of *Clusterings* using the provided random Clustering generators.
47 |
48 | A typical comparison using a correction for chance is illustrated in Fig. 2. Agglomerative Hierarchical Clustering was applied to gene expression data from [@deSouto2008geneclustering] and compared to the true classification of cancer types using the Rand Index ($0.5$, red). To determine if the Rand Index of $0.5$ is indeed a good score, it is assessed relative to the distribution of pairwise comparisons amongst a sample of 100 random *Clusterings* from the Permutation model (blue, see [Hubert1985adjrand]) with mean Rand index of $0.44$ (black). Thus, the naive assessment would conclude that Agglomerative Hierarchical Clustering has performed better than would be expected by chance. However, the more appropriate random model for this scenario is provided by the one-sided model with a Fixed Number of Clusters (see [Gates2017impact]), since Agglomerative Hierarchical Clustering fixes the number of clusters but not their sizes, and the comparison is made to a ground truth clustering. The distribution of pairwise comparisons amongst a sample of 100 random samples from this random model (blue) with a mean similarity of $0.59$ (black), demonstrates that Agglomerative Hierarchical Clustering actually performed worse than if we had drawn a random clustering!
49 |
50 |
51 |
52 | ![**Evaluating clustering comparisons w.r.t.\ random models.**. A comparison using the Rand Index between the classification of cancer types and clustering labels derived using Hierarchical Clustering on gene expression data ($0.5$, red). above, Pairwise comparisons between samples from the Permutation model (blue, see [Hubert1985adjrand]) with mean $0.44$ (black). below, Pairwise comparisons between samples from the one-sided model with a Fixed Number of Clusters (blue, see [Gates2017impact]) with mean $0.59$ (black). The Permutation model suggests Hierarchical Clustering is more similar to the ground truth than a random clustering, while the one-sized fixed number of clusterings model, the more appropriate model for this scenario, reveals that the result is less similar than random clusterings.](paperfigures/CluSimFig2.png)
53 |
54 |
55 |
56 | # Acknowledgements
57 | The authors would like to thank Ian Wood for thoughtful discussions, and Andre David for suggestions which significantly improved the presentation of this work.
58 |
59 | # References
60 |
61 |
--------------------------------------------------------------------------------
/docs/html/searchindex.js:
--------------------------------------------------------------------------------
1 | Search.setIndex({docnames:["clusim"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":2,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["clusim.rst"],objects:{"":{clugen:[0,0,0,"-"],clusimelement:[0,0,0,"-"],clustering:[0,0,0,"-"]},"clusim.clugen":{cluster_missing_elements:[0,1,1,""],enumerate_random_partition_num:[0,1,1,""],generate_random_partition_all:[0,1,1,""],make_equal_clustering:[0,1,1,""],make_random_clustering:[0,1,1,""],make_random_dendrogram:[0,1,1,""],make_singleton_clustering:[0,1,1,""],shuffle_memberships:[0,1,1,""],shuffle_memberships_pa:[0,1,1,""]},"clusim.clusimelement":{cL1:[0,1,1,""],calculate_ppr_with_power_iteration:[0,1,1,""],element_sim:[0,1,1,""],element_sim_elscore:[0,1,1,""],find_groups_in_cluster:[0,1,1,""],make_affinity_matrix:[0,1,1,""],make_cielg:[0,1,1,""],numerical_ppr_scores:[0,1,1,""],ppr_partition:[0,1,1,""]},"clusim.clustering":{Clustering:[0,2,1,"id0"],SetEncoder:[0,2,1,""],print_clustering:[0,1,1,""],remap2match:[0,1,1,""]},"clusim.clustering.Clustering":{clustering_from_igraph_cover:[0,3,1,"id9"],copy:[0,3,1,"id1"],downstream_elements:[0,3,1,"id21"],find_clu_size_seq:[0,3,1,"id12"],find_num_overlap:[0,3,1,"id15"],from_clu2elm_dict:[0,3,1,"id4"],from_cluster_list:[0,3,1,"id5"],from_dict:[0,3,1,"id18"],from_digraph:[0,3,1,"id23"],from_elm2clu_dict:[0,3,1,"id3"],from_membership_list:[0,3,1,"id7"],from_scipy_linkage:[0,3,1,"id22"],load:[0,3,1,"id20"],merge_clusters:[0,3,1,"id16"],relabel_clusters_by_size:[0,3,1,"id13"],relabel_clusters_to_match:[0,3,1,"id14"],save:[0,3,1,"id19"],to_clu2elm_dict:[0,3,1,"id10"],to_cluster_list:[0,3,1,"id6"],to_dict:[0,3,1,"id17"],to_elm2clu_dict:[0,3,1,"id11"],to_membership_list:[0,3,1,"id8"],validate_clustering:[0,3,1,"id2"]},"clusim.clustering.SetEncoder":{"default":[0,3,1,""]},"clusim.sim":{adj_mi:[0,1,1,""],adjrand_index:[0,1,1,""],classification_error:[0,1,1,""],contingency_table:[0,1,1,""],corrected_chance:[0,1,1,""],count_pairwise_cooccurence:[0,1,1,""],czekanowski_index:[0,1,1,""],dice_index:[0,1,1,""],expected_mi:[0,1,1,""],expected_rand_index:[0,1,1,""],fmeasure:[0,1,1,""],fowlkes_mallows_index:[0,1,1,""],geometric_accuracy:[0,1,1,""],jaccard_index:[0,1,1,""],mi:[0,1,1,""],nmi:[0,1,1,""],omega_index:[0,1,1,""],onmi:[0,1,1,""],overlap_quality:[0,1,1,""],pearson_correlation:[0,1,1,""],purity_index:[0,1,1,""],rand_index:[0,1,1,""],rmi:[0,1,1,""],rogers_tanimoto_index:[0,1,1,""],sample_expected_sim:[0,1,1,""],sorensen_index:[0,1,1,""],southwood_index:[0,1,1,""],vi:[0,1,1,""]},clusim:{clugen:[0,0,0,"-"],clusimelement:[0,0,0,"-"],clustering:[0,0,0,"-"],clusteringerror:[0,4,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","method","Python method"],"4":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:method","4":"py:attribute"},terms:{"\u0131":0,"boolean":0,"class":0,"default":0,"final":0,"float":0,"function":0,"import":0,"int":0,"j\u00e1no":0,"kert\u00e9sz":0,"meil\u0103":0,"new":0,"return":0,"tam\u00e1":0,"true":0,"try":0,For:0,Useful:0,Using:0,abl10:0,abov:0,accord:0,accuraci:0,acycl:0,add:0,add_edges_from:0,adding:0,adeel:0,adj_mi:0,adjrand_index:0,adjust:0,adjusted_rand:0,affin:0,agglom:0,ahn:0,albert:0,alberto:0,alex:0,alexand:0,algorithm:0,alia:0,all1:0,all:0,allow:0,allow_nan:0,alogrithm:0,alpha:0,alpin:0,also:0,american:0,analyt:0,andrea:0,applic:0,appropri:0,approxim:0,arabi:0,arbitrari:0,arena:0,around:0,arrai:0,art:0,arxiv:0,assign:0,associ:0,assum:0,attach:0,automat:0,avail:0,available_similarity_measur:0,averag:0,bagrow:0,base:0,behavior:0,belong:0,below:0,between:0,bit:0,bool:0,both:0,bound:0,calcuat:0,calcul:0,calculate_ppr_with_power_iter:0,call:0,calucalt:0,can:0,cantwel:0,captur:0,cd88:0,check:0,check_circular:0,choos:0,cielg:0,cl1:0,classif:0,classification_error:0,clsuter:0,clu1:0,clu2:0,clu2elm_dict:0,clu:0,clu_for_el1:0,clu_for_el2:0,clu_size_seq1:0,clu_size_seq2:0,clu_size_seq:0,clugen:0,cluser:0,clusid:0,clusimel:0,cluster_list:0,cluster_missing_el:0,clusterid:0,clustering1:0,clustering2:0,clustering_dict:0,clustering_ensemble_generator_num:0,clustering_from_igraph_cov:0,clusteringerror:0,clusterv:0,clyde:0,code:0,colin:0,collin:0,column:0,com:0,command:0,commun:0,compar:0,complet:0,complex:0,comput:0,concaten:0,consid:0,consistend:0,constant:0,constant_num_clust:0,cont_tabl:0,contain:0,conting:0,contingency_t:0,cooccur:0,copi:0,corrected_ch:0,correl:0,correspond:0,could:0,count_pairwise_cooccur:0,cover:0,creat:0,criteria:0,csr_matrix:0,custer:0,cut_at_depth:0,czekanowski:0,czekanowski_index:0,danon:0,data1:0,data2:0,ddiazgda05:0,decemb:0,deep:0,def:0,dendrogram:0,denot:0,dent:0,deriv:0,describ:0,detail:0,detect:0,determin:0,dice:0,dice_index:0,dict:0,dictionari:0,differ:0,digraph:0,directli:0,disjoint:0,dist_resc:0,distanc:0,distribut:0,distrubt:0,document:0,doe:0,downstream:0,downstream_el:0,draw:0,drawn:0,duch:0,dump:0,each:0,edward:0,effici:0,either:0,el1:0,el22:0,el2:0,el5:0,element_list:0,element_sim:0,element_sim_elscor:0,element_sim_elseq:0,elementcentr:0,elementgrouplist:0,elementid:0,elementscor:0,elm2clu_dict:0,els:0,empti:0,empty_start:0,ensembl:0,ensure_ascii:0,entri:0,entropi:0,enumerate_random_partition_num:0,equal:0,equival:0,error:0,evalu:0,everi:0,except:0,expect:0,expected_mi:0,expected_rand_index:0,experi:0,explain:0,explan:0,fall:0,fals:0,fascicl:0,faster:0,featur:0,file:0,find:0,find_clu_size_seq:0,find_groups_in_clust:0,find_num_overlap:0,fix:0,flora:0,fm83:0,fmeasur:0,follow:0,forc:0,form:0,format:0,formul:0,fortunato:0,found:0,fowlk:0,fowlkes_mallows_index:0,fraction:0,from:0,from_clu2elm_dict:0,from_cluster_list:0,from_dict:0,from_digraph:0,from_elm2clu_dict:0,from_membership_list:0,from_scipy_linkag:0,fuction:0,ga17:0,gabriel:0,gate:0,gender:0,generate_random_partition_al:0,geometr:0,geometric_accuraci:0,georg:0,get:0,giant:0,github:0,given:0,gold:0,graph:0,groundtruth:0,group:0,guarante:0,guilera:0,gwha19:0,ha85:0,haiyuan:0,has:0,have:0,height:0,hetrick:0,hier_clusdict:0,hier_graph:0,hierarch:0,hierarchi:0,hoosier:0,http:0,hubert:0,ian:0,ident:0,identif:0,igraph:0,igraphcov:0,impact:0,implement:0,implementaion:0,implemet:0,improv:0,includ:0,indent:0,index:0,indic:0,induc:0,inf:0,initi:0,inner:0,instanc:0,integ:0,intend:0,interact:0,interpret:0,iter:0,ith:0,its:0,itself:0,jac12:0,jaccard:0,jaccard_index:0,jame:0,jean:0,join:0,jordi:0,journal:0,json:0,jsonencod:0,june:0,jupyt:0,just:0,keep:0,keep_sampl:0,kei:0,kernel:0,known:0,knuth:0,label:0,lancichinetti:0,larg:0,lawrenc:0,layer:0,leaf:0,learn:0,least:0,leav:0,lehmann:0,leon:0,let:0,lfk09:0,like:0,linda:0,linearlli:0,link:0,linkag:0,linkage_matrix:0,list:0,load:0,log:0,logarithm:0,logbas:0,lowest:0,machin:0,make:0,make_affinity_matrix:0,make_cielg:0,make_equal_clust:0,make_random_clust:0,make_random_dendrogram:0,make_singleton_clust:0,mallow:0,mani:0,map:0,mape:0,marina:0,match:0,matric:0,matrix:0,max:0,maxim:0,maximum:0,mean:0,mechan:0,mei03:0,membership:0,membership_list:0,memebership:0,merg:0,merge_clust:0,method:0,metric:0,min:0,minimum:0,miss:0,model:0,modul:0,more:0,most:0,move:0,multiscal:0,multivari:0,multivariate_norm:0,must:0,mutual:0,n00:0,n01:0,n10:0,n11:0,n_cluster:0,n_clusters1:0,n_clusters2:0,n_element:0,n_sampl:0,n_step:0,name:0,natur:0,ncy19:0,need:0,nepusz:0,network:0,networkx:0,new_cluster_typ:0,new_nam:0,newman:0,nmi:0,node:0,non:0,none:0,norm:0,norm_typ:0,normal:0,note:0,notebook:0,num1:0,num:0,number:0,numerical_ppr_scor:0,numpi:0,nyp12:0,obj:0,object:0,omega:0,omega_index:0,one:0,onli:0,onmi:0,option:0,orig_clu:0,origin:0,otherwis:0,over:0,overlap_qu:0,own:0,p09008:0,p_i:0,paccanaro:0,packag:0,page:0,pair:0,param:0,paramet:0,parent:0,particularli:0,partit:0,pass:0,path:0,paul:0,pearson:0,pearson_correl:0,percent:0,percentag:0,perm1:0,perm:0,permut:0,person:0,phipp:0,physic:0,phytologist:0,pictur:0,pip:0,power:0,power_iter:0,ppr:0,ppr_implement:0,ppr_partit:0,pprmatrix2:0,pprmatrix:0,preferenti:0,print:0,print_clust:0,probabilti:0,probabl:0,program:0,project:0,propag:0,protein:0,provid:0,prpack:0,puriti:0,purity_index:0,put:0,pypi:0,python:0,qualiti:0,rais:0,ran71:0,rand:0,rand_index:0,random:0,random_mod:0,random_model:0,randomli:0,rang:0,rank:0,recommend:0,recoveri:0,reduc:0,reject:0,relabel_clusters_by_s:0,relabel_clusters_to_match:0,relabeled_el:0,remap2match:0,remap:0,renam:0,renumb:0,repetit:0,report:0,repres:0,represent:0,represetn:0,requir:0,rescal:0,rescale_path_typ:0,research:0,resolut:0,result:0,retun:0,reveal:0,rmi:0,roger:0,rogers_tanimoto_index:0,root:0,roughli:0,row:0,run:0,same:0,sampl:0,sample_expected_sim:0,santo:0,save:0,scale:0,scientif:0,scikit:0,scipi:0,score:0,second:0,see:0,seed:0,select:0,self:0,separ:0,seper:0,septemb:0,sequenc:0,serializ:0,set:0,setencod:0,shannon:0,shuffl:0,shuffle_clu:0,shuffle_membership:0,shuffle_memberships_pa:0,side:0,sim:0,simplest:0,sinc:0,singl:0,singleton:0,six:0,size:0,skipkei:0,solut:0,sometim:0,soomro:0,sorensen:0,sorensen_index:0,sort_kei:0,sourc:0,southwood:0,southwood_index:0,specif:0,specifi:0,springer:0,sqrt:0,standard:0,start:0,statist:0,stop:0,store:0,str:0,string:0,structur:0,subclass:0,suitabl:0,sum:0,sune:0,support:0,symmetr:0,tabl:0,tanimoto:0,target:0,target_clust:0,technic:0,term:0,termin:0,than:0,themselv:0,theori:0,thi:0,three:0,through:0,time:0,to_clu2elm_dict:0,to_cluster_list:0,to_dendropy_tre:0,to_dict:0,to_elm2clu_dict:0,to_membership_list:0,tol:0,toler:0,transform:0,transit:0,treat:0,turn:0,two:0,type:0,typeerror:0,unassign:0,under:0,unifi:0,uniform:0,uniformli:0,upper:0,use:0,used:0,useful:0,uses:0,using:0,util:0,valid:0,validate_clust:0,valu:0,variat:0,vector:0,vertex:0,vertexcov:0,vertic:0,vi_:0,via:0,visit:0,volum:0,w_matrix:0,wai:0,ward:0,weight:0,weightedgraph:0,welcom:0,when:0,where:0,which:0,william:0,wise:0,without:0,wood:0,work:0,wrapper:0,xdata:0,yeol:0,yong:0,you:0,young:0,zafar:0,zone:0},titles:["Installation"],titleterms:{The:0,addit:0,basic:0,centric:0,chanc:0,clusim:0,cluster:0,comparison:0,correct:0,count:0,element:0,exampl:0,first:0,gener:0,inform:0,instal:0,measur:0,overlap:0,pairwis:0,refer:0,similar:0,theoret:0,usag:0}})
--------------------------------------------------------------------------------
/docs/html/_static/doctools.js:
--------------------------------------------------------------------------------
1 | /*
2 | * doctools.js
3 | * ~~~~~~~~~~~
4 | *
5 | * Sphinx JavaScript utilities for all documentation.
6 | *
7 | * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | /**
13 | * select a different prefix for underscore
14 | */
15 | $u = _.noConflict();
16 |
17 | /**
18 | * make the code below compatible with browsers without
19 | * an installed firebug like debugger
20 | if (!window.console || !console.firebug) {
21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
23 | "profile", "profileEnd"];
24 | window.console = {};
25 | for (var i = 0; i < names.length; ++i)
26 | window.console[names[i]] = function() {};
27 | }
28 | */
29 |
30 | /**
31 | * small helper function to urldecode strings
32 | */
33 | jQuery.urldecode = function(x) {
34 | return decodeURIComponent(x).replace(/\+/g, ' ');
35 | };
36 |
37 | /**
38 | * small helper function to urlencode strings
39 | */
40 | jQuery.urlencode = encodeURIComponent;
41 |
42 | /**
43 | * This function returns the parsed url parameters of the
44 | * current request. Multiple values per key are supported,
45 | * it will always return arrays of strings for the value parts.
46 | */
47 | jQuery.getQueryParameters = function(s) {
48 | if (typeof s === 'undefined')
49 | s = document.location.search;
50 | var parts = s.substr(s.indexOf('?') + 1).split('&');
51 | var result = {};
52 | for (var i = 0; i < parts.length; i++) {
53 | var tmp = parts[i].split('=', 2);
54 | var key = jQuery.urldecode(tmp[0]);
55 | var value = jQuery.urldecode(tmp[1]);
56 | if (key in result)
57 | result[key].push(value);
58 | else
59 | result[key] = [value];
60 | }
61 | return result;
62 | };
63 |
64 | /**
65 | * highlight a given string on a jquery object by wrapping it in
66 | * span elements with the given class name.
67 | */
68 | jQuery.fn.highlightText = function(text, className) {
69 | function highlight(node, addItems) {
70 | if (node.nodeType === 3) {
71 | var val = node.nodeValue;
72 | var pos = val.toLowerCase().indexOf(text);
73 | if (pos >= 0 &&
74 | !jQuery(node.parentNode).hasClass(className) &&
75 | !jQuery(node.parentNode).hasClass("nohighlight")) {
76 | var span;
77 | var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
78 | if (isInSVG) {
79 | span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
80 | } else {
81 | span = document.createElement("span");
82 | span.className = className;
83 | }
84 | span.appendChild(document.createTextNode(val.substr(pos, text.length)));
85 | node.parentNode.insertBefore(span, node.parentNode.insertBefore(
86 | document.createTextNode(val.substr(pos + text.length)),
87 | node.nextSibling));
88 | node.nodeValue = val.substr(0, pos);
89 | if (isInSVG) {
90 | var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
91 | var bbox = node.parentElement.getBBox();
92 | rect.x.baseVal.value = bbox.x;
93 | rect.y.baseVal.value = bbox.y;
94 | rect.width.baseVal.value = bbox.width;
95 | rect.height.baseVal.value = bbox.height;
96 | rect.setAttribute('class', className);
97 | addItems.push({
98 | "parent": node.parentNode,
99 | "target": rect});
100 | }
101 | }
102 | }
103 | else if (!jQuery(node).is("button, select, textarea")) {
104 | jQuery.each(node.childNodes, function() {
105 | highlight(this, addItems);
106 | });
107 | }
108 | }
109 | var addItems = [];
110 | var result = this.each(function() {
111 | highlight(this, addItems);
112 | });
113 | for (var i = 0; i < addItems.length; ++i) {
114 | jQuery(addItems[i].parent).before(addItems[i].target);
115 | }
116 | return result;
117 | };
118 |
119 | /*
120 | * backward compatibility for jQuery.browser
121 | * This will be supported until firefox bug is fixed.
122 | */
123 | if (!jQuery.browser) {
124 | jQuery.uaMatch = function(ua) {
125 | ua = ua.toLowerCase();
126 |
127 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
128 | /(webkit)[ \/]([\w.]+)/.exec(ua) ||
129 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
130 | /(msie) ([\w.]+)/.exec(ua) ||
131 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
132 | [];
133 |
134 | return {
135 | browser: match[ 1 ] || "",
136 | version: match[ 2 ] || "0"
137 | };
138 | };
139 | jQuery.browser = {};
140 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
141 | }
142 |
143 | /**
144 | * Small JavaScript module for the documentation.
145 | */
146 | var Documentation = {
147 |
148 | init : function() {
149 | this.fixFirefoxAnchorBug();
150 | this.highlightSearchWords();
151 | this.initIndexTable();
152 | if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
153 | this.initOnKeyListeners();
154 | }
155 | },
156 |
157 | /**
158 | * i18n support
159 | */
160 | TRANSLATIONS : {},
161 | PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
162 | LOCALE : 'unknown',
163 |
164 | // gettext and ngettext don't access this so that the functions
165 | // can safely bound to a different name (_ = Documentation.gettext)
166 | gettext : function(string) {
167 | var translated = Documentation.TRANSLATIONS[string];
168 | if (typeof translated === 'undefined')
169 | return string;
170 | return (typeof translated === 'string') ? translated : translated[0];
171 | },
172 |
173 | ngettext : function(singular, plural, n) {
174 | var translated = Documentation.TRANSLATIONS[singular];
175 | if (typeof translated === 'undefined')
176 | return (n == 1) ? singular : plural;
177 | return translated[Documentation.PLURALEXPR(n)];
178 | },
179 |
180 | addTranslations : function(catalog) {
181 | for (var key in catalog.messages)
182 | this.TRANSLATIONS[key] = catalog.messages[key];
183 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
184 | this.LOCALE = catalog.locale;
185 | },
186 |
187 | /**
188 | * add context elements like header anchor links
189 | */
190 | addContextElements : function() {
191 | $('div[id] > :header:first').each(function() {
192 | $('').
193 | attr('href', '#' + this.id).
194 | attr('title', _('Permalink to this headline')).
195 | appendTo(this);
196 | });
197 | $('dt[id]').each(function() {
198 | $('').
199 | attr('href', '#' + this.id).
200 | attr('title', _('Permalink to this definition')).
201 | appendTo(this);
202 | });
203 | },
204 |
205 | /**
206 | * workaround a firefox stupidity
207 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
208 | */
209 | fixFirefoxAnchorBug : function() {
210 | if (document.location.hash && $.browser.mozilla)
211 | window.setTimeout(function() {
212 | document.location.href += '';
213 | }, 10);
214 | },
215 |
216 | /**
217 | * highlight the search words provided in the url in the text
218 | */
219 | highlightSearchWords : function() {
220 | var params = $.getQueryParameters();
221 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
222 | if (terms.length) {
223 | var body = $('div.body');
224 | if (!body.length) {
225 | body = $('body');
226 | }
227 | window.setTimeout(function() {
228 | $.each(terms, function() {
229 | body.highlightText(this.toLowerCase(), 'highlighted');
230 | });
231 | }, 10);
232 | $('' + _('Hide Search Matches') + '
')
234 | .appendTo($('#searchbox'));
235 | }
236 | },
237 |
238 | /**
239 | * init the domain index toggle buttons
240 | */
241 | initIndexTable : function() {
242 | var togglers = $('img.toggler').click(function() {
243 | var src = $(this).attr('src');
244 | var idnum = $(this).attr('id').substr(7);
245 | $('tr.cg-' + idnum).toggle();
246 | if (src.substr(-9) === 'minus.png')
247 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
248 | else
249 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
250 | }).css('display', '');
251 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
252 | togglers.click();
253 | }
254 | },
255 |
256 | /**
257 | * helper function to hide the search marks again
258 | */
259 | hideSearchWords : function() {
260 | $('#searchbox .highlight-link').fadeOut(300);
261 | $('span.highlighted').removeClass('highlighted');
262 | },
263 |
264 | /**
265 | * make the url absolute
266 | */
267 | makeURL : function(relativeURL) {
268 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
269 | },
270 |
271 | /**
272 | * get the current relative url
273 | */
274 | getCurrentURL : function() {
275 | var path = document.location.pathname;
276 | var parts = path.split(/\//);
277 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
278 | if (this === '..')
279 | parts.pop();
280 | });
281 | var url = parts.join('/');
282 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
283 | },
284 |
285 | initOnKeyListeners: function() {
286 | $(document).keydown(function(event) {
287 | var activeElementType = document.activeElement.tagName;
288 | // don't navigate when in search box or textarea
289 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
290 | && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
291 | switch (event.keyCode) {
292 | case 37: // left
293 | var prevHref = $('link[rel="prev"]').prop('href');
294 | if (prevHref) {
295 | window.location.href = prevHref;
296 | return false;
297 | }
298 | case 39: // right
299 | var nextHref = $('link[rel="next"]').prop('href');
300 | if (nextHref) {
301 | window.location.href = nextHref;
302 | return false;
303 | }
304 | }
305 | }
306 | });
307 | }
308 | };
309 |
310 | // quick alias for translations
311 | _ = Documentation.gettext;
312 |
313 | $(document).ready(function() {
314 | Documentation.init();
315 | });
316 |
--------------------------------------------------------------------------------
/examples/CluSim Examples - valid Clustering.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "import clusim.clugen as clugen\n",
10 | "import clusim.sim as sim\n",
11 | "from clusim.clustering import Clustering, print_clustering"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 2,
17 | "metadata": {},
18 | "outputs": [
19 | {
20 | "name": "stdout",
21 | "output_type": "stream",
22 | "text": [
23 | "0134|256\n"
24 | ]
25 | }
26 | ],
27 | "source": [
28 | "# A clustering over 7 elements\n",
29 | "c1 = clugen.make_random_clustering(n_elements = 7, n_clusters = 2, random_model='num')\n",
30 | "print_clustering(c1)"
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": 3,
36 | "metadata": {},
37 | "outputs": [
38 | {
39 | "ename": "UnassignedElementError",
40 | "evalue": "There are 3 elements unassigned to a cluster.",
41 | "output_type": "error",
42 | "traceback": [
43 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
44 | "\u001b[0;31mUnassignedElementError\u001b[0m Traceback (most recent call last)",
45 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;31m# if we try to make a clustering, it raises an UnassignedElementError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mc2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mClustering\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_elm2clu_dict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0melm2clu_dict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
46 | "\u001b[0;32m~/Documents/clusim/clusim/clustering.py\u001b[0m in \u001b[0;36mfrom_elm2clu_dict\u001b[0;34m(self, elm2clu_dict)\u001b[0m\n\u001b[1;32m 141\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn_clusters\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclusters\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 142\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 143\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalidate_clustering\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 144\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 145\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclu_size_seq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfind_clu_size_seq\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
47 | "\u001b[0;32m~/Documents/clusim/clusim/clustering.py\u001b[0m in \u001b[0;36mvalidate_clustering\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 112\u001b[0m \u001b[0mn_unassigned_elm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcl\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0melm\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcl\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0melm2clu_dict\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 113\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn_unassigned_elm\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 114\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mUnassignedElementError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn_unassigned\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mn_unassigned_elm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 115\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 116\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
48 | "\u001b[0;31mUnassignedElementError\u001b[0m: There are 3 elements unassigned to a cluster."
49 | ]
50 | }
51 | ],
52 | "source": [
53 | "# now mimic an instance where the algorithm doesnt cluster all 10 elements\n",
54 | "elm2clu_dict = c1.to_elm2clu_dict()\n",
55 | "elm2clu_dict[7] = []\n",
56 | "elm2clu_dict[8] = []\n",
57 | "elm2clu_dict[9] = []\n",
58 | "\n",
59 | "# if we try to make a clustering, it raises an UnassignedElementError\n",
60 | "c2 = Clustering().from_elm2clu_dict(elm2clu_dict)"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": 5,
66 | "metadata": {},
67 | "outputs": [
68 | {
69 | "name": "stdout",
70 | "output_type": "stream",
71 | "text": [
72 | "0134|256|897\n",
73 | "0134|256|8|9|7\n"
74 | ]
75 | }
76 | ],
77 | "source": [
78 | "# we can fix that error by grouping all of the missing elements to a single cluster\n",
79 | "elm2clu_dict2 = clugen.cluster_missing_elements(list(range(10)), c1.to_elm2clu_dict(), new_cluster_type = 'giant')\n",
80 | "c2 = Clustering().from_elm2clu_dict(elm2clu_dict2)\n",
81 | "print_clustering(c2)\n",
82 | "\n",
83 | "# or we can fix that error by placing each of the missing elements into a singleton cluster\n",
84 | "elm2clu_dict3 = clugen.cluster_missing_elements(list(range(10)), c1.to_elm2clu_dict(), new_cluster_type = 'singleton')\n",
85 | "c3 = Clustering().from_elm2clu_dict(elm2clu_dict3)\n",
86 | "print_clustering(c3)"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": 6,
92 | "metadata": {},
93 | "outputs": [
94 | {
95 | "ename": "ClusteringSimilarityError",
96 | "evalue": "The element sets must be the same for both clusterings.",
97 | "output_type": "error",
98 | "traceback": [
99 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
100 | "\u001b[0;31mClusteringSimilarityError\u001b[0m Traceback (most recent call last)",
101 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# so trying to compare Clustering c1 to c3 will produce a\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0msim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrand_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
102 | "\u001b[0;32m~/Documents/clusim/clusim/sim.py\u001b[0m in \u001b[0;36mrand_index\u001b[0;34m(clustering1, clustering2)\u001b[0m\n\u001b[1;32m 230\u001b[0m \"\"\"\n\u001b[1;32m 231\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 232\u001b[0;31m \u001b[0mN11\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN01\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN00\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcount_pairwise_cooccurence\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclustering1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclustering2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 233\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 234\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mN11\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mN00\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mN11\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mN10\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mN01\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mN00\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
103 | "\u001b[0;32m~/Documents/clusim/clusim/sim.py\u001b[0m in \u001b[0;36mcount_pairwise_cooccurence\u001b[0;34m(clustering1, clustering2)\u001b[0m\n\u001b[1;32m 133\u001b[0m \"\"\"\n\u001b[1;32m 134\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 135\u001b[0;31m \u001b[0mcont_tbl\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcontingency_table\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclustering1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclustering2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 136\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 137\u001b[0m \u001b[0mT\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msquare\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcont_tbl\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
104 | "\u001b[0;32m~/Documents/clusim/clusim/sim.py\u001b[0m in \u001b[0;36mcontingency_table\u001b[0;34m(clustering1, clustering2)\u001b[0m\n\u001b[1;32m 72\u001b[0m \"\"\"\n\u001b[1;32m 73\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mclustering1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn_elements\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mclustering2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn_elements\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 74\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mClusteringSimilarityError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 75\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0me1\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0me2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0me1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me2\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclustering1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0melements\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclustering2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0melements\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
105 | "\u001b[0;31mClusteringSimilarityError\u001b[0m: The element sets must be the same for both clusterings."
106 | ]
107 | }
108 | ],
109 | "source": [
110 | "# Also note that all similarity comparisons must be between Clusterings with the same element sets\n",
111 | "\n",
112 | "# so trying to compare Clustering c1 to c3 will produce a ClusteringSimilarityError\n",
113 | "sim.rand_index(c1, c3)"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {},
120 | "outputs": [],
121 | "source": []
122 | }
123 | ],
124 | "metadata": {
125 | "kernelspec": {
126 | "display_name": "Python 3 (ipykernel)",
127 | "language": "python",
128 | "name": "python3"
129 | },
130 | "language_info": {
131 | "codemirror_mode": {
132 | "name": "ipython",
133 | "version": 3
134 | },
135 | "file_extension": ".py",
136 | "mimetype": "text/x-python",
137 | "name": "python",
138 | "nbconvert_exporter": "python",
139 | "pygments_lexer": "ipython3",
140 | "version": "3.10.12"
141 | }
142 | },
143 | "nbformat": 4,
144 | "nbformat_minor": 2
145 | }
146 |
--------------------------------------------------------------------------------
/docs/html/_static/underscore.js:
--------------------------------------------------------------------------------
1 | // Underscore.js 1.3.1
2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
3 | // Underscore is freely distributable under the MIT license.
4 | // Portions of Underscore are inspired or borrowed from Prototype,
5 | // Oliver Steele's Functional, and John Resig's Micro-Templating.
6 | // For all details and documentation:
7 | // http://documentcloud.github.com/underscore
8 | (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
10 | h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
11 | b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==
12 | null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
13 | function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
14 | e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
17 | c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};
24 | b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
25 | 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
26 | b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
27 | b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
28 | function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
29 | u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
30 | function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
31 | true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
32 |
--------------------------------------------------------------------------------
/docs/html/_static/language_data.js:
--------------------------------------------------------------------------------
1 | /*
2 | * language_data.js
3 | * ~~~~~~~~~~~~~~~~
4 | *
5 | * This script contains the language-specific data used by searchtools.js,
6 | * namely the list of stopwords, stemmer, scorer and splitter.
7 | *
8 | * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
9 | * :license: BSD, see LICENSE for details.
10 | *
11 | */
12 |
13 | var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
14 |
15 |
16 | /* Non-minified version JS is _stemmer.js if file is provided */
17 | /**
18 | * Porter Stemmer
19 | */
20 | var Stemmer = function() {
21 |
22 | var step2list = {
23 | ational: 'ate',
24 | tional: 'tion',
25 | enci: 'ence',
26 | anci: 'ance',
27 | izer: 'ize',
28 | bli: 'ble',
29 | alli: 'al',
30 | entli: 'ent',
31 | eli: 'e',
32 | ousli: 'ous',
33 | ization: 'ize',
34 | ation: 'ate',
35 | ator: 'ate',
36 | alism: 'al',
37 | iveness: 'ive',
38 | fulness: 'ful',
39 | ousness: 'ous',
40 | aliti: 'al',
41 | iviti: 'ive',
42 | biliti: 'ble',
43 | logi: 'log'
44 | };
45 |
46 | var step3list = {
47 | icate: 'ic',
48 | ative: '',
49 | alize: 'al',
50 | iciti: 'ic',
51 | ical: 'ic',
52 | ful: '',
53 | ness: ''
54 | };
55 |
56 | var c = "[^aeiou]"; // consonant
57 | var v = "[aeiouy]"; // vowel
58 | var C = c + "[^aeiouy]*"; // consonant sequence
59 | var V = v + "[aeiou]*"; // vowel sequence
60 |
61 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
62 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
63 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
64 | var s_v = "^(" + C + ")?" + v; // vowel in stem
65 |
66 | this.stemWord = function (w) {
67 | var stem;
68 | var suffix;
69 | var firstch;
70 | var origword = w;
71 |
72 | if (w.length < 3)
73 | return w;
74 |
75 | var re;
76 | var re2;
77 | var re3;
78 | var re4;
79 |
80 | firstch = w.substr(0,1);
81 | if (firstch == "y")
82 | w = firstch.toUpperCase() + w.substr(1);
83 |
84 | // Step 1a
85 | re = /^(.+?)(ss|i)es$/;
86 | re2 = /^(.+?)([^s])s$/;
87 |
88 | if (re.test(w))
89 | w = w.replace(re,"$1$2");
90 | else if (re2.test(w))
91 | w = w.replace(re2,"$1$2");
92 |
93 | // Step 1b
94 | re = /^(.+?)eed$/;
95 | re2 = /^(.+?)(ed|ing)$/;
96 | if (re.test(w)) {
97 | var fp = re.exec(w);
98 | re = new RegExp(mgr0);
99 | if (re.test(fp[1])) {
100 | re = /.$/;
101 | w = w.replace(re,"");
102 | }
103 | }
104 | else if (re2.test(w)) {
105 | var fp = re2.exec(w);
106 | stem = fp[1];
107 | re2 = new RegExp(s_v);
108 | if (re2.test(stem)) {
109 | w = stem;
110 | re2 = /(at|bl|iz)$/;
111 | re3 = new RegExp("([^aeiouylsz])\\1$");
112 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
113 | if (re2.test(w))
114 | w = w + "e";
115 | else if (re3.test(w)) {
116 | re = /.$/;
117 | w = w.replace(re,"");
118 | }
119 | else if (re4.test(w))
120 | w = w + "e";
121 | }
122 | }
123 |
124 | // Step 1c
125 | re = /^(.+?)y$/;
126 | if (re.test(w)) {
127 | var fp = re.exec(w);
128 | stem = fp[1];
129 | re = new RegExp(s_v);
130 | if (re.test(stem))
131 | w = stem + "i";
132 | }
133 |
134 | // Step 2
135 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
136 | if (re.test(w)) {
137 | var fp = re.exec(w);
138 | stem = fp[1];
139 | suffix = fp[2];
140 | re = new RegExp(mgr0);
141 | if (re.test(stem))
142 | w = stem + step2list[suffix];
143 | }
144 |
145 | // Step 3
146 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
147 | if (re.test(w)) {
148 | var fp = re.exec(w);
149 | stem = fp[1];
150 | suffix = fp[2];
151 | re = new RegExp(mgr0);
152 | if (re.test(stem))
153 | w = stem + step3list[suffix];
154 | }
155 |
156 | // Step 4
157 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
158 | re2 = /^(.+?)(s|t)(ion)$/;
159 | if (re.test(w)) {
160 | var fp = re.exec(w);
161 | stem = fp[1];
162 | re = new RegExp(mgr1);
163 | if (re.test(stem))
164 | w = stem;
165 | }
166 | else if (re2.test(w)) {
167 | var fp = re2.exec(w);
168 | stem = fp[1] + fp[2];
169 | re2 = new RegExp(mgr1);
170 | if (re2.test(stem))
171 | w = stem;
172 | }
173 |
174 | // Step 5
175 | re = /^(.+?)e$/;
176 | if (re.test(w)) {
177 | var fp = re.exec(w);
178 | stem = fp[1];
179 | re = new RegExp(mgr1);
180 | re2 = new RegExp(meq1);
181 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
182 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
183 | w = stem;
184 | }
185 | re = /ll$/;
186 | re2 = new RegExp(mgr1);
187 | if (re.test(w) && re2.test(w)) {
188 | re = /.$/;
189 | w = w.replace(re,"");
190 | }
191 |
192 | // and turn initial Y back to y
193 | if (firstch == "y")
194 | w = firstch.toLowerCase() + w.substr(1);
195 | return w;
196 | }
197 | }
198 |
199 |
200 |
201 |
202 |
203 | var splitChars = (function() {
204 | var result = {};
205 | var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
206 | 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
207 | 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
208 | 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
209 | 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
210 | 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
211 | 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
212 | 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
213 | 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
214 | 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
215 | var i, j, start, end;
216 | for (i = 0; i < singles.length; i++) {
217 | result[singles[i]] = true;
218 | }
219 | var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
220 | [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
221 | [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
222 | [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
223 | [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
224 | [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
225 | [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
226 | [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
227 | [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
228 | [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
229 | [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
230 | [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
231 | [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
232 | [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
233 | [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
234 | [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
235 | [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
236 | [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
237 | [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
238 | [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
239 | [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
240 | [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
241 | [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
242 | [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
243 | [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
244 | [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
245 | [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
246 | [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
247 | [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
248 | [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
249 | [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
250 | [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
251 | [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
252 | [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
253 | [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
254 | [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
255 | [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
256 | [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
257 | [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
258 | [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
259 | [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
260 | [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
261 | [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
262 | [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
263 | [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
264 | [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
265 | [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
266 | [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
267 | [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
268 | for (i = 0; i < ranges.length; i++) {
269 | start = ranges[i][0];
270 | end = ranges[i][1];
271 | for (j = start; j <= end; j++) {
272 | result[j] = true;
273 | }
274 | }
275 | return result;
276 | })();
277 |
278 | function splitQuery(query) {
279 | var result = [];
280 | var start = -1;
281 | for (var i = 0; i < query.length; i++) {
282 | if (splitChars[query.charCodeAt(i)]) {
283 | if (start !== -1) {
284 | result.push(query.slice(start, i));
285 | start = -1;
286 | }
287 | } else if (start === -1) {
288 | start = i;
289 | }
290 | }
291 | if (start !== -1) {
292 | result.push(query.slice(start));
293 | }
294 | return result;
295 | }
296 |
297 |
298 |
--------------------------------------------------------------------------------
/docs/html/_static/fonts/source-serif-pro/SourceSerifProReadMe.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Source Serif Pro Read Me
10 |
25 |
26 |
27 |
28 |
29 | Source Serif Pro Read Me
30 |
31 |
32 |
53 |
54 |
55 |
Minimum system requirements and font installation instructions
56 |
57 |
61 |
62 |
63 |
Font versions
64 |
65 |
66 |
To check that you have the correct font file, compare the font version of your font file to the font version provided in the Release Notes section below.
67 |
68 |
73 |
74 |
75 | History
76 |
Source Serif Pro is a serif typeface in the transitional style, designed to complement Source Sans. Their close companionship is achieved by a careful match of letter proportions and typographic color. While designed to harmonize with its serif-less counterpart, Source Serif often takes its own direction, in part because the two are inspired by different historical precedents. Source Serif is loosely based on the work of Pierre Simon Fournier, and many idiosyncrasies typical to Fournier’s designs (like the bottom serif on the b or the middle serif on the w) are also found in Source Serif. Without being a pure historical revival, Source Serif takes cues from the Fournier model and reworks it for a modern age.
Source Sans and Source Serif also have different personalities because they spring from the hands of different designers. Source Serif was designed by Frank Grießhammer, Source Sans was designed by Paul Hunt. Robert Slimbach consulted on both designs, which helped maintain the overall family harmony. Either design feels confident on its own but also works in combination with the other — just like their designers do.
Source Serif continues Adobe’s line of high-quality open source typefaces. Designed for a digital environment, the letter shapes are simplified and highly readable. Its historical roots, combined with the guidance through an experienced designer give the typeface a strong character of its own that will shine when used for extended text on paper or on screen.
There is still more to come for Source Serif. Additional weights, Italic cuts, and Cyrillic and Greek language support are all planned. If you are interested in contributing to this open source project, please visit this project page for information on how to become involved. Source Serif Pro can be adapted and redistributed according to the terms of the Open Font License (OFL) agreement.
77 |
78 | Menu Names And Style Linking
79 |
80 |
In many Windows® applications, instead of every font appearing on
81 | the menu, fonts are grouped into style-linked sets, and only the name of
82 | the base style font for a set is shown in the menu. The italic and the
83 | bold weight fonts of the set (if any) are not shown in the font menu, but can still be
84 | accessed by selecting the base style font, and then using the italic
85 | and bold style buttons. In this family, such programs will show only the
86 | following base style font names in the menu:
87 |
Source Serif Pro
88 | Source Serif Pro Black
89 | Source Serif Pro ExtraLight
90 | Source Serif Pro Light
91 | Source Serif Pro SemiBold
92 |
The other fonts in this family must be selected by choosing a menu name
93 | and then a style option following the guide below.
94 |
95 | Menu Name plus Style Option... selects this font
96 | Source Serif Pro [none] Source Serif Pro Regular
97 | Source Serif Pro Bold Source Serif Pro Bold
98 |
99 | Source Serif Pro Black [none] Source Serif Pro Black
100 |
101 | Source Serif Pro ExtraLight [none] Source Serif Pro ExtraLight
102 |
103 | Source Serif Pro Light [none] Source Serif Pro Light
104 |
105 | Source Serif Pro SemiBold [none] Source Serif Pro Semibold
106 |
107 |
108 |
On the Mac OS operating system, although each font appears as a separate entry on the
109 | font menu, users may also select fonts by means of style links.
110 | Selecting a base style font and then using the style links (as described
111 | above for Windows applications) enhances cross-platform document compatibility with
112 | many applications, such as Microsoft Word and Adobe® PageMaker® software,
113 | although it is unnecessary with more sophisticated Adobe applications
114 | such as recent versions of Illustrator® , Photoshop® or
115 | InDesign® software.
116 |
One should not, however, select a base font which has no style-linked
117 | variant, and then use the bold or italic styling button. Doing so will
118 | either have no effect, or result in programmatic bolding or slanting of
119 | the base font, which will usually produce inferior screen and print
120 | results.
121 |
122 |
127 |
For all fonts of family Source Serif Pro: version 1.017 created on Tue Sep 16 17:12:36 2014.
128 |
version 1.017 created 2014/09/16
129 |
130 | Added three more weights: Black, Light, ExtraLight.
131 | Added missing L/lcommaaccent (U+013B/C) to all fonts.
132 |
133 |
version 1.014 created 2014/04/27
134 |
135 | First release.
136 |
137 |
138 |
143 |
Some glyphs in the font cannot be accessed unless you are using an OpenType® compatible application.
144 |
145 |
146 |
151 |
166 |
171 |
172 |
173 | Adobe Type Showroom
174 |
175 | Index page for all family Read Me files
176 |
177 |
178 |
179 |
180 | Adobe, the Adobe Logo, Source, Illustrator, InDesign, PageMaker and Photoshop are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries. Windows and OpenType are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Mac, Mac OS and TrueType are trademarks of Apple Inc., registered in the U.S. and other countries. All other trademarks are the property of their respective owners.
181 |
182 |
183 | © 2014 Adobe Systems Incorporated. All rights reserved. created 2014 Sep 24
184 |
185 |
186 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/docs/html/_static/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.1.0 (http://getbootstrap.com)
3 | * Copyright 2011-2014 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */
6 |
7 | .btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:linear-gradient(to bottom, #fff 0, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top, #428bca 0, #2d6ca2 100%);background-image:linear-gradient(to bottom, #428bca 0, #2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:linear-gradient(to bottom, #5cb85c 0, #419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #eb9316 100%);background-image:linear-gradient(to bottom, #f0ad4e 0, #eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c12e2a 100%);background-image:linear-gradient(to bottom, #d9534f 0, #c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top, #fff 0, #f8f8f8 100%);background-image:linear-gradient(to bottom, #fff 0, #f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f3f3f3 100%);background-image:linear-gradient(to bottom, #ebebeb 0, #f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.075);box-shadow:inset 0 3px 9px rgba(0,0,0,0.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top, #3c3c3c 0, #222 100%);background-image:linear-gradient(to bottom, #3c3c3c 0, #222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #222 0, #282828 100%);background-image:linear-gradient(to bottom, #222 0, #282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.25);box-shadow:inset 0 3px 9px rgba(0,0,0,0.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);background-image:linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top, #d9edf7 0, #b9def0 100%);background-image:linear-gradient(to bottom, #d9edf7 0, #b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);background-image:linear-gradient(to bottom, #fcf8e3 0, #f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top, #f2dede 0, #e7c3c3 100%);background-image:linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);background-image:linear-gradient(to bottom, #ebebeb 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top, #428bca 0, #3071a9 100%);background-image:linear-gradient(to bottom, #428bca 0, #3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #449d44 100%);background-image:linear-gradient(to bottom, #5cb85c 0, #449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #31b0d5 100%);background-image:linear-gradient(to bottom, #5bc0de 0, #31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #ec971f 100%);background-image:linear-gradient(to bottom, #f0ad4e 0, #ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c9302c 100%);background-image:linear-gradient(to bottom, #d9534f 0, #c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top, #428bca 0, #3278b3 100%);background-image:linear-gradient(to bottom, #428bca 0, #3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);background-image:linear-gradient(to bottom, #dff0d8 0, #d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);background-image:linear-gradient(to bottom, #d9edf7 0, #c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);background-image:linear-gradient(to bottom, #fcf8e3 0, #faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top, #f2dede 0, #ebcccc 100%);background-image:linear-gradient(to bottom, #f2dede 0, #ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);background-image:linear-gradient(to bottom, #e8e8e8 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)}
--------------------------------------------------------------------------------