Spencer525/IndSensor
0
1import streamlit as st2import pandas as pd3import numpy as np4from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering5from sklearn.metrics import silhouette_score6from sklearn.preprocessing import StandardScaler7from statsmodels.tsa.arima.model import ARIMA8import plotly.express as px9import plotly.graph_objects as go10 11# Streamlit app title12st.title('Clustering and Time Series Analysis')13 14# Step 1: Upload CSV file15uploaded_file = st.file_uploader("Upload a CSV file", type=["csv"])16 17if uploaded_file is not None:18 data = pd.read_csv(uploaded_file)19 st.write("Dataset Preview:", data.head())20 21 # Step 2: Data Preprocessing22 # Selecting only numerical columns for clustering23 numerical_cols = data.select_dtypes(include=[np.number]).columns.tolist()24 st.write("Numerical columns for clustering:", numerical_cols)25 26 # Step 2.1: Data Standardization using StandardScaler (always applied)27 scaler = StandardScaler()28 data_scaled = scaler.fit_transform(data[numerical_cols])29 st.write("Data has been standardized using StandardScaler.")30 31 # Step 3: Clustering Algorithm Selection32 clustering_method = st.selectbox("Choose a clustering method", ["K-Means", "Hierarchical Clustering", "DBSCAN"])33 34 if clustering_method == "K-Means":35 k_range = st.slider("Select number of clusters for K-Means", min_value=2, max_value=7, value=3)36 kmeans = KMeans(n_clusters=k_range, random_state=42)37 cluster_labels = kmeans.fit_predict(data_scaled)38 silhouette_avg = silhouette_score(data_scaled, cluster_labels)39 st.write(f"K-Means Silhouette Score for {k_range} clusters: {silhouette_avg}")40 41 elif clustering_method == "Hierarchical Clustering":42 k_range = st.slider("Select number of clusters for Hierarchical Clustering", min_value=2, max_value=7, value=3)43 hierarchical = AgglomerativeClustering(n_clusters=k_range)44 cluster_labels = hierarchical.fit_predict(data_scaled)45 silhouette_avg = silhouette_score(data_scaled, cluster_labels)46 st.write(f"Hierarchical Clustering Silhouette Score for {k_range} clusters: {silhouette_avg}")47 48 elif clustering_method == "DBSCAN":49 eps_value = st.slider("Select eps value for DBSCAN", min_value=0.1, max_value=2.0, value=0.5)50 min_samples_value = st.slider("Select minimum samples for DBSCAN", min_value=1, max_value=10, value=5)51 dbscan = DBSCAN(eps=eps_value, min_samples=min_samples_value)52 cluster_labels = dbscan.fit_predict(data_scaled)53 54 # Check if DBSCAN found valid clusters55 if len(set(cluster_labels)) > 1:56 silhouette_avg = silhouette_score(data_scaled, cluster_labels)57 st.write(f"DBSCAN Silhouette Score: {silhouette_avg}")58 else:59 st.write("DBSCAN did not form valid clusters. Try adjusting eps or min_samples.")60 61 # Step 4: Visualize the clusters using Plotly62 if len(set(cluster_labels)) > 1:63 st.write("Cluster Labels:", np.unique(cluster_labels))64 65 # Create Plotly scatter plot66 fig = px.scatter(x=data_scaled[:, 0], y=data_scaled[:, 1], color=cluster_labels, title="Clustering Results", 67 labels={'x': numerical_cols[0], 'y': numerical_cols[1]})68 69 # Update y-axis range to be from -1 to 1 with 0.2 intervals70 fig.update_layout(71 yaxis=dict(range=[-1, 1], dtick=0.2),72 xaxis_title=numerical_cols[0],73 yaxis_title=numerical_cols[1]74 )75 76 st.plotly_chart(fig)77 78 # Step 5: ARIMA Time Series Analysis79 # Checking if there are any time-related columns80 time_series_col = None81 for col in data.columns:82 if pd.api.types.is_datetime64_any_dtype(data[col]):83 time_series_col = col84 break85 86 if time_series_col:87 st.write("Time Series Analysis (ARIMA) on column:", time_series_col)88 time_series_data = data[time_series_col].dropna()89 90 # ARIMA model order91 p = st.number_input("ARIMA p value", min_value=0, max_value=5, value=1)92 d = st.number_input("ARIMA d value", min_value=0, max_value=2, value=1)93 q = st.number_input("ARIMA q value", min_value=0, max_value=5, value=1)94 95 arima_model = ARIMA(time_series_data, order=(p, d, q))96 arima_result = arima_model.fit()97 98 # Display ARIMA result summary99 st.write(arima_result.summary())100 101 # Plotting the ARIMA results102 fig = go.Figure()103 arima_result.plot_predict(dynamic=False, ax=fig.add_subplot(1, 1, 1))104 st.plotly_chart(fig)105 106 # Step 6: Create Silhouette Score Table for K-Means and Hierarchical Clustering107 st.write("### Silhouette Score Table for 2-7 Clusters")108 silhouette_scores = {'Number of Clusters': [], 'K-Means Silhouette Score': [], 'Hierarchical Silhouette Score': []}109 110 for n_clusters in range(2, 8):111 # K-Means112 kmeans = KMeans(n_clusters=n_clusters, random_state=42)113 kmeans_labels = kmeans.fit_predict(data_scaled)114 kmeans_silhouette = silhouette_score(data_scaled, kmeans_labels)115 116 # Hierarchical117 hierarchical = AgglomerativeClustering(n_clusters=n_clusters)118 hierarchical_labels = hierarchical.fit_predict(data_scaled)119 hierarchical_silhouette = silhouette_score(data_scaled, hierarchical_labels)120 121 silhouette_scores['Number of Clusters'].append(n_clusters)122 silhouette_scores['K-Means Silhouette Score'].append(kmeans_silhouette)123 silhouette_scores['Hierarchical Silhouette Score'].append(hierarchical_silhouette)124 125 silhouette_df = pd.DataFrame(silhouette_scores)126 127 # Plot the Silhouette Score Table using Plotly128 fig = go.Figure()129 130 # Plot K-Means Silhouette Scores131 fig.add_trace(go.Scatter(x=silhouette_df['Number of Clusters'], y=silhouette_df['K-Means Silhouette Score'],132 mode='lines+markers', name='K-Means Silhouette Score'))133 134 # Plot Hierarchical Silhouette Scores135 fig.add_trace(go.Scatter(x=silhouette_df['Number of Clusters'], y=silhouette_df['Hierarchical Silhouette Score'],136 mode='lines+markers', name='Hierarchical Silhouette Score'))137 138 # Set the y-axis range from -1 to 1 with intervals of 0.2139 fig.update_layout(140 title="Silhouette Scores for K-Means and Hierarchical Clustering",141 xaxis_title="Number of Clusters",142 yaxis_title="Silhouette Score",143 yaxis=dict(range=[-1, 1], dtick=0.2)144 )145 146 st.plotly_chart(fig)147 