{"cells": [{"cell_type": "code", "execution_count": 1, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.414041Z", "start_time": "2019-12-18T18:22:44.141041Z"}, "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19", "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5"}, "outputs": [], "source": ["# This Python 3 environment comes with many helpful analytics libraries installed\n", "# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n", "# For example, here's several helpful packages to load in \n", "\n", "import numpy as np # linear algebra\n", "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n", "import matplotlib.pyplot as plt\n", "import xgboost as xgb\n", "from xgboost import XGBClassifier, XGBRegressor\n", "from xgboost import plot_importance\n", "from matplotlib import pyplot\n", "#import shap\n", "\n", "import os\n", "for dirname, _, filenames in os.walk('/kaggle/input'):\n", "    for filename in filenames:\n", "        print(os.path.join(dirname, filename))\n", "\n", "# Any results you write to the current directory are saved as output.\n", "from time import time\n", "from tqdm import tqdm_notebook as tqdm\n", "from collections import Counter\n", "from scipy import stats\n", "import lightgbm as lgb\n", "from sklearn.metrics import cohen_kappa_score\n", "from sklearn.model_selection import KFold, StratifiedKFold\n", "import gc\n", "import json\n", "pd.set_option('display.max_columns', 1000)"]}, {"cell_type": "markdown", "metadata": {"_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0", "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a", "collapsed": true}, "source": ["# Objective\n", "\n", "* In the last notebook we create our baseline model including a feature selection part. \n", "* Cohen cappa score of 0.456 (lb) with a local cv score of 0.529\n", "* In this notebook we are going to add more features and remove others that i think they overfitt the train set and then check if our local cv score improve.\n", "* Next, we will check if this improvement aligns with the lb."]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Notes\n", "* Check the distribution of the target variable of the out of folds score and the prediction distribution. A good model should more or less have the same distribution."]}, {"cell_type": "code", "execution_count": 2, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.421900Z", "start_time": "2019-12-18T18:22:50.415888Z"}}, "outputs": [], "source": ["def eval_qwk_lgb_regr(y_true, y_pred):\n", "    \"\"\"\n", "    Fast cappa eval function for lgb.\n", "    \"\"\"\n", "    dist = Counter(reduce_train['accuracy_group'])\n", "    for k in dist:\n", "        dist[k] /= len(reduce_train)\n", "    reduce_train['accuracy_group'].hist()\n", "    \n", "    acum = 0\n", "    bound = {}\n", "    for i in range(3):\n", "        acum += dist[i]\n", "        bound[i] = np.percentile(y_pred, acum * 100)\n", "\n", "    def classify(x):\n", "        if x <= bound[0]:\n", "            return 0\n", "        elif x <= bound[1]:\n", "            return 1\n", "        elif x <= bound[2]:\n", "            return 2\n", "        else:\n", "            return 3\n", "\n", "    y_pred = np.array(list(map(classify, y_pred))).reshape(y_true.shape)\n", "\n", "    return 'cappa', cohen_kappa_score(y_true, y_pred, weights='quadratic'), True"]}, {"cell_type": "code", "execution_count": 3, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.431847Z", "start_time": "2019-12-18T18:22:50.424872Z"}}, "outputs": [], "source": ["def cohenkappa(ypred, y):\n", "    y = y.get_label().astype(\"int\")\n", "    ypred = ypred.reshape((4, -1)).argmax(axis = 0)\n", "    loss = cohenkappascore(y, y_pred, weights = 'quadratic')\n", "    return \"cappa\", loss, True"]}, {"cell_type": "code", "execution_count": 4, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.443965Z", "start_time": "2019-12-18T18:22:50.435851Z"}}, "outputs": [], "source": ["def read_data():\n", "    print('Reading train.csv file....')\n", "    train = pd.read_csv('../input/data-science-bowl-2019/train.csv')\n", "    print('Training.csv file have {} rows and {} columns'.format(train.shape[0], train.shape[1]))\n", "\n", "    print('Reading test.csv file....')\n", "    test = pd.read_csv('../input/data-science-bowl-2019/test.csv')\n", "    print('Test.csv file have {} rows and {} columns'.format(test.shape[0], test.shape[1]))\n", "\n", "    print('Reading train_labels.csv file....')\n", "    train_labels = pd.read_csv('../input/data-science-bowl-2019/train_labels.csv')\n", "    print('Train_labels.csv file have {} rows and {} columns'.format(train_labels.shape[0], train_labels.shape[1]))\n", "\n", "    print('Reading specs.csv file....')\n", "    specs = pd.read_csv('../input/data-science-bowl-2019/specs.csv')\n", "    print('Specs.csv file have {} rows and {} columns'.format(specs.shape[0], specs.shape[1]))\n", "\n", "    print('Reading sample_submission.csv file....')\n", "    sample_submission = pd.read_csv('../input/data-science-bowl-2019/sample_submission.csv')\n", "    print('Sample_submission.csv file have {} rows and {} columns'.format(sample_submission.shape[0], sample_submission.shape[1]))\n", "    return train, test, train_labels, specs, sample_submission"]}, {"cell_type": "code", "execution_count": 5, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.457780Z", "start_time": "2019-12-18T18:22:50.445819Z"}}, "outputs": [], "source": ["def encode_title(train, test, train_labels):\n", "    # encode title\n", "    train['title_event_code'] = list(map(lambda x, y: str(x) + '_' + str(y), train['title'], train['event_code']))\n", "    test['title_event_code'] = list(map(lambda x, y: str(x) + '_' + str(y), test['title'], test['event_code']))\n", "    all_title_event_code = list(set(train[\"title_event_code\"].unique()).union(test[\"title_event_code\"].unique()))\n", "    # make a list with all the unique 'titles' from the train and test set\n", "    list_of_user_activities = list(set(train['title'].unique()).union(set(test['title'].unique())))\n", "    # make a list with all the unique 'event_code' from the train and test set\n", "    list_of_event_code = list(set(train['event_code'].unique()).union(set(test['event_code'].unique())))\n", "    list_of_event_id = list(set(train['event_id'].unique()).union(set(test['event_id'].unique())))\n", "    # make a list with all the unique worlds from the train and test set\n", "    list_of_worlds = list(set(train['world'].unique()).union(set(test['world'].unique())))\n", "    # create a dictionary numerating the titles\n", "    activities_map = dict(zip(list_of_user_activities, np.arange(len(list_of_user_activities))))\n", "    activities_labels = dict(zip(np.arange(len(list_of_user_activities)), list_of_user_activities))\n", "    activities_world = dict(zip(list_of_worlds, np.arange(len(list_of_worlds))))\n", "    assess_titles = list(set(train[train['type'] == 'Assessment']['title'].value_counts().index).union(set(test[test['type'] == 'Assessment']['title'].value_counts().index)))\n", "    # replace the text titles with the number titles from the dict\n", "    train['title'] = train['title'].map(activities_map)\n", "    test['title'] = test['title'].map(activities_map)\n", "    train['world'] = train['world'].map(activities_world)\n", "    test['world'] = test['world'].map(activities_world)\n", "    train_labels['title'] = train_labels['title'].map(activities_map)\n", "    win_code = dict(zip(activities_map.values(), (4100*np.ones(len(activities_map))).astype('int')))\n", "    # then, it set one element, the 'Bird Measurer (Assessment)' as 4110, 10 more than the rest\n", "    win_code[activities_map['Bird Measurer (Assessment)']] = 4110\n", "    # convert text into datetime\n", "    train['timestamp'] = pd.to_datetime(train['timestamp'])\n", "    test['timestamp'] = pd.to_datetime(test['timestamp'])\n", "    \n", "    \n", "    return train, test, train_labels, win_code, list_of_user_activities, list_of_event_code, activities_labels, assess_titles, list_of_event_id, all_title_event_code"]}, {"cell_type": "code", "execution_count": 6, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.477737Z", "start_time": "2019-12-18T18:22:50.459770Z"}}, "outputs": [], "source": ["# this is the function that convert the raw data into processed features\n", "def get_data(user_sample, test_set=False):\n", "    '''\n", "    The user_sample is a DataFrame from train or test where the only one \n", "    installation_id is filtered\n", "    And the test_set parameter is related with the labels processing, that is only requered\n", "    if test_set=False\n", "    '''\n", "    # Constants and parameters declaration\n", "    last_activity = 0\n", "    \n", "    user_activities_count = {'Clip':0, 'Activity': 0, 'Assessment': 0, 'Game':0}\n", "    \n", "    # new features: time spent in each activity\n", "    last_session_time_sec = 0\n", "    accuracy_groups = {0:0, 1:0, 2:0, 3:0}\n", "    all_assessments = []\n", "    accumulated_accuracy_group = 0\n", "    accumulated_accuracy = 0\n", "    accumulated_correct_attempts = 0 \n", "    accumulated_uncorrect_attempts = 0\n", "    accumulated_actions = 0\n", "    counter = 0\n", "    time_first_activity = float(user_sample['timestamp'].values[0])\n", "    durations = []\n", "    last_accuracy_title = {'acc_' + title: -1 for title in assess_titles}\n", "    event_code_count: Dict[str, int] = {ev: 0 for ev in list_of_event_code}\n", "    event_id_count: Dict[str, int] = {eve: 0 for eve in list_of_event_id}\n", "    title_count: Dict[str, int] = {eve: 0 for eve in activities_labels.values()} \n", "    title_event_code_count: Dict[str, int] = {t_eve: 0 for t_eve in all_title_event_code}\n", "        \n", "    # last features\n", "    sessions_count = 0\n", "    \n", "    # itarates through each session of one instalation_id\n", "    for i, session in user_sample.groupby('game_session', sort=False):\n", "        # i = game_session_id\n", "        # session is a DataFrame that contain only one game_session\n", "        \n", "        # get some sessions information\n", "        session_type = session['type'].iloc[0]\n", "        session_title = session['title'].iloc[0]\n", "        session_title_text = activities_labels[session_title]\n", "                    \n", "            \n", "        # for each assessment, and only this kind off session, the features below are processed\n", "        # and a register are generated\n", "        if (session_type == 'Assessment') & (test_set or len(session)>1):\n", "            # search for event_code 4100, that represents the assessments trial\n", "            all_attempts = session.query(f'event_code == {win_code[session_title]}')\n", "            # then, check the numbers of wins and the number of losses\n", "            true_attempts = all_attempts['event_data'].str.contains('true').sum()\n", "            false_attempts = all_attempts['event_data'].str.contains('false').sum()\n", "            # copy a dict to use as feature template, it's initialized with some itens: \n", "            # {'Clip':0, 'Activity': 0, 'Assessment': 0, 'Game':0}\n", "            features = user_activities_count.copy()\n", "            features.update(last_accuracy_title.copy())\n", "            features.update(event_code_count.copy())\n", "            features.update(event_id_count.copy())\n", "            features.update(title_count.copy())\n", "            features.update(title_event_code_count.copy())\n", "            features.update(last_accuracy_title.copy())\n", "            features['installation_session_count'] = sessions_count\n", "            \n", "            # get installation_id for aggregated features\n", "            features['installation_id'] = session['installation_id'].iloc[-1]\n", "            # add title as feature, remembering that title represents the name of the game\n", "            features['session_title'] = session['title'].iloc[0]\n", "            # the 4 lines below add the feature of the history of the trials of this player\n", "            # this is based on the all time attempts so far, at the moment of this assessment\n", "            features['accumulated_correct_attempts'] = accumulated_correct_attempts\n", "            features['accumulated_uncorrect_attempts'] = accumulated_uncorrect_attempts\n", "            accumulated_correct_attempts += true_attempts \n", "            accumulated_uncorrect_attempts += false_attempts\n", "            # the time spent in the app so far\n", "            if durations == []:\n", "                features['duration_mean'] = 0\n", "                features['duration_std'] = 0\n", "            else:\n", "                features['duration_mean'] = np.mean(durations)\n", "                features['duration_std'] = np.std(durations)\n", "            durations.append((session.iloc[-1, 2] - session.iloc[0, 2] ).seconds)\n", "            # the accurace is the all time wins divided by the all time attempts\n", "            features['accumulated_accuracy'] = accumulated_accuracy/counter if counter > 0 else 0\n", "            accuracy = true_attempts/(true_attempts+false_attempts) if (true_attempts+false_attempts) != 0 else 0\n", "            accumulated_accuracy += accuracy\n", "            last_accuracy_title['acc_' + session_title_text] = accuracy\n", "            # a feature of the current accuracy categorized\n", "            # it is a counter of how many times this player was in each accuracy group\n", "            if accuracy == 0:\n", "                features['accuracy_group'] = 0\n", "            elif accuracy == 1:\n", "                features['accuracy_group'] = 3\n", "            elif accuracy == 0.5:\n", "                features['accuracy_group'] = 2\n", "            else:\n", "                features['accuracy_group'] = 1\n", "            features.update(accuracy_groups)\n", "            accuracy_groups[features['accuracy_group']] += 1\n", "            # mean of the all accuracy groups of this player\n", "            features['accumulated_accuracy_group'] = accumulated_accuracy_group/counter if counter > 0 else 0\n", "            accumulated_accuracy_group += features['accuracy_group']\n", "            # how many actions the player has done so far, it is initialized as 0 and updated some lines below\n", "            features['accumulated_actions'] = accumulated_actions\n", "            \n", "            # there are some conditions to allow this features to be inserted in the datasets\n", "            # if it's a test set, all sessions belong to the final dataset\n", "            # it it's a train, needs to be passed throught this clausule: session.query(f'event_code == {win_code[session_title]}')\n", "            # that means, must exist an event_code 4100 or 4110\n", "            if test_set:\n", "                all_assessments.append(features)\n", "            elif true_attempts+false_attempts > 0:\n", "                all_assessments.append(features)\n", "                \n", "            counter += 1\n", "        \n", "        sessions_count += 1\n", "        # this piece counts how many actions was made in each event_code so far\n", "        def update_counters(counter: dict, col: str):\n", "                num_of_session_count = Counter(session[col])\n", "                for k in num_of_session_count.keys():\n", "                    x = k\n", "                    if col == 'title':\n", "                        x = activities_labels[k]\n", "                    counter[x] += num_of_session_count[k]\n", "                return counter\n", "            \n", "        event_code_count = update_counters(event_code_count, \"event_code\")\n", "        event_id_count = update_counters(event_id_count, \"event_id\")\n", "        title_count = update_counters(title_count, 'title')\n", "        title_event_code_count = update_counters(title_event_code_count, 'title_event_code')\n", "\n", "        # counts how many actions the player has done so far, used in the feature of the same name\n", "        accumulated_actions += len(session)\n", "        if last_activity != session_type:\n", "            user_activities_count[session_type] += 1\n", "            last_activitiy = session_type \n", "                        \n", "    # if it't the test_set, only the last assessment must be predicted, the previous are scraped\n", "    if test_set:\n", "        return all_assessments[-1]\n", "    # in the train_set, all assessments goes to the dataset\n", "    return all_assessments"]}, {"cell_type": "code", "execution_count": 7, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.489699Z", "start_time": "2019-12-18T18:22:50.480716Z"}}, "outputs": [], "source": ["def get_train_and_test(train, test):\n", "    compiled_train = []\n", "    compiled_test = []\n", "    for i, (ins_id, user_sample) in tqdm(enumerate(train.groupby('installation_id', sort = False)), total = 17000):\n", "        compiled_train += get_data(user_sample)\n", "    for ins_id, user_sample in tqdm(test.groupby('installation_id', sort = False), total = 1000):\n", "        test_data = get_data(user_sample, test_set = True)\n", "        compiled_test.append(test_data)\n", "    reduce_train = pd.DataFrame(compiled_train)\n", "    reduce_test = pd.DataFrame(compiled_test)\n", "    categoricals = ['session_title']\n", "    return reduce_train, reduce_test, categoricals"]}, {"cell_type": "code", "execution_count": 8, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.505649Z", "start_time": "2019-12-18T18:22:50.491687Z"}}, "outputs": [], "source": ["def run_feature_selection(reduce_train, reduce_test, usefull_features, new_features):\n", "    kf = StratifiedKFold(n_splits = 10, shuffle = True, random_state = 42)\n", "    target = 'accuracy_group'\n", "    oof_pred = np.zeros((len(reduce_train), 4))\n", "    for fold, (tr_ind, val_ind) in enumerate(kf.split(reduce_train, reduce_train[target])):\n", "        print('Fold {}'.format(fold + 1))\n", "        x_train, x_val = reduce_train[usefull_features].iloc[tr_ind], reduce_train[usefull_features].iloc[val_ind]\n", "        y_train, y_val = reduce_train[target][tr_ind], reduce_train[target][val_ind]\n", "        train_set = lgb.Dataset(x_train, y_train, categorical_feature = categoricals)\n", "        val_set = lgb.Dataset(x_val, y_val, categorical_feature = categoricals)\n", "\n", "        params = {\n", "            'learning_rate': 0.01,\n", "            'metric': 'multiclass',\n", "            'objective': 'multiclass',\n", "            'num_classes': 4,\n", "            'feature_fraction': 0.75,\n", "            'subsample': 0.75,\n", "            'n_jobs': -1,\n", "            'seed': 50,\n", "            'max_depth': 10\n", "        }\n", "\n", "        model = lgb.train(params, train_set, num_boost_round = 100000, early_stopping_rounds = 100, \n", "                          valid_sets=[train_set, val_set], verbose_eval = 500)\n", "        oof_pred[val_ind] = model.predict(x_val)\n", "    # using cohen_kappa because it's the evaluation metric of the competition\n", "    loss_score = cohen_kappa_score(reduce_train[target], np.argmax(oof_pred, axis = 1), weights = 'quadratic')\n", "    score = loss_score\n", "    usefull_new_features = []\n", "    for i in new_features:\n", "        oof_pred = np.zeros((len(reduce_train), 4))\n", "        evaluating_features = usefull_features + usefull_new_features + [i]\n", "        print('Evaluating {} column'.format(i))\n", "        print('Out best cohen kappa score is : {}'.format(score))\n", "        for fold, (tr_ind, val_ind) in enumerate(kf.split(reduce_train, reduce_train[target])):\n", "            print('Fold {}'.format(fold + 1))\n", "            x_train, x_val = reduce_train[evaluating_features].iloc[tr_ind], reduce_train[evaluating_features].iloc[val_ind]\n", "            y_train, y_val = reduce_train[target][tr_ind], reduce_train[target][val_ind]\n", "            train_set = lgb.Dataset(x_train, y_train, categorical_feature = categoricals)\n", "            val_set = lgb.Dataset(x_val, y_val, categorical_feature = categoricals)\n", "\n", "            model = lgb.train(params, train_set, num_boost_round = 100000, early_stopping_rounds = 100, \n", "                              valid_sets=[train_set, val_set], verbose_eval = 500)\n", "            oof_pred[val_ind] = model.predict(x_val)\n", "        loss_score = cohen_kappa_score(reduce_train[target], np.argmax(oof_pred, axis = 1), weights = 'quadratic')\n", "        print('Our new cohen kappa score is : {}'.format(loss_score))\n", "        if loss_score > score:\n", "            print('Feature {} is usefull, adding feature to usefull_new_features_list'.format(i))\n", "            usefull_new_features.append(i)\n", "            score = loss_score\n", "        else:\n", "            print('Feature {} is useless'.format(i))\n", "        gc.collect()\n", "    print('The best features are: ', usefull_new_features)\n", "    print('Our best cohen kappa score is : ', score)\n", "\n", "    return usefull_features + usefull_new_features"]}, {"cell_type": "code", "execution_count": 9, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.518614Z", "start_time": "2019-12-18T18:22:50.508641Z"}}, "outputs": [], "source": ["def run_lgb_regression(reduce_train, reduce_test, usefull_features, n_splits, random_state=42):\n", "    kf = StratifiedKFold(n_splits=n_splits, shuffle = True, random_state = random_state)\n", "    target = 'accuracy_group'\n", "    oof_pred = np.zeros((len(reduce_train), ))\n", "    y_pred = np.zeros((len(reduce_test), ))\n", "    for fold, (tr_ind, val_ind) in enumerate(kf.split(reduce_train, reduce_train[target])):\n", "        print('Fold {}'.format(fold + 1))\n", "        x_train, x_val = reduce_train[usefull_features].iloc[tr_ind], reduce_train[usefull_features].iloc[val_ind]\n", "        y_train, y_val = reduce_train[target][tr_ind], reduce_train[target][val_ind]\n", "        train_set = lgb.Dataset(x_train, y_train, categorical_feature=categoricals)\n", "        val_set = lgb.Dataset(x_val, y_val, categorical_feature=categoricals)\n", "\n", "        params = {'n_estimators':5000,\n", "                    'boosting_type': 'gbdt',\n", "                    'objective': 'regression',\n", "                    'metric': 'rmse',\n", "                    'subsample': 0.75,\n", "                    'subsample_freq': 1,\n", "                    'learning_rate': 0.01,\n", "                    'feature_fraction': 0.9,\n", "                    'max_depth': 15,\n", "                    'lambda_l1': 1,  \n", "                    'lambda_l2': 1,\n", "                    'verbose': 100,\n", "                    'early_stopping_rounds': 100\n", "                    }\n", "\n", "        model = lgb.train(params, train_set, num_boost_round = 1000000, early_stopping_rounds = 300, \n", "                          valid_sets=[train_set, val_set], verbose_eval = 100)\n", "        oof_pred[val_ind] = model.predict(x_val)\n", "        y_pred += model.predict(reduce_test[usefull_features]) / n_splits\n", "    _, loss_score, _ = eval_qwk_lgb_regr(reduce_train[target], oof_pred)\n", "    print('Our oof cohen kappa score is: ', loss_score)\n", "\n", "    return y_pred\n"]}, {"cell_type": "code", "execution_count": 10, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.531580Z", "start_time": "2019-12-18T18:22:50.521605Z"}}, "outputs": [], "source": ["def run_xgb_regression(reduce_train, reduce_test, usefull_features, n_splits, random_state=42):\n", "    kf = StratifiedKFold(n_splits=n_splits, shuffle = True, random_state = random_state)\n", "    target = 'accuracy_group'\n", "    oof_pred = np.zeros((len(reduce_train), ))\n", "    y_pred = np.zeros((len(reduce_test), ))\n", "    for fold, (tr_ind, val_ind) in enumerate(kf.split(reduce_train, reduce_train[target])):\n", "        print('Fold {}'.format(fold + 1))\n", "        x_train, x_val = reduce_train[usefull_features].iloc[tr_ind], reduce_train[usefull_features].iloc[val_ind]\n", "        y_train, y_val = reduce_train[target][tr_ind], reduce_train[target][val_ind]\n", "        xgb_train = xgb.DMatrix(x_train, y_train)\n", "        xgb_eval = xgb.DMatrix(x_val, y_val)\n", "\n", "        pars = {\n", "            'colsample_bytree': 0.8,                 \n", "            'learning_rate': 0.01,\n", "            'max_depth': 10,\n", "            'subsample': 1,\n", "            'objective':'reg:squarederror',\n", "            #'eval_metric':'rmse',\n", "            'min_child_weight':3,\n", "            'gamma':0.25,\n", "            'n_estimators':5000\n", "        }\n", "\n", "        model = xgb.train(pars,\n", "                      xgb_train,\n", "                      num_boost_round=5000,\n", "                      evals=[(xgb_train, 'train'), (xgb_eval, 'val')],\n", "                      verbose_eval=100,\n", "                      early_stopping_rounds=100\n", "                     )\n", "        \n", "        val_X=xgb.DMatrix(x_val)\n", "        oof_pred[val_ind] = model.predict(val_X)\n", "        test_X = xgb.DMatrix(reduce_test[usefull_features])\n", "        y_pred += model.predict(test_X) / n_splits\n", "    _, loss_score, _ = eval_qwk_lgb_regr(reduce_train[target], oof_pred)\n", "    print('Our oof cohen kappa score is: ', loss_score)\n", "\n", "    return y_pred\n"]}, {"cell_type": "code", "execution_count": 11, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:22:50.540571Z", "start_time": "2019-12-18T18:22:50.534572Z"}}, "outputs": [], "source": ["#import gc\n", "#del reduce_train, reduce_test\n", "#gc.collect()"]}, {"cell_type": "code", "execution_count": 12, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:29:42.151161Z", "start_time": "2019-12-18T18:22:50.543549Z"}}, "outputs": [], "source": ["# read data\n", "train, test, train_labels, specs, sample_submission = read_data()\n", "# get usefull dict with maping encode\n", "train, test, train_labels, win_code, list_of_user_activities, list_of_event_code, activities_labels, assess_titles, list_of_event_id, all_title_event_code = encode_title(train, test, train_labels)\n", "# tranform function to get the train and test set\n", "reduce_train, reduce_test, categoricals = get_train_and_test(train, test)"]}, {"cell_type": "code", "execution_count": 13, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:29:43.072285Z", "start_time": "2019-12-18T18:29:42.155121Z"}}, "outputs": [], "source": ["def plot_train_test_comp(feature):\n", "    BINS = 50\n", "    #data = reduce_train[reduce_train['accuracy_group'] == 3][feature]\n", "    data = reduce_train[feature]\n", "    train_mean = data.mean()\n", "    perc_90 = np.percentile(data, 95)\n", "    plt.hist(np.clip(data, 0, perc_90), bins=BINS, color='blue', alpha=0.5, weights=np.ones(len(data)) / len(data))\n", "    data = reduce_test[feature] \n", "    test_mean = data.mean()\n", "    ajust_factor = train_mean / test_mean\n", "    plt.hist(np.clip(data * ajust_factor, 0, perc_90), bins=BINS, color='red', alpha=0.5, weights=np.ones(len(data)) / len(data))\n", "    plt.show()\n", "\n", "plot_train_test_comp('Clip')"]}, {"cell_type": "code", "execution_count": 14, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:29:46.731508Z", "start_time": "2019-12-18T18:29:43.074258Z"}}, "outputs": [], "source": ["# call feature engineering function\n", "features = reduce_train.loc[(reduce_train.sum(axis=1) != 0), (reduce_train.sum(axis=0) != 0)].columns # delete useless columns\n", "features = [x for x in features if x not in ['accuracy_group', 'installation_id']]"]}, {"cell_type": "code", "execution_count": 15, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:29:49.465170Z", "start_time": "2019-12-18T18:29:46.733493Z"}}, "outputs": [], "source": ["to_exclude = []\n", "ajusted_test = reduce_test.copy()\n", "for feature in ajusted_test.columns:\n", "    if feature not in ['accuracy_group', 'installation_id', 'accuracy_group', 'session_title']:\n", "        data = reduce_train[feature]\n", "        train_mean = data.mean()\n", "        data = ajusted_test[feature] \n", "        test_mean = data.mean()\n", "        try:\n", "            ajust_factor = train_mean / test_mean\n", "            if ajust_factor > 10 or ajust_factor < 0.1:\n", "                to_exclude.append(feature)\n", "                print(feature, train_mean, test_mean)\n", "            else:\n", "                ajusted_test[feature] *= ajust_factor\n", "        except:\n", "            to_exclude.append(feature)\n", "            print(feature, train_mean, test_mean)"]}, {"cell_type": "code", "execution_count": 16, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:29:49.582855Z", "start_time": "2019-12-18T18:29:49.468165Z"}}, "outputs": [], "source": ["features = [x for x in features if x not in to_exclude]\n", "reduce_train[features].shape"]}, {"cell_type": "code", "execution_count": 17, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:32:27.036055Z", "start_time": "2019-12-18T18:29:49.585849Z"}}, "outputs": [], "source": ["y_lgb_pred = 0\n", "for i in range(10):\n", "    y_lgb_pred += run_lgb_regression(reduce_train, ajusted_test, features, 5, random_state=i) / 10"]}, {"cell_type": "code", "execution_count": 18, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:03.104549Z", "start_time": "2019-12-18T18:32:27.038947Z"}}, "outputs": [], "source": ["y_lgb_pred = 0\n", "for i in range(10):\n", "    y_lgb_pred += run_lgb_regression(reduce_train, ajusted_test, features, 5, random_state=i) / 10\n", "\n", "y_xgb_pred = run_xgb_regression(reduce_train, ajusted_test, features, 5)"]}, {"cell_type": "code", "execution_count": 19, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:03.111530Z", "start_time": "2019-12-18T18:44:03.106529Z"}}, "outputs": [], "source": ["lgb_weight = 0.7\n", "final_pred = y_lgb_pred * lgb_weight + y_xgb_pred * (1 - lgb_weight)\n", "print(final_pred.shape, y_lgb_pred.shape, y_xgb_pred.shape)"]}, {"cell_type": "code", "execution_count": 20, "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:03.279658Z", "start_time": "2019-12-18T18:44:03.114494Z"}}, "outputs": [], "source": ["dist = Counter(reduce_train['accuracy_group'])\n", "for k in dist:\n", "    dist[k] /= len(reduce_train)\n", "reduce_train['accuracy_group'].hist()\n", "\n", "acum = 0\n", "bound = {}\n", "for i in range(3):\n", "    acum += dist[i]\n", "    bound[i] = np.percentile(final_pred, acum * 100)\n", "print(bound)\n", "\n", "def classify(x):\n", "    if x <= bound[0]:\n", "        return 0\n", "    elif x <= bound[1]:\n", "        return 1\n", "    elif x <= bound[2]:\n", "        return 2\n", "    else:\n", "        return 3\n", "    \n", "final_pred = np.array(list(map(classify, final_pred)))\n", "\n", "sample_submission['accuracy_group'] = final_pred.astype(int)\n", "sample_submission.to_csv('submission.csv', index=False)\n", "sample_submission['accuracy_group'].value_counts(normalize=True)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": []}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:30.721819Z", "start_time": "2019-12-18T18:44:29.245442Z"}}, "source": ["import abc\n", "import codecs\n", "import inspect\n", "import json\n", "import logging\n", "import gc\n", "import pickle\n", "import sys\n", "import time\n", "import warnings\n", "\n", "import catboost as cat\n", "import lightgbm as lgb\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pandas as pd\n", "import seaborn as sns\n", "import yaml\n", "\n", "from abc import abstractmethod\n", "from contextlib import contextmanager\n", "from pathlib import Path\n", "from numba import jit\n", "from typing import List, Optional, Union, Tuple, Dict\n", "\n", "from catboost import CatBoostClassifier, CatBoostRegressor\n", "from sklearn.model_selection import train_test_split, GroupKFold\n", "from tqdm import tqdm_notebook"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:30.732729Z", "start_time": "2019-12-18T18:44:30.723776Z"}}, "source": ["conf_string = '''\n", "dataset:\n", "  dir: \"../input/data-science-bowl-2019/\"\n", "  feature_dir: \"features\"\n", "  params:\n", "\n", "features:\n", "  - Basic\n", "\n", "av:\n", "  split_params:\n", "    test_size: 0.33\n", "    random_state: 42\n", "\n", "  model_params:\n", "    objective: \"binary\"\n", "    metric: \"auc\"\n", "    boosting: \"gbdt\"\n", "    max_depth: 7\n", "    num_leaves: 75\n", "    learning_rate: 0.01\n", "    colsample_bytree: 0.7\n", "    subsample: 0.1\n", "    subsample_freq: 1\n", "    seed: 111\n", "    feature_fraction_seed: 111\n", "    drop_seed: 111\n", "    verbose: -1\n", "    first_metric_only: True\n", "\n", "  train_params:\n", "    num_boost_round: 1000\n", "    early_stopping_rounds: 100\n", "    verbose_eval: 100\n", "\n", "model:\n", "  name: \"catboost\"\n", "  model_params:\n", "    loss_function: \"MultiClass\"\n", "    eval_metric: \"WKappa\"\n", "    task_type: \"CPU\"\n", "    iterations: 6000\n", "    early_stopping_rounds: 500\n", "    random_seed: 42\n", "\n", "  train_params:\n", "    mode: \"classification\"\n", "\n", "val:\n", "  name: \"group_kfold\"\n", "  params:\n", "    n_splits: 5\n", "\n", "output_dir: \"output\"\n", "'''"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:30.926434Z", "start_time": "2019-12-18T18:44:30.916493Z"}}, "source": ["config = dict(yaml.load(conf_string, Loader=yaml.SafeLoader))"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:34.199308Z", "start_time": "2019-12-18T18:44:34.182354Z"}}, "source": ["# type alias\n", "AoD = Union[np.ndarray, pd.DataFrame]\n", "AoS = Union[np.ndarray, pd.Series]\n", "CatModel = Union[cat.CatBoostClassifier, cat.CatBoostRegressor]\n", "LGBModel = Union[lgb.LGBMClassifier, lgb.LGBMRegressor]\n", "Model = Union[CatModel, LGBModel]\n", "\n", "\n", "class BaseModel(object):\n", "    @abstractmethod\n", "    def fit(self, x_train: AoD, y_train: AoS, x_valid: AoD, y_valid: AoS,\n", "            config: dict) -> Tuple[Model, dict]:\n", "        raise NotImplementedError\n", "\n", "    @abstractmethod\n", "    def get_best_iteration(self, model: Model) -> int:\n", "        raise NotImplementedError\n", "\n", "    @abstractmethod\n", "    def predict(self, model: Model, features: AoD) -> np.ndarray:\n", "        raise NotImplementedError\n", "\n", "    @abstractmethod\n", "    def get_feature_importance(self, model: Model) -> np.ndarray:\n", "        raise NotImplementedError\n", "\n", "    def cv(self,\n", "           y_train: AoS,\n", "           train_features: AoD,\n", "           test_features: AoD,\n", "           feature_name: List[str],\n", "           folds_ids: List[Tuple[np.ndarray, np.ndarray]],\n", "           config: dict,\n", "           log: bool = True\n", "           ) -> Tuple[List[Model], np.ndarray, np.ndarray, pd.DataFrame, dict]:\n", "        # initialize\n", "        test_preds = np.zeros(len(test_features))\n", "        oof_preds = np.zeros(len(train_features))\n", "        importances = pd.DataFrame(index=feature_name)\n", "        best_iteration = 0.0\n", "        cv_score_list: List[dict] = []\n", "        models: List[Model] = []\n", "\n", "        X = train_features.values if isinstance(train_features, pd.DataFrame) \\\n", "            else train_features\n", "        y = y_train.values if isinstance(y_train, pd.Series) \\\n", "            else y_train\n", "\n", "        for i_fold, (trn_idx, val_idx) in enumerate(folds_ids):\n", "            # get train data and valid data\n", "            x_trn = X[trn_idx]\n", "            y_trn = y[trn_idx]\n", "            x_val = X[val_idx]\n", "            y_val = y[val_idx]\n", "\n", "            # train model\n", "            model, best_score = self.fit(x_trn, y_trn, x_val, y_val, config)\n", "            cv_score_list.append(best_score)\n", "            models.append(model)\n", "            best_iteration += self.get_best_iteration(model) / len(folds_ids)\n", "\n", "            # predict oof and test\n", "            oof_preds[val_idx] = self.predict(model, x_val).reshape(-1)\n", "            test_preds += self.predict(\n", "                model, test_features).reshape(-1) / len(folds_ids)\n", "\n", "            # get feature importances\n", "            importances_tmp = pd.DataFrame(\n", "                self.get_feature_importance(model),\n", "                columns=[f\"gain_{i_fold+1}\"],\n", "                index=feature_name)\n", "            importances = importances.join(importances_tmp, how=\"inner\")\n", "\n", "        # summary of feature importance\n", "        feature_importance = importances.mean(axis=1)\n", "\n", "        # print oof score\n", "        oof_score = calc_metric(y_train, oof_preds)\n", "        print(f\"oof score: {oof_score:.5f}\")\n", "\n", "        if log:\n", "            logging.info(f\"oof score: {oof_score:.5f}\")\n", "\n", "        evals_results = {\n", "            \"evals_result\": {\n", "                \"oof_score\":\n", "                oof_score,\n", "                \"cv_score\": {\n", "                    f\"cv{i + 1}\": cv_score\n", "                    for i, cv_score in enumerate(cv_score_list)\n", "                },\n", "                \"n_data\":\n", "                len(train_features),\n", "                \"best_iteration\":\n", "                best_iteration,\n", "                \"n_features\":\n", "                len(train_features.columns),\n", "                \"feature_importance\":\n", "                feature_importance.sort_values(ascending=False).to_dict()\n", "            }\n", "        }\n", "\n", "        return models, oof_preds, test_preds, feature_importance, evals_results"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:35.730849Z", "start_time": "2019-12-18T18:44:35.723869Z"}}, "source": ["CatModel = Union[CatBoostClassifier, CatBoostRegressor]\n", "\n", "\n", "class CatBoost(BaseModel):\n", "    def fit(self, x_train: np.ndarray, y_train: np.ndarray,\n", "            x_valid: np.ndarray, y_valid: np.ndarray,\n", "            config: dict) -> Tuple[CatModel, dict]:\n", "        model_params = config[\"model\"][\"model_params\"]\n", "        mode = config[\"model\"][\"train_params\"][\"mode\"]\n", "        if mode == \"regression\":\n", "            model = CatBoostRegressor(**model_params)\n", "        else:\n", "            model = CatBoostClassifier(**model_params)\n", "\n", "        model.fit(\n", "            x_train,\n", "            y_train,\n", "            eval_set=(x_valid, y_valid),\n", "            use_best_model=True,\n", "            verbose=model_params[\"early_stopping_rounds\"])\n", "        best_score = model.best_score_\n", "        return model, best_score\n", "\n", "    def get_best_iteration(self, model: CatModel):\n", "        return model.best_iteration_\n", "\n", "    def predict(self, model: CatModel,\n", "                features: Union[pd.DataFrame, np.ndarray]) -> np.ndarray:\n", "        return model.predict(features)\n", "\n", "    def get_feature_importance(self, model: CatModel) -> np.ndarray:\n", "        return model.feature_importances_"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:44:36.840840Z", "start_time": "2019-12-18T18:44:36.836819Z"}}, "source": ["def catboost() -> CatBoost:\n", "    return CatBoost()\n", "\n", "\n", "def get_model(config: dict):\n", "    model_name = config[\"model\"][\"name\"]\n", "    func = globals().get(model_name)\n", "    if func is None:\n", "        raise NotImplementedError\n", "    return func()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["kf = StratifiedKFold(n_splits=n_splits, shuffle = True, random_state = 42)\n", "target = 'accuracy_group'\n", "oof_pred = np.zeros((len(reduce_train), ))\n", "y_pred = np.zeros((len(reduce_test), ))\n", "for fold, (tr_ind, val_ind) in enumerate(kf.split(reduce_train, reduce_train[target])):\n", "    print('Fold {}'.format(fold + 1))\n", "    x_train, x_val = reduce_train[usefull_features].iloc[tr_ind], reduce_train[usefull_features].iloc[val_ind]\n", "    y_train, y_val = reduce_train[target][tr_ind], reduce_train[target][val_ind]"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:53:01.485034Z", "start_time": "2019-12-18T18:53:01.477055Z"}}, "source": ["def group_kfold(df: pd.DataFrame, groups: pd.Series,\n", "                config: dict) -> List[Tuple[np.ndarray, np.ndarray]]:\n", "    params = config[\"val\"][\"params\"]\n", "    kf = GroupKFold(n_splits=params[\"n_splits\"])\n", "    split = list(kf.split(df, groups=groups))\n", "    return split\n", "\n", "\n", "def get_validation(df: pd.DataFrame,\n", "                   config: dict) -> List[Tuple[np.ndarray, np.ndarray]]:\n", "    name: str = config[\"val\"][\"name\"]\n", "\n", "    func = globals().get(name)\n", "    if func is None:\n", "        raise NotImplementedError\n", "\n", "    if \"group\" in name:\n", "        cols = df.columns.tolist()\n", "        cols.remove(\"group\")\n", "        groups = df[\"group\"]\n", "        return func(df[cols], groups, config)\n", "    else:\n", "        return func(df, config)"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"end_time": "2019-12-18T18:55:03.816846Z", "start_time": "2019-12-18T18:55:03.709135Z"}}, "source": ["n_splits=5\n", "target = 'accuracy_group'\n", "y_train = reduce_train[target]\n", "x_train = reduce_train[features]\n", "x_test = ajusted_test[features]\n", "cols: List[str] = x_train.columns.tolist()\n", "kf = (StratifiedKFold(n_splits=n_splits, shuffle = True, random_state = 42))\n", "splits = list(kf.split(x_train,y_train))"]}, {"cell_type": "markdown", "metadata": {"ExecuteTime": {"start_time": "2019-12-18T18:55:05.619Z"}}, "source": ["model = get_model(config)\n", "models, oof_preds, test_preds, feature_importance, eval_results = model.cv(\n", "    y_train, x_train, x_test, cols, splits, config, log=True)\n", "\n", "config[\"eval_results\"] = dict()\n", "for k, v in eval_results.items():\n", "    config[\"eval_results\"][k] = v\n", "\n", "feature_imp = feature_importance.reset_index().rename(columns={\n", "    \"index\": \"feature\",\n", "    0: \"value\"\n", "})\n", "plt.figure(figsize=(20, 10))\n", "sns.barplot(\n", "    x=\"value\",\n", "    y=\"feature\",\n", "    data=feature_imp.sort_values(by=\"value\", ascending=False).head(50))\n", "plt.title(\"Model Features\")\n", "plt.tight_layout()\n", "plt.savefig(output_dir / \"feature_importance_model.png\")"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": []}], "metadata": {"kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0"}, "widgets": {"application/vnd.jupyter.widget-state+json": {"state": {"0347dcb141204ebbb815612d3dc6cd46": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_d60aa3102d1e4f51bde1f5389c33038d", "IPY_MODEL_0f29ee46997e4718a0ab2c4963a39137"], "layout": "IPY_MODEL_1725ca7be005423d85f211c4fd79bc5e"}}, "0f29ee46997e4718a0ab2c4963a39137": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_ceadfdd037d1412d96a448f6b6d933db", "placeholder": "\u00e2\u20ac\u2039", "style": "IPY_MODEL_624eb6512c204c1b8064f5f13733c027", "value": " 17000/17000 [06:47&lt;00:00, 41.71it/s]"}}, "0fb911098dda40f0ba5c712615a22e9b": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_def5de6807dd479d890fa95812d31953", "placeholder": "\u00e2\u20ac\u2039", "style": "IPY_MODEL_6a5f82564d0a4e979a6f6de8152210a0", "value": " 1000/1000 [00:48&lt;00:00, 20.62it/s]"}}, "1725ca7be005423d85f211c4fd79bc5e": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "624eb6512c204c1b8064f5f13733c027": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": ""}}, "6a5f82564d0a4e979a6f6de8152210a0": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": ""}}, "70d39773f6b94e23b108ffbd8c4c2451": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "7ecc98e0df7c44dba27f055ba57f4385": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial"}}, "8e41a87d7ef24e1d8a8397fef905c774": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_ec43eff7bf6e4fc3991189cfe57eb25d", "max": 1000, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_b813338f697a4bd9b89caa53d0c2c0b7", "value": 1000}}, "b813338f697a4bd9b89caa53d0c2c0b7": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "initial"}}, "ceadfdd037d1412d96a448f6b6d933db": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "d60aa3102d1e4f51bde1f5389c33038d": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "100%", "description_tooltip": null, "layout": "IPY_MODEL_70d39773f6b94e23b108ffbd8c4c2451", "max": 17000, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_7ecc98e0df7c44dba27f055ba57f4385", "value": 17000}}, "dc771ba093ce455f857ecd2d7fbc5872": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_8e41a87d7ef24e1d8a8397fef905c774", "IPY_MODEL_0fb911098dda40f0ba5c712615a22e9b"], "layout": "IPY_MODEL_fb861edde3da400895d5fad6f2044a1c"}}, "def5de6807dd479d890fa95812d31953": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "ec43eff7bf6e4fc3991189cfe57eb25d": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "fb861edde3da400895d5fad6f2044a1c": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}}, "version_major": 2, "version_minor": 0}}}, "nbformat": 4, "nbformat_minor": 1}