{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Imports","metadata":{}},{"cell_type":"code","source":"import os\nimport re\nimport pandas as pd\nimport numpy as np\nfrom collections import defaultdict\n\nimport csv\n\nfrom gensim.utils import simple_preprocess\n\nfrom sklearn.model_selection import train_test_split\n\nimport fasttext","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:10.102432Z","iopub.execute_input":"2022-08-08T07:34:10.102751Z","iopub.status.idle":"2022-08-08T07:34:10.109255Z","shell.execute_reply.started":"2022-08-08T07:34:10.102725Z","shell.execute_reply":"2022-08-08T07:34:10.108439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Get data","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(\"../input/feedback-prize-effectiveness/train.csv\")\ntest_df = pd.read_csv(\"../input/feedback-prize-effectiveness/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:10.162636Z","iopub.execute_input":"2022-08-08T07:34:10.163535Z","iopub.status.idle":"2022-08-08T07:34:10.352095Z","shell.execute_reply.started":"2022-08-08T07:34:10.163498Z","shell.execute_reply":"2022-08-08T07:34:10.351472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prepare dataset file for fasttext","metadata":{}},{"cell_type":"markdown","source":"1. Add the full text","metadata":{}},{"cell_type":"code","source":"def get_full_essay(filename: str, mode: str, texts_dict: dict) -> str:\n    fp = f\"../input/feedback-prize-effectiveness/{mode}/{filename}.txt\"\n    try:\n        text = texts_dict[fp]\n    except:\n        try:\n            text = open(fp, \"r\").read()\n        except:\n            text = \"no further text is given.\"\n        text = \" \".join(simple_preprocess(text))\n        texts_dict[fp] = text\n    return text\n\n\ntexts_dict = dict()\ntrain_df[\"essay\"] = train_df[\"essay_id\"].apply(lambda x: get_full_essay(x, \"train\", texts_dict))\ntest_df[\"essay\"] = test_df[\"essay_id\"].apply(lambda x: get_full_essay(x, \"test\", texts_dict))","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:10.498063Z","iopub.execute_input":"2022-08-08T07:34:10.499136Z","iopub.status.idle":"2022-08-08T07:34:14.910005Z","shell.execute_reply.started":"2022-08-08T07:34:10.499108Z","shell.execute_reply":"2022-08-08T07:34:14.909363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2. Add some custom features and gensim preprocessing.","metadata":{}},{"cell_type":"code","source":"def locate(discourse: str, essay: str) -> str:\n    match = re.search(discourse, essay)\n    if match:\n        span = np.array([match.start(), match.end()]) / (len(essay) + 1)\n    else:\n        span = np.arange(2)\n    return \" \".join(span.round(2).astype(\"str\"))\n\n\ntrain_df[\"discourse_text\"] = train_df[\"discourse_text\"].apply(lambda x: \" \".join(simple_preprocess(x)))\ntest_df[\"discourse_text\"] = test_df[\"discourse_text\"].apply(lambda x: \" \".join(simple_preprocess(x)))\n\ntrain_df[\"essay_length\"] = train_df[\"essay\"].apply(lambda x: len(x)).astype(\"str\")\ntest_df[\"essay_length\"] = test_df[\"essay\"].apply(lambda x: len(x)).astype(\"str\")\n\ntrain_df[\"discourse_length\"] = train_df[\"discourse_text\"].apply(lambda x: len(x)).astype(\"str\")\ntest_df[\"discourse_length\"] = test_df[\"discourse_text\"].apply(lambda x: len(x)).astype(\"str\")\n\ntrain_df[\"discourse_position\"] = train_df.apply(lambda x: locate(x.discourse_text, x.essay), axis=1)\ntest_df[\"discourse_position\"] = test_df.apply(lambda x: locate(x.discourse_text, x.essay), axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:14.911810Z","iopub.execute_input":"2022-08-08T07:34:14.912990Z","iopub.status.idle":"2022-08-08T07:34:38.846240Z","shell.execute_reply.started":"2022-08-08T07:34:14.912954Z","shell.execute_reply":"2022-08-08T07:34:38.845652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"3. Encode the classes","metadata":{}},{"cell_type":"code","source":"train_df[\"class\"] = train_df[\"discourse_effectiveness\"].apply(lambda x: f\"__label__{x}\")","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:38.847406Z","iopub.execute_input":"2022-08-08T07:34:38.847688Z","iopub.status.idle":"2022-08-08T07:34:38.865831Z","shell.execute_reply.started":"2022-08-08T07:34:38.847663Z","shell.execute_reply":"2022-08-08T07:34:38.864966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"4.1 Join needed columns and add simple preprocess from gensim","metadata":{}},{"cell_type":"code","source":"train_df[\"text\"] = train_df.apply(lambda x:\" \".join([\n    x.essay_length,\n    x.discourse_length,\n    x.discourse_position,\n    x.discourse_text,\n    x.essay,\n    x.discourse_type\n]), axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:38.868153Z","iopub.execute_input":"2022-08-08T07:34:38.868369Z","iopub.status.idle":"2022-08-08T07:34:40.620135Z","shell.execute_reply.started":"2022-08-08T07:34:38.868348Z","shell.execute_reply":"2022-08-08T07:34:40.619231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df[\"text\"] = test_df.apply(lambda x:\" \".join([\n    x.essay_length,\n    x.discourse_length,\n    x.discourse_position,\n    x.discourse_text,\n    x.essay,\n    x.discourse_type\n]), axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:40.620973Z","iopub.execute_input":"2022-08-08T07:34:40.621196Z","iopub.status.idle":"2022-08-08T07:34:40.628732Z","shell.execute_reply.started":"2022-08-08T07:34:40.621174Z","shell.execute_reply":"2022-08-08T07:34:40.627805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"4.2 Split train dataset to train and validation","metadata":{}},{"cell_type":"code","source":"train_df, val_df = train_test_split(train_df, stratify=train_df[\"class\"])","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:40.630064Z","iopub.execute_input":"2022-08-08T07:34:40.630513Z","iopub.status.idle":"2022-08-08T07:34:40.719596Z","shell.execute_reply.started":"2022-08-08T07:34:40.630484Z","shell.execute_reply":"2022-08-08T07:34:40.718623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"4.3 Save filse","metadata":{}},{"cell_type":"code","source":"train_text_fp = \"train.txt\"\nval_text_fp = \"val.txt\"\n\ntrain_df[[\"class\", \"text\"]].to_csv(\n    train_text_fp,\n    index = False, \n    sep = \" \",\n    header = None, \n    quoting = csv.QUOTE_NONE, \n    quotechar = \"\", \n    escapechar = \" \"\n)\n\nval_df[[\"class\", \"text\"]].to_csv(\n    val_text_fp,\n    index = False, \n    sep = \" \",\n    header = None, \n    quoting = csv.QUOTE_NONE, \n    quotechar = \"\", \n    escapechar = \" \"\n)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:40.721476Z","iopub.execute_input":"2022-08-08T07:34:40.721880Z","iopub.status.idle":"2022-08-08T07:34:42.575490Z","shell.execute_reply.started":"2022-08-08T07:34:40.721857Z","shell.execute_reply":"2022-08-08T07:34:42.574560Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## FastText model","metadata":{}},{"cell_type":"markdown","source":"Train","metadata":{}},{"cell_type":"code","source":"model = fasttext.train_supervised(\n    train_text_fp,\n    epoch=8,\n    dim=128,\n    neg=10,\n    ws=15,\n    wordNgrams=3,\n    lr=1.,\n    lrUpdateRate=100,\n    thread=40,\n    loss=\"hs\"\n)\nmodel.test(val_text_fp) ","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:34:42.577094Z","iopub.execute_input":"2022-08-08T07:34:42.577446Z","iopub.status.idle":"2022-08-08T07:35:16.802549Z","shell.execute_reply.started":"2022-08-08T07:34:42.577383Z","shell.execute_reply":"2022-08-08T07:35:16.801212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Make predictions","metadata":{}},{"cell_type":"code","source":"result_dict = defaultdict(list)\n\nfor _, row in test_df.iterrows():\n    result_dict[\"discourse_id\"].append(row[\"discourse_id\"])\n    labels, probas = model.predict(row[\"text\"], k=3)\n    if len(labels) == 3:\n        result_dict[\"Ineffective\"].append(probas[labels.index(\"__label__Ineffective\")])\n        result_dict[\"Adequate\"].append(probas[labels.index(\"__label__Adequate\")])\n        result_dict[\"Effective\"].append(probas[labels.index(\"__label__Effective\")])\n    else:\n        result_dict[\"Ineffective\"].append(0.0)\n        result_dict[\"Adequate\"].append(0.0)\n        result_dict[\"Effective\"].append(0.0)\n    \n    \nfor k in result_dict:\n    print(k, len(result_dict[k]))\nresult = pd.DataFrame(data=result_dict)\nresult = result[[\"discourse_id\", \"Ineffective\", \"Adequate\", \"Effective\"]]\nresult.to_csv(\"submission.csv\", index = False)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:35:16.804036Z","iopub.execute_input":"2022-08-08T07:35:16.804254Z","iopub.status.idle":"2022-08-08T07:35:16.849080Z","shell.execute_reply.started":"2022-08-08T07:35:16.804232Z","shell.execute_reply":"2022-08-08T07:35:16.848524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Compare to sample submission.","metadata":{}},{"cell_type":"code","source":"pd.read_csv(\"submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:35:16.850929Z","iopub.execute_input":"2022-08-08T07:35:16.851149Z","iopub.status.idle":"2022-08-08T07:35:16.953601Z","shell.execute_reply.started":"2022-08-08T07:35:16.851126Z","shell.execute_reply":"2022-08-08T07:35:16.952804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.read_csv(\"../input/feedback-prize-effectiveness/sample_submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:35:16.954678Z","iopub.execute_input":"2022-08-08T07:35:16.954901Z","iopub.status.idle":"2022-08-08T07:35:16.968237Z","shell.execute_reply.started":"2022-08-08T07:35:16.954879Z","shell.execute_reply":"2022-08-08T07:35:16.967688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm train.txt\n!rm val.txt","metadata":{"execution":{"iopub.status.busy":"2022-08-08T07:35:16.969117Z","iopub.execute_input":"2022-08-08T07:35:16.969713Z","iopub.status.idle":"2022-08-08T07:35:17.690364Z","shell.execute_reply.started":"2022-08-08T07:35:16.969690Z","shell.execute_reply":"2022-08-08T07:35:17.689207Z"},"trusted":true},"execution_count":null,"outputs":[]}]}