{"cells":[{"metadata":{},"cell_type":"markdown","source":"This script can be run in the kaggle environment.\nGPU accelerator is required.\n\nThe original script is [CV Strategy](https://www.kaggle.com/its7171/cv-strategy)."},{"metadata":{"trusted":true},"cell_type":"code","source":"import gc\nimport random\nimport numpy as np\nimport pandas as pd\nimport cudf\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def fast_merge(left, right, key):\n    return cudf.concat([left.reset_index(drop=True), right.reindex(left[key].values).reset_index(drop=True)], axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"seed = 1\nrandom.seed(seed)\nnp.random.seed(seed)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The users are slightly biased in the original script.\nPlease see [this notebook](https://www.kaggle.com/marisakamozz/riiid-cv-strategy-users-are-slightly-biased) for details.\nTherefore, I will sample random numbers from the beta distribution instead of the uniform distribution."},{"metadata":{"trusted":true},"cell_type":"code","source":"a = 2.2\nb = 2.3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"size = 1000000\nsamples = np.random.beta(a, b, size)\nsamples = pd.Series(samples)\nsamples.hist(bins=100)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dtypes = {\n    'row_id': 'int64',\n    'timestamp': 'int64',\n    'user_id': 'int32',\n    'content_id': 'int16',\n    'content_type_id': 'int8',\n    'task_container_id': 'int16',\n    'user_answer': 'int8',\n    'answered_correctly':'int8',\n    'prior_question_elapsed_time': 'float32',\n    'prior_question_had_explanation': 'boolean'\n}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"%%time\ntrain = cudf.read_csv('/kaggle/input/riiid-test-answer-prediction/train.csv', dtype=dtypes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"max_timestamp_u = train[['user_id','timestamp']].groupby(['user_id']).max()\nmax_timestamp_u.columns = ['max_timestamp']\nmax_timestamp_u['interval'] = max_timestamp_u.max_timestamp.max() - max_timestamp_u.max_timestamp\n# max_timestamp_u['random'] = np.random.rand(len(max_timestamp_u))\nmax_timestamp_u['random'] = np.random.beta(a, b, len(max_timestamp_u))\nmax_timestamp_u['random_timestamp'] = max_timestamp_u.interval * max_timestamp_u.random\nmax_timestamp_u['random_timestamp'] = max_timestamp_u.random_timestamp.astype(int)\nmax_timestamp_u.drop(['interval', 'random'], axis=1, inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"max_timestamp_u.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = fast_merge(train, max_timestamp_u, 'user_id')\ntrain['virtual_timestamp'] = train.timestamp + train.random_timestamp\ntrain.set_index(['virtual_timestamp', 'row_id'], inplace=True)\ntrain.sort_index(inplace=True)\ntrain.reset_index(inplace=True)\ntrain.drop(columns=['max_timestamp', 'random_timestamp'], inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"last100m = train[-100000000:]\ninterval = 2500000\nmean_max_timestamp = []\ntarget_means = []\nfor i in range(40):\n    start = i * interval\n    user_list = last100m[start:start+interval].user_id.unique()\n    mean_max_timestamp.append(max_timestamp_u[['max_timestamp']].reindex(user_list).mean())\n    temp = last100m[last100m.answered_correctly != -1]\n    target_means.append(temp[start:start+interval].answered_correctly.mean())\nmean_max_timestamp = cudf.concat(mean_max_timestamp).to_pandas()\ntarget_means = pd.Series(target_means)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.bar(list(range(40)), mean_max_timestamp)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"target_means.plot()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"last10m = train[-10000000:]\ninterval = 1000000\nmean_max_timestamp = []\ntarget_means = []\nfor i in range(10):\n    start = i * interval\n    user_list = last10m[start:start+interval].user_id.unique()\n    mean_max_timestamp.append(max_timestamp_u[['max_timestamp']].reindex(user_list).mean())\n    temp = last10m[last10m.answered_correctly != -1]\n    target_means.append(temp[start:start+interval].answered_correctly.mean())\nmean_max_timestamp = cudf.concat(mean_max_timestamp).to_pandas()\ntarget_means = pd.Series(target_means)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.bar(list(range(10)), mean_max_timestamp)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"target_means.plot()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The timestamps are almost the same, but the accuracy rate is lower. It is difficult to make an unbiased CV.\nYou may want to throw away the last 2.5 million."},{"metadata":{"trusted":true},"cell_type":"code","source":"val_size = 2500000\nfor cv in range(5):\n    valid = train[-val_size:]\n    train = train[:-val_size]\n    valid.to_parquet(f'cv{cv+1}_valid.parquet')\n    train.to_parquet(f'cv{cv+1}_train.parquet')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}