Kaggle competition: Riiid Answer Correctness Prediction
<SOS> metric: AUC Kaggle data source: riiid-answer-correctness-prediction<count_missing_values>
dicts_path = '/kaggle/input/agg-riiid/agg_riiid/'
user_content_id_agg = pd.read_pickle(dicts_path + 'user_content_id_agg.pkl.gzip')
 user_content_id_agg['count'] = user_content_id_agg['count'].astype('int16' )
print("Total Test Features with NaN Values = " + str(test_df.columns[test_df.isnull().sum() != 0].size))
print("Features with NaN => {}".format(list(test_df.columns[test_df.isnull().sum() != 0])))
 test_df[test_df.columns[test_df.isnull().sum() != 0]].isnull().sum().sort_values(ascending = False )<concatenate>
user_content_id_count_dict = user_content_id_agg['count'].astype('int16' ).to_dict(defaultdict(int))
test_df['SalePrice'] = 0
combined_train_test_df = train_df.append(test_df)
 print("Shape of Combined Train and Test Data -> " + str(combined_train_test_df.shape))<count_missing_values>
del user_content_id_agg
gc.collect()
print("Total Features with NaN Values in Test and Train = " + str(combined_train_test_df.columns[combined_train_test_df.isnull().sum() != 0].size))
combined_train_test_df.columns[combined_train_test_df.isnull().sum() != 0]
missing_total = combined_train_test_df[combined_train_test_df.columns[combined_train_test_df.isnull().sum() != 0]].isnull().sum().sort_values(ascending = False)
 missing_percent =(combined_train_test_df[combined_train_test_df.columns[combined_train_test_df.isnull().sum() != 0]].isnull().sum() /combined_train_test_df.shape[0] * 100 ).sort_values(ascending = False )<concatenate>
import numpy as np
import lightgbm as lgb
import pickle
import riiideducation
import joblib
missing_features = missing_total.index
missing_features_tot = pd.concat([missing_total, missing_percent], axis = 1)
 print(missing_features_tot )<sort_values>
target = 'answered_correctly'
corr.sort_values(["SalePrice"], ascending = False, inplace = True)
 print(corr.SalePrice )<categorify>
features = [
'content_id',
'prior_question_elapsed_time',
'prior_question_had_explanation',
'user_correctness',
'user_correctness_window_10_mean',
'part',
'content_count',
'content_sum',
'content_id_correctness_total',
'repeated_times',
'user_count_questions',
'explanation_mean_user',
'timestamp',
'timestamp_diff_last',
'user_count_lectures',
'last_lecture_tag',
'prior_questions_mean_time',
'last_correct',
'task_container_id',
'first_tag',
'second_tag',
'repeated_times_tag',
'user_tag_correctness',
'timestamp_diff_last_window_10_mean',
'user_count_lectures_mean'
]
if(combined_train_test_df['BsmtFullBath'].isnull().sum() != 0):
combined_train_test_df['BsmtFullBath'].fillna(combined_train_test_df['BsmtFullBath'].mode().iloc[0], inplace = True )<categorify>
dicts_path = '/kaggle/input/agg-riiid/agg_riiid/'
user_agg = pd.read_pickle(dicts_path + 'user_agg.pkl.gzip')
 user_sum_dict = user_agg['sum'].astype('int32' ).to_dict(defaultdict(int))
user_count_dict = user_agg['count'].astype('int32' ).to_dict(defaultdict(int))
del user_agg
gc.collect()
content_agg = pd.read_pickle(dicts_path + 'content_agg.pkl.gzip')
 content_sum_dict = content_agg['sum'].astype('int32' ).to_dict(defaultdict(int))
content_count_dict = content_agg['count'].astype('int32' ).to_dict(defaultdict(int))
del content_agg
gc.collect()
user_target_window_10 = pd.read_pickle(dicts_path + 'user_target_window_10.pkl.gzip')
 user_target_window_10_dict = user_target_window_10.astype('int8' ).to_dict(defaultdict(int))
del user_target_window_10
gc.collect()
user_target_next_out_window_10_dict = defaultdict(int)
 timestamp_diff_window_10 = pd.read_pickle(dicts_path + 'timestamp_diff_window_10.pkl.gzip')
 timestamp_diff_window_10_dict = timestamp_diff_window_10.astype('int32' ).to_dict(defaultdict(int))
del timestamp_diff_window_10
gc.collect()
timestamp_diff_next_window_10_dict = defaultdict(int)
 explanation_agg = pd.read_pickle(dicts_path + 'explanation_agg.pkl.gzip')
 explanation_sum_dict = explanation_agg['sum'].astype('int32' ).to_dict(defaultdict(int))
explanation_count_dict = explanation_agg['count'].astype('int32' ).to_dict(defaultdict(int))
del explanation_agg
gc.collect()
user_lectures_agg = pd.read_pickle(dicts_path + 'user_lectures_agg.pkl.gzip')
 user_lectures_count_dict = user_lectures_agg['sum'].astype('int16' ).to_dict(defaultdict(int))
del user_lectures_agg
gc.collect()
last_lecture_agg = pd.read_pickle(dicts_path + 'last_lecture_agg.pkl.gzip')
 last_lecture_tag_dict = last_lecture_agg.astype('int16' ).to_dict(defaultdict(int))
del last_lecture_agg
gc.collect()
prior_questions_time_agg = pd.read_pickle(dicts_path + 'prior_questions_time_agg.pkl.gzip')
 prior_questions_time_sum_dict = prior_questions_time_agg['sum'].astype('int32' ).to_dict(defaultdict(float))
prior_questions_time_count_dict = prior_questions_time_agg['count'].astype('int32' ).to_dict(defaultdict(int))
del prior_questions_time_agg
gc.collect()
last_correct_agg = pd.read_pickle(dicts_path + 'last_correct_agg.pkl.gzip')
 last_correct_dict = last_correct_agg.astype('int8' ).to_dict(defaultdict(int))
del last_correct_agg
gc.collect()
user_tag_agg = pd.read_pickle(dicts_path + 'user_tag_agg.pkl.gzip')
 user_tag_agg_sum_dict = user_tag_agg['sum'].astype('int16' ).to_dict(defaultdict(int))
user_tag_agg_count_dict = user_tag_agg['count'].astype('int16' ).to_dict(defaultdict(int))
del user_tag_agg
gc.collect()
last_timestamp_agg = pd.read_pickle(dicts_path + 'last_timestamp_agg.pkl.gzip')
 last_timestamp_dict = last_timestamp_agg.astype('int32' ).to_dict(defaultdict(int))
del last_timestamp_agg
gc.collect()
if(combined_train_test_df['BsmtHalfBath'].isnull().sum() != 0):
combined_train_test_df['BsmtHalfBath'].fillna(combined_train_test_df['BsmtHalfBath'].mode().iloc[0], inplace = True )<categorify>
model_path = '/kaggle/input/trained-model/'
file = model_path + 'trained_model.pkl'
model = pickle.load(open(file, 'rb'))
print('Trained LGB model was loaded!' )
if(combined_train_test_df['TotalBsmtSF'].isnull().sum() != 0):
combined_train_test_df['TotalBsmtSF'].fillna(round(combined_train_test_df['TotalBsmtSF'].mean()), inplace = True )<set_options>
home_path = '/kaggle/input/riiid-test-answer-prediction/'
questions_df = pd.read_csv(home_path + 'questions.csv',
usecols=[0, 3, 4],
dtype={'question_id': 'int16', 'part': 'int8'}
)
if(combined_train_test_df['GarageCars'].isnull().sum() != 0):
combined_train_test_df['GarageCars'].fillna(combined_train_test_df['GarageCars'].mode().iloc[0], inplace = True )<set_options>
questions_df['tags'].fillna('92', inplace=True)
 questions_df['first_tag'] = questions_df['tags'].apply(lambda x: x.split() [0])
 questions_df['first_tag'] = questions_df['first_tag'].astype('int16')
 questions_df['second_tag'] = questions_df['tags'].apply(lambda x: x.split() [1] if len(x.split())> 1 else -1)
 questions_df['second_tag'] = questions_df['second_tag'].astype('int16')
 questions_df.drop('tags',axis=1,inplace=True )
if(combined_train_test_df['KitchenQual'].isnull().sum() != 0):
combined_train_test_df['KitchenQual'].fillna(combined_train_test_df['KitchenQual'].mode().iloc[0], inplace = True )<data_type_conversions>
lectures_df = pd.read_csv(home_path + 'lectures.csv',
dtype={'tag': 'int16', 'part': 'int8'} 
)
 type_of_dict = {'intention': 1, 'concept': 2, 'solving question': 3, 'starter': 4}
lectures_df['type_of'] = lectures_df['type_of'].map(type_of_dict )
if(combined_train_test_df['Electrical'].isnull().sum() != 0):
combined_train_test_df['Electrical'].fillna(combined_train_test_df['Electrical'].mode().iloc[0], inplace = True )<set_options>
import random
from tqdm.notebook import tqdm
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
if(combined_train_test_df['SaleType'].isnull().sum() != 0):
combined_train_test_df['SaleType'].fillna(combined_train_test_df['SaleType'].mode().iloc[0], inplace = True )<data_type_conversions>
skills = joblib.load("/kaggle/input/skills-pkl/skills.pkl.zip")
 n_skill = len(skills)
 group = joblib.load("/kaggle/input/group-pkl/group.pkl.zip")
 del joblib
gc.collect()
if(combined_train_test_df['Exterior1st'].isnull().sum() != 0):
combined_train_test_df['Exterior1st'].fillna(combined_train_test_df['Exterior1st'].mode().iloc[0], inplace = True )<data_type_conversions>
MAX_SEQ = 180
ACCEPTED_USER_CONTENT_SIZE = 4
EMBED_SIZE = 128
BATCH_SIZE = 64
DROPOUT = 0.1
if(combined_train_test_df['Exterior2nd'].isnull().sum() != 0):
combined_train_test_df['Exterior2nd'].fillna(combined_train_test_df['Exterior2nd'].mode().iloc[0], inplace = True )<data_type_conversions>
class FFN(nn.Module):
def __init__(self, state_size = 200, forward_expansion = 1, bn_size=MAX_SEQ - 1, dropout=0.2):
super(FFN, self ).__init__()
self.state_size = state_size
self.lr1 = nn.Linear(state_size, forward_expansion * state_size)
 self.relu = nn.ReLU()
self.bn = nn.BatchNorm1d(bn_size)
 self.lr2 = nn.Linear(forward_expansion * state_size, state_size)
 self.dropout = nn.Dropout(dropout)
 def forward(self, x):
x = self.relu(self.lr1(x))
x = self.bn(x)
 x = self.lr2(x)
 return self.dropout(x)
 FFN()
if(combined_train_test_df['Functional'].isnull().sum() != 0):
combined_train_test_df['Functional'].fillna(combined_train_test_df['Functional'].mode().iloc[0], inplace = True )<categorify>
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)
 future_mask(5 )
if(combined_train_test_df['Utilities'].isnull().sum() != 0):
combined_train_test_df['Utilities'].fillna(combined_train_test_df['Utilities'].mode().iloc[0], inplace = True )<count_missing_values>
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, dropout=dropout)
 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
if(combined_train_test_df['MSZoning'].isnull().sum() != 0):
combined_train_test_df['MSZoning'].fillna(combined_train_test_df['MSZoning'].mode().iloc[0], inplace = True )<count_missing_values>
del pickle
gc.collect()
if(combined_train_test_df['MasVnrArea'].isnull().sum() != 0):
combined_train_test_df['MasVnrArea'].fillna(0, inplace = True )<count_missing_values>
torch.cuda.is_available()
if(combined_train_test_df['MasVnrType'].isnull().sum() != 0):
combined_train_test_df['MasVnrType'].fillna('None', inplace = True )<categorify>
device = torch.device("cuda" if torch.cuda.is_available() else "cpu" )
if(combined_train_test_df['BsmtCond'].isnull().sum() != 0):
combined_train_test_df['BsmtCond'].fillna(combined_train_test_df['BsmtCond'].mode().iloc[0], inplace = True )<categorify>
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 )
if(combined_train_test_df['BsmtExposure'].isnull().sum() != 0):
combined_train_test_df['BsmtExposure'].fillna(combined_train_test_df['BsmtExposure'].mode().iloc[0], inplace = True )<categorify>
model_attention = create_model()
try:
model_attention.load_state_dict(torch.load("/kaggle/input/attention/attention.pth"))
except:
model_attention.load_state_dict(torch.load("/kaggle/input/attention/attention.pth", map_location='cpu'))
model_attention.to(device )
if(combined_train_test_df['BsmtQual'].isnull().sum() != 0):
combined_train_test_df['BsmtQual'].fillna(combined_train_test_df['BsmtQual'].mode().iloc[0], inplace = True )<categorify>
env = riiideducation.make_env()
iter_test = env.iter_test()
prior_test_df = None
prev_test_df = None
<categorify><EOS> 
%%time
model_attention.eval()
for(test_df, sample_prediction_df)in(iter_test):
if(prev_test_df is not None)&(psutil.virtual_memory().percent < 95):
print(psutil.virtual_memory().percent)
 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:
prev_group_content = prev_group[prev_user_id][0]
prev_group_answered_correctly = prev_group[prev_user_id][1]
if prev_user_id in group.index:
group[prev_user_id] =(np.append(group[prev_user_id][0], prev_group_content),
np.append(group[prev_user_id][1], prev_group_answered_correctly))
else:
group[prev_user_id] =(prev_group_content, prev_group_answered_correctly)
 if len(group[prev_user_id][0])> MAX_SEQ:
new_group_content = group[prev_user_id][0][-MAX_SEQ:]
new_group_answered_correctly = group[prev_user_id][1][-MAX_SEQ:]
group[prev_user_id] =(new_group_content, new_group_answered_correctly)
 prev_test_df = test_df.copy()
test_df_attention = test_df.copy()
test_df_attention = test_df_attention[test_df_attention.content_type_id == False]
test_dataset = TestDataset(group, test_df_attention, n_skill, max_seq=MAX_SEQ)
 test_dataloader = DataLoader(test_dataset, batch_size=len(test_df_attention), shuffle=False)
 attention_predictions = []
item = next(iter(test_dataloader))
x = item[0].to(device ).long()
target_id = item[1].to(device ).long()
with torch.no_grad() :
output, _ = model_attention(x, target_id)
 output = torch.sigmoid(output)
 output = output[:, -1]
attention_predictions.extend(output.cpu().numpy())
 if prior_test_df is not None:
prior_test_df[target] = eval(test_df['prior_group_answers_correct'].iloc[0])
 prior_test_df_lecture = prior_test_df[prior_test_df[target] == -1].reset_index(drop=True)
 if len(prior_test_df_lecture)> 0:
prior_test_df_lecture = pd.merge(prior_test_df_lecture, lectures_df, left_on='content_id', right_on='lecture_id', how='left')
 user_ids = prior_test_df_lecture['user_id'].values
lecture_tags = prior_test_df_lecture['tag'].values
for user_id, lecture_tag in zip(user_ids, lecture_tags):
user_lectures_count_dict[user_id] += 1
last_lecture_tag_dict[user_id] = lecture_tag
prior_test_df = prior_test_df[prior_test_df[target] != -1].reset_index(drop=True)
 user_ids = prior_test_df['user_id'].values
content_ids = prior_test_df['content_id'].values
targets = prior_test_df[target].values
prior_explanations = prior_test_df['prior_question_had_explanation'].values
prior_question_times = prior_test_df['prior_question_elapsed_time'].values
tags = prior_test_df['first_tag'].values
timestamps = prior_test_df['timestamp'].values
timestamp_diffs = prior_test_df['timestamp_diff_last'].values
for user_id, content_id, answered_correctly, explanation, prior_question_time, tag, timestamp, timestamp_diff in zip(user_ids, content_ids, targets, prior_explanations, prior_question_times, tags, timestamps, timestamp_diffs):
if answered_correctly != 1:
answered_correctly = 0
user_sum_dict[user_id] += answered_correctly
user_count_dict[user_id] += 1
content_sum_dict[content_id] += answered_correctly
content_count_dict[content_id] += 1
explanation_sum_dict[user_id] += explanation
explanation_count_dict[user_id] += 1
last_correct_dict[user_id] = answered_correctly
prior_questions_time_sum_dict[user_id] += prior_question_time
prior_questions_time_count_dict[user_id] += 1
user_tag_agg_sum_dict[user_id, tag] += answered_correctly
user_tag_agg_count_dict[user_id, tag] += 1
last_timestamp_dict[user_id] = timestamp
user_content_id = str(user_id)+ str(content_id)
 user_content_id_count_dict[user_content_id] += 1
change_next_out = True
if(user_id, 9)not in user_target_window_10_dict:
for k in range(10):
if(user_id, k)not in user_target_window_10_dict:
user_target_window_10_dict[user_id, k] = answered_correctly
change_next_out = False
break
if change_next_out:
next_out = user_target_next_out_window_10_dict[user_id]
user_target_window_10_dict[user_id, next_out] = answered_correctly
next_out += 1
if next_out > 9:
next_out = 0
user_target_next_out_window_10_dict[user_id] = next_out
else:
user_target_next_out_window_10_dict[user_id] = 0
change_next_out = True
if(user_id, 9)not in timestamp_diff_window_10_dict:
for k in range(10):
if(user_id, k)not in timestamp_diff_window_10_dict:
timestamp_diff_window_10_dict[user_id, k] = timestamp_diff
change_next_out = False
break
if change_next_out:
next_out = timestamp_diff_next_window_10_dict[user_id]
timestamp_diff_window_10_dict[user_id, next_out] = timestamp_diff
next_out += 1
if next_out > 9:
next_out = 0
timestamp_diff_next_window_10_dict[user_id] = next_out
else:
timestamp_diff_next_window_10_dict[user_id] = 0
test_df['content_id'] = test_df['content_id'].astype('int16')
 test_df['prior_question_elapsed_time'] = test_df['prior_question_elapsed_time'].apply(lambda x: x/1000)
 test_df['prior_question_elapsed_time'].fillna(25, inplace=True)
 test_df['prior_question_elapsed_time'] = test_df['prior_question_elapsed_time'].astype('int16')
 test_df['prior_question_had_explanation'] = test_df['prior_question_had_explanation'].fillna(False ).astype(int)
 test_df['timestamp'] = test_df['timestamp'].apply(lambda x: x/1000 ).astype('int32')
 prior_test_df = test_df.copy()
prior_test_df['first_tag'] = 0
prior_test_df['timestamp_diff_last'] = 0
test_df = test_df[test_df['content_type_id'] == 0].reset_index(drop=True)
 test_df = pd.merge(test_df, questions_df, left_on='content_id', right_on='question_id', how='left')
 prior_test_df.loc[prior_test_df['content_type_id'] == 0,'first_tag'] = test_df['first_tag'].values
user_sum = np.zeros(len(test_df), dtype=np.int32)
 user_count = np.zeros(len(test_df), dtype=np.int32)
 content_sum = np.zeros(len(test_df), dtype=np.int32)
 content_count = np.zeros(len(test_df), dtype=np.int32)
 user_content_id_count = np.zeros(len(test_df), dtype=np.int16)
 user_target_window_10_array = np.zeros(len(test_df))
timestamp_diff_window_10_array = np.zeros(len(test_df))
explanation_sum = np.zeros(len(test_df), dtype=np.int32)
 explanation_count = np.zeros(len(test_df), dtype=np.int32)
 user_lectures_count = np.zeros(len(test_df), dtype=np.int16)
 last_lecture_tag_array = np.zeros(len(test_df), dtype=np.int16)
 prior_questions_time_sum = np.zeros(len(test_df), dtype=np.int32)
 prior_questions_time_count = np.zeros(len(test_df), dtype=np.int32)
 last_correct_array = np.zeros(len(test_df), dtype=np.int8)
 user_tag_sum = np.zeros(len(test_df), dtype=np.int16)
 user_tag_count = np.zeros(len(test_df), dtype=np.int16)
 last_timestamp_array = np.zeros(len(test_df), dtype=np.int32)
 for i,(user_id, content_id, tag)in enumerate(zip(test_df['user_id'].values, test_df['content_id'].values, test_df['first_tag'].values)) :
user_sum[i] = user_sum_dict[user_id]
user_count[i] = user_count_dict[user_id]
content_sum[i] = content_sum_dict[content_id]
content_count[i] = content_count_dict[content_id]
explanation_sum[i] = explanation_sum_dict[user_id]
explanation_count[i] = explanation_count_dict[user_id]
user_tag_sum[i] = user_tag_agg_sum_dict[user_id, tag]
user_tag_count[i] = user_tag_agg_count_dict[user_id, tag]
last_timestamp_array[i] = last_timestamp_dict[user_id]
if(user_id)in last_lecture_tag_dict:
last_lecture_tag_array[i] = last_lecture_tag_dict[user_id]
else:
last_lecture_tag_array[i] = -9
if(user_id)in prior_questions_time_sum_dict:
prior_questions_time_sum[i] = prior_questions_time_sum_dict[user_id]
prior_questions_time_count[i] = prior_questions_time_count_dict[user_id]
else:
prior_questions_time_sum[i] = 0
prior_questions_time_count[i] = 0
if(user_id)in last_correct_dict:
last_correct_array[i] = last_correct_dict[user_id]
else:
last_correct_array[i] = -1
user_content_id = str(user_id)+ str(content_id)
 user_content_id_count[i] = user_content_id_count_dict[user_content_id]
user_target_10 = 0
for k in range(10):
if(user_id, k)in user_target_window_10_dict:
user_target_10 += user_target_window_10_dict[user_id, k]
else:
k -= 1
break
if k >= 0:
user_target_window_10_array[i] = user_target_10 /(k + 1)
 else:
user_target_window_10_array[i] = -1
timestamp_diff_10 = 0
for k in range(10):
if(user_id, k)in timestamp_diff_window_10_dict:
timestamp_diff_10 += timestamp_diff_window_10_dict[user_id, k]
else:
k -= 1
break
if k >= 0:
timestamp_diff_window_10_array[i] = timestamp_diff_10 /(k + 1)
 else:
timestamp_diff_window_10_array[i] = -1
test_df['timestamp_diff_last'] = test_df['timestamp'].values - last_timestamp_array
test_df['timestamp_diff_last'] = test_df['timestamp_diff_last'].astype('int32')
 prior_test_df.loc[prior_test_df['content_type_id'] == 0,'timestamp_diff_last'] = test_df['timestamp_diff_last'].values
test_df['last_correct'] = last_correct_array
test_df['last_correct'].fillna(-1, inplace=True)
 test_df['last_correct'] = test_df['last_correct'].astype('int8')
 test_df['task_container_id'] = test_df['task_container_id'].astype('int16')
 test_df['prior_questions_mean_time'] =(prior_questions_time_sum + test_df['prior_question_elapsed_time'].values)/(prior_questions_time_count + 1)
 test_df['prior_questions_mean_time'].fillna(25, inplace=True)
 test_df['prior_questions_mean_time'] = test_df['prior_questions_mean_time'].astype('int16')
 test_df['last_lecture_tag'] = last_lecture_tag_array
test_df['last_lecture_tag'].fillna(-9, inplace=True)
 test_df['last_lecture_tag'] = test_df['last_lecture_tag'].astype('int16')
 test_df['user_count_lectures'] = user_lectures_count
test_df['user_count_lectures'] = test_df['user_count_lectures'].astype('int16')
 test_df['user_correctness'] = user_sum / user_count
test_df['content_id_correctness_total'] = content_sum / content_count
test_df['user_correctness'].fillna(-1, inplace=True)
 test_df['user_correctness'] = test_df['user_correctness'].astype('float32')
 test_df['content_id_correctness_total'].fillna(0.600382459, inplace=True)
 test_df['content_id_correctness_total'] = test_df['content_id_correctness_total'].astype('float32')
 test_df['user_count_questions'] = user_count
test_df['user_count_questions'].fillna(0, inplace=True)
 test_df['user_count_questions'] = test_df['user_count_questions'].astype('int32')
 test_df['explanation_mean_user'] =(explanation_sum + test_df['prior_question_had_explanation'].values)/(explanation_count + 1)
 test_df['explanation_mean_user'].fillna(0, inplace=True)
 test_df['explanation_mean_user'] = test_df['explanation_mean_user'].astype('float32')
 test_df['content_count'] = content_count
test_df['content_sum'] = content_sum
test_df['repeated_times'] = user_content_id_count
test_df['repeated_times'] = test_df['repeated_times'].astype('int16')
 test_df['repeated_times_tag'] = user_tag_count
test_df['repeated_times_tag'] = test_df['repeated_times_tag'].astype('int16')
 test_df['user_tag_correctness'] = user_tag_sum / user_tag_count
test_df['user_tag_correctness'].fillna(-1, inplace=True)
 test_df['user_tag_correctness'] = test_df['user_tag_correctness'].astype('float32')
 test_df['user_correctness_window_10_mean'] = user_target_window_10_array
test_df['user_correctness_window_10_mean'].fillna(-1, inplace=True)
 test_df['user_correctness_window_10_mean'] = test_df['user_correctness_window_10_mean'].astype('float32')
 test_df['timestamp_diff_last_window_10_mean'] = timestamp_diff_window_10_array
test_df['timestamp_diff_last_window_10_mean'].fillna(-1, inplace=True)
 test_df['timestamp_diff_last_window_10_mean'] = test_df['timestamp_diff_last_window_10_mean'].astype('int32')
 test_df['user_count_lectures_mean'] = test_df['user_count_lectures'] / test_df['user_count_questions']
test_df['user_count_lectures_mean'].fillna(0, inplace=True)
 test_df['user_count_lectures_mean'] = test_df['user_count_lectures_mean'].astype('float32')
 lgbm_predictions = model.predict(test_df[features])
 test_df[target] = 0.2 * np.array(attention_predictions)+ 0.8 * lgbm_predictions
env.predict(test_df[['row_id', target]])