OMG-01/RG-SC_RobustGammaSpectralClustering
1
1import gradio as gr2import pandas as pd3import numpy as np4import matplotlib.pyplot as plt5import matplotlib.cm as cm6from sklearn.preprocessing import StandardScaler7from sklearn.decomposition import PCA8from mpl_toolkits.mplot3d import Axes3D9 10# 別ファイルからRG-SCアルゴリズムのコアロジックをインポート11from rg_sc import run_rgsc12 13def process_and_cluster(file_obj, k_nn, max_k):14 """15 アップロードされたCSVファイルを処理し、クラスタリングを実行し、16 結果のファイルと、データの次元数に応じた最適なプロットを返すGradioのメイン関数。17 """18 if file_obj is None:19 raise gr.Error("No file uploaded. Please upload a CSV file.")20 21 try:22 # アップロードされたファイルをDataFrameとして読み込む23 df = pd.read_csv(file_obj.name)24 except Exception as e:25 raise gr.Error(f"Failed to read the file: {e}")26 27 # ---- カラム名の問題を解決するロジック ----28 # DataFrameから数値型のカラムのみを自動で選択する。29 df_numeric = df.select_dtypes(include=np.number)30 31 if df_numeric.empty:32 raise gr.Error("No numerical columns found in the CSV file. Please provide a file with at least two numerical columns.")33 if df_numeric.shape[1] < 2:34 raise gr.Error("Clustering visualization requires at least 2 numerical columns.")35 36 print(f"Found {df_numeric.shape[1]} numerical columns for clustering: {list(df_numeric.columns)}")37 38 # データをNumpy配列に変換し、標準化39 X = df_numeric.values40 X_scaled = StandardScaler().fit_transform(X)41 42 # RG-SCアルゴリズムを実行43 labels, _, estimated_k = run_rgsc(X_scaled, int(k_nn), int(max_k))44 45 # ---- 結果のファイルを作成 ----46 df_result = df.copy()47 df_result['cluster_label'] = labels48 result_csv_path = "/tmp/clustered_result.csv"49 df_result.to_csv(result_csv_path, index=False)50 51 # ---- 結果のプロットを作成 (次元数に応じて分岐) ----52 n_features = X.shape[1]53 fig = plt.figure(figsize=(9, 9))54 55 # --- カラーマップとラベルの設定 ---56 unique_labels = sorted(list(set(labels)))57 n_clusters = len(unique_labels)58 colors = cm.get_cmap('nipy_spectral', n_clusters) if n_clusters > 1 else cm.get_cmap('gray')59 60 # --- プロットロジック ---61 if n_features == 2:62 # ** 2次元の場合: 2D散布図 **63 ax = fig.add_subplot(111)64 for k_idx, k in enumerate(unique_labels):65 mask = (labels == k)66 color_val = k_idx / (n_clusters - 1 if n_clusters > 1 else 1)67 ax.scatter(X[mask, 0], X[mask, 1], 68 color=colors(color_val),69 label=f'Cluster {k}', s=50, alpha=0.8, edgecolors='k')70 ax.set_xlabel(df_numeric.columns[0])71 ax.set_ylabel(df_numeric.columns[1])72 ax.set_title(f"2D Clustering Result (k={estimated_k})", fontsize=16)73 74 elif n_features == 3:75 # ** 3次元の場合: 3D散布図 **76 ax = fig.add_subplot(111, projection='3d')77 for k_idx, k in enumerate(unique_labels):78 mask = (labels == k)79 color_val = k_idx / (n_clusters - 1 if n_clusters > 1 else 1)80 ax.scatter(X[mask, 0], X[mask, 1], X[mask, 2],81 color=colors(color_val),82 label=f'Cluster {k}', s=50, alpha=0.8, edgecolors='k')83 ax.set_xlabel(df_numeric.columns[0])84 ax.set_ylabel(df_numeric.columns[1])85 ax.set_zlabel(df_numeric.columns[2])86 ax.set_title(f"3D Clustering Result (k={estimated_k})", fontsize=16)87 ax.view_init(elev=20., azim=45) # 見やすい角度に調整88 89 else: # n_features > 390 # ** 4次元以上の場合: PCAによる次元削減プロット **91 ax = fig.add_subplot(111)92 # PCAで2次元に削減93 pca = PCA(n_components=2)94 X_pca = pca.fit_transform(X_scaled)95 96 for k_idx, k in enumerate(unique_labels):97 mask = (labels == k)98 color_val = k_idx / (n_clusters - 1 if n_clusters > 1 else 1)99 ax.scatter(X_pca[mask, 0], X_pca[mask, 1],100 color=colors(color_val),101 label=f'Cluster {k}', s=50, alpha=0.8, edgecolors='k')102 103 explained_variance = pca.explained_variance_ratio_.sum() * 100104 ax.set_xlabel("Principal Component 1")105 ax.set_ylabel("Principal Component 2")106 title = (f"PCA Visualization of {n_features}D Data (k={estimated_k})\n"107 f"Explained Variance: {explained_variance:.2f}%")108 ax.set_title(title, fontsize=14)109 110 ax.grid(True)111 if n_clusters > 0:112 ax.legend()113 114 plot_path = "/tmp/clustering_plot.png"115 plt.savefig(plot_path)116 plt.close(fig)117 118 return result_csv_path, plot_path119 120 121# ---- Gradioインターフェースの構築 ----122with gr.Blocks(theme=gr.themes.Soft()) as demo:123 gr.Markdown("# RG-SC: Self-Tuning Robust Spectral Clustering")124 125 # Tabインターフェースを作成126 with gr.Tabs():127 # --- メインのクラスタリング用タブ ---128 with gr.TabItem("Clustering Tool"):129 gr.Markdown(130 "Upload a CSV file. The RG-SC algorithm will automatically detect all **numerical columns** "131 "to perform clustering, estimate the optimal number of clusters, and group the data."132 )133 with gr.Row():134 with gr.Column(scale=1):135 file_input = gr.File(label="Upload CSV File")136 137 with gr.Accordion("Advanced Settings (Optional)", open=False):138 k_nn_slider = gr.Slider(5, 30, value=10, step=1, label="k-NN", 139 info="Number of neighbors for graph construction. Larger values consider more global structure.")140 max_k_slider = gr.Slider(5, 15, value=10, step=1, label="Max Clusters", 141 info="The maximum number of clusters to search for.")142 143 submit_button = gr.Button("Run Clustering", variant="primary")144 145 with gr.Column(scale=2):146 gr.Markdown("### Results")147 plot_output = gr.Image(label="Clustering Result Plot")148 file_output = gr.File(label="Download Labeled Data")149 150 submit_button.click(151 fn=process_and_cluster,152 inputs=[file_input, k_nn_slider, max_k_slider],153 outputs=[file_output, plot_output]154 )155 156 # サンプルファイルをリポジトリに含めることが前提157 gr.Examples(158 examples=[159 "easy_unlabeled.csv",160 "medium_unlabeled.csv",161 "hard_unlabeled.csv"162 ],163 inputs=[file_input],164 label="Example Datasets (if uploaded to the Space)"165 )166 167 # --- アルゴリズム解説用のタブ ---168 with gr.TabItem("Algorithm Explanation"):169 gr.Markdown("""170 ## The RG-SC Algorithm: A Deep Dive171 172 **RG-SC (Robust, Gamma, Spectral Clustering)** is a sophisticated unsupervised learning algorithm designed to uncover hidden structures in data, even in complex scenarios where traditional methods fail.173 174 ### Core Philosophy: "Connectivity over Proximity"175 176 Unlike K-Means, which relies on distance to a center point, RG-SC is based on **Spectral Clustering**. It transforms the data into a **graph (network)**, where data points are nodes and the connections (edges) between them represent their "similarity" or "connectivity". This allows it to identify clusters of any shape, such as crescents or concentric circles.177 178 ---179 180 ### The 5 Key Steps181 182 #### **Step 1: Intelligent Graph Construction**183 - We build a **Mutual k-NN Graph**. An edge is created between point A and B only if both points consider each other a "close friend". This robust method filters out noise and weak connections, revealing the true skeleton of the data structure.184 - It also features a **Self-Tuning Gamma**, which automatically adjusts the sensitivity of similarity calculations based on the data's density. This ensures high performance across different datasets without manual tuning.185 186 #### **Step 2: Mathematical Representation (Graph Laplacian)**187 - The graph's structure is converted into a special matrix called the **Normalized Graph Laplacian (`L`)**. This matrix mathematically encodes all the connectivity information of the graph.188 189 #### **Step 3: Optimal k-Estimation via Eigen-analysis**190 - We analyze the spectrum of the Laplacian matrix by performing **eigendecomposition**. The **eigenvalues** represent its "cleavability".191 - The algorithm automatically finds the most natural number of clusters, `k`, by detecting the largest **eigengap**—a sharp jump in the sequence of sorted eigenvalues. This indicates the most stable point to partition the graph.192 193 #### **Step 4: Transformation to a Simpler Space (Feature Space)**194 - The `k` eigenvectors corresponding to the smallest eigenvalues are used as a new set of coordinate axes.195 - The original data is projected into this new **feature space**. In this space, complex, intertwined clusters from the original space become simple, well-separated groups.196 197 #### **Step 5: Final Classification**198 - Now that the problem has been drastically simplified, a fast and simple algorithm like **K-Means** is applied to the transformed data in the feature space to assign the final cluster labels.199 200 ---201 202 This multi-step process makes RG-SC a powerful and versatile tool, capable of handling complex shapes, non-uniform densities, and automatically determining the optimal number of clusters.203 """)204 205# Gradioアプリケーションを起動するための定型句206if __name__ == "__main__":207 demo.launch()