{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":87793,"databundleVersionId":12024591,"sourceType":"competition"}],"dockerImageVersionId":31011,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# ---------------------- Imports ----------------------\nimport pandas as pd\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler\nimport joblib\nimport xgboost as xgb\nfrom sklearn.metrics import mean_squared_error\nimport matplotlib.pyplot as plt\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n# ---------------------- Hyperparameters ----------------------\nWINDOW_SIZE = 31\nK_MER_SIZE = 3\nK_MER_COUNT = 16\nTEST_SIZE = 0.1\nRANDOM_STATE = 42\n\n# ---------------------- Load Data ----------------------\nlabels = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/train_labels.csv')\nsequences = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/train_sequences.csv').set_index(\"target_id\")[\"sequence\"]\n\nlabels[[\"target_id\", \"residue_index\"]] = labels[\"ID\"].str.rsplit(\"_\", n=1, expand=True)\nlabels[\"residue_index\"] = labels[\"residue_index\"].astype(int)\nlabels[\"sequence\"] = labels[\"target_id\"].map(sequences)\nlabels.dropna(subset=[\"sequence\", \"x_1\", \"y_1\", \"z_1\"], inplace=True)\n\n# ---------------------- Feature Engineering ----------------------\nnt_map = {'A': 0, 'C': 1, 'G': 2, 'U': 3}\npad_char = 'N'\n\ndef one_hot_encode(seq, center_idx, window):\n    pad = pad_char * window\n    padded = pad + seq + pad\n    center = center_idx + window\n    window_seq = padded[center - window:center + window + 1]\n    vec = np.zeros((len(window_seq), 4), dtype=np.float32)\n    for i, nt in enumerate(window_seq):\n        if nt in nt_map:\n            vec[i, nt_map[nt]] = 1.0\n    return vec\n\ndef get_kmer_features(seq, k):\n    kmers = {}\n    for i in range(len(seq) - k + 1):\n        kmer = seq[i:i+k]\n        kmers[kmer] = kmers.get(kmer, 0) + 1\n    return kmers\n\ndef create_kmer_vector(seq, top_kmers, k):\n    kmer_counts = get_kmer_features(seq, k)\n    vector = np.zeros(len(top_kmers), dtype=np.float32)\n    for i, kmer in enumerate(top_kmers):\n        vector[i] = kmer_counts.get(kmer, 0)\n    return vector\n\n# Generate top k-mers\nall_train_sequences = sequences.values.tolist()\nall_kmers = {}\nfor seq in all_train_sequences:\n    kmers = get_kmer_features(seq, K_MER_SIZE)\n    for kmer, count in kmers.items():\n        all_kmers[kmer] = all_kmers.get(kmer, 0) + count\ntop_kmers = sorted(all_kmers, key=all_kmers.get, reverse=True)[:K_MER_COUNT]\n\n# Save top k-mers\ntop_kmers_path = \"/kaggle/working/top_kmers.pkl\"\njoblib.dump(top_kmers, top_kmers_path)\nprint(f\"Top k-mers saved to {top_kmers_path}\")\n\nX_sequence = np.stack([\n    one_hot_encode(row.sequence, row.residue_index - 1, WINDOW_SIZE)\n    for _, row in labels.iterrows()\n])\n\nX_kmer = np.stack([\n    create_kmer_vector(row.sequence, top_kmers, K_MER_SIZE)\n    for _, row in labels.iterrows()\n])\n\n# Combine sequence and k-mer features\nX = np.concatenate((X_sequence, np.repeat(X_kmer[:, np.newaxis, :], X_sequence.shape[1], axis=1)), axis=2)\n\ntarget_columns = [\"x_1\", \"y_1\", \"z_1\"]\nY = labels[target_columns].values.astype(np.float32)\n\n# ---------------------- Train/Validation Split ----------------------\nX_train, X_val, y_train, y_val = train_test_split(X, Y, test_size=TEST_SIZE, random_state=RANDOM_STATE)\n\n# ---------------------- Target Scaling ----------------------\nscaler_y = StandardScaler()\ny_train_scaled = scaler_y.fit_transform(y_train)\ny_val_scaled = scaler_y.transform(y_val)\n\n# ---------------------- Train XGBoost Regressor ----------------------\nprint(\"Training XGBoost Regressor...\")\nxgbr = xgb.XGBRegressor(\n    objective='reg:squarederror',\n    n_estimators=100, # Tune this\n    learning_rate=0.1, # Tune this\n    max_depth=5,       # Tune this\n    random_state=RANDOM_STATE\n)\n\nxgbr.fit(X_train.reshape(X_train.shape[0], -1), y_train_scaled) # Flatten the input features\n\n# ---------------------- Evaluate XGBoost Model ----------------------\ny_pred_val_scaled = xgbr.predict(X_val.reshape(X_val.shape[0], -1))\ny_pred_val = scaler_y.inverse_transform(y_pred_val_scaled)\n\nrmse = np.sqrt(mean_squared_error(y_val, y_pred_val))\nprint(f\"XGBoost Validation RMSE: {rmse:.4f}\")\n\n# ---------------------- Visualization of Predictions ----------------------\nimport matplotlib.pyplot as plt\n\nplt.figure(figsize=(10, 6))\nplt.scatter(y_val[:, 0], y_pred_val[:, 0], alpha=0.5)\nplt.xlabel(\"Actual x_1\")\nplt.ylabel(\"Predicted x_1\")\nplt.title(\"Actual vs. Predicted x_1 (XGBoost on Validation Set)\")\nplt.grid(True)\nplt.show()\n\nplt.figure(figsize=(10, 6))\nplt.scatter(y_val[:, 1], y_pred_val[:, 1], alpha=0.5)\nplt.xlabel(\"Actual y_1\")\nplt.ylabel(\"Predicted y_1\")\nplt.title(\"Actual vs. Predicted y_1 (XGBoost on Validation Set)\")\nplt.grid(True)\nplt.show()\n\nplt.figure(figsize=(10, 6))\nplt.scatter(y_val[:, 2], y_pred_val[:, 2], alpha=0.5)\nplt.xlabel(\"Actual z_1\")\nplt.ylabel(\"Predicted z_1\")\nplt.title(\"Actual vs. Predicted z_1 (XGBoost on Validation Set)\")\nplt.grid(True)\nplt.show()\n\n# ---------------------- Save Trained XGBoost Model and Scaler ----------------------\nmodel_path = \"/kaggle/working/xgboost_rna_folding_model.joblib\"\nscaler_path = \"/kaggle/working/xgboost_scaler_y.joblib\"\njoblib.dump(xgbr, model_path)\njoblib.dump(scaler_y, scaler_path)\nprint(f\"Trained XGBoost model saved to {model_path}\")\nprint(f\"Target scaler saved to {scaler_path}\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-01T12:00:15.405171Z","iopub.execute_input":"2025-05-01T12:00:15.405368Z","iopub.status.idle":"2025-05-01T12:02:16.108559Z","shell.execute_reply.started":"2025-05-01T12:00:15.405351Z","shell.execute_reply":"2025-05-01T12:02:16.107788Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ---------------------- Imports ----------------------\nimport pandas as pd\nimport numpy as np\nimport joblib\nimport xgboost as xgb\n\n# ---------------------- Hyperparameters (Must match Notebook 1) ----------------------\nWINDOW_SIZE = 31\nK_MER_SIZE = 3\nK_MER_COUNT = 16\n\n# ---------------------- One-Hot Encoding (Same as Notebook 1) ----------------------\nnt_map = {'A': 0, 'C': 1, 'G': 2, 'U': 3}\npad_char = 'N'\n\ndef one_hot_encode(seq, center_idx, window):\n    pad = pad_char * window\n    padded = pad + seq + pad\n    center = center_idx + window\n    window_seq = padded[center - window:center + window + 1]\n    vec = np.zeros((len(window_seq), 4), dtype=np.float32)\n    for i, nt in enumerate(window_seq):\n        if nt in nt_map:\n            vec[i, nt_map[nt]] = 1.0\n    return vec\n\n# ---------------------- K-mer Feature Creation (Same as Notebook 1) ----------------------\ndef get_kmer_features(seq, k):\n    kmers = {}\n    for i in range(len(seq) - k + 1):\n        kmer = seq[i:i+k]\n        kmers[kmer] = kmers.get(kmer, 0) + 1\n    return kmers\n\ndef create_kmer_vector(seq, top_kmers, k):\n    kmer_counts = get_kmer_features(seq, k)\n    vector = np.zeros(len(top_kmers), dtype=np.float32)\n    for i, kmer in enumerate(top_kmers):\n        vector[i] = kmer_counts.get(kmer, 0)\n    return vector\n\n# Load the top k-mers saved from Notebook 1\ntop_kmers_path = \"/kaggle/working/top_kmers.pkl\"\ntry:\n    top_kmers = joblib.load(top_kmers_path)\n    print(f\"Loaded top k-mers from {top_kmers_path}\")\nexcept FileNotFoundError:\n    print(f\"Error: {top_kmers_path} not found. Make sure Notebook 1 was run and the file was saved to /kaggle/working/.\")\n    raise\n\n# ---------------------- Load Test Data ----------------------\ntest_sequences = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/test_sequences.csv').set_index(\"target_id\")[\"sequence\"]\nsample_sub = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/sample_submission.csv')\n\nsample_sub[[\"target_id\", \"residue_index\"]] = sample_sub.ID.str.rsplit(\"_\", n=1, expand=True)\nsample_sub[\"residue_index\"] = sample_sub[\"residue_index\"].astype(int)\nsample_sub[\"sequence\"] = sample_sub[\"target_id\"].map(test_sequences)\n\n# ---------------------- Prepare Test Features ----------------------\nX_test_sequence = np.stack([\n    one_hot_encode(row.sequence, row.residue_index - 1, WINDOW_SIZE)\n    for _, row in sample_sub.iterrows()\n])\n\nX_test_kmer = np.stack([\n    create_kmer_vector(row.sequence, top_kmers, K_MER_SIZE)\n    for _, row in sample_sub.iterrows()\n])\n\nX_test = np.concatenate((X_test_sequence, np.repeat(X_test_kmer[:, np.newaxis, :], X_test_sequence.shape[1], axis=1)), axis=2)\n\n# ---------------------- Load Trained XGBoost Model and Scaler ----------------------\nmodel_path = \"/kaggle/working/xgboost_rna_folding_model.joblib\"\nscaler_path = \"/kaggle/working/xgboost_scaler_y.joblib\"\ntry:\n    xgbr_loaded = joblib.load(model_path)\n    scaler_y_loaded = joblib.load(scaler_path)\n    print(f\"Loaded XGBoost model from {model_path}\")\n    print(f\"Loaded target scaler from {scaler_path}\")\nexcept FileNotFoundError:\n    print(f\"Error: Could not find model or scaler in /kaggle/working/. Make sure Notebook 1 was run successfully.\")\n    raise\n\n# ---------------------- Predict with XGBoost ----------------------\nprint(\"Predicting with XGBoost...\")\nX_test_flattened = X_test.reshape(X_test.shape[0], -1)\ny_pred_test_scaled = xgbr_loaded.predict(X_test_flattened)\ny_pred_test = scaler_y_loaded.inverse_transform(y_pred_test_scaled)\n\n# ---------------------- Create Submission ----------------------\npredictions_df = pd.DataFrame(y_pred_test, columns=[\"x_1\", \"y_1\", \"z_1\"])\n\nfor i in range(2, 6):\n    predictions_df[[f\"x_{i}\", f\"y_{i}\", f\"z_{i}\"]] = predictions_df[[\"x_1\", \"y_1\", \"z_1\"]].values\n\nsubmission_df = pd.concat([sample_sub[[\"ID\"]], predictions_df], axis=1)\n\nsubmission_df.to_csv(\"submission.csv\", index=False)\nprint(\"submission.csv created with shape:\", submission_df.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-01T12:02:16.109323Z","iopub.execute_input":"2025-05-01T12:02:16.110117Z","iopub.status.idle":"2025-05-01T12:02:16.657130Z","shell.execute_reply.started":"2025-05-01T12:02:16.110098Z","shell.execute_reply":"2025-05-01T12:02:16.656515Z"}},"outputs":[],"execution_count":null}]}