{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":84896,"databundleVersionId":10305135,"sourceType":"competition"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Setup The Project ","metadata":{}},{"cell_type":"code","source":"%load_ext cudf.pandas","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T10:02:05.99097Z","iopub.execute_input":"2025-01-01T10:02:05.991237Z","iopub.status.idle":"2025-01-01T10:02:11.344806Z","shell.execute_reply.started":"2025-01-01T10:02:05.99121Z","shell.execute_reply":"2025-01-01T10:02:11.344096Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib as plt\nimport seaborn as sns\nimport optuna\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import mean_squared_error, mean_squared_log_error\nfrom sklearn.preprocessing import PowerTransformer, QuantileTransformer, LabelEncoder\nfrom catboost import CatBoostRegressor, Pool\nimport xgboost as xgb\nimport warnings\nimport logging\nfrom datetime import datetime, timedelta\nimport gc\nfrom tqdm.notebook import tqdm\n\nwarnings.filterwarnings('ignore')\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nRANDOM_STATE = 42\nnp.random.seed(RANDOM_STATE)\n\nprint(\"Setup completed successfully\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-02-24T20:02:32.320372Z","iopub.execute_input":"2025-02-24T20:02:32.320608Z","iopub.status.idle":"2025-02-24T20:02:34.061384Z","shell.execute_reply.started":"2025-02-24T20:02:32.320582Z","shell.execute_reply":"2025-02-24T20:02:34.060541Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Collecting Data","metadata":{}},{"cell_type":"code","source":"print(\"Loading data...\")\ntrain_df = pd.read_csv('../input/playground-series-s4e12/train.csv', index_col='id')\ntest_df = pd.read_csv('../input/playground-series-s4e12/test.csv', index_col='id')\nsubmission_df = pd.read_csv('../input/playground-series-s4e12/sample_submission.csv')\nprint(\"Data loaded successfully!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:04.830682Z","iopub.execute_input":"2025-01-01T04:03:04.831318Z","iopub.status.idle":"2025-01-01T04:03:13.19243Z","shell.execute_reply.started":"2025-01-01T04:03:04.831277Z","shell.execute_reply":"2025-01-01T04:03:13.191521Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Exploratory Data Analysis (EDA)","metadata":{}},{"cell_type":"markdown","source":"### Basic Information","metadata":{}},{"cell_type":"code","source":"print(\"\\n1. Basic Information:\")\nprint(\"-\" * 50)\nprint(\"\\nDataset Shape:\", train_df.shape)\nprint(\"\\nFeature Types:\")\nprint(train_df.dtypes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.19368Z","iopub.execute_input":"2025-01-01T04:03:13.194356Z","iopub.status.idle":"2025-01-01T04:03:13.198453Z","shell.execute_reply.started":"2025-01-01T04:03:13.194312Z","shell.execute_reply":"2025-01-01T04:03:13.197381Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Missing Values Analysis","metadata":{}},{"cell_type":"code","source":"print(\"\\n2. Missing Values Analysis:\")\nprint(\"-\" * 50)\nmissing = train_df.isnull().sum()\nmissing_pct = (missing / len(train_df)) * 100\nmissing_info = pd.DataFrame({\n    'Missing Values': missing,\n    'Percentage': missing_pct\n})\n\nprint(missing_info[missing_info['Missing Values'] > 0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.200197Z","iopub.execute_input":"2025-01-01T04:03:13.200544Z","iopub.status.idle":"2025-01-01T04:03:13.210629Z","shell.execute_reply.started":"2025-01-01T04:03:13.200515Z","shell.execute_reply":"2025-01-01T04:03:13.209796Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Numerical Features Analysis","metadata":{}},{"cell_type":"code","source":"print(\"\\n3. Numerical Features Analysis:\")\nprint(\"-\" * 50)\nnumeric_cols = train_df.select_dtypes(include=['int64', 'float64']).columns\nnumeric_summary = train_df[numeric_cols].describe()\nprint(numeric_summary)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.211832Z","iopub.execute_input":"2025-01-01T04:03:13.212201Z","iopub.status.idle":"2025-01-01T04:03:13.218525Z","shell.execute_reply.started":"2025-01-01T04:03:13.212163Z","shell.execute_reply":"2025-01-01T04:03:13.217786Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Categorical Features Analysis","metadata":{}},{"cell_type":"code","source":"print(\"\\n4. Categorical Features Analysis:\")\nprint(\"-\" * 50)\ncategorical_cols = train_df.select_dtypes(include=['object']).columns\nfor col in categorical_cols:\n    print(f\"\\nUnique values in {col}:\", train_df[col].nunique())\n    print(\"\\nTop 5 categories:\")\n    print(train_df[col].value_counts().head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.21958Z","iopub.execute_input":"2025-01-01T04:03:13.219808Z","iopub.status.idle":"2025-01-01T04:03:13.229755Z","shell.execute_reply.started":"2025-01-01T04:03:13.219785Z","shell.execute_reply":"2025-01-01T04:03:13.22893Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Visualizations","metadata":{}},{"cell_type":"code","source":"# Distribution plots for numerical features\nplt.figure(figsize=(15, 5 * ((len(numeric_cols) + 2) // 3)))\nfor i, col in enumerate(numeric_cols, 1):\n    plt.subplot((len(numeric_cols) + 2) // 3, 3, i)\n    sns.histplot(train_df[col], kde=True)\n    plt.title(f'Distribution of {col}')\n    plt.xticks(rotation=45)\nplt.tight_layout()\nplt.show()\n\nfor i, col in enumerate(numeric_cols, 1):\n    plt.subplot((len(numeric_cols) + 2) // 3, 3, i)\n    sns.boxplot(y=df[col])\n    plt.title(f'Box Plot of {col}')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.230749Z","iopub.execute_input":"2025-01-01T04:03:13.230956Z","iopub.status.idle":"2025-01-01T04:03:13.238952Z","shell.execute_reply.started":"2025-01-01T04:03:13.230935Z","shell.execute_reply":"2025-01-01T04:03:13.23829Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Correlation analysis\nplt.figure(figsize=(12, 8))\ncorrelation_matrix = train_df[numeric_cols].corr()\nsns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)\nplt.title('Correlation Matrix of Numerical Features')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.239799Z","iopub.execute_input":"2025-01-01T04:03:13.240087Z","iopub.status.idle":"2025-01-01T04:03:13.246441Z","shell.execute_reply.started":"2025-01-01T04:03:13.240061Z","shell.execute_reply":"2025-01-01T04:03:13.245593Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(15, 5 * ((len(numeric_cols) + 2) // 3)))\nfor i, col in enumerate(numeric_cols, 1):\n    plt.subplot((len(numeric_cols) + 2) // 3, 3, i)\n    sns.boxplot(y=train_df[col])\n    plt.title(f'Box Plot of {col}')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.247525Z","iopub.execute_input":"2025-01-01T04:03:13.247846Z","iopub.status.idle":"2025-01-01T04:03:13.254617Z","shell.execute_reply.started":"2025-01-01T04:03:13.24782Z","shell.execute_reply":"2025-01-01T04:03:13.253865Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Target variable analysis\ntarget_col = 'Premium Amount'\n\nif target_col in train_df.columns:\n    plt.figure(figsize=(12, 5))\n\n    # Target distribution\n    plt.subplot(1, 2, 1)\n    sns.histplot(train_df[target_col], kde=True)\n    plt.title('Distribution of Premium Amount')\n\n    # Log-transformed target distribution\n    plt.subplot(1, 2, 2)\n    sns.histplot(np.log1p(train_df[target_col]), kde=True)\n    plt.title('Distribution of Log-transformed Premium Amount')\n\n    plt.tight_layout()\n    plt.show()\n\n    # Relationship between target and numerical features\n    plt.figure(figsize=(15, 5 * ((len(numeric_cols) - 1 + 2) // 3)))\n    for i, col in enumerate([c for c in numeric_cols if c != target_col], 1):\n        plt.subplot((len(numeric_cols) - 1 + 2) // 3, 3, i)\n        plt.scatter(train_df[col], train_df[target_col], alpha=0.5)\n        plt.xlabel(col)\n        plt.ylabel(target_col)\n        plt.title(f'{col} vs {target_col}')\n    plt.tight_layout()\n    plt.show()\n\nmonitor.checkpoint(\"EDA Complete\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.257139Z","iopub.execute_input":"2025-01-01T04:03:13.257467Z","iopub.status.idle":"2025-01-01T04:03:13.262575Z","shell.execute_reply.started":"2025-01-01T04:03:13.257442Z","shell.execute_reply":"2025-01-01T04:03:13.261878Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Feature Engineering","metadata":{}},{"cell_type":"code","source":"class FeatureEngineering:\n    \"\"\"GPU-accelerated feature engineering with systematic feature selection\"\"\"\n    \n    def __init__(self, n_folds=5, random_state=42):\n        self.n_folds = n_folds\n        self.random_state = random_state\n        self.best_combinations = []\n        \n    def _create_datetime_features(self, df):\n        \"\"\"Create datetime features using GPU acceleration\"\"\"\n        df = df.copy()\n        df[\"Policy Start Date\"] = pd.to_datetime(df[\"Policy Start Date\"])\n        df[\"year\"] = df[\"Policy Start Date\"].dt.year.astype(\"float32\")\n        df[\"month\"] = df[\"Policy Start Date\"].dt.month.astype(\"float32\")\n        df[\"day\"] = df[\"Policy Start Date\"].dt.day.astype(\"float32\")\n        df[\"dow\"] = df[\"Policy Start Date\"].dt.dayofweek.astype(\"float32\")\n        df[\"seconds\"] = (df[\"Policy Start Date\"].astype(\"int64\") // 10**9).astype(\"float32\")\n        return df\n    \n    def _prepare_data(self, train, test):\n        \"\"\"Prepare and combine data for feature engineering\"\"\"\n        # Combine train and test\n        train = self._create_datetime_features(train)\n        test = self._create_datetime_features(test)\n        \n        # Create target\n        train['y'] = np.log1p(train['Premium Amount'])\n        \n        # Remove unnecessary columns\n        remove_cols = [\"id\", \"Policy Start Date\", \"Premium Amount\", \"y\"]\n        features = [c for c in train.columns if c not in remove_cols]\n        \n        # Combine datasets\n        combined = pd.concat([train, test], axis=0, ignore_index=True)\n        \n        # Handle categorical features\n        cats = []\n        high_cardinality = []\n        \n        for c in features:\n            if combined[c].dtype == \"object\":\n                cats.append(c)\n                combined[c] = combined[c].fillna(\"NAN\")\n                combined[c], _ = combined[c].factorize()\n                combined[c] -= combined[c].min()\n            \n            if combined[c].dtype == \"int64\":\n                combined[c] = combined[c].astype(\"int32\")\n            elif combined[c].dtype == \"float64\":\n                combined[c] = combined[c].astype(\"float32\")\n                \n            n_unique = combined[c].nunique()\n            if n_unique >= 9:\n                high_cardinality.append(c)\n        \n        return combined, features, cats, high_cardinality\n    \n    def target_encode(self, train, valid, test, cols, target='y', smooth=20, agg='mean'):\n        \"\"\"Multi-fold target encoding with GPU acceleration\"\"\"\n        train['kfold'] = (train.index % self.n_folds)\n        col_name = '_'.join(cols)\n        train[f'TE_{agg.upper()}_{col_name}'] = 0.\n        \n        for i in range(self.n_folds):\n            df_tmp = train[train['kfold']!=i]\n            \n            if agg == \"mean\":\n                mn = train[target].mean()\n            elif agg == \"median\":\n                mn = train[target].median()\n            elif agg == \"min\":\n                mn = train[target].min()\n            elif agg == \"max\":\n                mn = train[target].max()\n            elif agg == \"nunique\":\n                mn = 0\n                \n            df_tmp = df_tmp[cols + [target]].groupby(cols).agg([agg, 'count']).reset_index()\n            df_tmp.columns = cols + [agg, 'count']\n            \n            if agg == \"nunique\":\n                df_tmp['TE_tmp'] = df_tmp[agg] / df_tmp['count']\n            else:\n                df_tmp['TE_tmp'] = ((df_tmp[agg]*df_tmp['count'])+(mn*smooth)) / (df_tmp['count']+smooth)\n                \n            df_tmp_m = train[cols + ['kfold', f'TE_{agg.upper()}_{col_name}']].merge(\n                df_tmp, how='left', left_on=cols, right_on=cols)\n            df_tmp_m.loc[df_tmp_m['kfold']==i, f'TE_{agg.upper()}_{col_name}'] = df_tmp_m.loc[df_tmp_m['kfold']==i, 'TE_tmp']\n            train[f'TE_{agg.upper()}_{col_name}'] = df_tmp_m[f'TE_{agg.upper()}_{col_name}'].fillna(mn).values\n            \n        # Encode validation and test\n        df_tmp = train[cols + [target]].groupby(cols).agg([agg, 'count']).reset_index()\n        df_tmp.columns = cols + [agg, 'count']\n        \n        if agg == \"nunique\":\n            df_tmp['TE_tmp'] = df_tmp[agg] / df_tmp['count']\n        else:\n            df_tmp['TE_tmp'] = ((df_tmp[agg]*df_tmp['count'])+(mn*smooth)) / (df_tmp['count']+smooth)\n            \n        valid = valid.merge(df_tmp[cols + ['TE_tmp']], how='left', left_on=cols, right_on=cols)\n        test = test.merge(df_tmp[cols + ['TE_tmp']], how='left', left_on=cols, right_on=cols)\n        \n        col_name = f'TE_{agg.upper()}_{col_name}'\n        valid[col_name] = valid['TE_tmp'].fillna(mn)\n        test[col_name] = test['TE_tmp'].fillna(mn)\n        \n        valid = valid.drop('TE_tmp', axis=1)\n        test = test.drop('TE_tmp', axis=1)\n        \n        return train, valid, test\n    \n    def find_best_combinations(self, X, y, features, max_features=6, n_trials=1000):\n        \"\"\"Find best feature combinations using forward selection\"\"\"\n        print(\"Finding best feature combinations...\")\n        \n        kf = KFold(n_splits=self.n_folds, shuffle=True, random_state=self.random_state)\n        base_score = float('inf')\n        \n        # Try combinations of different sizes\n        for n in range(2, max_features + 1):\n            print(f\"\\nTesting combinations of {n} features...\")\n            \n            for _ in tqdm(range(n_trials // max_features)):\n                # Randomly sample features\n                combo = list(np.random.choice(features, size=n, replace=False))\n                \n                # Create temporary features\n                X_tmp = X.copy()\n                scores = []\n                \n                # Cross-validation\n                for fold, (train_idx, val_idx) in enumerate(kf.split(X_tmp)):\n                    X_train, X_val = X_tmp.iloc[train_idx], X_tmp.iloc[val_idx]\n                    y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]\n                    \n                    # Apply target encoding\n                    X_train, X_val, _ = self.target_encode(\n                        X_train.copy(), X_val.copy(), X_val.copy(),\n                        combo, target='y', smooth=20\n                    )\n                    \n                    # Train quick model\n                    model = xgb.XGBRegressor(\n                        n_estimators=100,\n                        learning_rate=0.1,\n                        max_depth=6,\n                        tree_method='gpu_hist'\n                    )\n                    model.fit(\n                        X_train[[f'TE_MEAN_{\"_\".join(combo)}']], \n                        y_train,\n                        eval_set=[(X_val[[f'TE_MEAN_{\"_\".join(combo)}']], y_val)],\n                        early_stopping_rounds=10,\n                        verbose=False\n                    )\n                    \n                    # Predict and score\n                    pred = model.predict(X_val[[f'TE_MEAN_{\"_\".join(combo)}']])\n                    score = np.sqrt(mean_squared_error(y_val, pred))\n                    scores.append(score)\n                \n                avg_score = np.mean(scores)\n                if avg_score < base_score:\n                    base_score = avg_score\n                    self.best_combinations.append(combo)\n                    print(f\"\\nNew best combination found: {combo}\")\n                    print(f\"Score: {avg_score:.5f}\")\n                \n                gc.collect()\n        \n        return self.best_combinations[:20]  # Return top 20 combinations","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:03:13.263616Z","iopub.execute_input":"2025-01-01T04:03:13.26391Z","iopub.status.idle":"2025-01-01T04:03:13.285008Z","shell.execute_reply.started":"2025-01-01T04:03:13.263869Z","shell.execute_reply":"2025-01-01T04:03:13.284285Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Model Training","metadata":{}},{"cell_type":"code","source":"class Predictor:\n    \"\"\"GPU-accelerated premium prediction model\"\"\"\n    \n    def __init__(self, n_folds=20):\n        self.n_folds = n_folds\n        self.feature_engineer = FeatureEngineering(n_folds=5)\n        self.models = []\n        \n    def prepare_features(self, train, test):\n        \"\"\"Prepare all features including engineered ones\"\"\"\n        print(\"Preparing features...\")\n        combined, features, cats, high_card = self.feature_engineer._prepare_data(train, test)\n        \n        # Find best feature combinations\n        train_data = combined.iloc[:len(train)].copy()\n        self.best_combos = self.feature_engineer.find_best_combinations(\n            train_data, train_data['y'],\n            features, max_features=6, n_trials=1000\n        )\n        \n        # Create features for all data\n        for combo in self.best_combos:\n            print(f\"\\nCreating features for combination: {combo}\")\n            # Apply different types of encoding\n            for agg in ['mean', 'median', 'min', 'max', 'nunique']:\n                combined, _, _ = self.feature_engineer.target_encode(\n                    combined.iloc[:len(train)].copy(),\n                    combined.iloc[len(train):].copy(),\n                    combined.iloc[len(train):].copy(),\n                    combo, target='y',\n                    smooth=20 if agg=='mean' else 0,\n                    agg=agg\n                )\n        \n        return combined.iloc[:len(train)], combined.iloc[len(train):]\n    \n    def train_and_predict(self, train, test):\n        \"\"\"Train model and make predictions\"\"\"\n        print(\"Training and predicting...\")\n        \n        # Prepare data\n        X_train, X_test = self.prepare_features(train, test)\n        y = X_train['y']\n        X_train = X_train.drop(['y'], axis=1)\n        \n        # Setup cross-validation\n        kf = KFold(n_splits=self.n_folds, shuffle=True, random_state=42)\n        predictions = np.zeros(len(test))\n        oof = np.zeros(len(train))\n        \n        # Train and predict\n        for fold, (train_idx, val_idx) in enumerate(kf.split(X_train)):\n            print(f\"\\nTraining fold {fold + 1}/{self.n_folds}\")\n            \n            X_tr, X_val = X_train.iloc[train_idx], X_train.iloc[val_idx]\n            y_tr, y_val = y.iloc[train_idx], y.iloc[val_idx]\n            \n            model = xgb.XGBRegressor(\n                tree_method='gpu_hist',\n                predictor='gpu_predictor',\n                max_depth=8,\n                colsample_bytree=0.9,\n                subsample=0.9,\n                n_estimators=2000,\n                learning_rate=0.01,\n                early_stopping_rounds=25,\n                eval_metric='rmse'\n            )\n            \n            model.fit(\n                X_tr, y_tr,\n                eval_set=[(X_val, y_val)],\n                verbose=100\n            )\n            \n            self.models.append(model)\n            oof[val_idx] = model.predict(X_val)\n            predictions += model.predict(X_test) / self.n_folds\n            \n            # Print fold score\n            score = np.sqrt(mean_squared_error(y_val, oof[val_idx]))\n            print(f\"Fold {fold + 1} RMSE: {score:.5f}\")\n        \n        # Print overall score\n        score = np.sqrt(mean_squared_error(y, oof))\n        print(f\"\\nOverall CV RMSE: {score:.5f}\")\n        \n        return np.exp(predictions) - 1, np.exp(oof) - 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:08:42.778768Z","iopub.execute_input":"2025-01-01T04:08:42.779227Z","iopub.status.idle":"2025-01-01T04:08:42.802705Z","shell.execute_reply.started":"2025-01-01T04:08:42.779192Z","shell.execute_reply":"2025-01-01T04:08:42.801818Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Model Training and Evaluation","metadata":{}},{"cell_type":"code","source":"def main():\n    # Load data\n    train = pd.read_csv(\"/kaggle/input/playground-series-s4e12/train.csv\")\n    test = pd.read_csv(\"/kaggle/input/playground-series-s4e12/test.csv\")\n    \n    # Initialize and train model\n    model = Predictor(n_folds=15)\n    predictions, oof = model.train_and_predict(train, test)\n    \n    # Create submission\n    submission = pd.read_csv(\"/kaggle/input/playground-series-s4e12/sample_submission.csv\")\n    submission[\"Premium Amount\"] = predictions\n    submission.to_csv(\"optimized_submission.csv\", index=False)\n    \n    print(\"\\nPredictions saved to optimized_submission.csv\")\n\nif __name__ == \"__main__\":\n    main()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T04:08:44.105522Z","iopub.execute_input":"2025-01-01T04:08:44.106309Z","iopub.status.idle":"2025-01-01T04:10:22.002317Z","shell.execute_reply.started":"2025-01-01T04:08:44.106274Z","shell.execute_reply":"2025-01-01T04:10:22.00095Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}