Ranking et search engine#
Links: notebook
, html, PDF
, python
, slides, GitHub
C’est un petit exemple de ranking avec un très petit jeu de données, trop petit pour que le modèle soit performant, mais le code peut être réutilisé pour des exemples de taille raisonnable. C’est à dire probablement pas pour apprendre un moteur de recherche.
%matplotlib inline
from papierstat.datasets import load_search_engine_dataset
X, y, qid = load_search_engine_dataset()
X[:5,:6].todense()
matrix([[3., 3., 0., 0., 3., 1.],
[3., 0., 3., 0., 3., 1.],
[3., 0., 2., 0., 3., 1.],
[3., 0., 3., 0., 3., 1.],
[3., 0., 3., 0., 3., 1.]])
X.shape
(582, 136)
Le tableau qid
contient l’identifiant de la requête, toutes les
lignes associées à un identifiant correspondent à des résultats associés
à cette requête. Dans ce jeu, il y a 7 requêtes distinctes.
set(qid)
{1, 16, 31, 46, 61, 76, 91}
On peut essayer d’abord XGBoost. Ce petit jeu de données est aussi disponible sur github/papierstat/datasets/data.
X_train, y_train, qid_train = load_search_engine_dataset()
import pandas
df = pandas.DataFrame(qid_train)
df['c'] = 1
df.columns = ['qid', 'c']
gr_train = df.groupby('qid').count()
gr_train
c | |
---|---|
qid | |
1 | 86 |
16 | 106 |
31 | 92 |
46 | 120 |
61 | 59 |
76 | 45 |
91 | 74 |
from xgboost import DMatrix
dtrain = DMatrix(data=X_train, label=y_train)
dtrain.set_group(gr_train.values)
from xgboost import XGBRegressor, train
rk = train(params={'objective': 'rank:ndcg'}, dtrain=dtrain, num_boost_round=10)
X_test, y_test, qid_test = load_search_engine_dataset(False)
import pandas
df = pandas.DataFrame(qid_test)
df['c'] = 1
df.columns = ['qid', 'c']
gr_test = df.groupby('qid').count()
dtest = DMatrix(data=X_test)
dtest.set_group(gr_test.values)
pred = rk.predict(dtest)
On peut calculer l’erreur au carré.
from sklearn.metrics import mean_squared_error
mean_squared_error(y_test, pred)
0.9505686427514932
Mais cela n’est valable que si le score a un sens, ce qui est le cas ici. Si ce n’est pas le cas, il est possible d’évaluer les résultats avec la corrélation des rangs des résultats (coefficient de Kendall). Le module lightgbm est une autre option.
from lightgbm import LGBMRanker
model = LGBMRanker()
model.fit(X_train, y_train, group=gr_train.values.flatten())
LGBMRanker()
Epred = model.predict(X_test.toarray())
Epred[:5]
array([-5.23613848, -1.07701321, -4.46995424, -3.28967461, -1.87554731])
Autre option lightfm (article : Learning to Rank Sketchfab Models with LightFM). scikit-learn ne propose pas de modèle de ranking, il faut implémenter soi-même la transformation des données.