使用 TensorFlow 进行多元线性回归
Multiple Linear Regression with TensorFlow
我正在尝试使用 TensorFlow 执行多元线性回归,并使用 statsmodels
库检查结果。
我生成了两个随机变量 X1
和 X2
(以便任何人都可以重现)来解释 Y 变量。 X2
变量对于这个回归完全没有用,它只是一个大尺度的噪声,因此系数结果不显着(p-val 接近 1)。
最后我应该得到一个基本上是的模型。 y_data = alpha + (0.25)x1 + (0.00)x2 + error.
我试图使这个 适应我随机生成的数据,但不幸的是,这根本不起作用。
下面是我的尝试:
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
import statsmodels.api as sm
from statsmodels.sandbox.regression.predstd import wls_prediction_std
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import SGD
from tensorflow.keras import layers
from tensorflow.keras.layers.experimental import preprocessing
from tensorflow import keras
import datetime
#generating variables:
np.random.seed(1)
lin_x = np.arange(0,200,2)
y_data = np.true_divide(lin_x,4)
n = np.shape(lin_x)
##adding noise:
rand1 = norm.rvs(loc=0,scale=5,size=n)
np.random.seed(2)
rand2 = norm.rvs(loc=0,scale=1000,size=n)
x1 = np.add(lin_x,rand1)
x2 = rand2
#creating the X matrix: beta = (X'X)^-1(X'y):
x_data = np.column_stack((x1,x2))
#adding ones vector for the intercept:
x_data = sm.add_constant(x_data)
#MLR with statsmodels:
mod = sm.OLS(y_data,x_data)
LinReg = mod.fit()
print(LinReg.summary())
#MLR with tensorflow:
normalizer = preprocessing.Normalization()
normalizer.adapt(x_data)
normalized_data = normalizer(x_data)
print(normalized_data)
model = tf.keras.Sequential([
normalizer,
layers.Dense(units=1)
])
model.compile(loss = tf.losses.MeanSquaredError(),
optimizer = tf.keras.optimizers.SGD(
learning_rate=0.06, momentum=0.0, nesterov=True, name="SGD",
))
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
model.summary()
print('--------------')
weights = model.layers[0].get_weights()[0]
biases = model.layers[0].get_weights()[1]
print('--------------')
x_data_tf = tf.convert_to_tensor(x_data)
y_data_tf = tf.convert_to_tensor(y_data)
model.fit(y_data_tf,x_data_tf, epochs=1000, callbacks=[tensorboard_callback])
weights = model.layers[0].get_weights()[0]
biases = model.layers[0].get_weights()[1]
print("TensorFlow results: ")
print("weigths: ", weights)
print("biases: ", biases)
print(LinReg.summary())
如何使用 TensorFlow 获得与 statsmodels
库相同的系数?谢谢
您的代码的主要问题如下:
- 虽然在使用 statsmodels 运行 进行回归之前,需要向特征矩阵
x_data
添加一列 1,但在使用 tensorflow 进行回归时 运行 则没有必要。这意味着您将 3 个特征传递给 tensorflow 而不是 2 个,其中附加特征(x_data
的第一列)是常量。
- 在第一列 1 已经添加
x_data = sm.add_constant(x_data)
之后,您正在规范化 x_data
。由于一列的方差为零,因此在归一化后你会得到一列 nan
(因为你除以零)。这意味着您传递给 tensorflow 的 3 个特征中的第一个完全缺失(即它总是 nan
)。
- 虽然 statsmodels 首先
y
然后 X
作为输入,但 tensorflow 首先 X
然后 y
作为输入。这意味着当 运行 在 tensorflow 中进行回归时,您已经切换了特征和目标。
我在下面包含了一个完整的示例。
import numpy as np
import statsmodels.api as sm
import tensorflow as tf
np.random.seed(0)
N = 500 # number of samples
K = 2 # number of features
# generate the features
m = np.array([0, 0]) # means
s = np.array([5, 1000]) # variances
X = np.random.multivariate_normal(m * np.ones(K), s * np.eye(K), N)
# generate the target
b = 0.5 # bias
w = np.array([0.107, 0]) # weights
y = b + np.dot(X, w) + np.random.normal(0, 1, N)
# normalize the features
X = (X - np.mean(X, axis=0)) / np.std(X, axis=0, ddof=1)
# run a linear regression with statsmodels
reg = sm.OLS(y, sm.add_constant(X)).fit()
# run a linear regression with tensorflow
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1)
])
model.compile(loss=tf.losses.MeanSquaredError(), optimizer=tf.keras.optimizers.SGD(learning_rate=0.01))
model.fit(X, y, epochs=1000, verbose=0)
bias = model.layers[0].get_weights()[1]
weights = model.layers[0].get_weights()[0].flatten()
# compare the parameters
print('Statsmodels parameters:')
print(np.round(reg.params, 3))
# [0.523 0.25 0.063]
print('Tensorflow parameters:')
print(np.round(np.append(bias, weights), 3))
# [0.528 0.25 0.066]
我正在尝试使用 TensorFlow 执行多元线性回归,并使用 statsmodels
库检查结果。
我生成了两个随机变量 X1
和 X2
(以便任何人都可以重现)来解释 Y 变量。 X2
变量对于这个回归完全没有用,它只是一个大尺度的噪声,因此系数结果不显着(p-val 接近 1)。
最后我应该得到一个基本上是的模型。 y_data = alpha + (0.25)x1 + (0.00)x2 + error.
我试图使这个
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
import statsmodels.api as sm
from statsmodels.sandbox.regression.predstd import wls_prediction_std
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import SGD
from tensorflow.keras import layers
from tensorflow.keras.layers.experimental import preprocessing
from tensorflow import keras
import datetime
#generating variables:
np.random.seed(1)
lin_x = np.arange(0,200,2)
y_data = np.true_divide(lin_x,4)
n = np.shape(lin_x)
##adding noise:
rand1 = norm.rvs(loc=0,scale=5,size=n)
np.random.seed(2)
rand2 = norm.rvs(loc=0,scale=1000,size=n)
x1 = np.add(lin_x,rand1)
x2 = rand2
#creating the X matrix: beta = (X'X)^-1(X'y):
x_data = np.column_stack((x1,x2))
#adding ones vector for the intercept:
x_data = sm.add_constant(x_data)
#MLR with statsmodels:
mod = sm.OLS(y_data,x_data)
LinReg = mod.fit()
print(LinReg.summary())
#MLR with tensorflow:
normalizer = preprocessing.Normalization()
normalizer.adapt(x_data)
normalized_data = normalizer(x_data)
print(normalized_data)
model = tf.keras.Sequential([
normalizer,
layers.Dense(units=1)
])
model.compile(loss = tf.losses.MeanSquaredError(),
optimizer = tf.keras.optimizers.SGD(
learning_rate=0.06, momentum=0.0, nesterov=True, name="SGD",
))
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
model.summary()
print('--------------')
weights = model.layers[0].get_weights()[0]
biases = model.layers[0].get_weights()[1]
print('--------------')
x_data_tf = tf.convert_to_tensor(x_data)
y_data_tf = tf.convert_to_tensor(y_data)
model.fit(y_data_tf,x_data_tf, epochs=1000, callbacks=[tensorboard_callback])
weights = model.layers[0].get_weights()[0]
biases = model.layers[0].get_weights()[1]
print("TensorFlow results: ")
print("weigths: ", weights)
print("biases: ", biases)
print(LinReg.summary())
如何使用 TensorFlow 获得与 statsmodels
库相同的系数?谢谢
您的代码的主要问题如下:
- 虽然在使用 statsmodels 运行 进行回归之前,需要向特征矩阵
x_data
添加一列 1,但在使用 tensorflow 进行回归时 运行 则没有必要。这意味着您将 3 个特征传递给 tensorflow 而不是 2 个,其中附加特征(x_data
的第一列)是常量。 - 在第一列 1 已经添加
x_data = sm.add_constant(x_data)
之后,您正在规范化x_data
。由于一列的方差为零,因此在归一化后你会得到一列nan
(因为你除以零)。这意味着您传递给 tensorflow 的 3 个特征中的第一个完全缺失(即它总是nan
)。 - 虽然 statsmodels 首先
y
然后X
作为输入,但 tensorflow 首先X
然后y
作为输入。这意味着当 运行 在 tensorflow 中进行回归时,您已经切换了特征和目标。
我在下面包含了一个完整的示例。
import numpy as np
import statsmodels.api as sm
import tensorflow as tf
np.random.seed(0)
N = 500 # number of samples
K = 2 # number of features
# generate the features
m = np.array([0, 0]) # means
s = np.array([5, 1000]) # variances
X = np.random.multivariate_normal(m * np.ones(K), s * np.eye(K), N)
# generate the target
b = 0.5 # bias
w = np.array([0.107, 0]) # weights
y = b + np.dot(X, w) + np.random.normal(0, 1, N)
# normalize the features
X = (X - np.mean(X, axis=0)) / np.std(X, axis=0, ddof=1)
# run a linear regression with statsmodels
reg = sm.OLS(y, sm.add_constant(X)).fit()
# run a linear regression with tensorflow
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1)
])
model.compile(loss=tf.losses.MeanSquaredError(), optimizer=tf.keras.optimizers.SGD(learning_rate=0.01))
model.fit(X, y, epochs=1000, verbose=0)
bias = model.layers[0].get_weights()[1]
weights = model.layers[0].get_weights()[0].flatten()
# compare the parameters
print('Statsmodels parameters:')
print(np.round(reg.params, 3))
# [0.523 0.25 0.063]
print('Tensorflow parameters:')
print(np.round(np.append(bias, weights), 3))
# [0.528 0.25 0.066]