.. _searchrankrst: ======================== Ranking et search engine ======================== .. only:: html **Links:** :download:`notebook `, :downloadlink:`html `, :download:`PDF `, :download:`python `, :downloadlink:`slides `, :githublink:`GitHub|_doc/notebooks/lectures/search_rank.ipynb|*` 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. .. code:: ipython3 %matplotlib inline .. code:: ipython3 from papierstat.datasets import load_search_engine_dataset X, y, qid = load_search_engine_dataset() X[:5,:6].todense() .. parsed-literal:: 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.]]) .. code:: ipython3 X.shape .. parsed-literal:: (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. .. code:: ipython3 set(qid) .. parsed-literal:: {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 `__. .. code:: ipython3 X_train, y_train, qid_train = load_search_engine_dataset() .. code:: ipython3 import pandas df = pandas.DataFrame(qid_train) df['c'] = 1 df.columns = ['qid', 'c'] gr_train = df.groupby('qid').count() gr_train .. raw:: html
c
qid
1 86
16 106
31 92
46 120
61 59
76 45
91 74
.. code:: ipython3 from xgboost import DMatrix dtrain = DMatrix(data=X_train, label=y_train) dtrain.set_group(gr_train.values) .. code:: ipython3 from xgboost import XGBRegressor, train rk = train(params={'objective': 'rank:ndcg'}, dtrain=dtrain, num_boost_round=10) .. code:: ipython3 X_test, y_test, qid_test = load_search_engine_dataset(False) .. code:: ipython3 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) .. code:: ipython3 pred = rk.predict(dtest) On peut calculer l’erreur au carré. .. code:: ipython3 from sklearn.metrics import mean_squared_error mean_squared_error(y_test, pred) .. parsed-literal:: 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. .. code:: ipython3 from lightgbm import LGBMRanker model = LGBMRanker() model.fit(X_train, y_train, group=gr_train.values.flatten()) .. parsed-literal:: LGBMRanker() .. code:: ipython3 Epred = model.predict(X_test.toarray()) Epred[:5] .. parsed-literal:: 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.