This method is hard to read because it tries to do things in a very generic way. I think that I would much prefer adding a small number of calls to 'cache' in the original code.

One problem that you face is that an estimator object can have estimated parameters. These may render the cache invalid, while they really shouldn't affect the fit. The way to do this would be something like:
<pre>

def fit_model(estimator, X, y):


<pre>