@@ -908,9 +908,11 @@ def _score(self, X, y=None, cast_to_float=True):
908908 score_node ._skrub_impl .scorers , mode = "fit_transform" , environment = env
909909 )
910910 all_scores = []
911+ caching_estimator = _CachingXyPipeline (self .data_op , self .environment )
912+ _copy_attr (self , caching_estimator , ["_is_fitted" ])
911913 for scorer_info in scorers :
912914 scorer = self ._prepare_scorer (scorer_info ["scoring" ], scorer_info ["kwargs" ])
913- scorer_output = scorer (self , X , y )
915+ scorer_output = scorer (caching_estimator , X , y )
914916 all_scores .extend (self ._process_scores (scorer_info , scorer_output ))
915917 rename = unique_renaming ()
916918 result = {rename (name ): score for name , score in all_scores }
@@ -921,6 +923,16 @@ def _score(self, X, y=None, cast_to_float=True):
921923 return result
922924
923925
926+ class _CachingXyPipeline (_XyPipeline ):
927+ def _eval_in_mode (self , mode , X , y = None ):
928+ if not hasattr (self , "_cache" ):
929+ self ._cache = {}
930+ key = (mode , id (X ), id (y ))
931+ if key not in self ._cache :
932+ self ._cache [key ] = super ()._eval_in_mode (mode , X , y = y )
933+ return self ._cache [key ]
934+
935+
924936def _compute_X_y_and_cv (data_op , environment ):
925937 """Evaluate the nodes marked with `.skb.mark_as_X()` and `.skb.mark_as_y()`."""
926938 nodes = find_X_y_and_cv (data_op .skb .clone ())
0 commit comments