sklearn-docs/optics_clustering
0
1# Scikit learn example https://scikit-learn.org/stable/auto_examples/cluster/plot_optics.html2 3import gradio as gr4 5from sklearn.cluster import OPTICS, cluster_optics_dbscan6import matplotlib.gridspec as gridspec7import matplotlib.pyplot as plt8import numpy as np9 10plt.switch_backend("agg")11 12# Theme from - https://huggingface.co/spaces/trl-lib/stack-llama/blob/main/app.py13theme = gr.themes.Monochrome(14 primary_hue="indigo",15 secondary_hue="blue",16 neutral_hue="slate",17 radius_size=gr.themes.sizes.radius_sm,18 font=[19 gr.themes.GoogleFont("Open Sans"),20 "ui-sans-serif",21 "system-ui",22 "sans-serif",23 ],24)25 26 27def do_submit(n_points_per_cluster, min_samples, xi, min_cluster_size):28 # # Generate sample data29 np.random.seed(0)30 n_points_per_cluster = int(n_points_per_cluster)31 32 C1 = [-5, -2] + 0.8 * np.random.randn(n_points_per_cluster, 2)33 C2 = [4, -1] + 0.1 * np.random.randn(n_points_per_cluster, 2)34 C3 = [1, -2] + 0.2 * np.random.randn(n_points_per_cluster, 2)35 C4 = [-2, 3] + 0.3 * np.random.randn(n_points_per_cluster, 2)36 C5 = [3, -2] + 1.6 * np.random.randn(n_points_per_cluster, 2)37 C6 = [5, 6] + 2 * np.random.randn(n_points_per_cluster, 2)38 X = np.vstack((C1, C2, C3, C4, C5, C6))39 40 clust = OPTICS(41 min_samples=int(min_samples),42 xi=float(xi),43 min_cluster_size=float(min_cluster_size),44 )45 46 # Run the fit47 clust.fit(X)48 49 labels_050 = cluster_optics_dbscan(50 reachability=clust.reachability_,51 core_distances=clust.core_distances_,52 ordering=clust.ordering_,53 eps=0.5,54 )55 labels_200 = cluster_optics_dbscan(56 reachability=clust.reachability_,57 core_distances=clust.core_distances_,58 ordering=clust.ordering_,59 eps=2,60 )61 62 space = np.arange(len(X))63 reachability = clust.reachability_[clust.ordering_]64 labels = clust.labels_[clust.ordering_]65 66 plt.figure(figsize=(10, 6))67 G = gridspec.GridSpec(2, 3)68 ax1 = plt.subplot(G[0, :])69 ax2 = plt.subplot(G[1, 0])70 ax3 = plt.subplot(G[1, 1])71 ax4 = plt.subplot(G[1, 2])72 73 # Reachability plot74 colors = ["g.", "r.", "b.", "y.", "c."]75 for klass, color in zip(range(0, 5), colors):76 Xk = space[labels == klass]77 Rk = reachability[labels == klass]78 ax1.plot(Xk, Rk, color, alpha=0.3)79 ax1.plot(space[labels == -1], reachability[labels == -1], "k.", alpha=0.3)80 ax1.plot(space, np.full_like(space, 2.0, dtype=float), "k-", alpha=0.5)81 ax1.plot(space, np.full_like(space, 0.5, dtype=float), "k-.", alpha=0.5)82 ax1.set_ylabel("Reachability (epsilon distance)")83 ax1.set_title("Reachability Plot")84 85 # OPTICS86 colors = ["g.", "r.", "b.", "y.", "c."]87 for klass, color in zip(range(0, 5), colors):88 Xk = X[clust.labels_ == klass]89 ax2.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3)90 ax2.plot(X[clust.labels_ == -1, 0], X[clust.labels_ == -1, 1], "k+", alpha=0.1)91 ax2.set_title("Automatic Clustering\nOPTICS")92 93 # DBSCAN at 0.594 colors = ["g.", "r.", "b.", "c."]95 for klass, color in zip(range(0, 4), colors):96 Xk = X[labels_050 == klass]97 ax3.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3)98 ax3.plot(X[labels_050 == -1, 0], X[labels_050 == -1, 1], "k+", alpha=0.1)99 ax3.set_title("Clustering at 0.5 epsilon cut\nDBSCAN")100 101 # DBSCAN at 2.102 colors = ["g.", "m.", "y.", "c."]103 for klass, color in zip(range(0, 4), colors):104 Xk = X[labels_200 == klass]105 ax4.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3)106 ax4.plot(X[labels_200 == -1, 0], X[labels_200 == -1, 1], "k+", alpha=0.1)107 ax4.set_title("Clustering at 2.0 epsilon cut\nDBSCAN")108 109 plt.tight_layout()110 111 return plt112 113 114title = "Demo of OPTICS clustering algorithm"115with gr.Blocks(title=title, theme=theme) as demo:116 gr.Markdown(f"## {title}")117 gr.Markdown(118 "[Scikit-learn Example](https://scikit-learn.org/stable/auto_examples/cluster/plot_optics.html)"119 )120 121 gr.Markdown(122 "Finds core samples of high density and expands clusters from them. This example uses data that is \123 generated so that the clusters have different densities. The [OPTICS](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.OPTICS.html#sklearn.cluster.OPTICS) is first used with its Xi cluster detection \124 method, and then setting specific thresholds on the reachability, which corresponds to [DBSCAN](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN). We can see that \125 the different clusters of OPTICS’s Xi method can be recovered with different choices of thresholds in DBSCAN."126 )127 128 with gr.Row().style(equal_height=True):129 with gr.Column(scale=0.75):130 n_points_per_cluster = gr.Slider(131 minimum=200,132 maximum=500,133 label="Number of points per cluster",134 step=50,135 value=250,136 )137 with gr.Row(visible=False):138 gr.Markdown("##")139 140 min_samples = gr.Slider(141 minimum=10,142 maximum=100,143 label="OPTICS - Minimum number of samples",144 step=5,145 value=50,146 info="The number of samples in a neighborhood for a point to be considered as a core point.",147 )148 with gr.Row(visible=False):149 gr.Markdown("##")150 151 xi = gr.Slider(152 minimum=0,153 maximum=0.2,154 label="OPTICS - Xi",155 step=0.01,156 value=0.05,157 info="Determines the minimum steepness on the reachability plot that constitutes a cluster boundary. ",158 )159 with gr.Row(visible=False):160 gr.Markdown("##")161 min_cluster_size = gr.Slider(162 minimum=0.01,163 maximum=0.1,164 label="OPTICS - Minimum cluster size",165 step=0.01,166 value=0.05,167 info="Minimum number of samples in an OPTICS cluster, expressed as an absolute number or a fraction of the number of samples (rounded to be at least 2).",168 )169 170 plt_out = gr.Plot()171 172 n_points_per_cluster.change(173 do_submit,174 inputs=[n_points_per_cluster, min_samples, xi, min_cluster_size],175 outputs=plt_out,176 )177 min_samples.change(178 do_submit,179 inputs=[n_points_per_cluster, min_samples, xi, min_cluster_size],180 outputs=plt_out,181 )182 xi.change(183 do_submit,184 inputs=[n_points_per_cluster, min_samples, xi, min_cluster_size],185 outputs=plt_out,186 )187 min_cluster_size.change(188 do_submit,189 inputs=[n_points_per_cluster, min_samples, xi, min_cluster_size],190 outputs=plt_out,191 )192 193 194 195if __name__ == "__main__":196 demo.launch()197 198 