'Find the best feature value to reach the largest predicted value without iterating with sklearn estimator

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 ("a", "b", "c", "d"). I could interact with only one parameter ("c"). I try to find the best value of this parameter ("c") to reach the maximum value of another parameter ("d") in the least time possible.

For now, I fit some data ("a", "b", "c") to a sklearn estimator and then use it to predict the target value ("d"). Then I iterate prediction with last known values of "a", "b" and a list of "c" value to find the best "d" value.

Is it possible to do the same thing (find the best "c" value to maximize the "d" value) without iterating? (like predict "c" from "a" "b" "d" without knowing the exact value of "d")

My goal is to be more fast for the prediction part (I need to do find the best "c" value at 10Hz and the prediction is not the only part time-consuming).

Here is an exemple:

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 > d:
        d = test
        c = last_c_value+i

print("Actual a value is {a}, b value is {b}, c value is {c}".format(a =a, b=b, c=last_c_value))
print("the best d value in this case is {d} for a c value of {c}".format(d=d[0], c=c))

To speed the prediction, I also read and use (when it's possible) this:

pure-predict

Max Halford blog, Speeding up scikit-learn for single predictions

The final program will work on a Raspberry Pi.

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:

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 > d:
        d = j
        c = data[i][2]


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source