我使用Python的Scikit-learn
库编写了一个简单的线性回归和决策树分类器代码来预测结果。这个方法效果很好。
我的问题是,有没有办法反过来做,根据预设的结果(参数)来预测最佳的参数值组合(在这些参数下准确率会最高)。
或者我可以这样问,有没有一种分类、回归或其他类型的算法(决策树、SVM、KNN、逻辑回归、线性回归、多项式回归…)可以基于一个(或多个)参数预测多个结果?
我尝试使用多变量输出进行操作,但出现了错误:
ValueError: Expected 2D array, got 1D array instead: array=[101 905 182 268 646 624 465]. Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
这是我为回归编写的代码:
import pandas as pdfrom sklearn import linear_modelfrom sklearn import treedic = {'par_1': [10, 30, 13, 19, 25, 33, 23], 'par_2': [1, 3, 1, 2, 3, 3, 2], 'outcome': [101, 905, 182, 268, 646, 624, 465]}df = pd.DataFrame(dic)variables = df.iloc[:,:-1]results = df.iloc[:,-1]regression = linear_model.LinearRegression()regression.fit(variables, results)input_values = [14, 2]prediction = regression.predict([input_values])prediction = round(prediction[0], 2)print(prediction)
这是我为决策树编写的代码:
dic = {'par_1': [10, 30, 13, 19, 25, 33, 23], 'par_2': [1, 3, 1, 2, 3, 3, 2], 'outcome': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'yes']}df = pd.DataFrame(dic)variables = df.iloc[:,:-1]results = df.iloc[:,-1]decision_tree = tree.DecisionTreeClassifier()decision_tree.fit(variables, results)input_values = [18, 2]prediction = decision_tree.predict([input_values])[0]print(prediction)
回答:
正如@Justas提到的,如果你想找到输入值的最佳组合,使输出变量达到最大或最小值,那么这是一个优化问题。
在scipy中有很多不错的非线性优化器可供选择,或者你可以使用元启发式方法,如遗传算法、模因算法等。
另一方面,如果你的目标是学习逆函数,将输出变量映射到一组输入变量,那么可以使用MultiOuputRegresssor或MultiOutputClassifier。这两者都可以作为任何基础估计器(如线性回归、逻辑回归、KNN、决策树、SVM等)的包装器使用。
示例:
import pandas as pdfrom sklearn.multioutput import MultiOutputRegressor, RegressorChainfrom sklearn.linear_model import LinearRegressiondic = {'par_1': [10, 30, 13, 19, 25, 33, 23], 'par_2': [1, 3, 1, 2, 3, 3, 2], 'outcome': [101, 905, 182, 268, 646, 624, 465]}df = pd.DataFrame(dic)variables = df.iloc[:,:-1]results = df.iloc[:,-1]multi_output_reg = MultiOutputRegressor(LinearRegression())multi_output_reg.fit(results.values.reshape(-1, 1),variables)multi_output_reg.predict([[100]])# array([[12.43124217, 1.12571947]])# 根据训练数据,这听起来是合理的# 如果输入变量需要被视为类别,# 可以使用multiOutputClassifierfrom sklearn.multioutput import MultiOutputClassifierfrom sklearn.linear_model import LogisticRegressionmulti_output_clf = MultiOutputClassifier(LogisticRegression(solver='lbfgs'))multi_output_clf.fit(results.values.reshape(-1, 1),variables)multi_output_clf.predict([[100]])# array([[10, 1]])
在大多数情况下,找到一个输入变量的值可以帮助预测其他变量。这种方法可以通过ClassifierChain或RegressorChain来实现。
要了解ClassifierChain的优势,请参考这个示例。
更新:
dic = {'par_1': [10, 30, 13, 19, 25, 33, 23], 'par_2': [1, 3, 1, 2, 3, 3, 2], 'outcome': [0, 1, 1, 1, 1, 1 , 0]}df = pd.DataFrame(dic)variables = df.iloc[:,:-1]results = df.iloc[:,-1]multi_output_clf = MultiOutputClassifier(LogisticRegression(solver='lbfgs', multi_class='ovr'))multi_output_clf.fit(results.values.reshape(-1, 1),variables)multi_output_clf.predict([[1]])# array([[13, 3]])