diff --git a/year_prediction/ENV.yml b/year_prediction/ENV.yml new file mode 100644 index 0000000..66f3a50 --- /dev/null +++ b/year_prediction/ENV.yml @@ -0,0 +1,15 @@ +name: year_prediction +channels: + - defaults +dependencies: + - python=3.8 + - jupyterlab[version='>=3.0.0,<4.0.0a0'] + - jupyterlab-lsp + - pandas + - datasets + - ca-certificates + - certifi + - openssl + - scikit-learn + - ipywidgets +prefix: /Users/dvanstrien/miniconda3/envs/year_prediction diff --git a/year_prediction/T0_history_blog_nb.ipynb b/year_prediction/T0_history_blog_nb.ipynb new file mode 100644 index 0000000..5a0579d --- /dev/null +++ b/year_prediction/T0_history_blog_nb.ipynb @@ -0,0 +1,358 @@ +{ + "cells": [ + { + "cell_type": "code", + "source": [ + "TOKEN = \"\"" + ], + "metadata": { + "id": "2Nxaf2vKlj5W" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "lIYdn1woOS1n" + }, + "outputs": [], + "source": [ + "import requests\n", + "from functools import lru_cache\n", + "headers = {\"Authorization\": f\"Bearer {TOKEN}\"}\n" + ] + }, + { + "cell_type": "code", + "source": [ + "api_urls = {\"bert-base-historic-english-cased\":\"https://api-inference.huggingface.co/models/dbmdz/bert-base-historic-english-cased\", \n", + " \"T0pp\": \"https://api-inference.huggingface.co/models/bigscience/T0pp\"}" + ], + "metadata": { + "id": "5xIGUhQ_TnMp" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "def query(payload, model=\"T0pp\"):\n", + "\tresponse = requests.post(api_urls[model], headers=headers, json=payload)\n", + "\treturn response.json()" + ], + "metadata": { + "id": "6bg22dO5NYhF" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "@lru_cache(maxsize=None)\n", + "def query_api(inputs, model=\"T0pp\"):\n", + " output = query({\n", + " \"inputs\": f\"{inputs}\",\n", + " },model)\n", + " return output\n" + ], + "metadata": { + "id": "lg1ZJuj8Ub79" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "def query_time(text, time=\"year\"):\n", + " input = f\"\"\"During which {time} was the following text likely to have been published?\n", + "Text: \"{text}\"\"\"\n", + " print(input)\n", + " return input, query_api(input)" + ], + "metadata": { + "id": "1FYcwRU2axWI" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "HAVE_A_DREAM = \"\"\"So even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream. I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident, that all men are created equal.\"\"\"" + ], + "metadata": { + "id": "PYB-7taKDj_Q" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "query_time(HAVE_A_DREAM)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "eM44W59IDrDo", + "outputId": "9a909c0f-cfcd-4dae-cef1-d690e3a9408e" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "During which year was the following text likely to have been published?\n", + "Text: \"So even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream. I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident, that all men are created equal.\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "('During which year was the following text likely to have been published?\\nText: \"So even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream. I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident, that all men are created equal.',\n", + " [{'generated_text': '1963'}])" + ] + }, + "metadata": {}, + "execution_count": 7 + } + ] + }, + { + "cell_type": "code", + "source": [ + "query_time(HAVE_A_DREAM, time='decade')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "GdRHHaPZEASb", + "outputId": "34985f7e-ea2e-48d7-8178-30f6486348f3" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "During which decade was the following text likely to have been published?\n", + "Text: \"So even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream. I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident, that all men are created equal.\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "('During which decade was the following text likely to have been published?\\nText: \"So even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream. I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident, that all men are created equal.',\n", + " [{'generated_text': '1960s'}])" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "source": [ + "Frankenstein = \"How slowly the time passes here, encompassed as I am by frost and snow! Yet a second step is taken towards my enterprise. I have hired a vessel and am occupied in collecting my sailors; those whom I have already engaged appear to be men on whom I can depend and are certainly possessed of dauntless courage. \"" + ], + "metadata": { + "id": "wPBXIrzRKL7H" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "query_time(Frankenstein)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "CabPR1o5KQyd", + "outputId": "7bfb3ad1-1490-4abe-d799-c1291917f6d6" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "During which year was the following text likely to have been published?\n", + "Text: \"How slowly the time passes here, encompassed as I am by frost and snow! Yet a second step is taken towards my enterprise. I have hired a vessel and am occupied in collecting my sailors; those whom I have already engaged appear to be men on whom I can depend and are certainly possessed of dauntless courage. \n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "('During which year was the following text likely to have been published?\\nText: \"How slowly the time passes here, encompassed as I am by frost and snow! Yet a second step is taken towards my enterprise. I have hired a vessel and am occupied in collecting my sailors; those whom I have already engaged appear to be men on whom I can depend and are certainly possessed of dauntless courage. ',\n", + " [{'generated_text': '1797'}])" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "query_time(Frankenstein, time=\"decade\")" + ], + "metadata": { + "id": "sw8ZlGL6KiZQ", + "outputId": "27314ea1-74a6-4a04-e194-61130430de33", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "During which decade was the following text likely to have been published?\n", + "Text: \"How slowly the time passes here, encompassed as I am by frost and snow! Yet a second step is taken towards my enterprise. I have hired a vessel and am occupied in collecting my sailors; those whom I have already engaged appear to be men on whom I can depend and are certainly possessed of dauntless courage. \n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "('During which decade was the following text likely to have been published?\\nText: \"How slowly the time passes here, encompassed as I am by frost and snow! Yet a second step is taken towards my enterprise. I have hired a vessel and am occupied in collecting my sailors; those whom I have already engaged appear to be men on whom I can depend and are certainly possessed of dauntless courage. ',\n", + " [{'generated_text': '18th century'}])" + ] + }, + "metadata": {}, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "source": [ + "SPANISH_TRAGEDIE_1587 = \"\"\"Then rest we heere a-while in our vnrest;\n", + " And feede our sorrowes with inward sighes,\n", + " For deepest cares break neuer into teares.\n", + " But wherefore sit I in a regall throne?\n", + " This better fits a wretches endles moane.\n", + " Yet this is higher then my fortunes reach,\n", + " And therefore better then my state deserues.\"\"\"" + ], + "metadata": { + "id": "YBHMw2FciXwq" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "query_time(SPANISH_TRAGEDIE_1587)" + ], + "metadata": { + "id": "bKZ5FkseU4ZD", + "outputId": "82b959d9-93f1-4432-eaa6-3a6b0574ed76", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "During which year was the following text likely to have been published?\n", + "Text: \"Then rest we heere a-while in our vnrest;\n", + " And feede our sorrowes with inward sighes,\n", + " For deepest cares break neuer into teares.\n", + " But wherefore sit I in a regall throne?\n", + " This better fits a wretches endles moane.\n", + " Yet this is higher then my fortunes reach,\n", + " And therefore better then my state deserues.\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "('During which year was the following text likely to have been published?\\nText: \"Then rest we heere a-while in our vnrest;\\n And feede our sorrowes with inward sighes,\\n For deepest cares break neuer into teares.\\n But wherefore sit I in a regall throne?\\n This better fits a wretches endles moane.\\n Yet this is higher then my fortunes reach,\\n And therefore better then my state deserues.',\n", + " [{'generated_text': '1602'}])" + ] + }, + "metadata": {}, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "source": [ + "query_time(SPANISH_TRAGEDIE_1587, time=\"century\")" + ], + "metadata": { + "id": "KrLhigIwbtJL", + "outputId": "1a8a024e-293d-4f6b-c155-1d98b5a091bb", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "During which century was the following text likely to have been published?\n", + "Text: \"Then rest we heere a-while in our vnrest;\n", + " And feede our sorrowes with inward sighes,\n", + " For deepest cares break neuer into teares.\n", + " But wherefore sit I in a regall throne?\n", + " This better fits a wretches endles moane.\n", + " Yet this is higher then my fortunes reach,\n", + " And therefore better then my state deserues.\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "('During which century was the following text likely to have been published?\\nText: \"Then rest we heere a-while in our vnrest;\\n And feede our sorrowes with inward sighes,\\n For deepest cares break neuer into teares.\\n But wherefore sit I in a regall throne?\\n This better fits a wretches endles moane.\\n Yet this is higher then my fortunes reach,\\n And therefore better then my state deserues.',\n", + " [{'generated_text': '16th'}])" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ] + } + ], + "metadata": { + "colab": { + "name": "T0_history_blog_nb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/year_prediction/date_prediction.ipynb b/year_prediction/date_prediction.ipynb new file mode 100644 index 0000000..882427b --- /dev/null +++ b/year_prediction/date_prediction.ipynb @@ -0,0 +1,1455 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b0b2cb97-d68e-489d-97ff-0ee88455d50f", + "metadata": {}, + "source": [ + "*Notebook is a WIP* \n", + "\n", + "Since T0 variants are big, this notebook uses the HF inference API. You will need to pass an API token to use this. You get a generous free allowance, but you could still burn through this quite quickly if you repeat things many times. `requests_cache` is used to cache requests which means that the same request isn't passed to the API multiple times. \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "151b5b9e-0609-4206-ac4f-3c32a6b981d5", + "metadata": {}, + "outputs": [], + "source": [ + "from datasets import load_dataset\n", + "from datasets import concatenate_datasets" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "db2d0055-a5f1-4cd0-9fb5-42002f831517", + "metadata": {}, + "outputs": [], + "source": [ + "def load_datasets():\n", + " en_dataset = load_dataset(\"bigscience-historical-texts/HIPE2020_sent-split\",'en')\n", + " en_dataset = en_dataset.map(lambda x: {\"language\": \"en\"})\n", + " fr_dataset = load_dataset(\"bigscience-historical-texts/HIPE2020_sent-split\",'fr')\n", + " fr_dataset = fr_dataset.map(lambda x: {\"language\": \"fr\"})\n", + " de_dataset = load_dataset(\"bigscience-historical-texts/HIPE2020_sent-split\",'de')\n", + " de_dataset = de_dataset.map(lambda x: {\"language\": \"de\"})\n", + " dataset = concatenate_datasets([fr_dataset['train'], fr_dataset['validation'], en_dataset['validation'],de_dataset['validation'],de_dataset['train']])\n", + " dataset = dataset.remove_columns([column for column in dataset.features.keys() if column not in ['tokens','id', 'date', \"language\"]])\n", + " return dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "17c253bf-9599-4688-a88c-3546b3493a21", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5d3e5e86652d4c31a476acf498e3bb22", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Downloading: 0%| | 0.00/19.6k [00:00\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idtokensdatelanguageyear_predtrue_yearerror
01540[Son, remplaçant, sera, probablement, Frank, C...1978-09-27fr2009197831
15431[B, .]1978-10-11fr18651978-113
2141[General, St, ., Julien, ,, besides, the, Rati...1800-10-21en17451800-55
33493[Le, GrasUdanin, donne, les, détails, suivants...1888-11-01fr1912188824
41659[Es, handelt, sich, um, folgendes, .]1898-11-07de18901898-8
........................
49813880[M, ., Pichon, ,, ministre, des, affaires, étr...1908-01-07fr18481908-60
49821400[Das, alte, Haus, hatte, sich, heute, in, den,...1888-10-15de189018882
4983902[Thait, Is, what, I, bave, to, say, about, Alf...1920-07-08en18801920-40
49842564[7, ., Hendrickx, (, Belgien, ), 4, P, .]1938-08-09de19121938-26
49851053[]1950-11-25en18651950-85
\n", + "

4986 rows × 7 columns

\n", + "" + ], + "text/plain": [ + " id tokens date \\\n", + "0 1540 [Son, remplaçant, sera, probablement, Frank, C... 1978-09-27 \n", + "1 5431 [B, .] 1978-10-11 \n", + "2 141 [General, St, ., Julien, ,, besides, the, Rati... 1800-10-21 \n", + "3 3493 [Le, GrasUdanin, donne, les, détails, suivants... 1888-11-01 \n", + "4 1659 [Es, handelt, sich, um, folgendes, .] 1898-11-07 \n", + "... ... ... ... \n", + "4981 3880 [M, ., Pichon, ,, ministre, des, affaires, étr... 1908-01-07 \n", + "4982 1400 [Das, alte, Haus, hatte, sich, heute, in, den,... 1888-10-15 \n", + "4983 902 [Thait, Is, what, I, bave, to, say, about, Alf... 1920-07-08 \n", + "4984 2564 [7, ., Hendrickx, (, Belgien, ), 4, P, .] 1938-08-09 \n", + "4985 1053 [] 1950-11-25 \n", + "\n", + " language year_pred true_year error \n", + "0 fr 2009 1978 31 \n", + "1 fr 1865 1978 -113 \n", + "2 en 1745 1800 -55 \n", + "3 fr 1912 1888 24 \n", + "4 de 1890 1898 -8 \n", + "... ... ... ... ... \n", + "4981 fr 1848 1908 -60 \n", + "4982 de 1890 1888 2 \n", + "4983 en 1880 1920 -40 \n", + "4984 de 1912 1938 -26 \n", + "4985 en 1865 1950 -85 \n", + "\n", + "[4986 rows x 7 columns]" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9cd4a743-b04f-41ff-b148-ee4f688fc95e", + "metadata": {}, + "outputs": [], + "source": [ + "df['error'] = df['year_pred'].astype(int) - df['true_year'].astype(int)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6f949640-6aab-4583-9e38-b385198f79df", + "metadata": {}, + "outputs": [], + "source": [ + "df['year'] = df.date.dt.year" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34b5d526-98df-4b72-a5de-e7994eb2051e", + "metadata": {}, + "outputs": [], + "source": [ + "df['decade'] = df.year.astype(str).str[:3]+\"0\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65c0f67a-bae6-4d7b-90bf-ef8fb2f880f6", + "metadata": {}, + "outputs": [], + "source": [ + "df['century'] = df.year.astype(str).str[:2]+\"00\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f900e2aa-3602-4135-848a-835a91cf0da9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 132, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "df.groupby('decade')['error'].mean().plot(kind='barh', figsize=(20,5))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "e956d68a-3252-4a66-a031-bc6b51497406", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.read_json('results.json')" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "f6e35be0-07b4-4119-9202-48664b96a482", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idtokensdatelanguageyear_predtrue_yearerroryeardecade
01540[Son, remplaçant, sera, probablement, Frank, C...275702400000fr200919783119781970
15431[B, .]276912000000fr18651978-11319781970
2141[General, St, ., Julien, ,, besides, the, Rati...-5339347200000en17451800-5518001800
33493[Le, GrasUdanin, donne, les, détails, suivants...-2561328000000fr191218882418881880
41659[Es, handelt, sich, um, folgendes, .]-2245276800000de18901898-818981890
..............................
49813880[M, ., Pichon, ,, ministre, des, affaires, étr...-1956096000000fr18481908-6019081900
49821400[Das, alte, Haus, hatte, sich, heute, in, den,...-2562796800000de18901888218881880
4983902[Thait, Is, what, I, bave, to, say, about, Alf...-1561593600000en18801920-4019201920
49842564[7, ., Hendrickx, (, Belgien, ), 4, P, .]-990835200000de19121938-2619381930
49851053[]-602812800000en18651950-8519501950
\n", + "

4986 rows × 9 columns

\n", + "
" + ], + "text/plain": [ + " id tokens date \\\n", + "0 1540 [Son, remplaçant, sera, probablement, Frank, C... 275702400000 \n", + "1 5431 [B, .] 276912000000 \n", + "2 141 [General, St, ., Julien, ,, besides, the, Rati... -5339347200000 \n", + "3 3493 [Le, GrasUdanin, donne, les, détails, suivants... -2561328000000 \n", + "4 1659 [Es, handelt, sich, um, folgendes, .] -2245276800000 \n", + "... ... ... ... \n", + "4981 3880 [M, ., Pichon, ,, ministre, des, affaires, étr... -1956096000000 \n", + "4982 1400 [Das, alte, Haus, hatte, sich, heute, in, den,... -2562796800000 \n", + "4983 902 [Thait, Is, what, I, bave, to, say, about, Alf... -1561593600000 \n", + "4984 2564 [7, ., Hendrickx, (, Belgien, ), 4, P, .] -990835200000 \n", + "4985 1053 [] -602812800000 \n", + "\n", + " language year_pred true_year error year decade \n", + "0 fr 2009 1978 31 1978 1970 \n", + "1 fr 1865 1978 -113 1978 1970 \n", + "2 en 1745 1800 -55 1800 1800 \n", + "3 fr 1912 1888 24 1888 1880 \n", + "4 de 1890 1898 -8 1898 1890 \n", + "... ... ... ... ... ... ... \n", + "4981 fr 1848 1908 -60 1908 1900 \n", + "4982 de 1890 1888 2 1888 1880 \n", + "4983 en 1880 1920 -40 1920 1920 \n", + "4984 de 1912 1938 -26 1938 1930 \n", + "4985 en 1865 1950 -85 1950 1950 \n", + "\n", + "[4986 rows x 9 columns]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "4f5e839d-bbe5-46c3-bf94-66118b7d36ce", + "metadata": {}, + "outputs": [], + "source": [ + "metrics = defaultdict(list)\n", + "for lang in ['en','de','fr']:\n", + " metrics['language'].append(lang)\n", + " sub_df = df[df['language']==lang]\n", + " true_y = sub_df['true_year'].astype(int)\n", + " pred_y = sub_df['year_pred'].astype(int)\n", + " metrics['MAE'].append(mean_absolute_error(true_y, pred_y).round(2))\n", + " metrics['Median Absolute Error'].append(median_absolute_error(true_y, pred_y))\n", + " #metrics['Max Error'].append(max_error(true_y, pred_y))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "2b37d9b0-2d49-4f29-84ef-df61ca43e92c", + "metadata": {}, + "outputs": [], + "source": [ + "metrics = pd.DataFrame.from_dict(metrics)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "182d1803-da13-4056-8ac9-faf45d3f3a16", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
languageMAEMedian Absolute Error
0en40.4830.0
1de40.1132.0
2fr55.2548.0
\n", + "
" + ], + "text/plain": [ + " language MAE Median Absolute Error\n", + "0 en 40.48 30.0\n", + "1 de 40.11 32.0\n", + "2 fr 55.25 48.0" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metrics" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d6e6749-aff3-4efc-b671-3c2ac90c32b5", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "ee31fd5b-273d-4598-a7b8-569109654ae7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\\begin{tabular}{llrr}\n", + "\\toprule\n", + "{} & language & MAE & Median Absolute Error \\\\\n", + "\\midrule\n", + "0 & en & 40.48 & 30.0 \\\\\n", + "1 & de & 40.11 & 32.0 \\\\\n", + "2 & fr & 55.25 & 48.0 \\\\\n", + "\\bottomrule\n", + "\\end{tabular}\n", + "\n" + ] + } + ], + "source": [ + "print(metrics.to_latex())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "901fd108-72b6-4625-a381-c4711bcd99c8", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.8.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}