Modify the code below to use PCA to preprocess the input features:

import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from argparse import ArgumentParser

from analysis_utils import batch_data
from config import *


def participant_based_cross_validation(df, n_folds=5, random_state=42):
    """
    Performs participant-based k-fold cross-validation.

    Args:
        df (pd.DataFrame): The input DataFrame with a 'participant' column.
        n_folds (int): The number of folds for cross-validation.
        random_state (int): Random seed for shuffling participants.

    Returns:
        list: A list of tuples, where each tuple contains (train_df, test_df) for each fold.
    """
    participants = df['participant'].unique()
    np.random.seed(random_state)
    np.random.shuffle(participants)

    fold_size = len(participants) // n_folds
    remainder = len(participants) % n_folds
    folds = []
    start = 0
    for i in range(n_folds):
        end = start + fold_size + (1 if i < remainder else 0)
        test_participants = participants[start:end]
        train_participants = np.concatenate([participants[:start], participants[end:]])

        train_df = df[df['participant'].isin(train_participants)].copy()
        test_df = df[df['participant'].isin(test_participants)].copy()

        folds.append((train_df, test_df))
        start = end
    return folds


if __name__ == "__main__":

    with open('data.csv', 'r', encoding='utf-8') as f:
        df = pd.read_csv(f)
    df = df[df['action'] != 'Pick']

    input_features = []
    input_features += ['is_last_resolved'] 
    input_features += ['is_level_decreased']
    input_features += ['last_pos_speech_cnt', 'last_neg_speech_cnt']
    # input_features += ['has_crossed_arms', 'has_arms_back']
    # input_features += ['task_gaze_ratio', 'robot_gaze_ratio']
    for emotion in EMOTIONS:
        input_features.append(f'{emotion}_mean_change')

    # input_features = SELECTED_FEATURES

    target = 'is_resolved'

    # Split the data into training and testing sets based on participants
    participants = df['participant'].unique()
    train_participants, test_participants = train_test_split(
        participants, test_size=0.2, random_state=42, shuffle=True
    )
    train_df = df[df['participant'].isin(train_participants)].copy()
    test_df = df[df['participant'].isin(test_participants)].copy()
    # Reset the index of the DataFrames
    train_df.reset_index(drop=True, inplace=True)
    test_df.reset_index(drop=True, inplace=True)

    print(len(train_participants), len(test_participants))

    # Create the input features and target variable
    X_train = train_df[input_features]
    Y_train = train_df[target]
    X_test = test_df[input_features]
    Y_test = test_df[target]

    # Initialize the logistic regression model with scaling
    model = make_pipeline(StandardScaler(), 
                        LogisticRegression(random_state=42, penalty='l1', solver='liblinear'))
    model.fit(X_train, Y_train)

    Y_pred = model.predict(X_test)
    Y_pred_proba = model.predict_proba(X_test)

    accuracy = accuracy_score(Y_test, Y_pred)
    f1 = f1_score(Y_test, Y_pred)

    print(f"Accuracy: {accuracy:.4f}")
    print(f"F1 Score: {f1:.4f}")


    importance = model.named_steps['logisticregression'].coef_[0]
    
    importance_dict = dict(zip(input_features, importance))
    importance_dict = sorted(importance_dict.items(), key=lambda x: abs(x[1]), reverse=True)
    print("\nFeature Importance:")
    for feature, importance in importance_dict:
        print(f"{feature}: {importance:.4f}")

    print(len(train_df), len(test_df))