{"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":"**How to extract dataset names in a simple question answering task using Bert**","metadata":{}},{"cell_type":"markdown","source":"# Load Module","metadata":{}},{"cell_type":"code","source":"from transformers import BertForQuestionAnswering\nfrom transformers import BertTokenizer\nimport torch\n\nimport pandas as pd\n\nfrom tqdm import tqdm\ntqdm.pandas()\n\nimport os\nimport re\nimport json","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helper","metadata":{}},{"cell_type":"code","source":"def clean_text(txt):\n    return re.sub('[^A-Za-z0-9]+', ' ', str(txt)).strip()\n\ndef totally_clean_text(txt):\n    txt = clean_text(txt)\n    txt = re.sub(' +', ' ', txt)\n    return txt","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Const","metadata":{}},{"cell_type":"code","source":"TRAIN = \"../input/coleridgeinitiative-show-us-the-data/train\"\nTEST  = \"../input/coleridgeinitiative-show-us-the-data/test\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Data & Preprocess","metadata":{}},{"cell_type":"code","source":"## json to pandas\npaper_sentense = []\nfor file in tqdm(os.listdir(TRAIN)):\n    \n    texts = []\n    \n    ids = file.split(\".\")[0]\n    file_path = os.path.join(TRAIN, file)\n    with open(file_path, \"r\") as f:\n        json_datasets = json.load(f)\n    \n    for json_dataset in json_datasets:\n        for k, v in json_dataset.items():\n            if k == \"text\":\n                text = v\n            else:\n                title = v\n    \n        paper_sentense.append([ids, title, text])\npaper_sentense_df = pd.DataFrame(paper_sentense, columns=[\"Id\", \"Title\", \"Sentense\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## cleaned\npaper_sentense_df[\"CleanedSentense\"] = paper_sentense_df[\"Sentense\"].progress_apply(totally_clean_text)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# example\npaper_sentense_df[\"CleanedSentense\"].values[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load bert\n\nmodel = BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')\ntokenizer = BertTokenizer.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')\n\ndef answer_question(question, answer_text):\n    '''\n    Takes a `question` string and an `answer_text` string (which contains the\n    answer), and identifies the words within the `answer_text` that are the\n    answer. Prints them out.\n    '''\n    # ======== Tokenize ========\n    # Apply the tokenizer to the input text, treating them as a text-pair.\n    input_ids = tokenizer.encode(question, answer_text)\n\n    # Report how long the input sequence is.\n    print('Query has {:,} tokens.\\n'.format(len(input_ids)))\n    \n    if len(input_ids) > 512:\n        input_ids = input_ids[:512]\n\n    # ======== Set Segment IDs ========\n    # Search the input_ids for the first instance of the `[SEP]` token.\n    sep_index = input_ids.index(tokenizer.sep_token_id)\n\n    # The number of segment A tokens includes the [SEP] token istelf.\n    num_seg_a = sep_index + 1\n\n    # The remainder are segment B.\n    num_seg_b = len(input_ids) - num_seg_a\n\n    # Construct the list of 0s and 1s.\n    segment_ids = [0]*num_seg_a + [1]*num_seg_b\n\n    # There should be a segment_id for every input token.\n    assert len(segment_ids) == len(input_ids)\n\n    # ======== Evaluate ========\n    # Run our example question through the model.\n    scores = model(torch.tensor([input_ids]), # The tokens representing our input text.\n                                    token_type_ids=torch.tensor([segment_ids])) # The segment IDs to differentiate question from answer_text\n\n    # ======== Reconstruct Answer ========\n    # Find the tokens with the highest `start` and `end` scores.\n    answer_start = torch.argmax(scores[0])\n    answer_end = torch.argmax(scores[1])\n\n    # Get the string versions of the input tokens.\n    tokens = tokenizer.convert_ids_to_tokens(input_ids)\n\n    # Start with the first token.\n    answer = tokens[answer_start]\n\n    # Select the remaining answer tokens and join them with whitespace.\n    for i in range(answer_start + 1, answer_end + 1):\n        \n        # If it's a subword token, then recombine it with the previous token.\n        if tokens[i][0:2] == '##':\n            answer += tokens[i][2:]\n        \n        # Otherwise, add a space then the token.\n        else:\n            answer += ' ' + tokens[i]\n\n    print('Answer: \"' + answer + '\"')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def question_answer(index):\n    s = paper_sentense_df[\"CleanedSentense\"].tolist()[index]\n    \n    print(\"Base:\", s)\n    \n    question = \"What is the name of the dataset you are using?\"\n    answer_question(question, s)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"question_answer(0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"question_answer(1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"question_answer(7)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Good accuracy!!**","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}