文章目录

  • 1. 吴恩达机器学习课程-作业1-线性回归
  • 1.1 一元线性回归
  • 1) 题目介绍
  • 2) 数据介绍
  • 3) 代码
  • 1.2 多元线性回归
  • 1.2.1 问题注意
  • 1) 归一化好处
  • 2) 常用的规划方法
  • 1.2.2 模型简介
  • 1.2.3 题目介绍
  • 1.2.4 数据介绍
  • 1.2.5 代码如下


1. 吴恩达机器学习课程-作业1-线性回归

回归分析(Regression Analysis)定义与分类

回归分析(Regression Analysis)是一种统计学上分析数据的方法,目的在于了解两个或多个变量间是否相关、相关方向与强度,并建立数学模型以便观察特定变量来预测研究者感兴趣的变量。更具体的来说,回归分析可以帮助人们了解在只有一个自变量变化时因变量的变化量。

一般来说,通过回归分析我们可以由给出的自变量估计因变量的条件期望。回归分析是建立因变数 Y(或称依变数,反应变数)与自变数 X(或称独变数,解释变数)之间关系的模型。

回归分析的主要算法包括:

  • 线性回归(Linear Regression)
  • 逻辑回归(Logistic regressions)
  • 多项式回归(Polynomial Regression)
  • 逐步回归(Step Regression)
  • 岭回归(Ridge Regression)
  • 套索回归(Lasso Regression)
  • 弹性网回归(ElasticNet)

1.1 一元线性回归

pdf就是英文的题目

1) 题目介绍

在本部分的练习中,您将使用1实现线性回归变量来预测食品卡车的利润。

假设你是一家公司的首席执行官餐厅加盟店正在考虑在不同城市开设一家新的出口。

该连锁店在各个城市都有卡车,你有数据城市的利润和人口。

您希望使用这些数据来帮助选择要扩展的城市下一个。

2) 数据介绍

ex1data1.txt格式如下

6.1101,17.592
5.5277,9.1302
8.5186,13.662
7.0032,11.854
5.8598,6.8233
8.3829,11.886
7.4764,4.3483
8.5781,12
6.4862,6.5987

ex1data .txt文件包含线性回归问题的数据集。

第一列是一个城市的人口,第二列是那座城市里一辆餐车的利润。利润的负值表示的损失。

读入数据时按行读入,每行通过分解,获得两个数据。数据的存储使用列表。

# 读取文件a.txt中的数据,分隔符为",",以double格式读取数据
data = np.loadtxt('ex1data1.txt', delimiter=',', dtype=np.double)

接下来将数据可视化,需要用到matplotlib这个画图库

# 一共2*2,4个图,现在画第一个图
plt.subplot(2, 2, 1)
# 显示中文标签
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
plt.title("线性回归变量来预测食品卡车的利润")  # 设置x
plt.xlabel("城市人口,单位万")# 设置x轴
plt.ylabel("利润,单位千")  # 设置y轴
 # scatter绘制散点图
plt.scatter(data[:, 0], data[:, 1], marker='x')

plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qvw1FvSL-1645517549301)(picture/image-20211018164844778.png)]

使用梯度下降法更新函数—(不会的可以参考一下文章链接)

1. 吴恩达机器学习课程-作业1-线性回归_回归为所有损失值集合,1. 吴恩达机器学习课程-作业1-线性回归_数据_02为数据的组数
1. 吴恩达机器学习课程-作业1-线性回归_回归_03
在文章最下面就有梯度下降的更新公式1. 吴恩达机器学习课程-作业1-线性回归_机器学习_04

可得1. 吴恩达机器学习课程-作业1-线性回归_回归分析_051. 吴恩达机器学习课程-作业1-线性回归_线性回归_06的更新公式为:

1. 吴恩达机器学习课程-作业1-线性回归_回归分析_07

1. 吴恩达机器学习课程-作业1-线性回归_机器学习_08

1. 吴恩达机器学习课程-作业1-线性回归_回归_09

1. 吴恩达机器学习课程-作业1-线性回归_机器学习_10

其中1. 吴恩达机器学习课程-作业1-线性回归_回归分析_11一个大于0的正数,通常称之为步长或学习率(learning rate)。

3) 代码

import matplotlib.pyplot as plt
import numpy as np


class Linear_Regression:

    # 梯度下降,更新w和b
    def gradient_descent(self, w, b, alpha):
        for i in range(self.m):
            x_i = self.data[i][0]
            y_i = self.data[i][1]
            w -= (alpha / self.m) * (w * x_i + b - y_i) * x_i
            b -= (alpha / self.m) * (w * x_i + b - y_i)
        return w, b

    # 计算损失值
    def cal_loss(self, w, b):
        # J表示总损失
        J = 0
        for i in range(self.m):
            x_i = self.data[i][0]
            y_i = self.data[i][1]
            J += 1.0 / (2 * self.m) * pow((w * x_i + b - y_i), 2)
        return J

        # 初始化数据

    def __init__(self):
        # 读取文件a.txt中的数据,分隔符为",",以double格式读取数据
        self.data = np.loadtxt('ex1data1.txt', delimiter=',', dtype=np.float64)
        # m设置行数
        self.m = self.data.shape[0]

        # 数据值
        # 一共2*2,4个图,现在画第一个图
        plt.subplot(2, 2, 1)
        # 显示中文标签
        plt.rcParams["font.sans-serif"] = ["SimHei"]
        plt.rcParams["axes.unicode_minus"] = False
        plt.title("线性回归变量来预测食品卡车的利润")  # 设置x
        plt.xlabel("城市人口,单位万")  # 设置x轴
        plt.ylabel("利润,单位千")  # 设置y轴
        # scatter绘制散点图
        plt.scatter(self.data[:, 0], self.data[:, 1], marker='x')

    # 开始函数
    def main(self):

        alpha = 0.01  # 学习速率
        iterations = 1500  # 梯度下降的迭代轮数
        # 下面两个是带估计的参数值,每次需要更新一下两个值
        w = 0.0
        b = 0.0
        w_all = []
        b_all = []
        # 为损失总函数
        cost = []
        print("-------开始计算了-----")
        # 计算一下损失,初始值损失
        print("初始的损失值",self.cal_loss(w, b))
        # 大概训练1500个回合
        for i in range(iterations):
            w_all.append(w)
            b_all.append(b)
            w, b = self.gradient_descent(w, b, alpha)
            temp = self.cal_loss(w, b)
            cost.append(temp)

        print("最后结果的w---", w, "最后结果的b---", b)
        x = [5.0, 22.5]
        y = [5.0 * w + b, 22.5 * w + b]
        plt.subplot(2, 2, 2)
        plt.plot(x, y, color="red")
        plt.title("线性回归第一题")
        plt.xlabel("城市的人口数量")
        plt.ylabel("利润")
        plt.scatter(self.data[:, 0], self.data[:, 1], marker='x')

        print(str(cost))
        plt.subplot(2, 2, 3)
        plt.title("损失函数J")
        plt.xlabel("迭代次数")
        plt.ylabel("损失值")
        plt.plot(range(len(cost)), cost, color="red")
        plt.show()
        print("损失值", cost[0:5])
        print("b--", b_all[0:5])
        print("w--", w_all[0:5])
        print("-------结束了-----")

if __name__ == '__main__':
    obj = Linear_Regression()
    obj.main()

结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5nm3Yv9p-1645517549305)(picture/image-20211020194136114.png)]

1.2 多元线性回归

1.2.1 问题注意

在求解线性回归的模型时,有两个需要注意的问题

一就是特征组合问题,比如房子的长和宽作为两个特征参与模型的构造,不如把其相乘得到面积然后作为一个特征来进行求解,这样在特征选择上就做了减少维度的工作。

二就是特征归一化(Feature Scaling),这也是许多机器学习模型都需要注意的问题。

有些模型在各个维度进行不均匀伸缩后,最优解与原来不等价,例如SVM。对于这样的模型,除非本来各维数据的分布范围就比较接近,否则 必须进行标准化,以免模型参数被分布范围较大或较小的数据dominate。

有些模型在各个维度进行不均匀伸缩后,最优解与原来等价,例如logistic regression。对于这样的模型,是否标准化理论上不会改变最优解。但是,由于实际求解往往使用迭代算法,如果目标函数的形状太“扁”,迭代算法可能收敛得很慢甚至不收敛。所以对于具有伸缩不变性的模型, 最好也进行数据标准化。

1) 归一化好处

  • 提升模型的收敛速度
    如下图,x1的取值为0-2000,而x2的取值为1-5,假如只有这两个特征,对其进行优化时,会得到一个窄长的椭圆形,导致在梯度下降时,梯度的方向为垂直等高线的方向而走之字形路线,这样会使迭代很慢,相比之下,右图的迭代就会很快
    未归一化
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nyBc5jdI-1645517549306)(picture/20171126162643419.png)]
    归一化之后
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-50FlgnI6-1645517549307)(picture/20171126162702871.png)]
  • 提升模型的精度
    归一化的另一好处是提高精度,这在涉及到一些距离计算的算法时效果显著,比如算法要计算欧氏距离,上图中1. 吴恩达机器学习课程-作业1-线性回归_线性回归_12的取值范围比较小,涉及到距离计算时其对结果的影响远比1. 吴恩达机器学习课程-作业1-线性回归_回归分析_13带来的小,所以这就会造成精度的损失。所以归一化很有必要,他可以让各个特征对结果做出的贡献相同。

2) 常用的规划方法

  • 线性归一化
    (Min-Max Normalization)
    线性归一化会把输入数据都转换到[0 1]的范围,公式如下
    1. 吴恩达机器学习课程-作业1-线性回归_数据_14
  • 0均值标准化
    0均值归一化方法将原始数据集归一化为均值为0、方差1的数据集,归一化公式如下:
    1. 吴恩达机器学习课程-作业1-线性回归_回归分析_15
    其中,μ、σ分别为原始数据集的均值和方法。该种归一化方式要求原始数据的分布可以近似为高斯分布,否则归一化的效果会变得很糟糕。

1.2.2 模型简介

模型

1. 吴恩达机器学习课程-作业1-线性回归_线性回归_16

得到了模型,我们需要求出需要的损失函数,**一般线性回归我们用均方误差作为损失函数。**损失函数的代数法表示如下:

1. 吴恩达机器学习课程-作业1-线性回归_机器学习_17

用矩阵表达为1. 吴恩达机器学习课程-作业1-线性回归_回归分析_18

我们常用的有两种方法来求损失函数最小化时候的θθ参数:一种是梯度下降法,一种是最小二乘法

如果采用梯度下降法,则1. 吴恩达机器学习课程-作业1-线性回归_回归分析_19的迭代公式是这样的:

1. 吴恩达机器学习课程-作业1-线性回归_线性回归_20

def cost(self, X, theta, y):
        '''
        计算损失函数
        :param X: 矩阵
        :param theta: 步长
        :param y: 结果
        :return: 矩阵X的函数
        '''
        m = X.shape[0]
        temp = X.dot(theta) - y
        return temp.T.dot(temp) / (2 * m)
      
  def gradient_descent(self, X, theta, y, alpha, iterations):
        '''
        :param X: 矩阵X
        :param theta: 变量
        :param y: 结果
        :param alpha: 步长
        :param iterations: 迭代次数
        :return:
        '''
        m = X.shape[0]
        print("行数--", m)
        print("y行数", len(y))
        c = []  # 存储计算损失值
        for i in range(iterations):
            theta -= (alpha / m) * X.T.dot(X.dot(theta) - y)
            # 计算损失值
            c.append(self.cost(X, theta, y))

        return theta, c

如果采用最小二乘法,则θ的结果公式如下:

1. 吴恩达机器学习课程-作业1-线性回归_机器学习_21

python代码如下

def normal_equation(X, y):
    return np.linalg.pinv(X.T.dot(X)).dot(X.T).dot(y)

当然线性回归,还有其他的常用算法,比如牛顿法和拟牛顿法,这里不详细描述。

注意,在业务上对数据的拟合,要注意多重共线性的问题以及对回归方程的检验。

1.2.3 题目介绍

在本部分中,您将实现具有多个变量的线性回归预测房价。假设你要卖掉你的房子想知道什么是好的市场价格。

一种方法是首先收集最近出售的房屋的信息,并制作一个房屋模型价格。

1.2.4 数据介绍

2104,3,399900
1600,3,329900
2400,3,369000
1416,2,232000
3000,4,539900
1985,4,299900
1534,3,314900
1427,3,198999
1380,3,212000
1494,3,242500
1940,4,239999
2000,3,347000
1890,3,329999
4478,5,699900

ex1data2.txt文件包含俄勒冈州港口土地的房价培训集。

第一根柱子是房子的大小(平方英尺)

第二栏是卧室的数量,

第三栏是价格的房子。

1.2.5 代码如下

import matplotlib.pyplot as plt
import numpy as np


class Linear_Regression:

    def normal_equation(self, X, y):
        '''
        最小二乘法
        :param X:
        :param y:
        :return:
        '''
        return np.linalg.pinv(X.T.dot(X)).dot(X.T).dot(y)

    def cost(self, X, theta, y):
        '''
        计算损失函数
        :param X: 矩阵
        :param theta: 步长
        :param y: 结果
        :return: 矩阵X的函数
        '''
        m = X.shape[0]
        temp = X.dot(theta) - y
        return temp.T.dot(temp) / (2 * m)

    def gradient_descent(self, X, theta, y, alpha, iterations):
        '''

        :param X: 矩阵X
        :param theta: 变量
        :param y: 结果
        :param alpha: 步长
        :param iterations: 迭代次数
        :return:
        '''
        m = X.shape[0]
        print("行数--", m)
        print("y行数", len(y))
        c = []  # 存储计算损失值
        for i in range(iterations):
            theta -= (alpha / m) * X.T.dot(X.dot(theta) - y)
            # 计算损失值
            c.append(self.cost(X, theta, y))

        return theta, c

    def maxminnorm(self, array):
        '''
        Numpy数组的归一化处理
        :param array: 需要归一化的数组
        :return:
        '''
        maxcols = array.max(axis=0)
        mincols = array.min(axis=0)
        data_shape = array.shape
        data_rows = data_shape[0]
        data_cols = data_shape[1]
        t = np.empty((data_rows, data_cols))
        for i in range(data_cols):
            t[:, i] = (array[:, i] - mincols[i]) / (maxcols[i] - mincols[i])
        return t

    def __init__(self):
        # 读取文件a.txt中的数据,分隔符为",",以double格式读取数据
        self.data = np.loadtxt('ex1data2.txt', delimiter=',', dtype=np.float64)
        # m设置行数
        self.m = self.data.shape[0]
        # 进行数据归一化
        self.normalization_data = self.maxminnorm(self.data)

    def main(self):
        '''
        主函数
        :return:
        '''
        theta = np.zeros((2,))
        print(theta)
        alpha = 0.1
        iterations = 10000
        # 第一列和第二列是X,数据
        X = self.normalization_data[:, 0:2]
        # 第三列为价格
        y = self.normalization_data[:, 2]
        theta, c = self.gradient_descent(X=X,
                                         theta=theta,
                                         y=y,
                                         alpha=alpha,
                                         iterations=iterations)
        # 可视化下降过程
        plt.rcParams["font.sans-serif"] = ["SimHei"]
        plt.rcParams["axes.unicode_minus"] = False
        plt.plot()
        plt.title("损失函数J(θ)")
        plt.xlabel("接待次数")
        plt.ylabel("损失值")
        plt.plot([i for i in range(iterations)], c, color="red")
        plt.show()
        print("使用梯度下降:", theta)
        print("使用最小二乘法", self.normal_equation(X, y))
        pass


if __name__ == '__main__':
    obj = Linear_Regression()
    obj.main()

结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-74PRp4m5-1645517549309)(picture/image-20211103170549479.png)]