57 KiB
57 KiB
Prepare test set
import pandas as pd
import numpy as np
import scipy.sparse as sparse
from collections import defaultdict
from itertools import chain
import random
from tqdm import tqdm
# In evaluation we do not load train set - it is not needed
test=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\t', header=None)
test.columns=['user', 'item', 'rating', 'timestamp']
test['user_code'] = test['user'].astype("category").cat.codes
test['item_code'] = test['item'].astype("category").cat.codes
user_code_id = dict(enumerate(test['user'].astype("category").cat.categories))
user_id_code = dict((v, k) for k, v in user_code_id.items())
item_code_id = dict(enumerate(test['item'].astype("category").cat.categories))
item_id_code = dict((v, k) for k, v in item_code_id.items())
test_ui = sparse.csr_matrix((test['rating'], (test['user_code'], test['item_code'])))
Estimations metrics
estimations_df=pd.read_csv('Recommendations generated/ml-100k/Ready_Baseline_estimations.csv', header=None)
estimations_df.columns=['user', 'item' ,'score']
estimations_df['user_code']=[user_id_code[user] for user in estimations_df['user']]
estimations_df['item_code']=[item_id_code[item] for item in estimations_df['item']]
estimations=sparse.csr_matrix((estimations_df['score'], (estimations_df['user_code'], estimations_df['item_code'])), shape=test_ui.shape)
def estimations_metrics(test_ui, estimations):
result=[]
RMSE=(np.sum((estimations.data-test_ui.data)**2)/estimations.nnz)**(1/2)
result.append(['RMSE', RMSE])
MAE=np.sum(abs(estimations.data-test_ui.data))/estimations.nnz
result.append(['MAE', MAE])
df_result=(pd.DataFrame(list(zip(*result))[1])).T
df_result.columns=list(zip(*result))[0]
return df_result
# in case of error (in the laboratories) you might have to switch to the other version of pandas
# try !pip3 install pandas=='1.0.3' (or pip if you use python 2) and restart the kernel
estimations_metrics(test_ui, estimations)
RMSE | MAE | |
---|---|---|
0 | 0.949459 | 0.752487 |
Ranking metrics
import numpy as np
reco = np.loadtxt('Recommendations generated/ml-100k/Ready_Baseline_reco.csv', delimiter=',')
# Let's ignore scores - they are not used in evaluation:
users=reco[:,:1]
items=reco[:,1::2]
# Let's use inner ids instead of real ones
users=np.vectorize(lambda x: user_id_code.setdefault(x, -1))(users)
items=np.vectorize(lambda x: item_id_code.setdefault(x, -1))(items) # maybe items we recommend are not in test set
# Let's put them into one array
reco=np.concatenate((users, items), axis=1)
reco
array([[663, 475, 62, ..., 472, 269, 503], [ 48, 313, 475, ..., 591, 175, 466], [351, 313, 475, ..., 591, 175, 466], ..., [259, 313, 475, ..., 11, 591, 175], [ 33, 313, 475, ..., 11, 591, 175], [ 77, 313, 475, ..., 11, 591, 175]])
def ranking_metrics(test_ui, reco, super_reactions=[], topK=10):
nb_items=test_ui.shape[1]
relevant_users, super_relevant_users, prec, rec, F_1, F_05, prec_super, rec_super, ndcg, mAP, MRR, LAUC, HR=\
0,0,0,0,0,0,0,0,0,0,0,0,0
cg = (1.0 / np.log2(np.arange(2, topK + 2)))
cg_sum = np.cumsum(cg)
for (nb_user, user) in tqdm(enumerate(reco[:,0])):
u_rated_items=test_ui.indices[test_ui.indptr[user]:test_ui.indptr[user+1]]
nb_u_rated_items=len(u_rated_items)
if nb_u_rated_items>0: # skip users with no items in test set (still possible that there will be no super items)
relevant_users+=1
u_super_items=u_rated_items[np.vectorize(lambda x: x in super_reactions)\
(test_ui.data[test_ui.indptr[user]:test_ui.indptr[user+1]])]
# more natural seems u_super_items=[item for item in u_rated_items if test_ui[user,item] in super_reactions]
# but accesing test_ui[user,item] is expensive -we should avoid doing it
if len(u_super_items)>0:
super_relevant_users+=1
user_successes=np.zeros(topK)
nb_user_successes=0
user_super_successes=np.zeros(topK)
nb_user_super_successes=0
# evaluation
for (item_position,item) in enumerate(reco[nb_user,1:topK+1]):
if item in u_rated_items:
user_successes[item_position]=1
nb_user_successes+=1
if item in u_super_items:
user_super_successes[item_position]=1
nb_user_super_successes+=1
prec_u=nb_user_successes/topK
prec+=prec_u
rec_u=nb_user_successes/nb_u_rated_items
rec+=rec_u
F_1+=2*(prec_u*rec_u)/(prec_u+rec_u) if prec_u+rec_u>0 else 0
F_05+=(0.5**2+1)*(prec_u*rec_u)/(0.5**2*prec_u+rec_u) if prec_u+rec_u>0 else 0
prec_super+=nb_user_super_successes/topK
rec_super+=nb_user_super_successes/max(len(u_super_items),1) # to set 0 if no super items
ndcg+=np.dot(user_successes,cg)/cg_sum[min(topK, nb_u_rated_items)-1]
cumsum_successes=np.cumsum(user_successes)
mAP+=np.dot(cumsum_successes/np.arange(1,topK+1), user_successes)/min(topK, nb_u_rated_items)
MRR+=1/(user_successes.nonzero()[0][0]+1) if user_successes.nonzero()[0].size>0 else 0
LAUC+=(np.dot(cumsum_successes, 1-user_successes)+\
(nb_user_successes+nb_u_rated_items)/2*((nb_items-nb_u_rated_items)-(topK-nb_user_successes)))/\
((nb_items-nb_u_rated_items)*nb_u_rated_items)
HR+=nb_user_successes>0
result=[]
result.append(('precision', prec/relevant_users))
result.append(('recall', rec/relevant_users))
result.append(('F_1', F_1/relevant_users))
result.append(('F_05', F_05/relevant_users))
result.append(('precision_super', prec_super/super_relevant_users))
result.append(('recall_super', rec_super/super_relevant_users))
result.append(('NDCG', ndcg/relevant_users))
result.append(('mAP', mAP/relevant_users))
result.append(('MRR', MRR/relevant_users))
result.append(('LAUC', LAUC/relevant_users))
result.append(('HR', HR/relevant_users))
df_result=(pd.DataFrame(list(zip(*result))[1])).T
df_result.columns=list(zip(*result))[0]
return df_result
ranking_metrics(test_ui, reco, super_reactions=[4,5], topK=10)
943it [00:00, 10596.27it/s]
precision | recall | F_1 | F_05 | precision_super | recall_super | NDCG | mAP | MRR | LAUC | HR | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.09141 | 0.037652 | 0.04603 | 0.061286 | 0.079614 | 0.056463 | 0.095957 | 0.043178 | 0.198193 | 0.515501 | 0.437964 |
Diversity metrics
def diversity_metrics(test_ui, reco, topK=10):
frequencies=defaultdict(int)
# let's assign 0 to all items in test set
for item in list(set(test_ui.indices)):
frequencies[item]=0
# counting frequencies
for item in reco[:,1:].flat:
frequencies[item]+=1
nb_reco_outside_test=frequencies[-1]
del frequencies[-1]
frequencies=np.array(list(frequencies.values()))
nb_rec_items=len(frequencies[frequencies>0])
nb_reco_inside_test=np.sum(frequencies)
frequencies=frequencies/np.sum(frequencies)
frequencies=np.sort(frequencies)
with np.errstate(divide='ignore'): # let's put zeros put items with 0 frequency and ignore division warning
log_frequencies=np.nan_to_num(np.log(frequencies), posinf=0, neginf=0)
result=[]
result.append(('Reco in test', nb_reco_inside_test/(nb_reco_inside_test+nb_reco_outside_test)))
result.append(('Test coverage', nb_rec_items/test_ui.shape[1]))
result.append(('Shannon', -np.dot(frequencies, log_frequencies)))
result.append(('Gini', np.dot(frequencies, np.arange(1-len(frequencies), len(frequencies), 2))/(len(frequencies)-1)))
df_result=(pd.DataFrame(list(zip(*result))[1])).T
df_result.columns=list(zip(*result))[0]
return df_result
# in case of errors try !pip3 install numpy==1.18.4 (or pip if you use python 2) and restart the kernel
import evaluation_measures as ev
import imp
imp.reload(ev)
x=diversity_metrics(test_ui, reco, topK=10)
x
Reco in test | Test coverage | Shannon | Gini | |
---|---|---|---|---|
0 | 1.0 | 0.033911 | 2.836513 | 0.991139 |
To be used in other notebooks
import evaluation_measures as ev
import imp
imp.reload(ev)
estimations_df=pd.read_csv('Recommendations generated/ml-100k/Ready_Baseline_estimations.csv', header=None)
reco=np.loadtxt('Recommendations generated/ml-100k/Ready_Baseline_reco.csv', delimiter=',')
ev.evaluate(test=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\t', header=None),
estimations_df=estimations_df,
reco=reco,
super_reactions=[4,5])
#also you can just type ev.evaluate_all(estimations_df, reco) - I put above values as default
943it [00:00, 9831.71it/s]
RMSE | MAE | precision | recall | F_1 | F_05 | precision_super | recall_super | NDCG | mAP | MRR | LAUC | HR | Reco in test | Test coverage | Shannon | Gini | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.949459 | 0.752487 | 0.09141 | 0.037652 | 0.04603 | 0.061286 | 0.079614 | 0.056463 | 0.095957 | 0.043178 | 0.198193 | 0.515501 | 0.437964 | 1.0 | 0.033911 | 2.836513 | 0.991139 |
import evaluation_measures as ev
import imp
imp.reload(ev)
dir_path="Recommendations generated/ml-100k/"
super_reactions=[4,5]
test=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\t', header=None)
df=ev.evaluate_all(test, dir_path, super_reactions)
#also you can just type ev.evaluate_all() - I put above values as default
943it [00:00, 11236.19it/s] 943it [00:00, 10128.11it/s] 943it [00:00, 10299.38it/s] 943it [00:00, 10525.19it/s]
[1;31m---------------------------------------------------------------------------[0m [1;31mOSError[0m Traceback (most recent call last) [1;32m<ipython-input-24-bc90f36b06c1>[0m in [0;36m<module>[1;34m[0m [0;32m 7[0m [0mtest[0m[1;33m=[0m[0mpd[0m[1;33m.[0m[0mread_csv[0m[1;33m([0m[1;34m'./Datasets/ml-100k/test.csv'[0m[1;33m,[0m [0msep[0m[1;33m=[0m[1;34m'\t'[0m[1;33m,[0m [0mheader[0m[1;33m=[0m[1;32mNone[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0;32m 8[0m [1;33m[0m[0m [1;32m----> 9[1;33m [0mdf[0m[1;33m=[0m[0mev[0m[1;33m.[0m[0mevaluate_all[0m[1;33m([0m[0mtest[0m[1;33m,[0m [0mdir_path[0m[1;33m,[0m [0msuper_reactions[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0m[0;32m 10[0m [1;31m#also you can just type ev.evaluate_all() - I put above values as default[0m[1;33m[0m[1;33m[0m[1;33m[0m[0m [1;32m~\Desktop\warsztaty\moje\evaluation_measures.py[0m in [0;36mevaluate_all[1;34m(test, dir_path, super_reactions, topK)[0m [0;32m 205[0m [1;32mfor[0m [0mmodel[0m [1;32min[0m [0mmodels[0m[1;33m:[0m[1;33m[0m[1;33m[0m[0m [0;32m 206[0m [0mestimations_df[0m[1;33m=[0m[0mpd[0m[1;33m.[0m[0mread_csv[0m[1;33m([0m[1;34m'{}{}_estimations.csv'[0m[1;33m.[0m[0mformat[0m[1;33m([0m[0mdir_path[0m[1;33m,[0m [0mmodel[0m[1;33m.[0m[0mreplace[0m[1;33m([0m[1;34m".csv"[0m[1;33m,[0m [1;34m""[0m[1;33m)[0m[1;33m)[0m[1;33m,[0m [0mheader[0m[1;33m=[0m[1;32mNone[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [1;32m--> 207[1;33m [0mreco[0m[1;33m=[0m[0mnp[0m[1;33m.[0m[0mloadtxt[0m[1;33m([0m[1;34m'{}{}_reco.csv'[0m[1;33m.[0m[0mformat[0m[1;33m([0m[0mdir_path[0m[1;33m,[0m [0mmodel[0m[1;33m)[0m[1;33m,[0m [0mdelimiter[0m[1;33m=[0m[1;34m','[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0m[0;32m 208[0m [0mto_append[0m[1;33m=[0m[0mevaluate[0m[1;33m([0m[0mtest[0m[1;33m,[0m [0mestimations_df[0m[1;33m,[0m [0mreco[0m[1;33m,[0m [0msuper_reactions[0m[1;33m,[0m [0mtopK[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0;32m 209[0m [1;33m[0m[0m [1;32mc:\users\adrian\appdata\local\programs\python\python38-32\lib\site-packages\numpy\lib\npyio.py[0m in [0;36mloadtxt[1;34m(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack, ndmin, encoding, max_rows)[0m [0;32m 979[0m [0mfname[0m [1;33m=[0m [0mos_fspath[0m[1;33m([0m[0mfname[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0;32m 980[0m [1;32mif[0m [0m_is_string_like[0m[1;33m([0m[0mfname[0m[1;33m)[0m[1;33m:[0m[1;33m[0m[1;33m[0m[0m [1;32m--> 981[1;33m [0mfh[0m [1;33m=[0m [0mnp[0m[1;33m.[0m[0mlib[0m[1;33m.[0m[0m_datasource[0m[1;33m.[0m[0mopen[0m[1;33m([0m[0mfname[0m[1;33m,[0m [1;34m'rt'[0m[1;33m,[0m [0mencoding[0m[1;33m=[0m[0mencoding[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0m[0;32m 982[0m [0mfencoding[0m [1;33m=[0m [0mgetattr[0m[1;33m([0m[0mfh[0m[1;33m,[0m [1;34m'encoding'[0m[1;33m,[0m [1;34m'latin1'[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0;32m 983[0m [0mfh[0m [1;33m=[0m [0miter[0m[1;33m([0m[0mfh[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [1;32mc:\users\adrian\appdata\local\programs\python\python38-32\lib\site-packages\numpy\lib\_datasource.py[0m in [0;36mopen[1;34m(path, mode, destpath, encoding, newline)[0m [0;32m 267[0m [1;33m[0m[0m [0;32m 268[0m [0mds[0m [1;33m=[0m [0mDataSource[0m[1;33m([0m[0mdestpath[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [1;32m--> 269[1;33m [1;32mreturn[0m [0mds[0m[1;33m.[0m[0mopen[0m[1;33m([0m[0mpath[0m[1;33m,[0m [0mmode[0m[1;33m,[0m [0mencoding[0m[1;33m=[0m[0mencoding[0m[1;33m,[0m [0mnewline[0m[1;33m=[0m[0mnewline[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0m[0;32m 270[0m [1;33m[0m[0m [0;32m 271[0m [1;33m[0m[0m [1;32mc:\users\adrian\appdata\local\programs\python\python38-32\lib\site-packages\numpy\lib\_datasource.py[0m in [0;36mopen[1;34m(self, path, mode, encoding, newline)[0m [0;32m 621[0m encoding=encoding, newline=newline) [0;32m 622[0m [1;32melse[0m[1;33m:[0m[1;33m[0m[1;33m[0m[0m [1;32m--> 623[1;33m [1;32mraise[0m [0mIOError[0m[1;33m([0m[1;34m"%s not found."[0m [1;33m%[0m [0mpath[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m [0m[0;32m 624[0m [1;33m[0m[0m [0;32m 625[0m [1;33m[0m[0m [1;31mOSError[0m: Recommendations generated/ml-100k/Ready_I-KNNWithZScore.csv_reco.csv not found.
df.iloc[:,:9]
df.iloc[:,np.append(0,np.arange(9, df.shape[1]))]
Check metrics on toy dataset
import evaluation_measures as ev
import imp
import helpers
imp.reload(ev)
dir_path="Recommendations generated/toy-example/"
super_reactions=[4,5]
test=pd.read_csv('./Datasets/toy-example/test.csv', sep='\t', header=None)
display(ev.evaluate_all(test, dir_path, super_reactions, topK=3))
#also you can just type ev.evaluate_all() - I put above values as default
toy_train_read=pd.read_csv('./Datasets/toy-example/train.csv', sep='\t', header=None, names=['user', 'item', 'rating', 'timestamp'])
toy_test_read=pd.read_csv('./Datasets/toy-example/test.csv', sep='\t', header=None, names=['user', 'item', 'rating', 'timestamp'])
reco=pd.read_csv('Recommendations generated/toy-example/Self_BaselineUI_reco.csv', header=None)
estimations=pd.read_csv('Recommendations generated/toy-example/Self_BaselineUI_estimations.csv', names=['user', 'item', 'est_score'])
toy_train_ui, toy_test_ui, toy_user_code_id, toy_user_id_code, \
toy_item_code_id, toy_item_id_code = helpers.data_to_csr(toy_train_read, toy_test_read)
print('Training data:')
display(toy_train_ui.todense())
print('Test data:')
display(toy_test_ui.todense())
print('Recommendations:')
display(reco)
print('Estimations:')
display(estimations)
Sample recommendations
train=pd.read_csv('./Datasets/ml-100k/train.csv', sep='\t', header=None, names=['user', 'item', 'rating', 'timestamp'])
items=pd.read_csv('./Datasets/ml-100k/movies.csv')
user=random.choice(list(set(train['user'])))
train_content=pd.merge(train, items, left_on='item', right_on='id')
print('Here is what user rated high:')
display(train_content[train_content['user']==user][['user', 'rating', 'title', 'genres']]\
.sort_values(by='rating', ascending=False)[:15])
reco = np.loadtxt('Recommendations generated/ml-100k/Self_BaselineUI_reco.csv', delimiter=',')
items=pd.read_csv('./Datasets/ml-100k/movies.csv')
# Let's ignore scores - they are not used in evaluation:
reco_users=reco[:,:1]
reco_items=reco[:,1::2]
# Let's put them into one array
reco=np.concatenate((reco_users, reco_items), axis=1)
# Let's rebuild it user-item dataframe
recommended=[]
for row in reco:
for rec_nb, entry in enumerate(row[1:]):
recommended.append((row[0], rec_nb+1, entry))
recommended=pd.DataFrame(recommended, columns=['user','rec_nb', 'item'])
recommended_content=pd.merge(recommended, items, left_on='item', right_on='id')
print('Here is what we recommend:')
recommended_content[recommended_content['user']==user][['user', 'rec_nb', 'title', 'genres']].sort_values(by='rec_nb')
Here is what user rated high:
user | rating | title | genres | |
---|---|---|---|---|
153 | 1 | 5 | Toy Story (1995) | Animation, Children's, Comedy |
57962 | 1 | 5 | Wrong Trousers, The (1993) | Animation, Comedy |
52845 | 1 | 5 | Antonia's Line (1995) | Drama |
23811 | 1 | 5 | Chasing Amy (1997) | Drama, Romance |
53494 | 1 | 5 | Nightmare Before Christmas, The (1993) | Children's, Comedy, Musical |
23377 | 1 | 5 | Eat Drink Man Woman (1994) | Comedy, Drama |
54249 | 1 | 5 | 12 Angry Men (1957) | Drama |
56869 | 1 | 5 | Henry V (1989) | Drama, War |
22174 | 1 | 5 | Groundhog Day (1993) | Comedy, Romance |
21742 | 1 | 5 | Good, The Bad and The Ugly, The (1966) | Action, Western |
51915 | 1 | 5 | Mighty Aphrodite (1995) | Comedy |
58218 | 1 | 5 | Chasing Amy (1997) | Drama, Romance |
58440 | 1 | 5 | Manon of the Spring (Manon des sources) (1986) | Drama |
20120 | 1 | 5 | Return of the Jedi (1983) | Action, Adventure, Romance, Sci-Fi, War |
19043 | 1 | 5 | Mars Attacks! (1996) | Action, Comedy, Sci-Fi, War |
Here is what we recommend:
user | rec_nb | title | genres | |
---|---|---|---|---|
0 | 1.0 | 1 | Great Day in Harlem, A (1994) | Documentary |
942 | 1.0 | 2 | Tough and Deadly (1995) | Action, Drama, Thriller |
1884 | 1.0 | 3 | Aiqing wansui (1994) | Drama |
2826 | 1.0 | 4 | Delta of Venus (1994) | Drama |
3768 | 1.0 | 5 | Someone Else's America (1995) | Drama |
4710 | 1.0 | 6 | Saint of Fort Washington, The (1993) | Drama |
5652 | 1.0 | 7 | Celestial Clockwork (1994) | Comedy |
6594 | 1.0 | 8 | Some Mother's Son (1996) | Drama |
7535 | 1.0 | 9 | Prefontaine (1997) | Drama |
8477 | 1.0 | 10 | Santa with Muscles (1996) | Comedy |
project task 3: implement some other evaluation measure
# it may be your idea, modification of what we have already implemented
# (for example Hit2 rate which would count as a success users whoreceived at least 2 relevant recommendations)
# or something well-known
# expected output: modification of evaluation_measures.py such that evaluate_all will also display your measure
dir_path='Recommendations generated/ml-100k/'
super_reactions=[4,5]
test=pd.read_csv('./Datasets/ml-100k/test.csv', sep='\t', header=None)
ev.evaluate_all(test, dir_path, super_reactions)
943it [00:00, 12346.28it/s] 943it [00:00, 9951.36it/s] 943it [00:00, 10833.90it/s] 943it [00:00, 10505.70it/s] 943it [00:00, 10502.72it/s] 943it [00:00, 10505.98it/s] 943it [00:00, 10449.06it/s] 943it [00:00, 11646.25it/s] 943it [00:00, 8780.32it/s] 943it [00:00, 10063.91it/s] 943it [00:00, 10621.71it/s]
Model | RMSE | MAE | precision | recall | F_1 | F_05 | precision_super | recall_super | NDCG | mAP | MRR | LAUC | HR | Reco in test | Test coverage | Shannon | Gini | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Self_TopPop | 2.508258 | 2.217909 | 0.188865 | 0.116919 | 0.118732 | 0.141584 | 0.130472 | 0.137473 | 0.214651 | 0.111707 | 0.400939 | 0.555546 | 0.765642 | 1.000000 | 0.038961 | 3.159079 | 0.987317 |
0 | Ready_Baseline | 0.949459 | 0.752487 | 0.091410 | 0.037652 | 0.046030 | 0.061286 | 0.079614 | 0.056463 | 0.095957 | 0.043178 | 0.198193 | 0.515501 | 0.437964 | 1.000000 | 0.033911 | 2.836513 | 0.991139 |
0 | Self_GlobalAvg | 1.125760 | 0.943534 | 0.061188 | 0.025968 | 0.031383 | 0.041343 | 0.040558 | 0.032107 | 0.067695 | 0.027470 | 0.171187 | 0.509546 | 0.384942 | 1.000000 | 0.025974 | 2.711772 | 0.992003 |
0 | Ready_Random | 1.510030 | 1.211848 | 0.050053 | 0.022367 | 0.025984 | 0.033727 | 0.030687 | 0.023255 | 0.055392 | 0.021602 | 0.137690 | 0.507713 | 0.338282 | 0.987911 | 0.187590 | 5.111878 | 0.906685 |
0 | Ready_I-KNN | 1.030386 | 0.813067 | 0.026087 | 0.006908 | 0.010593 | 0.016046 | 0.021137 | 0.009522 | 0.024214 | 0.008958 | 0.048068 | 0.499885 | 0.154825 | 0.402333 | 0.434343 | 5.133650 | 0.877999 |
0 | Ready_I-KNNWithMeans | 0.955921 | 0.754037 | 0.004984 | 0.003225 | 0.003406 | 0.003956 | 0.004506 | 0.003861 | 0.006815 | 0.002906 | 0.020332 | 0.497969 | 0.039236 | 0.587699 | 0.071429 | 2.699278 | 0.991353 |
0 | Ready_I-KNNBaseline | 0.935327 | 0.737424 | 0.002545 | 0.000755 | 0.001105 | 0.001602 | 0.002253 | 0.000930 | 0.003444 | 0.001362 | 0.011760 | 0.496724 | 0.021209 | 0.482821 | 0.059885 | 2.232578 | 0.994487 |
0 | Ready_U-KNN | 1.023495 | 0.807913 | 0.000742 | 0.000205 | 0.000305 | 0.000449 | 0.000536 | 0.000198 | 0.000845 | 0.000274 | 0.002744 | 0.496441 | 0.007423 | 0.602121 | 0.010823 | 2.089186 | 0.995706 |
0 | Self_TopRated | 2.508258 | 2.217909 | 0.000954 | 0.000188 | 0.000298 | 0.000481 | 0.000644 | 0.000223 | 0.001043 | 0.000335 | 0.003348 | 0.496433 | 0.009544 | 0.699046 | 0.005051 | 1.945910 | 0.995669 |
0 | Self_BaselineUI | 0.967585 | 0.762740 | 0.000954 | 0.000170 | 0.000278 | 0.000463 | 0.000644 | 0.000189 | 0.000752 | 0.000168 | 0.001677 | 0.496424 | 0.009544 | 0.600530 | 0.005051 | 1.803126 | 0.996380 |
0 | Self_IKNN | 1.018363 | 0.808793 | 0.000318 | 0.000108 | 0.000140 | 0.000189 | 0.000000 | 0.000000 | 0.000214 | 0.000037 | 0.000368 | 0.496391 | 0.003181 | 0.392153 | 0.115440 | 4.174741 | 0.965327 |