模型训练 准确率下降_手写批量线性回归算法:在Python3中梯度下降方法实现模型训练
在這篇文章中,我們將看一個(gè)使用NumPy作為數(shù)據(jù)處理庫(kù)的Python3編寫的程序,來(lái)了解如何實(shí)現(xiàn)使用梯度下降法的(批量)線性回歸。
? 我將逐步解釋代碼的工作原理和代碼的每個(gè)部分的工作原理。
? 我們將使用此公式計(jì)算梯度。
? 在此,x(i)向量是一個(gè)點(diǎn),其中N是數(shù)據(jù)集的大小。 n(eta)是我們的學(xué)習(xí)率。 y(i)向量是目標(biāo)輸出。 f(x)向量是定義為f(x)= Sum(w * x)的回歸線性函數(shù),這里sum是sigma函數(shù)。 另外,我們將考慮初始偏差w0 = 0并使得x0 =1。所有權(quán)重均初始化為0。
? 在此方法中,我們將平方誤差總和用作損失函數(shù)。
? 除了將SSE初始化為零外,我們將在每次迭代中記錄SSE的變化,并將其與在程序執(zhí)行之前提供的閾值進(jìn)行比較。 如果SSE低于閾值,程序?qū)⑼顺觥?/p>
? 在該程序中,我們從命令行提供了三個(gè)輸入。 他們是:
threshold — 閾值,在算法終止之前,損失必須低于此閾值。
data — 數(shù)據(jù)集的位置。
learningRate — 梯度下降法的學(xué)習(xí)率。
? 因此,該程序的啟動(dòng)應(yīng)該是這樣的:
python3linearregr.py — datarandom.csv — learningRate 0.0001 — threshold 0.0001? 在深入研究代碼之前我們確定最后一件事,程序的輸出將如下所示:
iteration_number,weight0,weight1,weight2,...,weightN,sum_of_squared_errors? 該程序包括6個(gè)部分,我們逐個(gè)進(jìn)行查看。
導(dǎo)入模塊
import argparse # to read inputs from command lineimport csv # to read the input data set fileimport numpy as np # to work with the data set初始化部分
# initialise argument parser and read argumentsfrom command line with the respective flags and then call the main() functionif __name__ == '__main__': parser = argparse.ArgumentParser()parser.add_argument("-d", "--data", help="Data File")parser.add_argument("-l", "--learningRate", help="Learning Rate") parser.add_argument("-t", "--threshold", help="Threshold") main()main函數(shù)部分
defmain():args = parser.parse_args()file, learningRate, threshold = args.data, float(args.learningRate), float(args.threshold) # save respective command line inputs into variables# read csv file and the last column is the target output and is separated from the input (X) as Ywith open(file) as csvFile:reader = csv.reader(csvFile, delimiter=',')X = []Y = []for row in reader:X.append([1.0] + row[:-1])Y.append([row[-1]])# Convert data points into float and initialise weight vector with 0s.n = len(X)X = np.array(X).astype(float)Y = np.array(Y).astype(float)W = np.zeros(X.shape[1]).astype(float)# this matrix is transposed to match the necessary matrix dimensions for calculating dot productW = W.reshape(X.shape[1], 1).round(4)# Calculate the predicted output valuef_x = calculatePredicatedValue(X, W)# Calculate the initial SSEsse_old = calculateSSE(Y, f_x)outputFile = 'solution_' + 'learningRate_' + str(learningRate) + '_threshold_' + str(threshold) + '.csv''''Output file is opened in writing mode and the data is written in the format mentioned in the post. After thefirst values are written, the gradient and updated weights are calculated using the calculateGradient function.An iteration variable is maintained to keep track on the number of times the batch linear regression is executedbefore it falls below the threshold value. In the infinite while loop, the predicted output value is calculated again and new SSE value is calculated. If the absolute difference between the older(SSE from previous iteration) and newer(SSE from current iteration) SSE is greater than the threshold value, then above process is repeated.The iteration is incremented by 1 and the current SSE is stored into previous SSE. If the absolute difference between the older(SSE from previous iteration) and newer(SSE from current iteration) SSE falls below the threshold value, the loop breaks and the last output values are written to the file.'''with open(outputFile, 'w', newline='') as csvFile:writer = csv.writer(csvFile, delimiter=',', quoting=csv.QUOTE_NONE, escapechar='')writer.writerow([*[0], *["{0:.4f}".format(val) for val in W.T[0]], *["{0:.4f}".format(sse_old)]])gradient, W = calculateGradient(W, X, Y, f_x, learningRate)iteration = 1whileTrue:f_x = calculatePredicatedValue(X, W)sse_new = calculateSSE(Y, f_x)if abs(sse_new - sse_old) > threshold:writer.writerow([*[iteration], *["{0:.4f}".format(val) for val in W.T[0]], *["{0:.4f}".format(sse_new)]])gradient, W = calculateGradient(W, X, Y, f_x, learningRate)iteration += 1sse_old = sse_newelse:breakwriter.writerow([*[iteration], *["{0:.4f}".format(val) for val in W.T[0]], *["{0:.4f}".format(sse_new)]])print("Output File Name: " + outputFile? main函數(shù)的流程如下所示:
calculatePredicatedValue函數(shù)
? 在此,通過(guò)執(zhí)行輸入矩陣X和權(quán)重矩陣W的點(diǎn)積來(lái)計(jì)算預(yù)測(cè)輸出。
# dot product of X(input) and W(weights) as numpy matrices and returning the result which is the predicted outputdefcalculatePredicatedValue(X, W):f_x = np.dot(X, W)return f_xcalculateGradient函數(shù)
? 使用文章中提到的第一個(gè)公式計(jì)算梯度并更新權(quán)重。
defcalculateGradient(W, X, Y, f_x, learningRate):gradient = (Y - f_x) * Xgradient = np.sum(gradient, axis=0)temp = np.array(learningRate * gradient).reshape(W.shape)W = W + tempreturn gradient, WcalculateSSE函數(shù)
? 使用上述公式計(jì)算SSE。
defcalculateSSE(Y, f_x): sse = np.sum(np.square(f_x - Y)) return sse? 現(xiàn)在,看完了完整的代碼。 讓我們看一下程序的執(zhí)行結(jié)果。
? 這是輸出的樣子:00.00000.00000.00007475.31491-0.0940-0.5376-0.25922111.51052-0.1789-0.7849-0.3766880.69803-0.2555-0.8988-0.4296538.86384-0.3245-0.9514-0.4533399.80925-0.3867-0.9758-0.4637316.16826-0.4426-0.9872-0.4682254.51267-0.4930-0.9926-0.4699205.84798-0.5383-0.9952-0.4704166.69329-0.5791-0.9966-0.4704135.029310-0.6158-0.9973-0.4702109.389211-0.6489-0.9978-0.470088.619712-0.6786-0.9981-0.469771.794113-0.7054-0.9983-0.469458.163114-0.7295-0.9985-0.469147.120115-0.7512-0.9987-0.468938.173816-0.7708-0.9988-0.468730.926117-0.7883-0.9989-0.468525.054418-0.8042-0.9990-0.468320.297519-0.8184-0.9991-0.468116.443820-0.8312-0.9992-0.468013.321821-0.8427-0.9993-0.467810.792522-0.8531-0.9994-0.46778.743423-0.8625-0.9994-0.46767.083324-0.8709-0.9995-0.46755.738525-0.8785-0.9995-0.46744.649026-0.8853-0.9996-0.46743.766327-0.8914-0.9996-0.46733.051228-0.8969-0.9997-0.46722.471929-0.9019-0.9997-0.46722.002630-0.9064-0.9997-0.46711.622431-0.9104-0.9998-0.46711.314432-0.9140-0.9998-0.46701.064833-0.9173-0.9998-0.46700.862634-0.9202-0.9998-0.46700.698935-0.9229-0.9998-0.46690.566236-0.9252-0.9999-0.46690.458737-0.9274-0.9999-0.46690.371638-0.9293-0.9999-0.46690.301039-0.9310-0.9999-0.46680.243940-0.9326-0.9999-0.46680.197641-0.9340-0.9999-0.46680.160142-0.9353-0.9999-0.46680.129743-0.9364-0.9999-0.46680.105144-0.9374-0.9999-0.46680.085145-0.9384-0.9999-0.46680.069046-0.9392-0.9999-0.46680.055947-0.9399-1.0000-0.46670.045348-0.9406-1.0000-0.46670.036749-0.9412-1.0000-0.46670.029750-0.9418-1.0000-0.46670.024151-0.9423-1.0000-0.46670.019552-0.9427-1.0000-0.46670.015853-0.9431-1.0000-0.46670.012854-0.9434-1.0000-0.46670.010455-0.9438-1.0000-0.46670.008456-0.9441-1.0000-0.46670.006857-0.9443-1.0000-0.46670.005558-0.9446-1.0000-0.46670.004559-0.9448-1.0000-0.46670.003660-0.9450-1.0000-0.46670.002961-0.9451-1.0000-0.46670.002462-0.9453-1.0000-0.46670.001963-0.9454-1.0000-0.46670.001664-0.9455-1.0000-0.46670.001365-0.9457-1.0000-0.46670.001066-0.9458-1.0000-0.46670.000867-0.9458-1.0000-0.46670.000768-0.9459-1.0000-0.46670.000569-0.9460-1.0000-0.46670.000470-0.9461-1.0000-0.46670.0004最終程序
import argparse import csv import numpy as npdefmain():args = parser.parse_args()file, learningRate, threshold = args.data, float(args.learningRate), float(args.threshold) # save respective command line inputs into variables# read csv file and the last column is the target output and is separated from the input (X) as Ywith open(file) as csvFile:reader = csv.reader(csvFile, delimiter=',')X = []Y = []for row in reader:X.append([1.0] + row[:-1])Y.append([row[-1]])# Convert data points into float and initialise weight vector with 0s.n = len(X)X = np.array(X).astype(float)Y = np.array(Y).astype(float)W = np.zeros(X.shape[1]).astype(float)# this matrix is transposed to match the necessary matrix dimensions for calculating dot productW = W.reshape(X.shape[1], 1).round(4)# Calculate the predicted output valuef_x = calculatePredicatedValue(X, W)# Calculate the initial SSEsse_old = calculateSSE(Y, f_x)outputFile = 'solution_' + 'learningRate_' + str(learningRate) + '_threshold_' + str(threshold) + '.csv''''Output file is opened in writing mode and the data is written in the format mentioned in the post. After thefirst values are written, the gradient and updated weights are calculated using the calculateGradient function.An iteration variable is maintained to keep track on the number of times the batch linear regression is executedbefore it falls below the threshold value. In the infinite while loop, the predicted output value is calculated again and new SSE value is calculated. If the absolute difference between the older(SSE from previous iteration) and newer(SSE from current iteration) SSE is greater than the threshold value, then above process is repeated.The iteration is incremented by 1 and the current SSE is stored into previous SSE. If the absolute difference between the older(SSE from previous iteration) and newer(SSE from current iteration) SSE falls below the threshold value, the loop breaks and the last output values are written to the file.'''with open(outputFile, 'w', newline='') as csvFile:writer = csv.writer(csvFile, delimiter=',', quoting=csv.QUOTE_NONE, escapechar='')writer.writerow([*[0], *["{0:.4f}".format(val) for val in W.T[0]], *["{0:.4f}".format(sse_old)]])gradient, W = calculateGradient(W, X, Y, f_x, learningRate)iteration = 1whileTrue:f_x = calculatePredicatedValue(X, W)sse_new = calculateSSE(Y, f_x)if abs(sse_new - sse_old) > threshold:writer.writerow([*[iteration], *["{0:.4f}".format(val) for val in W.T[0]], *["{0:.4f}".format(sse_new)]])gradient, W = calculateGradient(W, X, Y, f_x, learningRate)iteration += 1sse_old = sse_newelse:breakwriter.writerow([*[iteration], *["{0:.4f}".format(val) for val in W.T[0]], *["{0:.4f}".format(sse_new)]])print("Output File Name: " + outputFiledefcalculateGradient(W, X, Y, f_x, learningRate):gradient = (Y - f_x) * Xgradient = np.sum(gradient, axis=0)# gradient = np.array([float("{0:.4f}".format(val)) for val in gradient])temp = np.array(learningRate * gradient).reshape(W.shape)W = W + tempreturn gradient, WdefcalculateSSE(Y, f_x):sse = np.sum(np.square(f_x - Y))return ssedefcalculatePredicatedValue(X, W):f_x = np.dot(X, W)return f_xif __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument("-d", "--data", help="Data File")parser.add_argument("-l", "--learningRate", help="Learning Rate")parser.add_argument("-t", "--threshold", help="Threshold")main()? 這篇文章介紹了使用梯度下降法進(jìn)行批線性回歸的數(shù)學(xué)概念。 在此,考慮了損失函數(shù)(在這種情況下為平方誤差總和)。 我們沒(méi)有看到最小化SSE的方法,而這是不應(yīng)該的(需要調(diào)整學(xué)習(xí)率),我們看到了如何在閾值的幫助下使線性回歸收斂。
? 該程序使用numpy來(lái)處理數(shù)據(jù),也可以使用python的基礎(chǔ)知識(shí)而不使用numpy來(lái)完成,但是它將需要嵌套循環(huán),因此時(shí)間復(fù)雜度將增加到O(n * n)。 無(wú)論如何,numpy提供的數(shù)組和矩陣的內(nèi)存效率更高。 另外,如果您喜歡使用pandas模塊,建議您使用它,并嘗試使用它來(lái)實(shí)現(xiàn)相同的程序。
? 希望您喜歡這篇文章。 謝謝閱讀。
總結(jié)
以上是生活随笔為你收集整理的模型训练 准确率下降_手写批量线性回归算法:在Python3中梯度下降方法实现模型训练的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 深圳python如何评价_Python分
- 下一篇: python创建列表_python创建与