Tao-Lab-Breast-Cancer / code / grid_search.py
grid_search.py
Raw
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, GridSearchCV, cross_val_predict
from sklearn.metrics import roc_auc_score, accuracy_score, confusion_matrix
from tqdm import tqdm

# Load the dataset
# LAB
file_path = '/Users/rachitbisht/Desktop/research/data/BC_Machine_Learning/datasets/LAB_30.xlsx'

# TN
#file_path = '/Users/rachitbisht/Desktop/research/data/BC_Machine_Learning/datasets/TN_30.xlsx'

data = pd.read_excel(file_path)

def perform_grid_search(data, comparison_groups, target_group, feature_names):
    # Adjust binary labeling: '1' for target group (LAB), '0' for comparison groups (TN, Control)
    data['Binary_Label'] = data['Type'].apply(lambda x: 1 if x == target_group else 0 if x in comparison_groups else None)
    
    # Filter data to include only the relevant groups and features
    data_filtered = data[data['Type'].isin(comparison_groups + [target_group])].copy()
    
    # Use only the selected features
    X = data_filtered[feature_names]
    y = data_filtered['Binary_Label']
    
    # Initialize the Random Forest classifier with class_weight='balanced'
    rf_clf = RandomForestClassifier(random_state=42, class_weight='balanced')
    
    param_grid = {
        'n_estimators': [300, 350, 400, 450, 500],
        'min_samples_split': [2, 3, 4],               
        'min_samples_leaf': [1, 2, 3, 4],              
        'max_features': ['sqrt', 'log2'],         
        'bootstrap': [True],                      
        'max_depth': [4, 12, 20, None]            
    }

    # Setup stratified cross-validation
    cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
    
    # Perform grid search with cross-validation
    grid_search = GridSearchCV(estimator=rf_clf, param_grid=param_grid, cv=cv, scoring='roc_auc', n_jobs=-1, return_train_score=False)
    grid_search.fit(X, y)

    # Extract results into a pandas DataFrame
    results = pd.DataFrame(grid_search.cv_results_)
    
    # Add accuracy, AUC scores, FPR, and False Positives for each combination with a progress bar
    all_results = []
    total_combinations = len(grid_search.cv_results_['params'])
    
    for idx, (params, mean_test_score) in enumerate(tqdm(zip(grid_search.cv_results_['params'], grid_search.cv_results_['mean_test_score']), total=total_combinations, desc="Grid Search Progress")):
        # Train the model for each parameter set
        best_rf_clf = RandomForestClassifier(random_state=42, class_weight='balanced', **params)
        best_rf_clf.fit(X, y)
        
        # Get cross-validated predictions for accuracy
        y_pred = cross_val_predict(best_rf_clf, X, y, cv=cv)
        accuracy = accuracy_score(y, y_pred)
        
        # Calculate the confusion matrix
        cm = confusion_matrix(y, y_pred)
        
        # Extract TN, FP, FN, TP from confusion matrix
        tn, fp, fn, tp = cm.ravel()
        
        # Compute False Positive Rate (FPR)
        fpr = fp / (fp + tn)
        
        # Store the result, including false positives for TN
        all_results.append({
            'params': params,
            'AUC Score': mean_test_score,
            'Accuracy': accuracy,
            'FPR (TN)': fpr,  # Minimizing this to optimize for TN
            'False Positives (TN)': fp  # Number of false positives for TN
        })
    
    # Convert the list of results to a DataFrame
    df_results = pd.DataFrame(all_results)
    
    # Save the DataFrame to an Excel file
    output_file = 'grid_search_results_with_fpr_and_fp_for_lab.xlsx'
    df_results.to_excel(output_file, index=False)

    print(f"Results saved to {output_file}")

    return df_results

# List of selected features without numeric suffixes

#TN features 
# selected_features = [
#     "Q06187|BTK_Phospho_STGDPQGVIR_1",
#     "Q06187|BTK_Phospho_STGDPQGVIR_2",
#     "Q99501|GA2L1_Phospho_VSPTTSPRPASPVPGSER_2",
#     "Q9Y3Q8|T22D4_Phospho_SPDPFGAVAAQK",
#     "P78324|SHPS1_Glyco_GTANLSETIR",
#     "P01133|EGF_Glyco_VFLNGSR",
#     "Q6WCQ1|MPRIP_Phospho_SNPDFLK"
# ]

#LAB features 
selected_features = [
    "Q14517|FAT1_Glyco_TGALTVQNTTQLR",
    "O95772|STR3N_Phospho_LLIVQDASER",
    "P50851|LRBA_Phospho_SPVDIVTGGISPVR",
    "Q15942|ZYX_Phospho_SPGAPGPLTLK",
    "O75326|SEM7A_Glyco_NPEAPLNVSR",
    "P01137|TGFB1_Glyco_YSNNSWR",
    "Q6WCQ1|MPRIP_Phospho_SNPDFLK"
]

# Perform the grid search for LAB vs TN and Control using the specified features
df_results = perform_grid_search(data, ['TN', 'Control'], 'LAB', selected_features)