目录
思路
依然是按照吴恩达老师机器学习课程上的思路进行编写,重点截图如下。
代码
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D # plot 3d
class Mul_V_Linear_Regression():
def __init__(self, dataset, learning_rate):
self.dataset = dataset
self.learning_rate = learning_rate
self.row = len(dataset.data)
self.col = len(dataset.data[0])+1
self.features = np.c_[np.ones(self.row), dataset.data]
self.label = dataset.target
self.theta = np.zeros(self.col)
# hypothesis
def h(self, x): # x's size = col+1, the first one is 1.
res = 0
for i in range(len(self.theta)):
res += x[i] * self.theta[i]
return res
# cost function
def J(self):
temp = 0
for i in range(self.row):
temp += pow(self.h(self.features[i]) - self.label[i], 2)
#print(temp)
return 1 / (2 * self.row) * temp
# partial derivative
def pd_theta_J(self, index):
temp = 0
for i in range(self.row):
temp += (self.h(self.features[i]) - self.label[i]) * self.features[i][index]
return 1 / self.row * temp
# gradient descent
def gd(self):
min_cost = 0.01
round = 1
max_round = 100
while (min_cost < abs(self.J()) and round <= max_round):
temp = np.zeros(self.col)
for i in range(self.col):
temp[i] = self.theta[i] - self.learning_rate * self.pd_theta_J(i)
self.theta = temp
print('round', round, ':')
for i in range(self.col):
print(self.theta[i])
round += 1
print(self.J())
return self.theta
if __name__ == '__main__':
boston = datasets.load_boston()
x = boston.data[:, 5]
y = boston.data[:, 12]
z = boston.target
boston.data = np.c_[x, y] # only 5th and 12th is linear
mul = Mul_V_Linear_Regression(boston, 0.008)
theta = mul.gd()
# plot scatter
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(x, y, z)
# plot line
x = [8, 9]
y = [40, 5]
z = [theta[0]+theta[1]*x[0]+theta[2]*y[0], theta[0]+theta[1]*x[1]+theta[2]*y[1]]
print(z)
figure = ax.plot(x, y, z, c='r')
ax.set_zlabel('Z', fontdict={'size': 15, 'color': 'red'})
ax.set_ylabel('Y', fontdict={'size': 15, 'color': 'red'})
ax.set_xlabel('X', fontdict={'size': 15, 'color': 'red'})
plt.show()
选用sklearn的boston房价的数据,其中只有第5列和第12列(从0开始)与最终的房价呈线性关系。在画直线的时候选取的[9.3, 28.6, z1], [3.25, 1.25, z2]是根据数据画出来的散点图选取的x,y的点,但是感觉这样并不准确,最终形成的应该是一个平面(z = theta0 + theta1*x + theta2*y), 所以选取的点不同,直线应该会有一定的偏移,这是需要后续再弄明白的地方。(另外main中的代码有点丑陋...)
效果
迭代100次最终的损失值为15+
这样看起来还可以,但是换个角度...T T