我正在尝试编写两个演示局部加权线性回归的脚本。在第一个脚本中,我使用Numpy来解决矩阵问题,代码如下:
trX = np.linspace(0, 1, 100) trY= trX + np.random.normal(0,1,100)xArr = []yArr = []for i in range(len(trX)): xArr.append([1.0,float(trX[i])]) yArr.append(float(trY[i]))xMat = mat(xArr); yMat = mat(yArr).Tm = shape(xMat)[0]weights = mat(eye((m)))k = 0.01yHat = zeros(m)for i in range(m): for j in range(m): diffMat = xArr[i] - xMat[j,:] weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) xTx = xMat.T * (weights * xMat) if linalg.det(xTx) == 0.0: print("This matrix is singular, cannot do inverse") ws = xTx.I * (xMat.T * (weights * yMat)) yHat[i] = xArr[i]*wsplt.scatter(trX, trY) plt.plot(trX, yHat, 'r')plt.show()
在第二个脚本中,我使用TensorFlow来解决矩阵问题。该脚本如下所示:
trX = np.linspace(0, 1, 100) trY= trX + np.random.normal(0,1,100)sess = tf.Session()xArr = []yArr = []for i in range(len(trX)): xArr.append([1.0,float(trX[i])]) yArr.append(float(trY[i]))xMat = mat(xArr); yMat = mat(yArr).TA_tensor = tf.constant(xMat)b_tensor = tf.constant(yMat)m = shape(xMat)[0]weights = mat(eye((m)))k = 0.01yHat = zeros(m)for i in range(m): for j in range(m): diffMat = xMat[i]- xMat[j,:] weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) weights_tensor = tf.constant(weights) # Matrix inverse solution wA = tf.matmul(weights_tensor, A_tensor) tA_A = tf.matmul(tf.transpose(A_tensor), wA) tA_A_inv = tf.matrix_inverse(tA_A) wb = tf.matmul(weights_tensor, b_tensor) tA_wb = tf.matmul(tf.transpose(A_tensor), wb) solution = tf.matmul(tA_A_inv, tA_wb) sol_val = sess.run(solution) yHat[i] =sol_val[0][0]*xArr[i][1] + sol_val[1][0] plt.scatter(trX, trY) plt.plot(trX, yHat, 'r')plt.show()
运行后,得到的结果如下:
导致两种结果不同的原因是什么?或者我的脚本中是否有错误的地方?请帮帮我。
回答:
问题出在代码的这一行,
yHat[i] =sol_val[0][0]*xArr[i][1] + sol_val[1][0]
Numpy数组乘法计算不正确。
如果将上述代码行替换为以下内容,将会正常工作
yHat[i] =sol_val[0][0]*xArr[i][0] + sol_val[1][0]*xArr[i][1]
完整的工作代码如下:
import numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltfrom numpy import *import tensorflow as tftrX = np.linspace(0, 1, 100) trY= trX + np.random.normal(0,1,100)#print('trY = ', trY)sess = tf.Session()xArr = []yArr = []for i in range(len(trX)): xArr.append([1.0,float(trX[i])]) yArr.append(float(trY[i]))xMat = mat(xArr); yMat = mat(yArr).TA_tensor = tf.constant(xMat)b_tensor = tf.constant(yMat)#print("A_Tensor = xMat = ", sess.run(A_tensor))#print("B_Tensor = yMat = ", sess.run(b_tensor))m = shape(xMat)[0]weights = mat(eye((m)))k = 0.01yHat = zeros(m)for i in range(m): for j in range(m): diffMat = xMat[i]- xMat[j,:] weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) weights_tensor = tf.constant(weights) # Matrix inverse solution wA = tf.matmul(weights_tensor, A_tensor) tA_A = tf.matmul(tf.transpose(A_tensor), wA) tA_A_inv = tf.matrix_inverse(tA_A) wb = tf.matmul(weights_tensor, b_tensor) tA_wb = tf.matmul(tf.transpose(A_tensor), wb) solution = tf.matmul(tA_A_inv, tA_wb) sol_val = sess.run(solution) #plt.plot(sol_val, 'b') #plt.show() #print("Sol_Val = ", sol_val) #print("Sol_Val[0][0] = ", sol_val[0][0]) #print("Sol_Val[1][0] = ", sol_val[1][0]) #print('xArr[i] = ', np.array(xArr[i])) #print('xArr[i][0] = ', np.array(xArr[i][0])) #print('xArr[i][1] = ', np.array(xArr[i][1])) #yHat[i] =sol_val[0][0]*xArr[i][1] + sol_val[1][0] yHat[i] =sol_val[0][0]*xArr[i][0] + sol_val[1][0]*xArr[i][1] #print("Weights = ", sess.run(weights_tensor)) #yHat[i] = np.array(xArr[i])*sol_val #print(sol_val)plt.scatter(trX, trY) plt.plot(trX, yHat, 'r')plt.show()
下图显示了结果: