使用Python实现线性回归

举报
不良使 发表于 2022/04/07 11:42:55 2022/04/07
【摘要】 使用Python实现线性回归

实验目的
使用Python实现线性回归
实验原理
使用最小二乘法进行线性回归,采用均方误差来表示误差,使用梯度下降法进行最小化误差。
实验内容(表格区域可拉长)
(1)已知样本输入和标签如x.txt和y.txt所示,试使用Python求出i.) y=2x+2;ii.) y=x+3;iii.)y = 3x-1这三条直线哪个更加接近于样本给出的值。
(2)对于上述数据,采用线性回归拟合出该线性方程。
(要求:采用直接读取文件的方式,不要复制粘贴。)

import numpy as np
import matplotlib.pyplot as plt

x = list()
y = list()
with open("x.txt", "r") as f:
    for line in f.readlines():
        line = float(line.strip())
        x.append(line)
# print(x)
with open("y.txt", "r") as f:
    for line in f.readlines():
        line = float(line.strip())
        y.append(line)

loss_sum1 = 0
for i in range(0, 10):
    a = (2 * x[i] + 2 - y[i]) ** 2
    loss_sum1 += a
average1 = loss_sum1 / len(x)
print("损失值为:%.15f"%average1)

loss_sum2 = 0
for i in range(0, 10):
    b = (x[i] + 3 - y[i]) ** 2
    loss_sum2 += b
average2 = loss_sum2 / len(x)
print("损失值为:%.15f"%average2)

loss_sum3 = 0
for i in range(0, 10):
    b = (3 * x[i] - 1 - y[i]) ** 2
    loss_sum3 += b
average3 = loss_sum3 / len(x)
print("损失值为:%.15f"%average3)

if (loss_sum1 < loss_sum2) and (loss_sum1 < loss_sum3):
    print("y=2x+2更加接近样本给出的值")
if (loss_sum2 < loss_sum1) and (loss_sum2 < loss_sum3):
    print("y=x+1更加接近样本给出的值")
else:
    print("y=3x-1更加接近样本给出的值")

# def updatekb(data, k, b, learning_rate):
#     x=data[0]
#     y=data[1]
#     n = len(x)
#     dk, db = 0, 0
#     for i in range(n):
#         dk += 2 / 10 * (k*x[i] + b - y[i]) * x[i]
#         db += 2 / 10 * (k * x[i] + b - y[i])
#     new_k = k - learning_rate * dk
#     new_b = b - learning_rate * db
#     return new_k, new_b
#
#
# def learningcregression(data, k, b, r, h):
#     dk, db = k, b
#     n = len(x)
#     for i in range(n):
#         dk, db = updatekb(data, dk, db, r)
#     return dk, db
#
#
# #入口函数
# def getdata():
#     x, y = getdata()
#     return x, y
#
#
# if __name__ == "__main__":
#     k, b = learningcregression(getdata, 2, 1, 0.001, 10000)

# 取步长为0.001
k = [3, 0]
b = [-1, 0]
ones = 0

while True:
    dk, db = 0, 0
    for i in range(0, 10):
        dk += 2 / 10 * (k[0] * x[i] + b[0] - y[i]) * x[i]
        db += 2 / 10 * (k[0] * x[i] + b[0] - y[i])
    k[1] = k[0] - 0.001 * dk
    b[1] = b[0] - 0.001 * db
    if ones == 100000:
        break
    else:
        k[0] = k[1]
        b[0] = b[1]
        ones += 1
print("拟合回归方程的斜率k为:%.7f"%k[1])
print("拟合回归方程的斜率k为:%.7f"%b[1])
print(ones)
print("拟合回归方程为:%.7f * x + %.7f" % (k[1], b[1]))

x = np.array(x)
y = np.array(y)
Y = k[1] * x + b[1]
plt.scatter(x, y)
plt.plot(x, Y, '*-g')
plt.show()

在这里插入图片描述

思考题(表格区域可拉长)
(1)试引入sklearn包,直接计算该线性方程。(注:选做)
(2)试将上述坐标点和线性方程的图像使用Python画入平面直角坐标系中。

在这里插入图片描述

(3)试思考当有2个及以上特征时,如何使用线性回归方法来实现拟合。(注:文字描述即可)

3)当特征值为两个的时候,则是一个二维平面(横纵坐标分别表示一个特征值)。当出现两个以上的特征值时,特征值越多,坐标的维数越多,那么模型建立起来就比较繁琐,而且多特征有时还会存在多重共线性问题,即相互之间具有关联关系,导致解空间不稳定,模型泛化能力弱,过多特征也会妨碍模型学习规律。因此,当特征值比较多时我们通常可以采用降维的方式减少维数,使模型简单准确,简单来说就是指可以用更少维度的特征替代更高维度的特征,同时保留有用的信息,把高维空间上的多个特征组合成少数几个无关的主成分,同时包含原数据中大部分的变异信息,简单的来说就是在二维坐标(x,y)内均匀分布在一条回归线上下,在三维坐标内(x,y,z)还是按照近似二维平面分布,第三个维度(z)对回归拟合的影响非常小,故可以删除这个特征向量(z),用二维(x,y)来反映原始数据,除此之外还有其他的方法进行降维,例如缺失值比率 、低方差滤波 、高相关滤波 、随机森林/组合树等
注:变异信息就用方差来衡量,第一主成分是高维空间上的一个向量,所有的点沿着这条线波动最大,或者说所有的点到直线的距离的平方和最小。如下图所示,所有的点沿着绿色直线的波动最大,它就代表着第一主成分向量。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。