title: Find the best feature value to reach the largest predicted value without iterating with sklearn estimator
body: <p>I have a complex system with a lot of parameters, each parameter interact with others.
  I could have some parameters values of this system at one time (&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;).
  I could interact with only one parameter (&quot;c&quot;).
  I try to find the best value of this parameter (&quot;c&quot;) to reach the maximum value of another parameter (&quot;d&quot;) in the least time possible.</p>
  <p>For now, I fit some data (&quot;a&quot;, &quot;b&quot;, &quot;c&quot;) to a sklearn estimator and then use it to predict the target value (&quot;d&quot;).
  Then I iterate prediction with last known values of &quot;a&quot;, &quot;b&quot; and a list of &quot;c&quot; value to find the best &quot;d&quot; value.</p>
  <p>Is it possible to do the same thing (find the best &quot;c&quot; value to maximize the &quot;d&quot; value) without iterating? (like predict &quot;c&quot; from &quot;a&quot; &quot;b&quot; &quot;d&quot; without knowing the exact value of &quot;d&quot;)</p>
  <p>My goal is to be more fast for the prediction part (I need to do find the best &quot;c&quot; value at 10Hz and the prediction is not the only part time-consuming).</p>
  <p>Here is an exemple:</p>
  <pre><code>from math import cos
  from random import randint
  import pandas as pd
  from sklearn import preprocessing, pipeline, neural_network
  
  data = {'a': [], 'b': [], 'c': [], 'd':[]}
  for i in range(10000):
      a = randint(-100,100)
      b = randint(-100,100)
      c = randint(0,360)
      d = 2*a + b*cos(c) + randint(-3,3)
  
      data['a'].append(a)
      data['b'].append(b)
      data['c'].append(c)
      data['d'].append(d)
  
  data = pd.DataFrame(data=data)
  
  print(data)
  
  prepro = preprocessing.StandardScaler()
  model = neural_network.MLPRegressor()
  
  tube = pipeline.make_pipeline(prepro, model)
  
  tube.fit(data[['a', 'b', 'c']], data['d'])
  
  a_value = randint(-100,100)
  b_value = randint(-100,100)
  last_c_value = randint(0,360)
  d = False
  c_value_to_keep = False
  for i in range(-20,21):
      test = tube.predict([[a_value, b_value, last_c_value+i]])
      if d is False:
          d = test
          c = last_c_value+i
      elif test &gt; d:
          d = test
          c = last_c_value+i
  
  print(&quot;Actual a value is {a}, b value is {b}, c value is {c}&quot;.format(a =a, b=b, c=last_c_value))
  print(&quot;the best d value in this case is {d} for a c value of {c}&quot;.format(d=d[0], c=c))
  </code></pre>
  <p>To speed the prediction, I also read and use (when it's possible) this:</p>
  <p><a href="https://medium.com/building-ibotta/predict-with-sklearn-20x-faster-9f2803944446" rel="nofollow noreferrer">pure-predict</a></p>
  <p><a href="https://maxhalford.github.io/blog/speeding-up-sklearn-single-predictions/" rel="nofollow noreferrer">Max Halford blog, Speeding up scikit-learn for single predictions</a></p>
  <p>The final program will work on a Raspberry Pi.</p>
  <p>Edit 04/25/2022:
  It's really faster (10x to 30x) to make prediction with an array of value than a bunch of single prediction:</p>
  <pre><code>data = []
  for i in range(-20,21):
      data.append([a_value, b_value, last_c_value+i])
  prediction = tube.predict(data)
  d = False
  for i,j in enumerate(prediction):
      if d is False:
          d = j
          c = data[i][2]
      elif j &gt; d:
          d = j
          c = data[i][2]
  </code></pre>