程序猿成长史(一):用自生成的数据,实现最小二乘法线性拟合

程序猿成长史(一):初探自生成数据,最小二乘法线性拟合及非线性多项式拟合

近来刚好在实验室里,学习的过程中刚好碰到了人工智能最基础的方面,线性拟合。同时也是接到实验室里一个大佬的任务,生成所需线性拟合的数据集。然后也就顺手整理写下了这篇文章。主要内容包括:

  • 数据生成
  • 基于最小二乘法的线性拟合
  • 基于梯度下降+最小二乘法的非线性多项式拟合

然后这次,博主也是很认真的用了Python来实现整一个过程。(认真脸)
话不多说,直接开始吧。

  1. 数据生成
    首先,数据的生成是自己写的函数,思路大概如下:首先是选定x和y的大致范围和生成的数据的个数(在我的代码中,x和y都是一百个数据,x的范围是从0到100,y的范围是从0到200),然后就是选取合适的函数,再逐一生成即可。Talk is cheap , let’s see the code.
import Random
Datax = []
Datay = []	
noise = 10 				#噪声
FilePath="/XXXXX/XXXX/XXXXX/文件储存/4.txt" #自己想保存的文件路径
while(len(Datay)<100):          #生成一百个数据点
    x=random.uniform(0,100)
    y=x*2+6+random.uniform(-noise, noise) 		#生成y=2x+6的函数的点
    if(y<=200):				#选择其中y小于200的点
        Datay.append(y)
        Datax.append(x)

File = open(FilePath,mode='w')			#打开文件并以txt的格式写入
for i in range(100):
    File.write(str(Datax[i])+'\t'+str(Datay[i])+'\n')
    
# 用Excel表保存的写法
# workbook = xlwt.Workbook()
# sheet1 = workbook.add_sheet('DataSet',cell_overwrite_ok=True)
# for i in range(100):
#     sheet1.write(i,0,str(Datax[i]))
#     sheet1.write(i,1,str(Datay[i]))
# workbook.save(FilePath)

File.close()

保存数据的方法有两种,txt方式和excel方式,大家可以自行选择。 但是要注意的是,在生成的数据点的时候,要加上适当的噪声,以便更好的反应你的算法的泛化性。同时有心的可以生成一些随机的噪声点,然后可以通过一些方法去除这些对算法正确性干扰较大的点。我其实是做了五个噪声点的但是发现其实并没有特别好的去处纯噪点的方法,所以又舍去了 然后这个算法生成的数据都是乱序的,大家可以事先sorted排序点,再用matplotlib去检验数据点的准确性。

  1. 基于最小二乘法的线性拟合
    线性拟合这部分,我是参考着西瓜书《机器学习》里面的公式,自己写的方法,然后将预测的直线也可视化了。用的最小二乘法其实也就是求出预测函数和实际的y的值的平方差,求他的最小值,也就是y=wt+b中对w和b求偏导,并令它们偏导为零的情况。算法证明等大家可以自行百度一下,毕竟我也只是初次探索,未必有别家大牛理解那么深刻,先上程序。
import matplotlib.pyplot as plt
import numpy as np

def ReadFile(Filepath,length):			#从txt.文件中读取dataset
    file = open(Filepath,'r')
    datax = []
    datay = []

    for i in range(length):
        line = file.readline().replace('\n','')
        tem=line.split('\t')
        x = float(tem[0])
        y = float(tem[1])
        datax.append(x)
        datay.append(y)
    return datax,datay

def Cal(datax,datay,length):
    avgx = np.mean(datax)
    tem = 0
    squ = 1
    for i in range(length):	#计算wx+b中的w
        tem = tem + datay[i]*(datax[i]-avgx)
        squ = squ + datax[i] * datax[i]

    squ = squ - sum(datax)**2/length
    answ = tem / squ
    b = 0
    for i in range(length):
        b = b + datay[i] - answ * datax[i]
    b = b / length
    return answ,b

def DrawPicture(datax,datay,w,b,c):
	#绘制相应的拟合直线线
    plt.scatter(datax,datay)
    x = [i for i in range(100)]
    y = [i*w+b for i in range(100)]
    plt.plot(x, y, color=c)
    plt.show()

def NumpyRegression(datax,datay):					
	#用了np库中的拟合函数,相比较性能
    w = np.polyfit(datax, datay, 1)
    print(w[0], w[1])
    return w[0], w[1]

if __name__=="__main__":
    Filepath = '/XXXXX/XXXXX/Documents/文件储存/1.txt'
    length = 105
    datax, datay = ReadFile(Filepath, length)
    w, b = Cal(datax, datay, length)
    w1, b1 = NumpyRegression(datax, datay)
    DrawPicture(datax, datay, w, b, 'r') 	#绘制自写预测函数的图
    DrawPicture(datax, datay, w1, b1, 'b')	#绘制np库中函数预测图像

然后代码最后实现的结果大致如下图:

  1. 基于梯度下降+最小二乘法的非线性多项式拟合
    相比较线性拟合,非线性多项式拟合就显得更为的复杂。博主也是从网上看了别人的教程一点点学着写的。网址如下:
    最小二乘法–多项式拟合非线性函数

    代码方面我也借鉴了很多,只有学习率(LearningRate)和训练轮次(iternum)是我后期依据自己的训练集修改的。不得不说梯度下降方法真的是一个靠运气和调参的算法,调参调的好,拟合就好,但是博主最后也没有找到最合适的学习率,故拟合的效果也没有非常非常好。各位可以自己试着调参。

def CalLoss(datax,datay,A):#计算损失函数
    error = 0.0
    for i in range(len(datax)):
        y1 = 0.0
        for k in range(len(A)):
            y1 += A[k]*(datay[i]**k)
        error += (datay[i]-y1) ** 2
        #计算从0到最大值n的所有误差
    return error

def FittingCurveGradient(datax, datay, order, iternum= 41100, learnrate=0.0000000000001):#order所求多项式最高次数
    A = [0.0]*(order+1)     #初始化order个0
    tem = A
    for r in range(iternum+1):
        for k in range(len(A)):
            gradient = 0.0
            for i in range(len(datax)):#100个
                y1 = 0.0
                for j in range(len(A)):#计算每一轮ak总的梯度值
                    y1 += A[j] * datax[i]**j
                gradient += -2 * (datay[i]-y1) * (datax[i]**k)   #计算A[k]的梯度
            A[k] = A[k] - (learnrate*gradient)  #更新A[k]梯度
            error=CalLoss(datax,datay,A)#用于回溯
            if(r==0):
                errormin=error
            elif(errormin > error):
                errormin=error
                tem[k] = A[k]
            else:
                A[k] = tem[k] #实现回溯
        #检查误差
        if r % 100 == 0:
            error = CalLoss(datax,datay,A)
            print('第{}次迭代,误差下降至:{}'.format(r, error))
    return A

然后自己也偷偷调用了一下np库里的函数去拟合,效果也没有很好。可能是我了解的不够深刻,希望大家和我一起进步。这就是本次项目的基本内容了。期待着未来自己回头看的时候,可以有更多收获嘻嘻。

全部评论

相关推荐

想踩缝纫机的小师弟练...:不理解你们这些人,要放记录就把对方公司名字放出来啊。不然怎么网暴他们
点赞 评论 收藏
分享
03-01 21:45
中北大学 golang
孤蓝长空:请你说一下为什么你用websocket而不是http,请你说一下什么是rpc,为什么用rpc,你的rpc的传输协议是JSON,xml还是什么 请你描述一下你的鉴权流程(完整的) 我问的是第二个项目,随便问的哈哈哈
开工第一帖
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 一张图晒出你司的标语 #
4402次浏览 77人参与
# 找AI工作可以去哪些公司? #
9571次浏览 260人参与
# 米连集团26产品管培生项目 #
13431次浏览 285人参与
# 你的实习产出是真实的还是包装的? #
20546次浏览 343人参与
# AI面会问哪些问题? #
28498次浏览 578人参与
# 春招至今,你的战绩如何? #
66857次浏览 589人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
15503次浏览 225人参与
# 从事AI岗需要掌握哪些技术栈? #
9419次浏览 334人参与
# 中国电信笔试 #
32166次浏览 295人参与
# 你做过最难的笔试是哪家公司 #
34783次浏览 258人参与
# 投递几十家公司,到现在0offer,大家都一样吗 #
341064次浏览 2175人参与
# 金三银四,你的春招进行到哪个阶段了? #
22404次浏览 284人参与
# 同bg的你秋招战况如何? #
212254次浏览 1121人参与
# 哪些公司真双非友好? #
69762次浏览 289人参与
# 如何准备秋招 #
78321次浏览 868人参与
# 阿里笔试 #
179170次浏览 1318人参与
# 机械人避雷的岗位/公司 #
62716次浏览 393人参与
# 小马智行求职进展汇总 #
25149次浏览 80人参与
# 第一份工作一定要去大厂吗 #
15003次浏览 122人参与
# 担心入职之后被发现很菜怎么办 #
291410次浏览 1210人参与
# 为了减少AI幻觉,你注入过哪些设定? #
26298次浏览 310人参与
# 应届生第一份工资要多少合适 #
20709次浏览 86人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务