预期函数:y = 5+3*x
函数模型:y = a +b*x,训练求参:a,b值
数据集:第一列是x值,第二列是y值
梯度下降算法:原理请看吴恩达机器学习课程“单变量线性回归”
# 数据获取函数 def fileIn(fileName): data = [[],[]] fr = open(fileName,'r',encoding='utf-8') # 读出文件所有内容 arrayLines = fr.readlines() # 针对有BOM的UTF-8文本,应该去掉BOM,否则后面会引发错误。 arrayLines[0] = arrayLines[0].lstrip('\ufeff') for line in arrayLines: # s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ') line = line.strip() line = line.split(' ') # line = [xxx,xxx,xxx,xxx] 列表 data[0].append(float(line[0])) data[1].append(float(line[1])) return data # [[0.0,0.1,0.2,0.3,...x],[5.0,5.3,5.6,5.9,...y]] # 梯度下降核心计算机参数值 ,inialArg表示a,b初始化参数值,stepL表示梯度下降时学习速率 # 假设函数:f(x)=a+bx # 代价函数:J = 1/(2len(data[0]))Sum((a+bx-y)^2) # 代价函数对参数a求偏导:deva=suma/len(data[0]),len(data[0])表示数据的数量 # 代价函数对参数b求偏导:deva=sumb/len(data[0]), # a = a - stepL*deva # b = b - stepL*devb def calArg(data,inialArg,stepL): a,b = inialArg[0],inialArg[1] while 1: dev1 = 0 # 参数a的偏导 dev2 = 0 # 参数b的偏导 suma = 0 # 参数a的偏导值求和 sumb = 0 # 参数b的偏导值求和 for i in range(len(data[0])): tempy1 = a+b*data[0][i]-data[1][i] # (a+b*xi) - yi x=xi时,参数a的偏导值 tempy2 = (a+b*data[0][i]-data[1][i])*data[0][i] # [(a+b*xi) - yi]*xi x=xi时,参数b的偏导值 suma += tempy1 sumb += tempy2 dev1 = suma/len(data[0]) dev2 = sumb/len(data[0]) tempa = a - stepL*(dev1) tempb = b - stepL*(dev2) a = tempa b = tempb print(dev1,dev2) # 每次参数a,b相应的偏导数值 if abs(dev1-0)<0.00001 and abs(dev2-0)<0.00001: # 当偏导都趋近于0时,代表已经达到最优点了,训练完成,凸面的最小值导数等于0 break return a,b def alg(stepL): data = fileIn("data.txt") a,b=0,0 # 初始化(a,b)参数值为0,0 a,b=calArg(data,[a,b],stepL) print(a,b) if __name__ == '__main__': alg(0.0001) # 设置参数修改步长为0.0001梯度下降效果:前面的数值是参数a,b在相应变化值的偏导数值,最后一行是最终得到的参数值