{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"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":"code","source":"import pandas as pd\nimport numpy as np\nfrom catboost import CatBoostRegressor\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import mean_squared_log_error\nfrom sklearn.preprocessing import LabelEncoder, OrdinalEncoder\nfrom sklearn.preprocessing import OneHotEncoder\nimport joblib\n\n\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:34.579388Z","iopub.execute_input":"2024-12-19T02:33:34.579866Z","iopub.status.idle":"2024-12-19T02:33:34.58458Z","shell.execute_reply.started":"2024-12-19T02:33:34.579835Z","shell.execute_reply":"2024-12-19T02:33:34.583753Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_csv(\"/kaggle/input/playground-series-s4e12/train.csv\")\ntest = pd.read_csv(\"/kaggle/input/playground-series-s4e12/test.csv\")\n\nsample = pd.read_csv('/kaggle/input/playground-series-s4e12/sample_submission.csv')\n\ntrain.drop('id', axis=1, inplace=True)\ntest.drop('id', axis=1, inplace=True) \n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:35.304927Z","iopub.execute_input":"2024-12-19T02:33:35.305307Z","iopub.status.idle":"2024-12-19T02:33:44.083115Z","shell.execute_reply.started":"2024-12-19T02:33:35.305273Z","shell.execute_reply":"2024-12-19T02:33:44.08242Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def date(Df):\n\n    Df['Policy Start Date'] = pd.to_datetime(Df['Policy Start Date'])\n    Df['Year'] = Df['Policy Start Date'].dt.year\n    Df['Day'] = Df['Policy Start Date'].dt.day\n    Df['Month'] = Df['Policy Start Date'].dt.month\n    Df['Month_name'] = Df['Policy Start Date'].dt.month_name()\n    Df['Day_of_week'] = Df['Policy Start Date'].dt.day_name()\n    Df['Week'] = Df['Policy Start Date'].dt.isocalendar().week\n    Df['Year_sin'] = np.sin(2 * np.pi * Df['Year'])\n    Df['Year_cos'] = np.cos(2 * np.pi * Df['Year'])\n    Df['Month_sin'] = np.sin(2 * np.pi * Df['Month'] / 12) \n    Df['Month_cos'] = np.cos(2 * np.pi * Df['Month'] / 12)\n    Df['Day_sin'] = np.sin(2 * np.pi * Df['Day'] / 31)  \n    Df['Day_cos'] = np.cos(2 * np.pi * Df['Day'] / 31)\n    Df['Group']=(Df['Year']-2020)*48+Df['Month']*4+Df['Day']//7\n    \n    Df.drop('Policy Start Date', axis=1, inplace=True)\n\n    return Df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:44.084769Z","iopub.execute_input":"2024-12-19T02:33:44.085414Z","iopub.status.idle":"2024-12-19T02:33:44.092361Z","shell.execute_reply.started":"2024-12-19T02:33:44.085383Z","shell.execute_reply":"2024-12-19T02:33:44.09152Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def fe(df):\n    \n    df['contract length'] = pd.cut(\n        df[\"Insurance Duration\"].fillna(99),  \n        bins=[-float('inf'), 1, 3, float('inf')],  \n        labels=[0, 1, 2]  \n    ).astype(int)\n    return df\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:44.093194Z","iopub.execute_input":"2024-12-19T02:33:44.093459Z","iopub.status.idle":"2024-12-19T02:33:44.104263Z","shell.execute_reply.started":"2024-12-19T02:33:44.093418Z","shell.execute_reply":"2024-12-19T02:33:44.103447Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = date(train)\ntest = date(test)\n\ntrain = fe(train)\ntest = fe(test)\n\ncat_cols = [col for col in train.columns if train[col].dtype == 'object']\nfeature_cols = list(test.columns)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:44.106212Z","iopub.execute_input":"2024-12-19T02:33:44.107015Z","iopub.status.idle":"2024-12-19T02:33:46.951175Z","shell.execute_reply.started":"2024-12-19T02:33:44.106978Z","shell.execute_reply":"2024-12-19T02:33:46.950479Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CategoricalEncoder:\n    def __init__(self, train, test):\n        self.train = train\n        self.test = test\n\n    def frequency_encode(self, cat_cols, feature_cols, drop_org=False):\n        combined = pd.concat([self.train, self.test], axis=0, ignore_index=True)\n\n        new_cat_cols = [] \n        for col in cat_cols:\n            freq_encoding = combined[col].value_counts().to_dict()\n            \n            self.train[f\"{col}_freq\"] = self.train[col].map(freq_encoding).astype('float')\n            self.test[f\"{col}_freq\"] = self.test[col].map(freq_encoding).astype('float')\n\n            new_col_name = f\"{col}_freq\"\n            new_cat_cols.append(new_col_name)\n            feature_cols.append(new_col_name)\n            if drop_org:\n                feature_cols.remove(col)\n\n        return self.train, self.test, new_cat_cols, feature_cols","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:46.95256Z","iopub.execute_input":"2024-12-19T02:33:46.953125Z","iopub.status.idle":"2024-12-19T02:33:46.960076Z","shell.execute_reply.started":"2024-12-19T02:33:46.953081Z","shell.execute_reply":"2024-12-19T02:33:46.959202Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"encoder = CategoricalEncoder(train, test)\ntrain, test, cat_cols, feature_cols = encoder.frequency_encode(cat_cols, feature_cols, drop_org=True)\n\ntrain = train[feature_cols + ['Premium Amount']]\ntest = test[feature_cols]\n\n# train = train.fillna(-111)\n# test = test.fillna(-111)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:46.961314Z","iopub.execute_input":"2024-12-19T02:33:46.961678Z","iopub.status.idle":"2024-12-19T02:33:50.806472Z","shell.execute_reply.started":"2024-12-19T02:33:46.961638Z","shell.execute_reply":"2024-12-19T02:33:50.805664Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = train.drop('Premium Amount', axis=1)  \ny = train['Premium Amount']\n\ny_log = np.log1p(y)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:50.807985Z","iopub.execute_input":"2024-12-19T02:33:50.808443Z","iopub.status.idle":"2024-12-19T02:33:50.989815Z","shell.execute_reply.started":"2024-12-19T02:33:50.808397Z","shell.execute_reply":"2024-12-19T02:33:50.989059Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import optuna\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import KFold, train_test_split\nfrom catboost import CatBoostRegressor, Pool\nfrom sklearn.metrics import mean_squared_error\nimport joblib\n\n# Define the RMSLE metric\ndef rmsle(y_true, y_pred):\n    y_pred = np.maximum(y_pred, 0)  # Clamp predictions to prevent log issues\n    return np.sqrt(mean_squared_error(y_true, y_pred))\n\n# Feature importance analysis\ndef plot_feature_importance(model, feature_names, top_n=20):\n    import matplotlib.pyplot as plt\n    importance = model.get_feature_importance()\n    sorted_idx = np.argsort(importance)[::-1][:top_n]\n    plt.barh(range(len(sorted_idx)), importance[sorted_idx], align=\"center\")\n    plt.yticks(range(len(sorted_idx)), np.array(feature_names)[sorted_idx])\n    plt.xlabel(\"Feature Importance\")\n    plt.title(\"Top Features\")\n    plt.gca().invert_yaxis()\n    plt.show()\n\n# Optuna objective function\n# Optuna objective function\ndef objective(trial):\n    # Define the parameter search space\n    params = {\n        \"iterations\": trial.suggest_int('iterations', 2000, 5000),\n        \"learning_rate\": trial.suggest_loguniform('learning_rate', 0.001, 0.1),\n        \"depth\": trial.suggest_int('depth', 4, 12),\n        \"l2_leaf_reg\": trial.suggest_float('l2_leaf_reg', 1, 100),\n        \"bagging_temperature\": trial.suggest_float('bagging_temperature', 0, 1),\n        \"subsample\": trial.suggest_float('subsample', 0.5, 1.0),\n        \"border_count\": trial.suggest_int('border_count', 32, 255),\n        \"bootstrap_type\": trial.suggest_categorical('bootstrap_type', ['Bernoulli', 'MVS'])\n    }\n    \n    # Ensure subsample is only used with Bernoulli bootstrap\n    if params[\"bootstrap_type\"] != \"Bernoulli\":\n        params[\"subsample\"] = 1.0\n\n    kf = KFold(n_splits=5, shuffle=True, random_state=42)\n    rmsle_scores = []\n    \n    for train_idx, valid_idx in kf.split(X):\n        X_train, X_valid = X.iloc[train_idx], X.iloc[valid_idx]\n        y_train, y_valid = y_log.iloc[train_idx], y_log.iloc[valid_idx]\n        \n        model = CatBoostRegressor(\n            iterations=params['iterations'],\n            learning_rate=params['learning_rate'],\n            depth=params['depth'],\n            l2_leaf_reg=params['l2_leaf_reg'],\n            eval_metric=\"RMSE\",\n            random_seed=42,\n            verbose=0,\n            task_type='GPU',  # Or 'CPU'\n        )\n\n        \n        \n        # Train model with early stopping\n        model.fit(\n            X_train,\n            y_train,\n            eval_set=(X_valid, y_valid),\n            early_stopping_rounds=300,\n        )\n        \n        # Validate and calculate RMSLE\n        predictions = np.maximum(0, model.predict(X_valid))\n        fold_rmsle = rmsle(np.expm1(y_valid), np.expm1(predictions))\n        rmsle_scores.append(fold_rmsle)\n    \n    # Return the mean RMSLE over all folds\n    return np.mean(rmsle_scores)\n\n# Run Optuna to find the best parameters\nstudy = optuna.create_study(direction=\"minimize\")\nstudy.optimize(objective, n_trials=20)\n\n# Get the best parameters\nbest_params = study.best_trial.params\nprint(\"Best parameters found:\")\nprint(best_params)\n\n# Train with best parameters using K-Fold\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\nmodels = []\n\nfor fold, (train_idx, valid_idx) in enumerate(kf.split(X)):\n    print(f\"Training Fold {fold + 1}...\")\n    X_train, X_valid = X.iloc[train_idx], X.iloc[valid_idx]\n    y_train, y_valid = y_log.iloc[train_idx], y_log.iloc[valid_idx]\n    \n    model = CatBoostRegressor(\n        iterations=best_params['iterations'],\n        learning_rate=best_params['learning_rate'],\n        depth=best_params['depth'],\n        l2_leaf_reg=best_params['l2_leaf_reg'],\n        eval_metric=\"RMSE\",\n        random_seed=42,\n        verbose=200,\n        task_type='GPU',\n    )\n    \n    # Train model\n    model.fit(\n        X_train,\n        y_train,\n        eval_set=(X_valid, y_valid),\n        early_stopping_rounds=300,\n    )\n    \n    # Save model for each fold\n    models.append(model)\n\nprint(\"All folds trained.\")\n\n# Feature importance analysis for one model\nplot_feature_importance(models[0], feature_names=X.columns)\n\n# Make predictions on the test dataset by averaging across folds\ntest_predictions = np.zeros(len(test))\nfor model in models:\n    test_predictions += np.maximum(0, np.expm1(model.predict(test))) / len(models)\n\n# Prepare the submission file\nsample['Premium Amount'] = test_predictions\nsubmission_file = 'submission.csv'\nsample.to_csv(submission_file, index=False)\nprint(f\"Submission file saved as '{submission_file}'\")\n\n\n\n# Preview the submission file\nprint(sample.head())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-10T15:41:51.93017Z","iopub.execute_input":"2024-12-10T15:41:51.930439Z","iopub.status.idle":"2024-12-10T16:42:39.982245Z","shell.execute_reply.started":"2024-12-10T15:41:51.930415Z","shell.execute_reply":"2024-12-10T16:42:39.981413Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def rmsle(y_true, y_pred):\n    return np.sqrt(mean_squared_log_error(y_true, y_pred))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import optuna\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import KFold\nfrom catboost import CatBoostRegressor\nfrom sklearn.metrics import mean_squared_error\nimport joblib\n\n# Define the RMSLE metric\ndef rmsle(y_true, y_pred):\n    y_pred = np.maximum(y_pred, 0)  # Clamp predictions to prevent log issues\n    return np.sqrt(mean_squared_error(y_true, y_pred))\n\n# Optuna objective function\ndef objective(trial):\n    # Define the parameter search space\n    params = {\n        \"iterations\": trial.suggest_int('iterations', 1000, 4000),\n        \"learning_rate\": trial.suggest_loguniform('learning_rate', 0.01, 0.1),\n        \"depth\": trial.suggest_int('depth', 4, 10),\n        \"l2_leaf_reg\": trial.suggest_float('l2_leaf_reg', 0.1, 10),\n    }\n    \n    kf = KFold(n_splits=5, shuffle=True, random_state=42)\n    rmsle_scores = []\n    \n    for train_idx, valid_idx in kf.split(X):\n        X_train, X_valid = X.iloc[train_idx], X.iloc[valid_idx]\n        y_train, y_valid = y_log.iloc[train_idx], y_log.iloc[valid_idx]\n        \n        model = CatBoostRegressor(\n            iterations=params['iterations'],\n            learning_rate=params['learning_rate'],\n            depth=params['depth'],\n            l2_leaf_reg=params['l2_leaf_reg'],\n            eval_metric=\"RMSE\",\n            random_seed=42,\n            verbose=0,\n            task_type='GPU',\n        )\n        \n        # Train model with early stopping\n        model.fit(\n            X_train,\n            y_train,\n            eval_set=(X_valid, y_valid),\n            early_stopping_rounds=200,\n        )\n        \n        # Validate and calculate RMSLE\n        predictions = np.maximum(0, model.predict(X_valid))\n        fold_rmsle = rmsle(np.expm1(y_valid), np.expm1(predictions))\n        rmsle_scores.append(fold_rmsle)\n    \n    # Return the mean RMSLE over all folds\n    return np.mean(rmsle_scores)\n\n# Run Optuna to find the best parameters\nstudy = optuna.create_study(direction=\"minimize\")\nstudy.optimize(objective, n_trials=20)\n\n# Get the best parameters\nbest_params = study.best_trial.params\nprint(\"Best parameters found:\")\nprint(best_params)\n\n# Train with best parameters using K-Fold\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\nmodels = []\n\nfor fold, (train_idx, valid_idx) in enumerate(kf.split(X)):\n    print(f\"Training Fold {fold + 1}...\")\n    X_train, X_valid = X.iloc[train_idx], X.iloc[valid_idx]\n    y_train, y_valid = y_log.iloc[train_idx], y_log.iloc[valid_idx]\n    \n    model = CatBoostRegressor(\n        iterations=best_params['iterations'],\n        learning_rate=best_params['learning_rate'],\n        depth=best_params['depth'],\n        l2_leaf_reg=best_params['l2_leaf_reg'],\n        eval_metric=\"RMSE\",\n        random_seed=42,\n        verbose=200,\n        task_type='GPU',\n    )\n    \n    # Train model\n    model.fit(\n        X_train,\n        y_train,\n        eval_set=(X_valid, y_valid),\n        early_stopping_rounds=200,\n    )\n    \n    # Save model for each fold\n    models.append(model)\n\nprint(\"All folds trained.\")\n\n# Make predictions on the test dataset by averaging across folds\ntest_predictions = np.zeros(len(test))\nfor model in models:\n    test_predictions += np.maximum(0, np.expm1(model.predict(test))) / len(models)\n\n# Prepare the submission file\nsample['Premium Amount'] = test_predictions\nsubmission_file = 'submission.csv'\nsample.to_csv(submission_file, index=False)\nprint(f\"Submission file saved as '{submission_file}'\")\n\n# Save the trained models for future use\nfor i, model in enumerate(models):\n    joblib.dump(model, f\"fold_{i + 1}_model.pkl\")\n    print(f\"Fold {i + 1} model saved as 'fold_{i + 1}_model.pkl'\")\n\n# Example of loading one of the saved models\n# loaded_model = joblib.load(\"fold_1_model.pkl\")\n# print(\"Loaded Fold 1 Model\")\n\n# Preview the submission file\nprint(sample.head())\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import optuna\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import KFold\nfrom catboost import CatBoostRegressor, Pool\nfrom sklearn.metrics import mean_squared_error\nimport logging\n\n# Set up logging\nlogging.basicConfig(level=logging.INFO)\n\n# Define RMSLE metric\ndef rmsle(y_true, y_pred):\n    y_pred = np.maximum(y_pred, 0)  # Clamp predictions to prevent log issues\n    return np.sqrt(mean_squared_error(y_true, y_pred))\n\n# Plot feature importance\ndef plot_feature_importance(model, feature_names, top_n=20, save_path=None):\n    import matplotlib.pyplot as plt\n    importance = model.get_feature_importance()\n    sorted_idx = np.argsort(importance)[::-1][:top_n]\n    plt.figure(figsize=(10, 6))\n    plt.barh(range(len(sorted_idx)), importance[sorted_idx], align=\"center\", color='skyblue')\n    plt.yticks(range(len(sorted_idx)), np.array(feature_names)[sorted_idx])\n    plt.xlabel(\"Feature Importance\")\n    plt.title(\"Top Features\")\n    plt.gca().invert_yaxis()\n    if save_path:\n        plt.savefig(save_path)\n    plt.show()\n\n# Train model\ndef train_model(params, X_train, y_train, X_valid, y_valid, cat_features=None):\n    train_pool = Pool(X_train, y_train, cat_features=cat_features)\n    valid_pool = Pool(X_valid, y_valid, cat_features=cat_features)\n    \n    model = CatBoostRegressor(\n        iterations=params['iterations'],\n        learning_rate=params['learning_rate'],\n        depth=params['depth'],\n        l2_leaf_reg=params['l2_leaf_reg'],\n        eval_metric=\"RMSE\",\n        random_seed=42,\n        verbose=200,\n        task_type='GPU',  # Change to 'CPU' if GPU is unavailable\n    )\n    model.fit(train_pool, eval_set=valid_pool, early_stopping_rounds=300)\n    return model\n\n# Predict with models\ndef predict_with_models(models, test_data):\n    predictions = np.zeros(len(test_data))\n    for model in models:\n        predictions += np.maximum(0, np.expm1(model.predict(test_data))) / len(models)\n    return predictions\n\n# Save submission\ndef save_submission(sample, predictions, filename='submission.csv'):\n    sample['Premium Amount'] = predictions\n    sample.to_csv(filename, index=False)\n    print(f\"Submission file saved as '{filename}'\")\n\n# Optuna objective function\ndef objective(trial):\n    params = {\n        \"iterations\": trial.suggest_int('iterations', 2000, 5000),\n        \"learning_rate\": trial.suggest_loguniform('learning_rate', 0.001, 0.1),\n        \"depth\": trial.suggest_int('depth', 4, 12),\n        \"l2_leaf_reg\": trial.suggest_float('l2_leaf_reg', 1, 100),\n        \"bagging_temperature\": trial.suggest_float('bagging_temperature', 0, 1),\n        \"subsample\": trial.suggest_float('subsample', 0.5, 1.0),\n        \"border_count\": trial.suggest_int('border_count', 32, 255),\n        \"bootstrap_type\": trial.suggest_categorical('bootstrap_type', ['Bernoulli', 'MVS']),\n        \"grow_policy\": trial.suggest_categorical('grow_policy', ['SymmetricTree', 'Depthwise', 'Lossguide']),\n        \"loss_function\": trial.suggest_categorical('loss_function', ['RMSE', 'MAE']),\n    }\n    \n    if params[\"bootstrap_type\"] != \"Bernoulli\":\n        params[\"subsample\"] = 1.0\n    \n    kf = KFold(n_splits=5, shuffle=True, random_state=42)\n    rmsle_scores = []\n    \n    for train_idx, valid_idx in kf.split(X):\n        X_train, X_valid = X.iloc[train_idx], X.iloc[valid_idx]\n        y_train, y_valid = y_log.iloc[train_idx], y_log.iloc[valid_idx]\n        \n        model = train_model(params, X_train, y_train, X_valid, y_valid)\n        predictions = np.maximum(0, model.predict(X_valid))\n        fold_rmsle = rmsle(np.expm1(y_valid), np.expm1(predictions))\n        rmsle_scores.append(fold_rmsle)\n    \n    mean_rmsle = np.mean(rmsle_scores)\n    logging.info(f\"Trial {trial.number} completed with RMSLE: {mean_rmsle}\")\n    return mean_rmsle\n\n\n# Run Optuna to find the best parameters\nstudy = optuna.create_study(direction=\"minimize\")\nstudy.optimize(objective, n_trials=20)\n\n# Get the best parameters\nbest_params = study.best_trial.params\nlogging.info(f\"Best parameters: {best_params}\")\n\n# K-Fold training with best parameters\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\nmodels = []\n\nfor fold, (train_idx, valid_idx) in enumerate(kf.split(X)):\n    logging.info(f\"Training Fold {fold + 1}...\")\n    X_train, X_valid = X.iloc[train_idx], X.iloc[valid_idx]\n    y_train, y_valid = y_log.iloc[train_idx], y_log.iloc[valid_idx]\n    \n    model = train_model(best_params, X_train, y_train, X_valid, y_valid)\n    models.append(model)\n\nlogging.info(\"All folds trained.\")\n\n# Feature importance analysis\nplot_feature_importance(models[0], feature_names=X.columns)\n\n# Predict on test dataset\ntest_predictions = predict_with_models(models, test)\n\n# Save submission\nsave_submission(sample, test_predictions)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T02:33:52.73213Z","iopub.execute_input":"2024-12-19T02:33:52.732923Z","iopub.status.idle":"2024-12-19T03:49:08.18375Z","shell.execute_reply.started":"2024-12-19T02:33:52.732893Z","shell.execute_reply":"2024-12-19T03:49:08.182856Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}