{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import riiideducation\nimport pandas as pd, numpy as np\nfrom tqdm.notebook import tqdm\nimport json\n\n# You can only call make_env() once, so don't lose it!\nenv = riiideducation.make_env()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DTYPE={\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    }\n\nUSECOLS = [\"user_id\", \"content_id\", \"answered_correctly\"]\nCHUNKSIZE = 10**7","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class StreamingStats:\n    def __init__(self):\n        self.stats = {}\n        \n    def add_item(self, item, score, weight=1):\n        stat = self.stats.get(item)\n        if stat is not None:\n            stat[\"ncount\"] += weight\n            stat[\"cum_score\"] += score\n            stat[\"score\"] = stat[\"cum_score\"]/stat[\"ncount\"]\n        else:\n            self.stats[item] = {\"ncount\": weight, \"cum_score\": score, \"score\": score/weight}\n            \n    def mean(self, item):\n        stat =  self.stats.get(item)\n        return stat[\"score\"] if stat is not None else 0.\n    \n    def __repr__(self):\n        return \"<StreamingStats of size {} >\".format(len(self.stats))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"user_stats = StreamingStats()\ncontent_stats = StreamingStats()\n\nuser_stats, content_stats","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"chunked_df = pd.read_csv(\"../input/riiid-test-answer-prediction/train.csv\", usecols=USECOLS, chunksize=CHUNKSIZE)\nchunked_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for df in tqdm(chunked_df):\n    \n    df = df[df[\"answered_correctly\"].isin([0,1])]\n    \n    stats = df.groupby(\"user_id\")[\"answered_correctly\"].agg([\"count\", \"sum\"])\n    for user_id,row in stats.iterrows():\n        user_stats.add_item(user_id , row[\"sum\"], row[\"count\"])\n        \n    stats = df.groupby(\"content_id\")[\"answered_correctly\"].agg([\"count\", \"sum\"])\n    for content_id,row in stats.iterrows():\n        content_stats.add_item(content_id , row[\"sum\"], row[\"count\"])\n        \nuser_stats, content_stats","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def scorer(u_score, c_score, beta=1.0, epsilon=1e-6):\n    return (1+beta)*u_score*c_score/(epsilon + u_score + beta*c_score)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def predict(user_id, content_id, beta=1.0):\n    u_score = user_stats.stats.get(user_id)\n    if u_score is None:\n        c_score = content_stats.stats.get(content_id)\n        if c_score is None: return 0.5\n        return c_score[\"score\"]\n    else:\n        c_score = content_stats.stats.get(content_id)\n        if c_score is None: return u_score[\"score\"]\n        return scorer(u_score[\"score\"], c_score[\"score\"], beta=beta)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def predict(user_id, content_id, beta=1.0):\n#     u_score = (user_stats.stats.get(user_id) or {\"score\": 0.5})[\"score\"]\n#     c_score = (content_stats.stats.get(content_id) or {\"score\": 0.5})[\"score\"]\n#     return scorer(u_score, c_score, beta=beta)\n\n\ndef predict_from_df(test_df, beta=1.0, update=True):\n    test_df = test_df.loc[test_df['content_type_id'] == 0]\n    \n    answers_correct_not_null = test_df[\"prior_group_answers_correct\"].notnull()\n    \n    scores = []\n    \n    for user_id, content_id, answers_correct, notnull in zip(test_df[\"user_id\"], test_df[\"content_id\"], \n                                                                test_df[\"prior_group_answers_correct\"], answers_correct_not_null):\n        \n        score = predict(user_id, content_id, beta=beta)\n        scores.append(score)\n        \n        \n        if update and notnull and answers_correct:\n#             print(answers_correct)\n            answers_correct = json.loads(answers_correct.strip())\n            if len(answers_correct):\n                user_stats.add_item(user_id, np.sum(answers_correct), weight=len(answers_correct))\n    \n    test_df['answered_correctly'] = [predict(user_id, content_id, beta=beta)  \n                                     for user_id, content_id in zip(test_df[\"user_id\"], test_df[\"content_id\"])]\n    return test_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BETA = 2.5\nUPDATE = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(\"../input/riiid-test-answer-prediction/example_test.csv\")\npredict_from_df(test_df, beta=BETA, update=UPDATE)[[\"row_id\", \"user_id\", \"content_id\", \"answered_correctly\"]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\niter_test = env.iter_test()\nfor (test_df, sample_prediction_df) in iter_test:\n    env.predict(predict_from_df(test_df, beta=BETA, update=UPDATE)[['row_id', 'answered_correctly']])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}