Kaggle competition: TensorFlow 2.0 Question Answering
<SOS> metric: NQMicroF1 Kaggle data source: tensorflow-2.0-question-answering<something_strange>
import sys
import json
from tqdm.notebook import tqdm
import numpy as np
import pandas as pd
import time
from contextlib import contextmanager
df = df.set_index('Date' )<define_variables>
PATH_TO_DATA = '.. /input/tensorflow2-question-answering/'
PATH_TO_CUSTOM_BERT = '.. /input/bert-wwm-063065-checkpoint/'
PATH_TO_CUSTOM_BERT_WEIGHTS = PATH_TO_CUSTOM_BERT + \
'20200109_bert_joint_wwm_output/20200109_bert_joint_wwm_output/'
CKPT_NAME = PATH_TO_CUSTOM_BERT_WEIGHTS + '20200109_bert_joint_wwm_output_model.ckpt-15458'
PATH_TO_TF_WHEELS = PATH_TO_CUSTOM_BERT + \
'tensorflow_gpu_1_13_1_with_deps_whl/tensorflow_gpu_1_13_1_with_deps_whl/'
OUT_PREDICT_JSON = 'simplified-nq-test-pred.json'
columns = ['SchoolHoliday', 'StateHoliday', 'Promo']<data_type_conversions>
LRU_CACHE_SIZE = 30000
MAX_SEQ_LEN = 512
DOC_STRIDE = 192
MAX_QUERY_LEN = 24
LONG_ANS_THRES = 4.4524
SHORT_ANS_THRES = 7.7251
LONG_ANS_THRES_FINAL = 2.1165
SHORT_ANS_THRES_FINAL = 7.6657
for o in ['Before', 'After']:
for p in columns:
a = o+p
df[a] = df[a].fillna(0 ).astype(int )<groupby>
def process_test_set_for_bert_joint() :
with open(PATH_TO_DATA + 'simplified-nq-test.jsonl')as f_in, \
open('simplified-nq-test_with_doc_tokens.jsonl', 'w')as f_out:
for i, line in tqdm(enumerate(f_in)) :
json_line = json.loads(line)
 json_line["document_tokens"] = []
for token in json_line['document_text'].split(' '):
json_line["document_tokens"].append({"token":token,
"start_byte": -1,
"end_byte": -1,
"html_token": '<' in token})
 json_line['annotations'] = []
json_line["document_title"] = \
json_line["document_tokens"][0]["token"]
f_out.write(json.dumps(json_line)+ '
')
 !gzip simplified-nq-test_with_doc_tokens.jsonl
bwd = df[['Store']+columns].sort_index().groupby("Store" ).rolling(7, min_periods=1 ).sum()<sort_values>
def setup_tensorflow_1_13_1() :
!pip install --no-deps $PATH_TO_TF_WHEELS/*.whl > /dev/null 2>&1
!cp -r $PATH_TO_CUSTOM_BERT/bert-tensorflow-1.0.1/.
 !cd bert-tensorflow-1.0.1/bert-tensorflow-1.0.1/; python setup.py install > /dev/null 2>&1
fwd = df[['Store']+columns].sort_index(ascending=False
).groupby("Store" ).rolling(7, min_periods=1 ).sum()<drop_column>
def run_bert_inference() :
!python $PATH_TO_CUSTOM_BERT/run_nq.py --logtostderr \
--bert_config_file=$PATH_TO_CUSTOM_BERT/bert_config.json \
--vocab_file=$PATH_TO_CUSTOM_BERT/vocab-nq.txt \
--tokenizer_cache_size=$LRU_CACHE_SIZE \
--max_seq_length=$MAX_SEQ_LEN \
--doc_stride=$DOC_STRIDE \
--max_query_length=$MAX_QUERY_LEN \
--init_checkpoint=$CKPT_NAME \
--predict_file=simplified-nq-test_with_doc_tokens.jsonl.gz \
--do_predict \
--output_dir=bert_model_output \
--output_prediction_file=simplified-nq-test-pred.json \
> /dev/null 2>&1
!rm -rf bert-tensorflow-1.0.1/
!rm simplified-nq-test_with_doc_tokens.jsonl.gz
!rm -rf bert_model_output
bwd.drop('Store',1,inplace=True)
 bwd.reset_index(inplace=True )<drop_column>
def postprocess_predictions(pred_json_path=OUT_PREDICT_JSON,
long_thres=LONG_ANS_THRES,
short_thres=SHORT_ANS_THRES):
empty_answer = {'candidate_index': -1,
'end_byte': -1,
'end_token': -1,
'start_byte': -1,
'start_token': -1}
with open(pred_json_path)as f:
pred_json = json.load(f)
 pred_json_processed = {'predictions': []}
for i, entry in enumerate(pred_json['predictions']):
entry_copy = entry.copy()
ans_type = entry['answer_type']
if entry['long_answer_score'] < long_thres:
entry_copy['long_answer'] = empty_answer
if entry['short_answers_score'] < short_thres:
entry_copy['short_answers'] = []
if ans_type== 0:
entry_copy['long_answer'] = empty_answer
entry_copy['short_answers'] = [empty_answer]
elif ans_type == 1:
entry_copy['yes_no_answer'] = "YES"
entry_copy['short_answers'] = [empty_answer]
elif ans_type== 2:
entry_copy['yes_no_answer'] = "NO"
entry_copy['short_answers'] = [empty_answer]
elif ans_type == 3:
entry_copy['yes_no_answer'] = "NONE"
elif ans_type == 4:
entry_copy['yes_no_answer'] = "NONE"
entry_copy['short_answers'] = [empty_answer]
pred_json_processed['predictions'].append(entry_copy)
 return pred_json_processed
fwd.drop('Store',1,inplace=True)
 fwd.reset_index(inplace=True )<merge>
def form_submission_file(pred_json,
long_thres=LONG_ANS_THRES,
short_thres=SHORT_ANS_THRES):
example_ids, preds = [], []
for entry in pred_json['predictions']:
example_ids.append(str(entry['example_id'])+ '_long')
 example_ids.append(str(entry['example_id'])+ '_short')
 score = entry['long_answer_score']
if score >= long_thres:
long_pred = '{}:{}'.format(entry['long_answer']['start_token'],
entry['long_answer']['end_token'])
 if long_pred == '-1:-1':
long_pred = ""
else:
long_pred = ""
if entry['yes_no_answer'] != "NONE":
short_pred = entry['yes_no_answer']
elif score >= short_thres:
if entry['short_answers']:
short_pred = '{}:{}'.format(entry['short_answers'][0]['start_token'],
entry['short_answers'][0]['end_token'])
 else:
short_pred = ""
if short_pred == '-1:-1':
short_pred = ""
else:
short_pred = ""
preds.extend([long_pred, short_pred])
 sub_df = pd.DataFrame({'example_id':example_ids,
'PredictionString': preds})\ 
.sort_values(by='example_id' ).reset_index(drop=True)
 return sub_df
df = df.merge(bwd, 'left', ['Date', 'Store'], suffixes=['', '_bw'])
 df = df.merge(fwd, 'left', ['Date', 'Store'], suffixes=['', '_fw'] )<drop_column>
with timer('ALL'):
with timer('Processing test set'):
process_test_set_for_bert_joint()
with timer('Setting up packages'):
setup_tensorflow_1_13_1()
with timer('Running inference'):
run_bert_inference()
with timer('Forming final submission file'):
pred_json_processed = postprocess_predictions(OUT_PREDICT_JSON,
long_thres=LONG_ANS_THRES,
short_thres=SHORT_ANS_THRES 
)
 sub_df = form_submission_file(pred_json_processed,
long_thres=LONG_ANS_THRES_FINAL,
short_thres=SHORT_ANS_THRES_FINAL 
)
 sub_df.to_csv("submission.csv", index=False )