使用 Scikit 神经网络 MLPRegressor 的多输入单输出回归

Multi-input single output regression using Scikit neural networks MLPRegressor

我有一个二维数组数据如下(以M&C为自变量):

数据

我正在尝试使用 Scikit MLPRegressor 对此回归 (f(M,C) = y) 建模。由于不知道如何对多变量输入进行建模,我尝试将其建模为两个独立的单输入问题。例如,我如何使用此输出来预测 C=2.3 的曲线?如果有人能提出一个更优雅的方法来解决这个问题,我将不胜感激。

代码

# importing module
import numpy as np
import pandas as pd
from pandas import *
from matplotlib import pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPRegressor

# reading CSV file
#data = read_csv("data\Ex2.csv")
data = pd.DataFrame([[1,1,1],[2,4.28,5.65],[3,10.04,15.59],[4,18.38,32],[5,29.36,55.90],[6,43.06,88.18],[7,59.52,129.64],[8,78.79,181.02],[9,100.90,243],[10,125.89,316.22]], columns=['M','C=2.1','C=2.5'])

# converting column data to list
M = data['M'].values
C1 = data['C=2.1'].values
C2 = data['C=2.5'].values
C = np.column_stack((C1,C2))

M = M.reshape(M.shape[0],-1)

for i in range(0, 2):

    Xtrain, Xtest, Ytrain, Ytest = train_test_split(M, C[:,i], test_size=0.2, random_state=42)            
    mlp = MLPRegressor(random_state=42, activation='relu', hidden_layer_sizes=(100,100,100,100,100,100,100,100,8))    
    
    mlp.fit(Xtrain, Ytrain.ravel())    
    Yguess = mlp.predict(Xtest)
    Y = mlp.predict(M)
    
    #plt.plot(Xtest[:,0], Ytest, '.')
    #plt.plot(Xtest[:,0], Yguess, 'r.')
    plt.plot(M, C[:,i], 'o')
    plt.plot(M, Y, 'r')
 

结果

IIUC,你需要递归神经网络(RNN)或长 short-term 记忆(LSTM),你可以用 tensorflow 解决你的问题,如下所示:

import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import pandas as pd


data = pd.DataFrame([[1,1,1],[2,4.28,5.65],
                     [3,10.04,15.59],[4,18.38,32],
                     [5,29.36,55.90],[6,43.06,88.18],
                     [7,59.52,129.64],[8,78.79,181.02],
                     [9,100.90,243],[10,125.89,316.22]], 
                    columns=['M','C=2.1','C=2.5']) 
arr = data.values[:, 1:]
arr = np.insert(arr, 0, [2.1 , 2.5], axis=0).T
arr = np.lib.stride_tricks.sliding_window_view(arr, 3, axis=1)

X_train = arr[...,:-1]
y_train = arr[..., -1]
X_train = X_train.reshape([-1,2])
y_train = y_train.ravel()

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.SimpleRNN(200, input_shape=(2,1), activation='tanh'))
model.add(tf.keras.layers.Dense(1))
model.compile(loss='mean_absolute_error', optimizer='adam')

model.fit(X_train, y_train, epochs=1000, batch_size=16)

X_test = np.array([[2.3,1]], dtype=np.float64)
res = []
for _ in range(10):
    y_pred = model.predict(X_test)
    X_test = np.append(X_test, y_pred[0][0])[1:][None,...]
    res.append(y_pred[0][0])

# predict res for 2.3 => [4.725103, 10.564905, 19.61012, 30.361404, 43.3811, 60.815994, 86.90681, 118.34455, 154.1196, 181.1613]


M = data['M'].values
C1 = data['C=2.1'].values
C2 = data['C=2.5'].values
C = np.column_stack((C1,C2))
M = M.reshape(M.shape[0],-1)

for i in range(0, 2):
    plt.plot(M, C[:,i])
plt.plot(res)
plt.show()

输出:

...
Epoch 999/1000
2/2 [==============================] - 0s 8ms/step - loss: 13.2078
Epoch 1000/1000
2/2 [==============================] - 0s 10ms/step - loss: 13.0156

我能够解决以下问题。感谢@l'mahdi 的帮助和@D.L 的评论

代码解决方案

# importing module
import numpy as np
import pandas as pd
from pandas import *
from matplotlib import pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPRegressor

# reading CSV file
data = pd.DataFrame([[1,1,1],[2,4.28,5.65],[3,10.04,15.59],[4,18.38,32],[5,29.36,55.90],[6,43.06,88.18],[7,59.52,129.64],[8,78.79,181.02],[9,100.90,243],[10,125.89,316.22]], columns=['M','C=2.1','C=2.5'])

# converting column data to array
M = data['M'].values
C1 = data['C=2.1'].values
C2 = data['C=2.5'].values

C = np.concatenate((C1,C2))
I = np.full_like(M,1)
MC1 = np.column_stack((M,I*2.1))
MC2 = np.column_stack((M,I*2.5))
MC3 = np.column_stack((M,I*2.4))
MC = np.concatenate((MC1,MC2))

MC = MC.reshape(MC.shape[0],-1)

mlp = MLPRegressor(random_state=0, activation='relu', hidden_layer_sizes=(100,100,100,100,100,100,100,100,100,100,100,100,8))    

mlp.fit(MC,C)  
Y = mlp.predict(MC3)
    
plt.plot(M, C1)
plt.plot(M, C2)
plt.plot(M, Y, 'r')

结果