nikos99n commited on
Commit
2607de5
·
1 Parent(s): 2d9d6c4

remove random state, matrix labels on specific rows

Browse files
models/X_train_sample.npy CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:dacc23f02577d428bb68c9f15def2373ee2dfac9ed3e55f4f328add123f54384
3
- size 11027608
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6c297b12b2ad73e2c32805b123ab456d0c57135c33469314cbb570588a653f1f
3
+ size 12393352
models/scaler.pkl CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:27ae467c5aa5c69269cb2c2524518b1985eda83b9bed02ebf0fd1ad16e61d8a2
3
  size 1487
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c7c5bd15219def3155b39a51b6627cf54d82b87acc63de2be03e7e3073793435
3
  size 1487
models/skin_cancer_model.pkl CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:7867c457b12b6d092ccadcb34d0c6c2921620b2416f6f1e53b925a0ad24d700c
3
- size 118655649
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e815f34d3e4a2538499199c8eb4529d3b8719263b736727ea1c992941c287dc8
3
+ size 135524049
src/data.py CHANGED
@@ -25,8 +25,7 @@ def balance_dataset(df):
25
  df_resampled = resample(
26
  class_subset,
27
  replace=True,
28
- n_samples=max_count,
29
- random_state=42
30
  )
31
  balanced_dfs.append(df_resampled)
32
 
@@ -34,7 +33,7 @@ def balance_dataset(df):
34
  df_balanced = pd.concat(balanced_dfs)
35
 
36
  # Shuffle the dataset so classes aren't grouped together
37
- df_balanced = df_balanced.sample(frac=1, random_state=42).reset_index(drop=True)
38
 
39
  print(f"Original size: {len(df)} -> Balanced size: {len(df_balanced)}")
40
  return df_balanced
@@ -62,7 +61,7 @@ def load_metadata(limit=None, balance=True):
62
  if limit:
63
  print(f"Subsampling to {limit}...")
64
  actual_limit = min(limit, len(df))
65
- df, _ = train_test_split(df, train_size=actual_limit, stratify=df['label_idx'], random_state=42)
66
 
67
  # Apply balancing (Upsampling)
68
  # if balance:
 
25
  df_resampled = resample(
26
  class_subset,
27
  replace=True,
28
+ n_samples=max_count
 
29
  )
30
  balanced_dfs.append(df_resampled)
31
 
 
33
  df_balanced = pd.concat(balanced_dfs)
34
 
35
  # Shuffle the dataset so classes aren't grouped together
36
+ df_balanced = df_balanced.sample(frac=1).reset_index(drop=True)
37
 
38
  print(f"Original size: {len(df)} -> Balanced size: {len(df_balanced)}")
39
  return df_balanced
 
61
  if limit:
62
  print(f"Subsampling to {limit}...")
63
  actual_limit = min(limit, len(df))
64
+ df, _ = train_test_split(df, train_size=actual_limit, stratify=df['label_idx'])
65
 
66
  # Apply balancing (Upsampling)
67
  # if balance:
src/explainability.py CHANGED
@@ -67,10 +67,22 @@ def generate_lime_explanations(model, X_train, X_test, y_test, feature_names, cl
67
  )
68
 
69
  # 4. Save Plot
70
- # We title it with the True Label for context
71
- true_label = class_names[y_test[i]]
72
- fig = exp.as_pyplot_figure()
73
- plt.title(f"LIME ({model_name}): Test Instance {i} | True Label: {true_label}")
 
 
 
 
 
 
 
 
 
 
 
 
74
  plt.tight_layout()
75
 
76
  save_path = os.path.join(output_dir, f'{model_name}_inst_{i}_lime.png')
 
67
  )
68
 
69
  # 4. Save Plot
70
+ # FIX: We must explicitly tell pyplot which label to plot.
71
+ # exp.local_exp keys are the class indices that were explained.
72
+ # Since we used top_labels=1, there is only one key.
73
+ available_labels = list(exp.local_exp.keys())
74
+ if not available_labels:
75
+ continue
76
+
77
+ explained_label_idx = available_labels[0]
78
+
79
+ # Get class name for title
80
+ pred_label_name = class_names[explained_label_idx]
81
+ true_label_name = class_names[y_test[i]]
82
+
83
+ # Pass the specific label we computed to avoid KeyError
84
+ fig = exp.as_pyplot_figure(label=explained_label_idx)
85
+ plt.title(f"LIME ({model_name}): Test Inst {i}\nTrue: {true_label_name} | Pred: {pred_label_name}")
86
  plt.tight_layout()
87
 
88
  save_path = os.path.join(output_dir, f'{model_name}_inst_{i}_lime.png')
src/model.py CHANGED
@@ -18,8 +18,8 @@ def train_and_evaluate_split(X_train, y_train, X_test, y_test, classes):
18
 
19
  # 1. Define Models
20
  techniques = {
21
- "RF": RandomForestClassifier(n_estimators=100, class_weight='balanced', random_state=42),
22
- "SVM": SVC(probability=True, class_weight='balanced', random_state=42)
23
  }
24
 
25
  best_score = 0
 
18
 
19
  # 1. Define Models
20
  techniques = {
21
+ "RF": RandomForestClassifier(n_estimators=100, class_weight='balanced'),
22
+ "SVM": SVC(probability=True, class_weight='balanced')
23
  }
24
 
25
  best_score = 0
src/plots.py CHANGED
@@ -10,23 +10,31 @@ from . import config
10
  def plot_confusion_matrix(y_true, y_pred, classes, model_name):
11
  """Generates and saves both Raw and Normalized confusion matrix heatmaps."""
12
 
13
- # 1. Calculate Raw Matrix
14
- cm = confusion_matrix(y_true, y_pred)
 
 
 
 
 
 
 
15
 
16
  # Plot Raw Counts
17
  plt.figure(figsize=(10, 8))
18
  sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
19
- xticklabels=classes, yticklabels=classes)
20
  plt.title(f"{model_name} Confusion Matrix (Counts)")
21
  plt.ylabel('True Label')
22
  plt.xlabel('Predicted Label')
 
23
  plt.tight_layout()
24
 
25
  filename = f"{model_name.lower()}_confusion_matrix.png"
26
  plt.savefig(os.path.join(config.MODEL_DIR, filename))
27
  plt.close()
28
 
29
- # 2. Calculate Normalized Matrix
30
  # Divide each row element by the sum of that row (True Label count)
31
  cm_norm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
32
  # Replace NaN with 0 (safe guard for empty classes)
@@ -36,10 +44,11 @@ def plot_confusion_matrix(y_true, y_pred, classes, model_name):
36
  plt.figure(figsize=(10, 8))
37
  # Use fmt='.2f' to show 2 decimal places (e.g., 0.95)
38
  sns.heatmap(cm_norm, annot=True, fmt='.2f', cmap='Greens',
39
- xticklabels=classes, yticklabels=classes)
40
  plt.title(f"{model_name} Confusion Matrix (Normalized)")
41
  plt.ylabel('True Label')
42
  plt.xlabel('Predicted Label')
 
43
  plt.tight_layout()
44
 
45
  filename_norm = f"{model_name.lower()}_confusion_matrix_normalized.png"
 
10
  def plot_confusion_matrix(y_true, y_pred, classes, model_name):
11
  """Generates and saves both Raw and Normalized confusion matrix heatmaps."""
12
 
13
+ # 1. Determine Alphabetical Order
14
+ # y_true/y_pred are indices (0, 1, 2...) mapping to the original 'classes' list.
15
+ # We want to display them in alphabetical order of the class names.
16
+ sorted_indices = np.argsort(classes)
17
+ sorted_classes = np.array(classes)[sorted_indices]
18
+
19
+ # 2. Calculate Raw Matrix
20
+ # passing 'labels=sorted_indices' forces the matrix rows/cols to follow the alphabetical order
21
+ cm = confusion_matrix(y_true, y_pred, labels=sorted_indices)
22
 
23
  # Plot Raw Counts
24
  plt.figure(figsize=(10, 8))
25
  sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
26
+ xticklabels=sorted_classes, yticklabels=sorted_classes)
27
  plt.title(f"{model_name} Confusion Matrix (Counts)")
28
  plt.ylabel('True Label')
29
  plt.xlabel('Predicted Label')
30
+ plt.xticks(rotation=45)
31
  plt.tight_layout()
32
 
33
  filename = f"{model_name.lower()}_confusion_matrix.png"
34
  plt.savefig(os.path.join(config.MODEL_DIR, filename))
35
  plt.close()
36
 
37
+ # 3. Calculate Normalized Matrix
38
  # Divide each row element by the sum of that row (True Label count)
39
  cm_norm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
40
  # Replace NaN with 0 (safe guard for empty classes)
 
44
  plt.figure(figsize=(10, 8))
45
  # Use fmt='.2f' to show 2 decimal places (e.g., 0.95)
46
  sns.heatmap(cm_norm, annot=True, fmt='.2f', cmap='Greens',
47
+ xticklabels=sorted_classes, yticklabels=sorted_classes)
48
  plt.title(f"{model_name} Confusion Matrix (Normalized)")
49
  plt.ylabel('True Label')
50
  plt.xlabel('Predicted Label')
51
+ plt.xticks(rotation=45)
52
  plt.tight_layout()
53
 
54
  filename_norm = f"{model_name.lower()}_confusion_matrix_normalized.png"
train_main.py CHANGED
@@ -68,7 +68,7 @@ def main():
68
 
69
  # Split DataFrame FIRST to avoid data leakage
70
  df_train, df_test = train_test_split(
71
- df, test_size=0.2, stratify=df['label_idx'], random_state=42
72
  )
73
 
74
  print(f"Training Samples (Files): {len(df_train)}")
 
68
 
69
  # Split DataFrame FIRST to avoid data leakage
70
  df_train, df_test = train_test_split(
71
+ df, test_size=0.1, stratify=df['label_idx']
72
  )
73
 
74
  print(f"Training Samples (Files): {len(df_train)}")