{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":94147,"databundleVersionId":11390004,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import h5py\nimport numpy as np\nimport cudf\nimport cupy as cp\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nfrom cuml.preprocessing import MinMaxScaler\nfrom cuml.ensemble import RandomForestRegressor\nfrom sklearn.multioutput import MultiOutputRegressor\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.model_selection import GridSearchCV, RandomizedSearchCV, KFold\nfrom sklearn.metrics import mean_squared_error\n\nclass CellTypeGPUPipeline:\n    \"\"\"\n    A GPU-based pipeline for cell type prediction using cuML's MinMaxScaler and \n    RandomForestRegressor (wrapped in MultiOutputRegressor). This class handles\n    loading data from an H5 file and preparing the training set.\n    \"\"\"\n    def __init__(self, h5_file_path):\n        self.h5_file_path = h5_file_path\n        self.train_spot_tables = {}\n        self.cell_type_columns = None\n\n    def load_train_data(self):\n        \"\"\"\n        Loads training spot data from the H5 file and converts each slide to a pandas DataFrame.\n        \"\"\"\n        with h5py.File(self.h5_file_path, \"r\") as f:\n            train_spots = f[\"spots/Train\"]\n            for slide_name in train_spots.keys():\n                spot_array = np.array(train_spots[slide_name])\n                df = pd.DataFrame(spot_array)\n                self.train_spot_tables[slide_name] = df\n        print(\"Training data loaded (GPU version) successfully.\")\n\n    def prepare_training_set(self, slide_id='S_1'):\n        \"\"\"\n        Prepares training features and targets from a given slide.\n        Assumes that the first two columns are 'x' and 'y' (coordinates) and the rest are continuous targets.\n        \"\"\"\n        if slide_id not in self.train_spot_tables:\n            raise ValueError(f\"Slide {slide_id} not found in training data.\")\n        df = self.train_spot_tables[slide_id]\n        feature_cols = ['x', 'y']\n        target_cols = [col for col in df.columns if col not in feature_cols]\n        self.cell_type_columns = target_cols\n        X = df[feature_cols].astype('float32')\n        y = df[target_cols].astype('float32')\n        return X, y\n\ndef load_test_data(h5_file_path, slide_id):\n    \"\"\"\n    Loads test data for a given slide and returns a pandas DataFrame.\n    \"\"\"\n    with h5py.File(h5_file_path, \"r\") as f:\n        test_spots = f[\"spots/Test\"]\n        if slide_id not in test_spots:\n            raise ValueError(f\"Slide {slide_id} not found in test data.\")\n        spot_array = np.array(test_spots[slide_id])\n        df = pd.DataFrame(spot_array)\n    print(f\"Test data for slide {slide_id} loaded successfully.\")\n    return df\n\ndef create_submission(test_df, predictions, submission_filename=\"submission.csv\", cell_type_columns=None):\n    \"\"\"\n    Creates a submission CSV file from the predictions.\n    \"\"\"\n    # Create a DataFrame with predictions and add an ID column.\n    pred_df = pd.DataFrame(predictions, columns=cell_type_columns, index=test_df.index)\n    pred_df.insert(0, 'ID', test_df.index)\n    pred_df.to_csv(submission_filename, index=False)\n    print(f\"Submission file '{submission_filename}' created!\")\n\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# --------------------------\n# Main grid/random search code\n# --------------------------\nif __name__ == \"__main__\":\n    # Specify the path to your dataset file.\n    h5_file_path = \"/kaggle/input/el-hackathon-2025/elucidata_ai_challenge_data.h5\"\n    \n    # Initialize and load training data using our pipeline object.\n    pipeline_obj = CellTypeGPUPipeline(h5_file_path)\n    pipeline_obj.load_train_data()\n    X_train, y_train = pipeline_obj.prepare_training_set(slide_id='S_1')\n    \n    # Convert training data to numpy arrays.\n    if hasattr(X_train, 'to_pandas'):\n        X_train_np = X_train.to_pandas().values\n    else:\n        X_train_np = X_train.values\n        \n    if hasattr(y_train, 'to_pandas'):\n        y_train_np = y_train.to_pandas().values\n    else:\n        y_train_np = y_train.values\n    \n    # Create a scikit-learn pipeline using cuML's MinMaxScaler and a multi-output RandomForest regressor.\n    pipe = Pipeline([\n        ('scaler', MinMaxScaler()),\n        ('model', MultiOutputRegressor(RandomForestRegressor(random_state=42)))\n    ])\n    \n    # Define a parameter grid for hyperparameter tuning.\n    param_grid = {\n        'model__estimator__n_estimators': [50, 100, 200],\n        'model__estimator__max_depth': [5, 10, 15],\n        'model__estimator__min_samples_split': [2, 5, 10]\n    }\n    \n    # Set up GridSearchCV using a 5-fold cross-validation.\n    grid_search = GridSearchCV(pipe, param_grid, cv=3, scoring='neg_mean_squared_error', verbose=2)\n    grid_search.fit(X_train_np, y_train_np)\n    best_params_grid = grid_search.best_params_\n    best_score_grid = -grid_search.best_score_\n    print(\"Best parameters from GridSearchCV:\", best_params_grid)\n    print(\"Best CV MSE from GridSearchCV:\", best_score_grid)\n    \n    # Set up RandomizedSearchCV as an alternative (n_iter=5).\n    random_search = RandomizedSearchCV(pipe, param_grid, cv=5, scoring='neg_mean_squared_error', \n                                         n_iter=5, random_state=42, verbose=2)\n    random_search.fit(X_train_np, y_train_np)\n    best_params_random = random_search.best_params_\n    best_score_random = -random_search.best_score_\n    print(\"Best parameters from RandomizedSearchCV:\", best_params_random)\n    print(\"Best CV MSE from RandomizedSearchCV:\", best_score_random)\n    \n    # Use the best estimator from grid search for final predictions.\n    best_model = grid_search.best_estimator_\n    \n    # Load test data.\n    test_df = load_test_data(h5_file_path, slide_id='S_7')\n    # Prepare test features: here we simply select 'x' and 'y' and convert to numpy.\n    X_test = test_df[['x', 'y']].astype('float32').values\n    \n    # Predict on test data using the best model.\n    predictions = best_model.predict(X_test)\n    \n    # Create the submission CSV file.\n    create_submission(test_df, predictions, submission_filename=\"submission.csv\", cell_type_columns=pipeline_obj.cell_type_columns)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}