成本函数在线性回归中的实现
Implementation of cost function in linear regression
我正在尝试在简单的训练数据集上实现成本函数,并在 3D 中可视化成本函数。
我的成本函数的形状与预期的不一样。
这是我的代码:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.axes3d import Axes3D
import pandas as pd
from scipy.interpolate import griddata
def create_array(start, end, resolution):
return np.linspace(start, end, int((end - start)/resolution + 1))
def f(x,a,b):
x = np.array(x)
return a*x+b # or Theta_1 * x + Theta_0
def get_J(x, y, a, b):
x = np.array(x)
y = np.array(y)
# return 1/(2*len(y)) * sum(pow(f(x,a,b) - y, 2))
# Simple implementation
sum = 0
for i in range(0, len(x)):
sum+= (f(x[i],a,b) - y[i])**2
return 1/(2*len(y))*sum
# Training set
x = np.array([0,1,2,3])
y = np.array([0,1,2,3])
Theta_0 = create_array(-20, 10, 0.5)
Theta_1 = create_array(-20, 10, 0.5)
X,Y = np.meshgrid(Theta_0, Theta_1)
X=X.flatten()
Y=Y.flatten()
J = [get_J(x, y, X[i], Y[i]) for i in range(0,len(X))]
# simple set to verify 3D plotting is doing as expetected - OK
# X = [10, 0, -10,-20, 10, 0, -10,-20, 10, 0,-10, -20, 10, 0, -10,-20]
# Y = [-20, -20, -20, -20, -10, -10, -10, -10, 0, 0, 0, 0, 10, 10, 10, 10]
# J = [50, 25, 26, 60, 24, 10, 11, 26, 10, 0, 2, 11, 52, 26, 27, 63]
# Create the graphing elements
xyz = {'x': X, 'y': Y, 'z': J}
# put the data into a pandas DataFrame (this is what my data looks like)
df = pd.DataFrame(xyz, index=range(len(xyz['x'])))
# re-create the 2D-arrays
x1 = np.linspace(df['x'].min(), df['x'].max(), len(df['x'].unique()))
y1 = np.linspace(df['y'].min(), df['y'].max(), len(df['y'].unique()))
x2, y2 = np.meshgrid(x1, y1)
z2 = griddata((df['x'], df['y']), df['z'], (x2, y2), method='cubic')
fig = plt.figure(figsize =(14, 9))
ax = Axes3D(fig)
surf = ax.plot_surface(x2, y2, z2, rstride=1, cstride=1, cmap=plt.get_cmap('coolwarm'),linewidth=0, antialiased=False)
plt.gca().invert_xaxis()
ax.set_xlabel('\u03B81', fontweight ='bold')
ax.set_ylabel('\u03B80', fontweight ='bold')
ax.set_zlabel('J (\u03B81, \u03B80)', fontweight ='bold')
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
3D 图具有以下形状:
当它应该具有这种形状时:
如果你拿纸和笔分析推导你已经实现的 J
,你会得出这样的结果:
a = theta_1: -20 ... 10
b = theta_0: -20 ... 10
J(a,b) ~ b^2 + (a+b-1)^2 + (2a+b-2)^2 + (3a+b-3)^2
这基本上意味着 a
和 b
像 a+b
一样耦合。 a+b
类似的项是平方的,(a+b)^2
的图看起来像这样(用 gnuplot 制作):
参考图有另一种形式,看起来更像是 a
和 b
是独立的,如 a^2 + b^2
,让我们绘制这个:
所以如果J
具有
的形式,我们应该能够重现参考图
J(a, b) ~ a^2 + b^2 + (other terms except a*b)
J
的形式由训练集x
和y
给出。我留给你分析地表明 x
中的值建立了 a
和 b
之间的耦合。对于 y
,我使用这些值并得出:
x = np.array([-1, 1])
y = np.array([1, -4])
这是我能想到的最简单的设置。还有更多的可能性。
我对机器学习和这些值的含义不是很深入。我的知识基本来自here。所以如果我错了请告诉我。
现在我得到了下图,我认为它与参考图非常接近,至少形状:
总结:我认为您的实施中没有错误。我想,你绘制了不同的数据。
我正在尝试在简单的训练数据集上实现成本函数,并在 3D 中可视化成本函数。
我的成本函数的形状与预期的不一样。
这是我的代码:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.axes3d import Axes3D
import pandas as pd
from scipy.interpolate import griddata
def create_array(start, end, resolution):
return np.linspace(start, end, int((end - start)/resolution + 1))
def f(x,a,b):
x = np.array(x)
return a*x+b # or Theta_1 * x + Theta_0
def get_J(x, y, a, b):
x = np.array(x)
y = np.array(y)
# return 1/(2*len(y)) * sum(pow(f(x,a,b) - y, 2))
# Simple implementation
sum = 0
for i in range(0, len(x)):
sum+= (f(x[i],a,b) - y[i])**2
return 1/(2*len(y))*sum
# Training set
x = np.array([0,1,2,3])
y = np.array([0,1,2,3])
Theta_0 = create_array(-20, 10, 0.5)
Theta_1 = create_array(-20, 10, 0.5)
X,Y = np.meshgrid(Theta_0, Theta_1)
X=X.flatten()
Y=Y.flatten()
J = [get_J(x, y, X[i], Y[i]) for i in range(0,len(X))]
# simple set to verify 3D plotting is doing as expetected - OK
# X = [10, 0, -10,-20, 10, 0, -10,-20, 10, 0,-10, -20, 10, 0, -10,-20]
# Y = [-20, -20, -20, -20, -10, -10, -10, -10, 0, 0, 0, 0, 10, 10, 10, 10]
# J = [50, 25, 26, 60, 24, 10, 11, 26, 10, 0, 2, 11, 52, 26, 27, 63]
# Create the graphing elements
xyz = {'x': X, 'y': Y, 'z': J}
# put the data into a pandas DataFrame (this is what my data looks like)
df = pd.DataFrame(xyz, index=range(len(xyz['x'])))
# re-create the 2D-arrays
x1 = np.linspace(df['x'].min(), df['x'].max(), len(df['x'].unique()))
y1 = np.linspace(df['y'].min(), df['y'].max(), len(df['y'].unique()))
x2, y2 = np.meshgrid(x1, y1)
z2 = griddata((df['x'], df['y']), df['z'], (x2, y2), method='cubic')
fig = plt.figure(figsize =(14, 9))
ax = Axes3D(fig)
surf = ax.plot_surface(x2, y2, z2, rstride=1, cstride=1, cmap=plt.get_cmap('coolwarm'),linewidth=0, antialiased=False)
plt.gca().invert_xaxis()
ax.set_xlabel('\u03B81', fontweight ='bold')
ax.set_ylabel('\u03B80', fontweight ='bold')
ax.set_zlabel('J (\u03B81, \u03B80)', fontweight ='bold')
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
3D 图具有以下形状:
当它应该具有这种形状时:
如果你拿纸和笔分析推导你已经实现的 J
,你会得出这样的结果:
a = theta_1: -20 ... 10
b = theta_0: -20 ... 10
J(a,b) ~ b^2 + (a+b-1)^2 + (2a+b-2)^2 + (3a+b-3)^2
这基本上意味着 a
和 b
像 a+b
一样耦合。 a+b
类似的项是平方的,(a+b)^2
的图看起来像这样(用 gnuplot 制作):
参考图有另一种形式,看起来更像是 a
和 b
是独立的,如 a^2 + b^2
,让我们绘制这个:
所以如果J
具有
J(a, b) ~ a^2 + b^2 + (other terms except a*b)
J
的形式由训练集x
和y
给出。我留给你分析地表明 x
中的值建立了 a
和 b
之间的耦合。对于 y
,我使用这些值并得出:
x = np.array([-1, 1])
y = np.array([1, -4])
这是我能想到的最简单的设置。还有更多的可能性。
我对机器学习和这些值的含义不是很深入。我的知识基本来自here。所以如果我错了请告诉我。
现在我得到了下图,我认为它与参考图非常接近,至少形状:
总结:我认为您的实施中没有错误。我想,你绘制了不同的数据。