Kaggle competition: COVID19 Global Forecasting (Week 4)
<SOS> metric: MCRMSLE Kaggle data source: covid19-global-forecasting-(week-4)<define_variables>
plt.style.use('default')
 warnings.filterwarnings('ignore')
other_input_dim = 2
hidden_layer_size = 50
input_dim_order = train_current_question.max() + 1
prev_q_perform_dim = train_past_question_answer.max() + 1 
<categorify>
train=pd.read_csv('/kaggle/input/covid19-global-forecasting-week-4/train.csv')
 test=pd.read_csv('/kaggle/input/covid19-global-forecasting-week-4/test.csv')
 train.head()
def dkt_build(hidden_layer_size, input_dim_order, prev_q_perform_dim, other_input_dim):
masking_func = lambda inputs, previous_mask: previous_mask
prev_question_ans = Input(batch_shape =(None, None), dtype = 'int32', name = 'prev_qn_ans')
 one_hot_prev_question_ans = tf.one_hot(prev_question_ans, prev_q_perform_dim, axis = -1)
 other_input = Input(batch_shape =(None, None, other_input_dim), name= 'other_input')
 one_hot = Concatenate()([one_hot_prev_question_ans, other_input])
 masked_one_hot =(Masking(mask_value= 0, input_shape =(None, None, prev_q_perform_dim + other_input_dim)) )(one_hot)
 lstm_out = LSTM(hidden_layer_size, input_shape =(None, None, prev_q_perform_dim + other_input_dim),
dropout=0.2, recurrent_dropout =0.2, return_sequences = True )(masked_one_hot)
 dense_out = Dense(input_dim_order, input_shape =(None, None, hidden_layer_size), activation='sigmoid' )(lstm_out)
 order = Input(batch_shape =(None, None), dtype = 'int32', name = 'order')
 one_hot_order = tf.one_hot(order, input_dim_order, axis = -1)
 merged = multiply([dense_out, one_hot_order])
 def reduce_dim(x):
x = K.max(x, axis = 2, keepdims = True)
 return x
def reduce_dim_shape(input_shape):
shape = list(input_shape)
 shape[-1] = 1
print("reduced_shape", shape)
 return tuple(shape)
 reduced = Lambda(reduce_dim, output_shape = reduce_dim_shape, mask = masking_func )(merged)
 model = Model(inputs=[prev_question_ans, other_input, order], outputs=reduced)
 model.compile(optimizer = 'adam',
loss = 'binary_crossentropy',
metrics=['accuracy',AUC() ])
 return model<choose_model_class>
pd.concat([round(100*train[catcols].isnull().sum() /train.shape[0],2 ).to_frame('train'),
round(100*test[catcols].isnull().sum() /test.shape[0],2 ).to_frame('test')],axis=1 )
dkt_model = dkt_build(hidden_layer_size, input_dim_order, prev_q_perform_dim, other_input_dim )<train_model>
print(f'TRAIN -> date_min= {train["Date"].min() } ; date_max= {train["Date"].max() }')
 print(f'TEST -> date_min= {test["Date"].min() } ; date_max= {test["Date"].max() }' )
dkt_model.fit([train_past_question_answer, train_other_feats, train_current_question], train_answered_correcly,
validation_data=([valid_past_question_answer, valid_other_feats, valid_current_question], valid_answered_correcly),
epochs = 2, verbose = 1, batch_size = 200 )<predict_on_test>
len(set(train.Date.unique())& set(test.Date.unique()))
env = riiideducation.make_env()
iter_test = env.iter_test()
set_predict = env.predict<merge>
def prepare_features(data):
data['Province_State']=data['Province_State'].str.lower()
data['Country_Region']=data['Country_Region'].str.lower()
data['UnkownProvince_State']=data['Province_State'].isnull().astype(int)
 data.fillna({'Province_State':''},inplace=True)
 data['Province_State']=data['Province_State'].apply(lambda x: ''.join([ch for ch in x if ch.isalpha() ]))
data['Country_Region']=data['Country_Region'].apply(lambda x: ''.join([ch for ch in x if ch.isalpha() ]))
data['Country_RegionFreq']=data['Country_Region'].map(data['Country_Region'].value_counts(1 ).to_dict())
 return data
catcols.append('UnkownProvince_State' )
previous_test_df = None
for(test_df, sample_prediction_df)in iter_test:
if previous_test_df is not None:
previous_test_df[TARGET] = np.array(eval(test_df["prior_group_answers_correct"].iloc[0])) [mask]
update_user_feats(previous_test_df, last_time_u_dict, answered_correctly_sum_u_dict, count_u_dict)
 test_df = pd.merge(test_df, questions_df[['question_id', 'part','tag']], left_on='content_id', right_on = 'question_id', how='left')
 mask =(test_df['content_type_id'] == 0 ).values.tolist()
test_df = test_df[test_df['content_type_id'] == 0].reset_index(drop=True)
 test_df = add_user_feats_without_update(test_df , last_time_u_dict, answered_correctly_sum_u_dict, count_u_dict)
 test_df = pd.merge(test_df, content_df, on='content_id', how="left")
 test_df['prior_question_had_explanation'] = test_df.prior_question_had_explanation.fillna(False ).astype('int8')
 test_df['prior_question_elapsed_time'] = test_df.prior_question_elapsed_time.fillna(prior_question_elapsed_time_mean)
 previous_test_df = test_df.copy()
lgbm_predict = lgbm_model.predict(test_df[FEATS])
 current_question, past_question_answer, past_other_feats, past_answer_correctly = get_user_feats_for_nn_without_update(test_df, past_question, past_answer, past_prior_elaps, past_time_diff)
 prior_elaps_time = np.reshape(past_other_feats[:,:,0],(-1,30,1))
time_diff = np.reshape(past_other_feats[:,:,1],(-1,30,1))
sakt_predict = SAKT_model.predict([past_question_answer, prior_elaps_time, time_diff, current_question], batch_size = 500)
 saint_predict = SAINT_model.predict([current_question, past_answer_correctly, prior_elaps_time, time_diff], batch_size = 500)
 past_question_answer = past_question_answer - 1
current_question = current_question - 1
dkt_predict = dkt_model.predict([past_question_answer, past_other_feats, current_question], batch_size = 200)
 test_df[TARGET] = dkt_predict[:,-1,0]*(0.1)+ sakt_predict[:,-1,0]*(0.15)+ lgbm_predict*0.6 + saint_predict[:,-1,0]*(0.15)
 set_predict(test_df[['row_id', TARGET]])
<import_modules>
train=prepare_features(train)
 test=prepare_features(test)
 train.head(3 )
import numpy as np
import pandas as pd
import psutil<define_variables>
train['Country_Region'].nunique()
sys.path.append('/kaggle/input/riiid-dataset/')
 question_metadata_dir = r'/kaggle/input/riiid-dataset/question_metadata.csv'
lesson_metadata_dir = r'/kaggle/input/riiid-dataset/lesson_metadata.csv'
pickle_dir= r'/kaggle/input/riiid-dataset/stage.pickle'
model_dir = r'/kaggle/input/riiid-dataset/classifier.model'
print("{} 提交启动".format(str(datetime.datetime.now())))
 try:
except ImportError as e:
print("{} 导入错误，错误信息：{}".format(str(datetime.datetime.now()), e))
print("{} 包导入完成".format(str(datetime.datetime.now())))
 env = trueskill.TrueSkill(mu=0.3, sigma=0.164486, beta=0.05, tau=0.00164, draw_probability=0)
 env.make_as_global()
def win_probability(team1, team2):

 delta_mu = team1.mu - team2.mu
sum_sigma = sum([team1.sigma ** 2, team2.sigma ** 2])
 size = 2
denom = math.sqrt(size *(0.05 * 0.05)+ sum_sigma)
 ts = trueskill.global_env()
return ts.cdf(delta_mu / denom)
 class user:

 def __init__(self):

 self.question_answered_num = 0
self.question_answered_num_agg_field = [0] * 7
self.question_answered_mean_accuracy = 0
self.question_answered_mean_accuracy_agg_field = [0] * 7
self.question_answered_mean_difficulty_weighted_accuracy = 0
self.question_answered_mean_difficulty_weighted_accuracy_agg_field = [0] * 7
self.max_solved_difficulty = 1
self.max_solved_difficulty_agg_field = [1] * 7
self.min_wrong_difficulty = 0
self.min_wrong_difficulty_agg_field = [0] * 7
self.lessons_overall = 0
self.lessons_overall_agg_field = [0] * 7
self.session_time = 0
self.since_last_session_time = 0
self._mmr_object = trueskill.setup(mu=0.3, sigma=0.164486, beta=0.05, tau=0.00164,
draw_probability=0 ).Rating()
self._mmr_object_agg_field = [trueskill.setup(mu=0.3, sigma=0.164486, beta=0.05, tau=0.00164,
draw_probability=0 ).Rating() ] * 7
self._most_liked_guess = [0] * 4
self._last_session_start_time = 0
self._first_action_time = 0
self._question_num_dict = {}
self._first_processed_flag = False
def update_user(self, data: pd.DataFrame):

 _temp = None
if data['content_type_id'] == 0:
self.question_answered_num = self.question_answered_num + 1
question_field = int(data['content_field'])
 self.question_answered_num_agg_field[question_field - 1] = int(self.question_answered_num_agg_field[
question_field - 1])+ 1
if data['answered_correctly'] == 1:
self.question_answered_mean_accuracy = \ 
(self.question_answered_mean_accuracy *(
 self.question_answered_num - 1)+ 1)/ self.question_answered_num
self.question_answered_mean_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)+ 1)\
/ self.question_answered_num_agg_field[question_field - 1]
self.question_answered_mean_difficulty_weighted_accuracy = \ 
(self.question_answered_mean_difficulty_weighted_accuracy *(self.question_answered_num - 1)+(
 1 - data['mean_question_accuracy'])* 3)\
/ self.question_answered_num
self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)+(
 1 - data['mean_question_accuracy'])* 3)\
/ self.question_answered_num_agg_field[question_field - 1]
else:
self.question_answered_mean_accuracy = \ 
(self.question_answered_mean_accuracy *(
 self.question_answered_num - 1)) / self.question_answered_num
self.question_answered_mean_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)) / \
self.question_answered_num_agg_field[question_field - 1]
self.question_answered_mean_difficulty_weighted_accuracy = \ 
(self.question_answered_mean_difficulty_weighted_accuracy *(self.question_answered_num - 1)) \
/ self.question_answered_num
self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)) \
/ self.question_answered_num_agg_field[question_field - 1]
if data['answered_correctly'] == 1:
if data['mean_question_accuracy'] < self.max_solved_difficulty:
self.max_solved_difficulty = data['mean_question_accuracy']
if data['mean_question_accuracy'] < self.max_solved_difficulty_agg_field[question_field - 1]:
self.max_solved_difficulty_agg_field[question_field - 1] = data['mean_question_accuracy']
else:
if data['mean_question_accuracy'] > self.min_wrong_difficulty:
self.min_wrong_difficulty = data['mean_question_accuracy']
if data['mean_question_accuracy'] > self.min_wrong_difficulty_agg_field[question_field - 1]:
self.min_wrong_difficulty_agg_field[question_field - 1] = data['mean_question_accuracy']
if data['answered_correctly'] == 0:
self._most_liked_guess[int(data['user_answer'])] = self._most_liked_guess[
int(data['user_answer'])] + 1
if self._first_action_time == 0:
self._first_action_time = data['timestamp']
self._last_session_start_time = data['timestamp']
else:
if data['timestamp'] - self._last_session_start_time >= 7200 * 1000:
self.since_last_session_time =(data[
'timestamp'] - self._last_session_start_time)/ 1000 / 3600
self._last_session_start_time = data['timestamp']
self.session_time = 0
else:
self.session_time =(data['timestamp'] - self._last_session_start_time)/ 1000 / 60
if str(data['content_id'])in self._question_num_dict:
self._question_num_dict[str(data['content_id'])] = self._question_num_dict[str(data['content_id'])] + 1
else:
self._question_num_dict[str(data['content_id'])] = 1
if data['answered_correctly'] == 1:
self._mmr_object, _temp = \
trueskill.rate_1vs1(self._mmr_object,
trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05, tau=0.00164, draw_probability=0 ).Rating())
 self._mmr_object_agg_field[question_field - 1], _temp = \
trueskill.rate_1vs1(self._mmr_object_agg_field[question_field - 1],
trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05,
tau=0.00164, draw_probability=0 ).Rating())
 else:
_temp, self._mmr_object = \
trueskill.rate_1vs1(trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05, tau=0.00164, draw_probability=0 ).Rating() ,
self._mmr_object)
 _temp, self._mmr_object_agg_field[question_field - 1] = \
trueskill.rate_1vs1(trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05,
tau=0.00164, draw_probability=0 ).Rating() ,
self._mmr_object_agg_field[question_field - 1])
 else:
self.lessons_overall = self.lessons_overall + 1
lesson_field = int(data['content_field'])
 self.lessons_overall_agg_field[lesson_field - 1] = self.lessons_overall_agg_field[lesson_field - 1] + 1
def process_output(self, data):

 output_dict = {}
output_dict['question_answered_num'] = self.question_answered_num
output_dict['question_answered_num_agg_field'] = self.question_answered_num_agg_field[
int(data['content_field'])- 1]
output_dict['question_answered_mean_accuracy'] = self.question_answered_mean_accuracy
output_dict['question_answered_mean_accuracy_agg_field'] = self.question_answered_mean_accuracy_agg_field[
int(data['content_field'])- 1]
output_dict[
'question_answered_mean_difficulty_weighted_accuracy'] = self.question_answered_mean_difficulty_weighted_accuracy
output_dict['question_answered_mean_difficulty_weighted_accuracy_agg_field'] = \
self.question_answered_mean_difficulty_weighted_accuracy_agg_field[int(data['content_field'])- 1]
output_dict['max_solved_difficulty'] = self.max_solved_difficulty
output_dict['max_solved_difficulty_agg_field'] = self.max_solved_difficulty_agg_field[
int(data['content_field'])- 1]
output_dict['min_wrong_difficulty'] = self.min_wrong_difficulty
output_dict['min_wrong_difficulty_agg_field'] = self.min_wrong_difficulty_agg_field[
int(data['content_field'])- 1]
output_dict['lessons_overall'] = self.lessons_overall
output_dict['lessons_overall_agg_field'] = self.lessons_overall_agg_field[int(data['content_field'])- 1]
if output_dict['lessons_overall_agg_field'] > 0:
output_dict['field_learnt'] = 1
else:
output_dict['field_learnt'] = 0
output_dict['session_time'] = self.session_time
output_dict['time_to_last_session'] = self.since_last_session_time
output_dict['task_id'] = data['task_container_id']
output_dict['prior_time'] = data['prior_question_elapsed_time']
output_dict['mean_question_accuracy'] = data['mean_question_accuracy']
output_dict['std_question_accuracy'] = data['std_accuracy']
output_dict['question_id'] = data['content_id']
output_dict['mmr_overall'] = self._mmr_object.mu
output_dict['mmr_overall_agg_field'] = self._mmr_object_agg_field[int(data['content_field'])- 1].mu
output_dict['mmr_confidence'] = self._mmr_object.sigma
output_dict['mmr_overall_agg_field'] = self._mmr_object_agg_field[int(data['content_field'])- 1].sigma
output_dict['mmr_win_prob'] = win_probability(self._mmr_object,
trueskill.setup(mu=1 - data['mean_question_accuracy'],
sigma=0.164486,
beta=0.05, tau=0.00164,
draw_probability=0 ).Rating())
 output_dict['mmr_win_prob_agg_field'] = win_probability(
 self._mmr_object_agg_field[int(data['content_field'])- 1],
trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486, beta=0.05,
tau=0.00164, draw_probability=0 ).Rating())
 output_dict['user_id'] = data['user_id']
output_dict['tag_1'] = data['tag_1']
output_dict['tag_2'] = data['tag_2']
output_dict['tags_encoded'] = data['tags_encoded']
if not pd.isna(['prior_question_had_explanation']):
output_dict['previous_explained'] = data['prior_question_had_explanation']
else:
output_dict['previous_explained'] = False
if str(data['content_id'])in self._question_num_dict:
output_dict['question_seen'] = 1
else:
output_dict['question_seen'] = 0
max_choice = 0
max_choice_num = 0
i = 0
for item in self._most_liked_guess:
if item > max_choice_num:
max_choice_num = item
max_choice = i
i = i + 1
if output_dict['mmr_win_prob'] <= 0.4:
if max_choice == data['correct_answer']:
output_dict['most_liked_guess_correct'] = True
else:
output_dict['most_liked_guess_correct'] = False
else:
output_dict['most_liked_guess_correct'] = True
return output_dict
question_metadata = pd.read_csv(question_metadata_dir)
 lesson_metadata = pd.read_csv(lesson_metadata_dir)
 print("{} Metadata 文件导入完成".format(str(datetime.datetime.now())))
 question_metadata = question_metadata.set_index(keys=['content_id'])
 lesson_metadata = lesson_metadata.set_index(keys=['content_id'])
 print("{} Metadata 索引设置完成".format(str(datetime.datetime.now())))
 with open(pickle_dir, 'rb')as fo:
user_pickle = pickle.load(fo)
 print("{} Pickle 导入完成".format(str(datetime.datetime.now())))
 for user_id,user_info in user_pickle.items() :
user_pickle[user_id]._mmr_object = trueskill.setup(mu=user_pickle[user_id]._mmr_object[0],
sigma=user_pickle[user_id]._mmr_object[1],
beta=0.05, tau=0.00164,
draw_probability=0 ).Rating()
for i in range(0, 7):
user_pickle[user_id]._mmr_object_agg_field[i] = trueskill.setup(mu=user_pickle[user_id]._mmr_object_agg_field[i][0],
sigma=user_pickle[user_id]._mmr_object_agg_field[i][1],
beta=0.05, tau=0.00164,
draw_probability=0 ).Rating()
print("{} Pickle Trueskill状态重置完成".format(str(datetime.datetime.now())))
 model = lgb.Booster(model_file=model_dir)
 print("{} 模型导入完成".format(str(datetime.datetime.now())))
<choose_model_class>
cols_to_keep=['Country Name','Population ages 0-14, total', 'Population ages 15-64, female','Population ages 15-64, male',
'Population ages 15-64, total','Population ages 65 and above, total',
'Population ages 80 and above, female(% of female population)',
'Population ages 80 and above, male(% of male population)','Population, male',
'Population, total','Rural population(% of total population)']
add_inf=pd.read_csv('/kaggle/input/world-population-and-development-indicators/data.csv')[cols_to_keep]
add_inf.head(3 )
MAX_SEQ = 100
class FFN(nn.Module):
def __init__(self, state_size=200):
super(FFN, self ).__init__()
self.state_size = state_size
self.lr1 = nn.Linear(state_size, state_size)
 self.relu = nn.ReLU()
self.lr2 = nn.Linear(state_size, state_size)
 self.dropout = nn.Dropout(0.2)
 def forward(self, x):
x = self.lr1(x)
 x = self.relu(x)
 x = self.lr2(x)
 return self.dropout(x)
 def future_mask(seq_length):
future_mask = np.triu(np.ones(( seq_length, seq_length)) , k=1 ).astype('bool')
 return torch.from_numpy(future_mask)
 class SAKTModel(nn.Module):
def __init__(self, n_skill, max_seq=MAX_SEQ, embed_dim=128):
super(SAKTModel, self ).__init__()
self.n_skill = n_skill
self.embed_dim = embed_dim
self.embedding = nn.Embedding(2*n_skill+1, embed_dim)
 self.pos_embedding = nn.Embedding(max_seq-1, embed_dim)
 self.e_embedding = nn.Embedding(n_skill+1, embed_dim)
 self.multi_att = nn.MultiheadAttention(embed_dim=embed_dim, num_heads=8, dropout=0.2)
 self.dropout = nn.Dropout(0.2)
 self.layer_normal = nn.LayerNorm(embed_dim)
 self.ffn = FFN(embed_dim)
 self.pred = nn.Linear(embed_dim, 1)
 def forward(self, x, question_ids):
device = x.device
x = self.embedding(x)
 pos_id = torch.arange(x.size(1)).unsqueeze(0 ).to(device)
 pos_x = self.pos_embedding(pos_id)
 x = x + pos_x
e = self.e_embedding(question_ids)
 x = x.permute(1, 0, 2)
 e = e.permute(1, 0, 2)
 att_mask = future_mask(x.size(0)).to(device)
 att_output, att_weight = self.multi_att(e, x, x, attn_mask=att_mask)
 att_output = self.layer_normal(att_output + e)
 att_output = att_output.permute(1, 0, 2)
 x = self.ffn(att_output)
 x = self.layer_normal(x + att_output)
 x = self.pred(x)
 return x.squeeze(-1), att_weight
skills = joblib.load("/kaggle/input/riiid-sakt-model-dataset-public/skills.pkl.zip")
 n_skill = len(skills)
 group = joblib.load("/kaggle/input/riiid-sakt-model-dataset-public/group.pkl.zip")
 device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 model_SAKT = SAKTModel(n_skill, embed_dim=128)
 try:
model_SAKT.load_state_dict(torch.load("/kaggle/input/riiid-sakt-model-dataset-public/sakt_model.pt"))
except:
model_SAKT.load_state_dict(torch.load("/kaggle/input/riiid-sakt-model-dataset-public/sakt_model.pt", map_location='cpu'))
model_SAKT.to(device)
 model_SAKT.eval()
class TestDataset(Dataset):
def __init__(self, samples, test_df, skills, max_seq=MAX_SEQ):
super(TestDataset, self ).__init__()
self.samples = samples
self.user_ids = [x for x in test_df["user_id"].unique() ]
self.test_df = test_df
self.skills = skills
self.n_skill = len(skills)
 self.max_seq = max_seq
def __len__(self):
return self.test_df.shape[0]
def __getitem__(self, index):
test_info = self.test_df.iloc[index]
user_id = test_info["user_id"]
target_id = test_info["content_id"]
q = np.zeros(self.max_seq, dtype=int)
 qa = np.zeros(self.max_seq, dtype=int)
 if user_id in self.samples.index:
q_, qa_ = self.samples[user_id]
seq_len = len(q_)
 if seq_len >= self.max_seq:
q = q_[-self.max_seq:]
qa = qa_[-self.max_seq:]
else:
q[-seq_len:] = q_
qa[-seq_len:] = qa_
x = np.zeros(self.max_seq-1, dtype=int)
 x = q[1:].copy()
x +=(qa[1:] == 1)* self.n_skill
questions = np.append(q[2:], [target_id])
 return x, questions
prev_test_df = None<split>
add_inf['Country Name'].replace({'bahamasthe':'bahamas','bruneidarussalam':'bahamas','czechrepublic':'czechia',
'congodemrep':'congokinshasa','congorep':'congobrazzaville','egyptarabrep':'egypt',
'gambiathe':'gambia','iranislamicrep':'iran','korearep':'koreasouth','unitedstates':'us',
'kyrgyzrepublic':'kyrgyzstan','russianfederation':'russia','stkittsandnevis':'saintkittsandnevis',
'stlucia':'saintlucia','stvincentandthegrenadines':'saintvincentandthegrenadines',
'slovakrepublic':'slovakia','syrianarabrepublic':'syria','venezuelarb':'venezuela'},inplace=True)
 print('us' in add_inf['Country Name'].unique())
 add_inf.drop_duplicates(subset=['Country Name'],inplace=True)
 print(add_inf['Country Name'].nunique() )
env = riiideducation.make_env()
iter_test = env.iter_test()
prev_test_df = None 
<create_dataframe>
print('From train:{} ; From add_inf:{} ; intersection:{}'.format(train['Country_Region'].nunique() ,add_inf['Country Name'].nunique() ,
len(set(train['Country_Region'])& set(add_inf['Country Name']))))
print('From test:{} ; From add_inf:{} ; intersection:{}'.format(test['Country_Region'].nunique() ,add_inf['Country Name'].nunique() ,
len(set(test['Country_Region'])& set(add_inf['Country Name']))))
print("{} 比赛环境设置完成".format(str(datetime.datetime.now())))
 rows_accum = 0
first_submission = True
model_prd = [0]
true_value = []
last_df = pd.DataFrame()
print("{} 比赛变量设置完成".format(str(datetime.datetime.now())))
 for(test_df, sample_prediction_df)in iter_test:
cur =(test_df, sample_prediction_df)
 if(prev_test_df is not None)&(psutil.virtual_memory().percent < 90):
prev_test_df['answered_correctly'] = eval(test_df['prior_group_answers_correct'].iloc[0])
 prev_test_df = prev_test_df[prev_test_df.content_type_id == False]
prev_group = prev_test_df[['user_id', 'content_id', 'answered_correctly']].groupby('user_id' ).apply(lambda r:(
 r['content_id'].values,
r['answered_correctly'].values))
for prev_user_id in prev_group.index:
if prev_user_id in group.index:
group[prev_user_id] =(
 np.append(group[prev_user_id][0], prev_group[prev_user_id][0])[-MAX_SEQ:],
np.append(group[prev_user_id][1], prev_group[prev_user_id][1])[-MAX_SEQ:] 
)
 else:
group[prev_user_id] =(
 prev_group[prev_user_id][0],
prev_group[prev_user_id][1] 
)
 prev_test_df = test_df.copy()
test_df = test_df[test_df.content_type_id == False]
TEST = test_df[test_df.content_type_id == False]
test_dataset = TestDataset(group, test_df, skills)
 test_dataloader = DataLoader(test_dataset, batch_size=51200, shuffle=False)
 outs = []
for item in test_dataloader:
x = item[0].to(device ).long()
target_id = item[1].to(device ).long()
with torch.no_grad() :
output, att_weight = model_SAKT(x, target_id)
 outs.extend(torch.sigmoid(output)[:, -1].view(-1 ).data.cpu().numpy())
 TEST['answered_correctly'] = outs
TEST = TEST.loc[TEST['content_type_id'] == 0, ['row_id', 'answered_correctly']] 
(test_df, sample_prediction_df)= cur
if first_submission == False:
last_df['answered_correctly'] = eval(test_df.iloc[0]['prior_group_answers_correct'])
 last_df['user_answer'] = eval(test_df.iloc[0]['prior_group_responses'])
 true_value.extend(eval(test_df.iloc[0]['prior_group_answers_correct']))
for index,row in last_df.iterrows() :
user_pickle[row['user_id']].update_user(row)
 rows_accum = rows_accum + test_df.shape[0]
if first_submission == False:
1+1
test_df['answered_correctly'] = 0.6524
st = float(time.time())
 try:
sub_1 = test_df[test_df['content_type_id'] == False]
sub_2 = test_df[test_df['content_type_id'] == True]
del test_df
sub_1 = sub_1.merge(question_metadata, on="content_id", how="left")
 sub_2 = sub_2.merge(lesson_metadata, on="content_id", how="left")
 test_df = pd.DataFrame()
test_df = pd.concat([sub_1,sub_2])
 except Exception:
pass
for index, row in test_df.iterrows() :
try:
if row['user_id'] not in user_pickle:
user_pickle[row['user_id']] = user()
if row['content_type_id'] == 0:
predict_dict = user_pickle[row['user_id']].process_output(row)
 l = []
for i,v in predict_dict.items() :
l.append(v)
 prd_value = float(model.predict([l])[0])
 test_df.loc[test_df.row_id == row.row_id, 'answered_correctly'] = 0.5*prd_value+float(TEST[TEST['row_id']==row.row_id]['answered_correctly'])*0.5
model_prd.append(prd_value)
 except Exception as e:
print(e)
 pass
time_taken = float(time.time())- st
print("{} 基于当前速率，共需要 {} 分钟完成预测".format(
 str(datetime.datetime.now()),int(time_taken / test_df.shape[0] * 2500000 / 60)))
 if first_submission == True:
first_submission = False
last_df = test_df
env.predict(test_df.loc[test_df['content_type_id'] == 0, ['row_id', 'answered_correctly']] )<filter>
def scale_popultaion_features(data):
data['Population ages 0-14, total'].replace(0,data['Population ages 0-14, total'].mode() ,inplace=True)
 data['Population ages 15-64, total'].replace(0,data['Population ages 15-64, total'].mode() ,inplace=True)
 data['Population ages 65 and above, total'].replace(0,data['Population ages 65 and above, total'].mode() ,inplace=True)
 data['Population, total'].replace(0,data['Population, total'].mode() ,inplace=True)
 data['Population ages 15-64, male']=data['Population ages 15-64, male']/data['Population ages 15-64, total']
data['Population ages 15-64, female']=data['Population ages 15-64, female']/data['Population ages 15-64, total']
data['Population ages 0-14, total']=data['Population ages 0-14, total']/data['Population, total']
data['Population ages 15-64, total']=data['Population ages 15-64, total']/data['Population, total']
data['Population ages 65 and above, total']=data['Population ages 65 and above, total']/data['Population, total']
data['Population, male']=data['Population, male']/data['Population, total']
pcq_features=[col for col in data.columns if '%' in col]
print(pcq_features)
 data[pcq_features]=.01*data[pcq_features]
data.drop(columns=['Population, total'],inplace=True)
 data.fillna(data.median().to_dict() ,inplace=True)
 return data
float(TEST[TEST['row_id']==row.row_id]['answered_correctly']*0.5 )<filter>
print('train shape: {} ; test shape: {}'.format(train.shape,test.shape))
train=train.merge(add_inf,left_on='Country_Region',right_on='Country Name',how='left')
 test=test.merge(add_inf,left_on='Country_Region',right_on='Country Name',how='left')
 print('train shape: {} ; test shape: {}'.format(train.shape,test.shape))
train.head()
test_df.loc[test_df['content_type_id'] == 0, ['row_id', 'answered_correctly']]<define_variables>
cols_to_keep=['country', 'total_covid_19_tests',
'total_covid_19_tests_per_million_people',
'inform_risk', 'inform_p2p_hazard_and_exposure_dimension',
'people_using_at_least_basic_sanitation_services',
'inform_vulnerability', 'inform_health_conditions',
'inform_epidemic_vulnerability', 'mortality_rate_under_5',
'prevalence_of_undernourishment', 'inform_lack_of_coping_capacity',
'inform_access_to_healthcare',
'inform_epidemic_lack_of_coping_capacity', 'physicians_density',
'current_health_expenditure_per_capita',
'maternal_mortality_ratio', 'entry_date', 'category',
'measure', 'global-school-closures']
who_data=pd.read_csv('/kaggle/input/whodata/WHO data.csv')[cols_to_keep]
who_data.drop_duplicates(subset=['country'],inplace=True)
 print(who_data.shape)
 who_data.head(2 )
sys.path.append('/kaggle/input/riiid-dataset/')
 question_metadata_dir = r'/kaggle/input/riiid-dataset/question_metadata.csv'
lesson_metadata_dir = r'/kaggle/input/riiid-dataset/lesson_metadata.csv'
pickle_dir= r'/kaggle/input/riiid-dataset/stage.pickle'
model_dir = r'/kaggle/input/riiid-dataset/classifier.model'
print("{} 提交启动".format(str(datetime.datetime.now())))
 try:
except ImportError as e:
print("{} 导入错误，错误信息：{}".format(str(datetime.datetime.now()), e))
print("{} 包导入完成".format(str(datetime.datetime.now())))
 env = trueskill.TrueSkill(mu=0.3, sigma=0.164486, beta=0.05, tau=0.00164, draw_probability=0)
 env.make_as_global()
def win_probability(team1, team2):

 delta_mu = team1.mu - team2.mu
sum_sigma = sum([team1.sigma ** 2, team2.sigma ** 2])
 size = 2
denom = math.sqrt(size *(0.05 * 0.05)+ sum_sigma)
 ts = trueskill.global_env()
return ts.cdf(delta_mu / denom)
 class user:

 def __init__(self):

 self.question_answered_num = 0
self.question_answered_num_agg_field = [0] * 7
self.question_answered_mean_accuracy = 0
self.question_answered_mean_accuracy_agg_field = [0] * 7
self.question_answered_mean_difficulty_weighted_accuracy = 0
self.question_answered_mean_difficulty_weighted_accuracy_agg_field = [0] * 7
self.max_solved_difficulty = 1
self.max_solved_difficulty_agg_field = [1] * 7
self.min_wrong_difficulty = 0
self.min_wrong_difficulty_agg_field = [0] * 7
self.lessons_overall = 0
self.lessons_overall_agg_field = [0] * 7
self.session_time = 0
self.since_last_session_time = 0
self._mmr_object = trueskill.setup(mu=0.3, sigma=0.164486, beta=0.05, tau=0.00164,
draw_probability=0 ).Rating()
self._mmr_object_agg_field = [trueskill.setup(mu=0.3, sigma=0.164486, beta=0.05, tau=0.00164,
draw_probability=0 ).Rating() ] * 7
self._most_liked_guess = [0] * 4
self._last_session_start_time = 0
self._first_action_time = 0
self._question_num_dict = {}
self._first_processed_flag = False
def update_user(self, data: pd.DataFrame):

 _temp = None
if data['content_type_id'] == 0:
self.question_answered_num = self.question_answered_num + 1
question_field = int(data['content_field'])
 self.question_answered_num_agg_field[question_field - 1] = int(self.question_answered_num_agg_field[
question_field - 1])+ 1
if data['answered_correctly'] == 1:
self.question_answered_mean_accuracy = \ 
(self.question_answered_mean_accuracy *(
 self.question_answered_num - 1)+ 1)/ self.question_answered_num
self.question_answered_mean_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)+ 1)\
/ self.question_answered_num_agg_field[question_field - 1]
self.question_answered_mean_difficulty_weighted_accuracy = \ 
(self.question_answered_mean_difficulty_weighted_accuracy *(self.question_answered_num - 1)+(
 1 - data['mean_question_accuracy'])* 3)\
/ self.question_answered_num
self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)+(
 1 - data['mean_question_accuracy'])* 3)\
/ self.question_answered_num_agg_field[question_field - 1]
else:
self.question_answered_mean_accuracy = \ 
(self.question_answered_mean_accuracy *(
 self.question_answered_num - 1)) / self.question_answered_num
self.question_answered_mean_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)) / \
self.question_answered_num_agg_field[question_field - 1]
self.question_answered_mean_difficulty_weighted_accuracy = \ 
(self.question_answered_mean_difficulty_weighted_accuracy *(self.question_answered_num - 1)) \
/ self.question_answered_num
self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] = \ 
(self.question_answered_mean_difficulty_weighted_accuracy_agg_field[question_field - 1] *(
 self.question_answered_num_agg_field[question_field - 1] - 1)) \
/ self.question_answered_num_agg_field[question_field - 1]
if data['answered_correctly'] == 1:
if data['mean_question_accuracy'] < self.max_solved_difficulty:
self.max_solved_difficulty = data['mean_question_accuracy']
if data['mean_question_accuracy'] < self.max_solved_difficulty_agg_field[question_field - 1]:
self.max_solved_difficulty_agg_field[question_field - 1] = data['mean_question_accuracy']
else:
if data['mean_question_accuracy'] > self.min_wrong_difficulty:
self.min_wrong_difficulty = data['mean_question_accuracy']
if data['mean_question_accuracy'] > self.min_wrong_difficulty_agg_field[question_field - 1]:
self.min_wrong_difficulty_agg_field[question_field - 1] = data['mean_question_accuracy']
if data['answered_correctly'] == 0:
self._most_liked_guess[int(data['user_answer'])] = self._most_liked_guess[
int(data['user_answer'])] + 1
if self._first_action_time == 0:
self._first_action_time = data['timestamp']
self._last_session_start_time = data['timestamp']
else:
if data['timestamp'] - self._last_session_start_time >= 7200 * 1000:
self.since_last_session_time =(data[
'timestamp'] - self._last_session_start_time)/ 1000 / 3600
self._last_session_start_time = data['timestamp']
self.session_time = 0
else:
self.session_time =(data['timestamp'] - self._last_session_start_time)/ 1000 / 60
if str(data['content_id'])in self._question_num_dict:
self._question_num_dict[str(data['content_id'])] = self._question_num_dict[str(data['content_id'])] + 1
else:
self._question_num_dict[str(data['content_id'])] = 1
if data['answered_correctly'] == 1:
self._mmr_object, _temp = \
trueskill.rate_1vs1(self._mmr_object,
trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05, tau=0.00164, draw_probability=0 ).Rating())
 self._mmr_object_agg_field[question_field - 1], _temp = \
trueskill.rate_1vs1(self._mmr_object_agg_field[question_field - 1],
trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05,
tau=0.00164, draw_probability=0 ).Rating())
 else:
_temp, self._mmr_object = \
trueskill.rate_1vs1(trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05, tau=0.00164, draw_probability=0 ).Rating() ,
self._mmr_object)
 _temp, self._mmr_object_agg_field[question_field - 1] = \
trueskill.rate_1vs1(trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486,
beta=0.05,
tau=0.00164, draw_probability=0 ).Rating() ,
self._mmr_object_agg_field[question_field - 1])
 else:
self.lessons_overall = self.lessons_overall + 1
lesson_field = int(data['content_field'])
 self.lessons_overall_agg_field[lesson_field - 1] = self.lessons_overall_agg_field[lesson_field - 1] + 1
def process_output(self, data):

 output_dict = {}
output_dict['question_answered_num'] = self.question_answered_num
output_dict['question_answered_num_agg_field'] = self.question_answered_num_agg_field[
int(data['content_field'])- 1]
output_dict['question_answered_mean_accuracy'] = self.question_answered_mean_accuracy
output_dict['question_answered_mean_accuracy_agg_field'] = self.question_answered_mean_accuracy_agg_field[
int(data['content_field'])- 1]
output_dict[
'question_answered_mean_difficulty_weighted_accuracy'] = self.question_answered_mean_difficulty_weighted_accuracy
output_dict['question_answered_mean_difficulty_weighted_accuracy_agg_field'] = \
self.question_answered_mean_difficulty_weighted_accuracy_agg_field[int(data['content_field'])- 1]
output_dict['max_solved_difficulty'] = self.max_solved_difficulty
output_dict['max_solved_difficulty_agg_field'] = self.max_solved_difficulty_agg_field[
int(data['content_field'])- 1]
output_dict['min_wrong_difficulty'] = self.min_wrong_difficulty
output_dict['min_wrong_difficulty_agg_field'] = self.min_wrong_difficulty_agg_field[
int(data['content_field'])- 1]
output_dict['lessons_overall'] = self.lessons_overall
output_dict['lessons_overall_agg_field'] = self.lessons_overall_agg_field[int(data['content_field'])- 1]
if output_dict['lessons_overall_agg_field'] > 0:
output_dict['field_learnt'] = 1
else:
output_dict['field_learnt'] = 0
output_dict['session_time'] = self.session_time
output_dict['time_to_last_session'] = self.since_last_session_time
output_dict['task_id'] = data['task_container_id']
output_dict['prior_time'] = data['prior_question_elapsed_time']
output_dict['mean_question_accuracy'] = data['mean_question_accuracy']
output_dict['std_question_accuracy'] = data['std_accuracy']
output_dict['question_id'] = data['content_id']
output_dict['mmr_overall'] = self._mmr_object.mu
output_dict['mmr_overall_agg_field'] = self._mmr_object_agg_field[int(data['content_field'])- 1].mu
output_dict['mmr_confidence'] = self._mmr_object.sigma
output_dict['mmr_overall_agg_field'] = self._mmr_object_agg_field[int(data['content_field'])- 1].sigma
output_dict['mmr_win_prob'] = win_probability(self._mmr_object,
trueskill.setup(mu=1 - data['mean_question_accuracy'],
sigma=0.164486,
beta=0.05, tau=0.00164,
draw_probability=0 ).Rating())
 output_dict['mmr_win_prob_agg_field'] = win_probability(
 self._mmr_object_agg_field[int(data['content_field'])- 1],
trueskill.setup(mu=1 - data['mean_question_accuracy'], sigma=0.164486, beta=0.05,
tau=0.00164, draw_probability=0 ).Rating())
 output_dict['user_id'] = data['user_id']
output_dict['tag_1'] = data['tag_1']
output_dict['tag_2'] = data['tag_2']
output_dict['tags_encoded'] = data['tags_encoded']
if not pd.isna(['prior_question_had_explanation']):
output_dict['previous_explained'] = data['prior_question_had_explanation']
else:
output_dict['previous_explained'] = False
if str(data['content_id'])in self._question_num_dict:
output_dict['question_seen'] = 1
else:
output_dict['question_seen'] = 0
max_choice = 0
max_choice_num = 0
i = 0
for item in self._most_liked_guess:
if item > max_choice_num:
max_choice_num = item
max_choice = i
i = i + 1
if output_dict['mmr_win_prob'] <= 0.4:
if max_choice == data['correct_answer']:
output_dict['most_liked_guess_correct'] = True
else:
output_dict['most_liked_guess_correct'] = False
else:
output_dict['most_liked_guess_correct'] = True
return output_dict
question_metadata = pd.read_csv(question_metadata_dir)
 lesson_metadata = pd.read_csv(lesson_metadata_dir)
 print("{} Metadata 文件导入完成".format(str(datetime.datetime.now())))
 question_metadata = question_metadata.set_index(keys=['content_id'])
 lesson_metadata = lesson_metadata.set_index(keys=['content_id'])
 print("{} Metadata 索引设置完成".format(str(datetime.datetime.now())))
 with open(pickle_dir, 'rb')as fo:
user_pickle = pickle.load(fo)
 print("{} Pickle 导入完成".format(str(datetime.datetime.now())))
 for user_id,user_info in user_pickle.items() :
user_pickle[user_id]._mmr_object = trueskill.setup(mu=user_pickle[user_id]._mmr_object[0],
sigma=user_pickle[user_id]._mmr_object[1],
beta=0.05, tau=0.00164,
draw_probability=0 ).Rating()
for i in range(0, 7):
user_pickle[user_id]._mmr_object_agg_field[i] = trueskill.setup(mu=user_pickle[user_id]._mmr_object_agg_field[i][0],
sigma=user_pickle[user_id]._mmr_object_agg_field[i][1],
beta=0.05, tau=0.00164,
draw_probability=0 ).Rating()
print("{} Pickle Trueskill状态重置完成".format(str(datetime.datetime.now())))
 model = lgb.Booster(model_file=model_dir)
 print("{} 模型导入完成".format(str(datetime.datetime.now())))
 env = riiideducation.make_env()
iter_test = env.iter_test()
print("{} 比赛环境设置完成".format(str(datetime.datetime.now())))
 rows_accum = 0
first_submission = True
model_prd = [0]
true_value = []
last_df = pd.DataFrame()
print("{} 比赛变量设置完成".format(str(datetime.datetime.now())))
 for(test_df, sample_prediction_df)in iter_test:
if first_submission == False:
last_df['answered_correctly'] = eval(test_df.iloc[0]['prior_group_answers_correct'])
 last_df['user_answer'] = eval(test_df.iloc[0]['prior_group_responses'])
 true_value.extend(eval(test_df.iloc[0]['prior_group_answers_correct']))
for index,row in last_df.iterrows() :
user_pickle[row['user_id']].update_user(row)
 rows_accum = rows_accum + test_df.shape[0]
if first_submission == False:
1+1
test_df['answered_correctly'] = 0.6524
st = float(time.time())
 try:
sub_1 = test_df[test_df['content_type_id'] == False]
sub_2 = test_df[test_df['content_type_id'] == True]
del test_df
sub_1 = sub_1.merge(question_metadata, on="content_id", how="left")
 sub_2 = sub_2.merge(lesson_metadata, on="content_id", how="left")
 test_df = pd.DataFrame()
test_df = pd.concat([sub_1,sub_2])
 except Exception:
pass
for index, row in test_df.iterrows() :
try:
if row['user_id'] not in user_pickle:
user_pickle[row['user_id']] = user()
if row['content_type_id'] == 0:
predict_dict = user_pickle[row['user_id']].process_output(row)
 l = []
for i,v in predict_dict.items() :
l.append(v)
 prd_value = float(model.predict([l])[0])
 test_df.loc[test_df.row_id == row.row_id, 'answered_correctly'] = prd_value
model_prd.append(prd_value)
 except Exception as e:
print(e)
 pass
time_taken = float(time.time())- st
print("{} 基于当前速率，共需要 {} 分钟完成预测".format(
 str(datetime.datetime.now()),int(time_taken / test_df.shape[0] * 2500000 / 60)))
 if first_submission == True:
first_submission = False
last_df = test_df
env.predict(test_df.loc[test_df['content_type_id'] == 0, ['row_id', 'answered_correctly']])
<import_modules>
who_data['country'].replace({'capeverde':'caboverde','czechrepublic':'czechia','myanmar':'burma',
'congodemrep':'congokinshasa','congorep':'congobrazzaville','guinea':'guineabissau',
'swaziland':'eswatini','southkorea':'koreasouth','macedonia':'northmacedonia',
'timor':'timorleste','unitedstates':'us','unitedstatesvirginislands':'us',
'vatican':'holysee','palestine':'westbankandgaza'},inplace=True)
 print(who_data['country'].nunique())
 who_data.drop_duplicates(subset=['country'],inplace=True )
import gc
import random
from tqdm import tqdm
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
import seaborn as sns
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.nn.utils.rnn as rnn_utils
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader<define_variables>
print('From train:{} ; From who-data:{} ; intersection:{}'.format(train['Country_Region'].nunique() ,who_data['country'].nunique() ,
len(set(train['Country_Region'])& set(who_data['country']))))
print('From test:{} ; From who-data:{} ; intersection:{}'.format(test['Country_Region'].nunique() ,who_data['country'].nunique() ,
len(set(test['Country_Region'])& set(who_data['country']))))
MAX_SEQ = 170
ACCEPTED_USER_CONTENT_SIZE = 5
EMBED_SIZE = 128
BATCH_SIZE=64
DROPOUT=0.1<load_from_csv>
who_data.select_dtypes(include='number' ).isnull().sum() /who_data.shape[0]
%%time
dtype = {'timestamp':'int64',
'user_id':'int32' ,
'content_id':'int16',
'content_type_id':'int8',
'answered_correctly':'int8'}
train_df = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/train.csv', usecols=[1, 2, 3, 4, 7], dtype=dtype)
 train_df.head()<sort_values>
print('train shape: {} ; test shape: {}'.format(train.shape,test.shape))
train=train.merge(who_data,left_on='Country_Region',right_on='country',how='left')
 test=test.merge(who_data,left_on='Country_Region',right_on='country',how='left')
 train.fillna(train.quantile (.15 ).to_dict() ,inplace=True)
 test.fillna(train.quantile (.15 ).to_dict() ,inplace=True)
 print('train shape: {} ; test shape: {}'.format(train.shape,test.shape))
train.head(3 )
train_df = train_df[train_df.content_type_id == False]
train_df = train_df.sort_values(['timestamp'], ascending=True ).reset_index(drop = True )<count_unique_values>
train['Date'] = pd.to_datetime(train['Date'], format = '%Y-%m-%d')
 test['Date'] = pd.to_datetime(test['Date'], format = '%Y-%m-%d' )
skills = train_df["content_id"].unique()
n_skill = len(skills)
 print("number skills", len(skills))<groupby>
def create_date_features(df):
df['day'] = df['Date'].dt.day
df['month'] = df['Date'].dt.month
df['dayofweek'] = df['Date'].dt.dayofweek
df['dayofyear'] = df['Date'].dt.dayofyear
df['weekofyear'] = df['Date'].dt.weekofyear
df['Date_day_month'] = df['Date'].dt.strftime("%m%d" ).astype(int)
 return df
train=create_date_features(train)
 test=create_date_features(test)
 test.head(3 )
group = train_df[['user_id', 'content_id', 'answered_correctly']].groupby('user_id' ).apply(lambda r:(
 r['content_id'].values,
r['answered_correctly'].values))
del train_df
gc.collect()<define_variables>
train['Province_State']=train['Country_Region']+' '+train['Province_State']
test['Province_State']=test['Country_Region']+' '+test['Province_State']
train['Province_State']=train['Province_State'].str.replace(' ','')
 test['Province_State']=test['Province_State'].str.replace(' ','')
 train.drop(columns=['Country Name','Country_Region','country'],inplace=True)
 test.drop(columns=['Country Name','Country_Region','country'],inplace=True)
 train.head(2 )
random.seed(1)
<define_variables>
train['measures_applied']=(train.Date.dt.strftime('%Y-%m-%d')>=train['entry_date'] ).astype(int)
 test['measures_applied']=(test.Date.dt.strftime('%Y-%m-%d')>=test['entry_date'] ).astype(int)
 train.drop(columns=['entry_date'],inplace=True)
 test.drop(columns=['entry_date'],inplace=True)
 train.head(3 )
class SAKTDataset(Dataset):
def __init__(self, group, n_skill, max_seq=MAX_SEQ):
super(SAKTDataset, self ).__init__()
self.max_seq = max_seq
self.n_skill = n_skill
self.samples = group
self.user_ids = []
for user_id in group.index:
q, qa = group[user_id]
if len(q)< 2:
continue
self.user_ids.append(user_id)
 def __len__(self):
return len(self.user_ids)
 def __getitem__(self, index):
user_id = self.user_ids[index]
q_, qa_ = self.samples[user_id]
seq_len = len(q_)
 q = np.zeros(self.max_seq, dtype=int)
 qa = np.zeros(self.max_seq, dtype=int)
 if seq_len >= self.max_seq:
if random.random() >0.1:
start = random.randint(0,(seq_len-self.max_seq))
end = start + self.max_seq
q[:] = q_[start:end]
qa[:] = qa_[start:end]
else:
q[:] = q_[-self.max_seq:]
qa[:] = qa_[-self.max_seq:]
else:
if random.random() >0.1:
start = 0
end = random.randint(2,seq_len)
 seq_len = end - start
q[-seq_len:] = q_[0:seq_len]
qa[-seq_len:] = qa_[0:seq_len]
else:
q[-seq_len:] = q_
qa[-seq_len:] = qa_
target_id = q[1:]
label = qa[1:]
x = np.zeros(self.max_seq-1, dtype=int)
 x = q[:-1].copy()
x +=(qa[:-1] == 1)* self.n_skill
return x, target_id, label<create_dataframe>
train=pd.get_dummies(columns=['category','measure','global-school-closures'],data=train)
 test=pd.get_dummies(columns=['category','measure','global-school-closures'],data=test)
 train.head(3 )
dataset = SAKTDataset(group, n_skill)
 dataloader = DataLoader(dataset, batch_size=2048, shuffle=True, num_workers=8)
 item = dataset.__getitem__(5)
<choose_model_class>
s=test.select_dtypes(include='number' ).nunique()
binary_features=s[s==2].index.values
binary_features
class FFN(nn.Module):
def __init__(self, state_size = 200, forward_expansion = 1, bn_size=MAX_SEQ - 1):
super(FFN, self ).__init__()
self.state_size = state_size
self.lr1 = nn.Linear(state_size, forward_expansion * state_size)
 self.relu = nn.ReLU()
self.lr2 = nn.Linear(forward_expansion * state_size, state_size)
 self.dropout = nn.Dropout(0.2)
 def forward(self, x):
x = self.relu(self.lr1(x))
x = self.lr2(x)
 return self.dropout(x)
 def future_mask(seq_length):
future_mask = np.triu(np.ones(( seq_length, seq_length)) , k=1 ).astype('bool')
 return torch.from_numpy(future_mask)
 class TransformerBlock(nn.Module):
def __init__(self, embed_dim, heads = 8, dropout = DROPOUT, forward_expansion = 1):
super(TransformerBlock, self ).__init__()
self.multi_att = nn.MultiheadAttention(embed_dim=embed_dim, num_heads=heads, dropout=dropout)
 self.dropout = nn.Dropout(dropout)
 self.layer_normal = nn.LayerNorm(embed_dim)
 self.ffn = FFN(embed_dim, forward_expansion = forward_expansion)
 self.layer_normal_2 = nn.LayerNorm(embed_dim)
 def forward(self, value, key, query, att_mask):
att_output, att_weight = self.multi_att(value, key, query, attn_mask=att_mask)
 att_output = self.dropout(self.layer_normal(att_output + value))
att_output = att_output.permute(1, 0, 2)
 x = self.ffn(att_output)
 x = self.dropout(self.layer_normal_2(x + att_output))
return x.squeeze(-1), att_weight
class Encoder(nn.Module):
def __init__(self, n_skill, max_seq=100, embed_dim=128, dropout = DROPOUT, forward_expansion = 1, num_layers=1, heads = 8):
super(Encoder, self ).__init__()
self.n_skill, self.embed_dim = n_skill, embed_dim
self.embedding = nn.Embedding(2 * n_skill + 1, embed_dim)
 self.pos_embedding = nn.Embedding(max_seq - 1, embed_dim)
 self.e_embedding = nn.Embedding(n_skill+1, embed_dim)
 self.layers = nn.ModuleList([TransformerBlock(embed_dim, forward_expansion = forward_expansion)for _ in range(num_layers)])
 self.dropout = nn.Dropout(dropout)
 def forward(self, x, question_ids):
device = x.device
x = self.embedding(x)
 pos_id = torch.arange(x.size(1)).unsqueeze(0 ).to(device)
 pos_x = self.pos_embedding(pos_id)
 x = self.dropout(x + pos_x)
 x = x.permute(1, 0, 2)
 e = self.e_embedding(question_ids)
 e = e.permute(1, 0, 2)
 for layer in self.layers:
att_mask = future_mask(e.size(0)).to(device)
 x, att_weight = layer(e, x, x, att_mask=att_mask)
 x = x.permute(1, 0, 2)
 x = x.permute(1, 0, 2)
 return x, att_weight
class SAKTModel(nn.Module):
def __init__(self, n_skill, max_seq=100, embed_dim=128, dropout = DROPOUT, forward_expansion = 1, enc_layers=1, heads = 8):
super(SAKTModel, self ).__init__()
self.encoder = Encoder(n_skill, max_seq, embed_dim, dropout, forward_expansion, num_layers=enc_layers)
 self.pred = nn.Linear(embed_dim, 1)
 def forward(self, x, question_ids):
x, att_weight = self.encoder(x, question_ids)
 x = self.pred(x)
 return x.squeeze(-1), att_weight<choose_model_class>
train.fillna({col:0 for col in binary_features},inplace=True)
 test.fillna({col:0 for col in binary_features},inplace=True)
 filling_dict=train.median().to_dict()
train.fillna(filling_dict,inplace=True)
 test.fillna(filling_dict,inplace=True)
 train.head(2 )
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 def create_model() :
return SAKTModel(n_skill, max_seq=MAX_SEQ, embed_dim=EMBED_SIZE, forward_expansion=1, enc_layers=1, heads=8, dropout=0.1)
 model = create_model()
LR = 2e-3
EPOCHS = 10
optimizer = torch.optim.Adam(model.parameters() , lr=LR)
 criterion = nn.BCEWithLogitsLoss()
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=LR,
steps_per_epoch=1930, epochs=EPOCHS)
 model.to(device)
 criterion.to(device )<train_model>
out = pd.DataFrame({'ForecastId': [], 'ConfirmedCases': [], 'Fatalities': []})
 for province in tqdm(train['Province_State'].unique()):
train_province = train.loc[(train['Province_State'] == province)].copy()
y_Conf_true = train_province['ConfirmedCases']
y_Fat_true = train_province['Fatalities']
X_train_prov = train_province[features]
test_province = test[(test['Province_State']== province)].copy()
X_test_Id = test_province['ForecastId']
X_test_prov = test_province[features]
reg_Conf = XGBRegressor(n_estimators=1000)
 reg_Conf.fit(X_train_prov, y_Conf_true)
 y_Conf_pred = reg_Conf.predict(X_test_prov)
 reg_Fat = XGBRegressor(n_estimators=1000)
 reg_Fat.fit(X_train_prov, y_Fat_true)
 y_Fat_pred = reg_Fat.predict(X_test_prov)
 predictions = pd.DataFrame({'ForecastId': X_test_Id, 'ConfirmedCases': y_Conf_pred, 'Fatalities': y_Fat_pred})
 out = pd.concat([out, predictions], axis=0)
 out['ForecastId']=out['ForecastId'].astype(int )
<save_model><EOS> 
out.to_csv('submission.csv',index=False )