import pandas as pd import scipy.stats as stats import matplotlib.pyplot as plt import numpy as np import os def interpret_correlation(rho): abs_rho = abs(rho) if abs_rho < 0.20: return 'sangat lemah' elif abs_rho < 0.40: return 'lemah' elif abs_rho < 0.60: return 'sedang' elif abs_rho < 0.80: return 'kuat' else: return 'sangat kuat' def run_correlation_analysis(csv_path: str): df = pd.read_csv(csv_path) results = [] for layer in range(1, 13): col_name = f'Score L{layer}' # Dropna just in case valid_data = df.dropna(subset=[col_name, 'rating']) spearman_rho, spearman_p = stats.spearmanr(valid_data[col_name], valid_data['rating']) pearson_r, pearson_p = stats.pearsonr(valid_data[col_name], valid_data['rating']) interpretation = interpret_correlation(spearman_rho) results.append({ 'layer': col_name, 'spearman_rho': spearman_rho, 'spearman_p': spearman_p, 'pearson_r': pearson_r, 'pearson_p': pearson_p, 'interpretasi_spearman': interpretation }) df_results = pd.DataFrame(results) return df, df_results def plot_correlation_bar(df_corr): fig, ax = plt.subplots(figsize=(10, 6)) ax.bar(df_corr['layer'], df_corr['spearman_rho']) ax.set_title('Korelasi Spearman (rho) per Layer vs Rating Ustadz') ax.set_xlabel('Layer') ax.set_ylabel('Spearman rho') plt.xticks(rotation=45) fig.tight_layout() return fig def plot_scatter_best_layer(df, best_layer): fig, ax = plt.subplots(figsize=(8, 6)) valid_data = df.dropna(subset=[best_layer, 'rating']) x = valid_data[best_layer] y = valid_data['rating'] ax.scatter(x, y, alpha=0.5, label='Data points') # Linear regression line m, b = np.polyfit(x, y, 1) ax.plot(x, m*x + b, label=f'Trend line') ax.set_title(f'Scatter Plot: {best_layer} vs Rating Ustadz') ax.set_xlabel(f'Skor Sistem ({best_layer})') ax.set_ylabel('Rating Ustadz') ax.legend() fig.tight_layout() return fig def plot_heatmap(df_corr): fig, ax = plt.subplots(figsize=(10, 4)) # Create a simple heatmap data = df_corr[['spearman_rho', 'pearson_r']].values.T cax = ax.imshow(data, aspect='auto') # Add values for i in range(data.shape[0]): for j in range(data.shape[1]): ax.text(j, i, f'{data[i, j]:.2f}', ha='center', va='center', color='black') ax.set_yticks([0, 1]) ax.set_yticklabels(['Spearman rho', 'Pearson r']) ax.set_xticks(range(len(df_corr))) ax.set_xticklabels(df_corr['layer'], rotation=45) ax.set_title('Heatmap Korelasi') fig.colorbar(cax) fig.tight_layout() return fig def plot_pairing_diagram(df): # Get unique participants and files participants = df['ID_Peserta'].unique()[:1] files = df['ID_Frasa'].unique() # Sesuaikan ukuran agar tidak terlalu bertumpuk jika datanya banyak height = max(5, max(len(participants), len(files)) * 0.4) fig, ax = plt.subplots(figsize=(12, height)) # Positions x_peserta = 1 x_frasa = 2 x_ref = 3 # Draw nodes y_peserta = np.linspace(len(files), 1, len(files)) y_frasa = np.linspace(len(files), 1, len(files)) y_ref = np.linspace(len(files), 1, len(files)) # Peserta nodes ax.scatter([x_peserta]*len(files), y_peserta, s=200, zorder=2) if len(participants) > 0: p_name = participants[0] for i, f in enumerate(files): ax.annotate(f"Peserta {p_name} (Rekaman {i+1})", (x_peserta - 0.1, y_peserta[i]), ha='right', va='center', fontsize=10) # Frasa nodes ax.scatter([x_frasa]*len(files), y_frasa, s=200, zorder=2) for i, f in enumerate(files): # f is filename, format slightly for display e.g. "01.wav" -> "Frasa 1" frasa_label = f"Frasa {i+1}" ax.annotate(frasa_label, (x_frasa, y_frasa[i] + 0.15), ha='center', va='bottom', fontsize=10) # Referensi nodes ax.scatter([x_ref]*len(files), y_ref, s=200, zorder=2) for i, f in enumerate(files): ax.annotate(f"Referensi {i+1}", (x_ref + 0.1, y_ref[i]), ha='left', va='center', fontsize=10) # Draw lines for j, _ in enumerate(files): # Peserta to Frasa ax.plot([x_peserta, x_frasa], [y_peserta[j], y_frasa[j]], zorder=1, alpha=0.5) for j, _ in enumerate(files): # Frasa to Referensi ax.plot([x_frasa, x_ref], [y_frasa[j], y_ref[j]], zorder=1, alpha=0.5) peserta_name = participants[0] if len(participants) > 0 else "Peserta" ax.set_title(f"Ilustrasi Struktur Dataset Pasangan Frasa", fontsize=14) ax.set_xlim(0.5, 3.5) ax.set_ylim(0, len(files) + 1) ax.axis('off') fig.tight_layout() return fig