線性迴歸的代價函數: 線性迴歸的迭代過程: 特徵值縮放:
學習率: 如果學習率 α 過小, 則達到收斂所需的迭代次數會非常高;如果學習率 α 過大,每次迭代可能不會減小代價函數,可能會越過局部最小值導致無法收斂。 特徵和多項式迴歸: 正規方程:
擴充知識: 這裡知乎上有個問題很好的解釋最小二乘法,這個跟正規方程有很多相關的地方,值得一看: https://www.zhihu.com/question/37031188/answer/111336809 還有一個知乎問題關於泰勒公式的,數學知識忘記得差不多的可以看看: https://www.zhihu.com/question/21149770
下面是作業的代碼:
# -*- coding: utf-8 -*-"""__author__ = 'ljyn4180'"""import numpy as npimport pandas as pdimport matplotlib.pyplot as plt# 代價函數def CostFunction(matrixX, matrixY, matrixTheta): Inner = np.power(((matrixX * matrixTheta.T) - matrixY), 2) return np.sum(Inner) / (2 * len(matrixX))# 梯度下降迭代函數def GradientDescent(matrixX, matrixY, matrixTheta, fAlpha, nIterCounts): matrixThetaTemp = np.matrix(np.zeros(matrixTheta.shape)) nParameters = int(matrixTheta.ravel().shape[1]) arrayCost = np.zeros(nIterCounts) for i in xrange(nIterCounts): matrixError = (matrixX * matrixTheta.T) - matrixY for j in xrange(nParameters): matrixSumTerm = np.multiply(matrixError, matrixX[:, j]) matrixThetaTemp[0, j] = matrixTheta[0, j] - fAlpha / len(matrixX) * np.sum(matrixSumTerm) matrixTheta = matrixThetaTemp arrayCost[i] = CostFunction(matrixX, matrixY, matrixTheta) return matrixTheta, arrayCost# 顯示線性迴歸結果def ShowLineRegressionResult(dataFrame, matrixTheta): x = np.linspace(dataFrame.Population.min(), dataFrame.Population.max(), 100) f = matrixTheta[0, 0] + (matrixTheta[0, 1] * x) plt.subplot(221) plt.plot(x, f, 'r', label='Prediction') plt.scatter(dataFrame.Population, dataFrame.Profit, label='Training Data') plt.legend(loc=2) plt.xlabel('Population') plt.ylabel('Profit') plt.title('Predicted Profit vs. Population Size')# 顯示代價函數的值的變化情況def ShowCostChange(arrayCost, nIterCounts): plt.subplot(222) plt.plot(np.arange(nIterCounts), arrayCost, 'r') plt.xlabel('Iterations') plt.ylabel('Cost') plt.title('Error vs. Training Epoch')# 顯示不同Alpha值得學習曲線def ShowLearningRateChange(dictCost, nIterCounts): plt.subplot(223) for fAlpha, arrayCost in dictCost.iteritems(): plt.plot(np.arange(nIterCounts), arrayCost, label=fAlpha) plt.xlabel('Iterations') plt.ylabel('Cost') plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) plt.title('learning rate')# 正規方程def NormalEquation(matrixX, matrixY): matrixTheta = np.linalg.inv(matrixX.T * matrixX) * matrixX.T * matrixY # Python2.7 # matrixTheta = np.linalg.inv(matrixX.T @ matrixX) @ matrixX.T @ matrixY # Python3 return matrixTheta# 標準化特徵值def NormalizeFeature(dataFrame): return dataFrame.apply(lambda column: (column - column.mean()) / column.std())def ExerciseOne(): path = 'ex1data1.txt' dataFrame = pd.read_csv(path, header=None, names=['Population', 'Profit']) # 補項 dataFrame.insert(0, 'Ones', 1) nColumnCount = dataFrame.shape[1] dataFrameX = dataFrame.iloc[:, 0:nColumnCount - 1] dataFrameY = dataFrame.iloc[:, nColumnCount - 1:nColumnCount] # 初始化資料 matrixX = np.matrix(dataFrameX.values) matrixY = np.matrix(dataFrameY.values) matrixOriginTheta = np.matrix(np.zeros(dataFrameX.shape[1])) # 設定學習率和迭代次數 fAlpha = 0.01 nIterCounts = 1000 matrixTheta, arrayCost = GradientDescent(matrixX, matrixY, matrixOriginTheta, fAlpha, nIterCounts) print matrixTheta print NormalEquation(matrixX, matrixY) # 設定不同的學習率 arrayAlpha = [0.000001, 0.00001, 0.0001, 0.001, 0.01] dictCost = {} for fAlpha in arrayAlpha: _, arrayCostTemp = GradientDescent(matrixX, matrixY, matrixOriginTheta, fAlpha, nIterCounts) dictCost[fAlpha] = arrayCostTemp # 顯示不同圖表 plt.figure(figsize=(12, 12)) ShowLineRegressionResult(dataFrame, matrixTheta) ShowCostChange(arrayCost, nIterCounts) ShowLearningRateChange(dictCost, nIterCounts) plt.show()ExerciseOne()
# -*- coding: utf-8 -*-"""__author__ = 'ljyn4180'"""import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport mpl_toolkits.mplot3d.axes3d as Axes3Ddef CostFunction(matrixX, matrixY, matrixTheta): Inner = np.power(((matrixX * matrixTheta.T) - matrixY), 2) return np.sum(Inner) / (2 * len(matrixX))def GradientDescent(matrixX, matrixY, matrixTheta, fAlpha, nIterCounts): matrixThetaTemp = np.matrix(np.zeros(matrixTheta.shape)) nParameters = int(matrixTheta.ravel().shape[1]) arrayCost = np.zeros(nIterCounts) for i in xrange(nIterCounts): matrixError = (matrixX * matrixTheta.T) - matrixY for j in xrange(nParameters): matrixSumTerm = np.multiply(matrixError, matrixX[:, j]) matrixThetaTemp[0, j] = matrixTheta[0, j] - fAlpha / len(matrixX) * np.sum(matrixSumTerm) matrixTheta = matrixThetaTemp arrayCost[i] = CostFunction(matrixX, matrixY, matrixTheta) return matrixTheta, arrayCostdef ShowLineRegressionResult(dataFrame, matrixTheta): x = np.array(dataFrame.square) y = np.array(dataFrame.bedrooms) z = matrixTheta[0, 0] + (matrixTheta[0, 1] * x) + (matrixTheta[0, 2] * y) print z ax = plt.subplot(211, projection='3d') ax.plot_trisurf(x, y, z) ax.scatter(dataFrame.square, dataFrame.bedrooms, dataFrame.price, label='Training Data') ax.set_xlabel('square') ax.set_ylabel('bedrooms') ax.set_zlabel('price') # plt.title('Predicted Profit vs. Population Size')def ShowCostChange(arrayCost, nIterCounts): plt.subplot(212) plt.plot(np.arange(nIterCounts), arrayCost, 'r') plt.xlabel('Iterations') plt.ylabel('Cost') plt.title('Error vs. Training Epoch')def NormalizeFeature(dataFrame): return dataFrame.apply(lambda column: (column - column.mean()) / column.std())def ExerciseTwo(): path = 'ex1data2.txt' dataFrame = pd.read_csv(path, header=None, names=['square', 'bedrooms', 'price']) dataFrame = NormalizeFeature(dataFrame) # data['square'] = data['square'] / 1000 # data['price'] = data['price'] / 100000 # 補項 dataFrame.insert(0, 'Ones', 1) nColumnCount = dataFrame.shape[1] dataFrameX = dataFrame.iloc[:, 0:nColumnCount - 1] dataFrameY = dataFrame.iloc[:, nColumnCount - 1:nColumnCount] matrixX = np.matrix(dataFrameX.values) matrixY = np.matrix(dataFrameY.values) matrixTheta = np.matrix(np.zeros(dataFrameX.shape[1])) fAlpha = 0.01 nIterCounts = 1000 matrixTheta, arrayCost = GradientDescent(matrixX, matrixY, matrixTheta, fAlpha, nIterCounts) print matrixTheta plt.figure(figsize=(8, 10)) ShowLineRegressionResult(dataFrame, matrixTheta) ShowCostChange(arrayCost, nIterCounts) plt.show()ExerciseTwo()