机器学习——线性回归

参考:
https://cuijiahua.com/blog/2017/11/ml_6_logistic_1.html
https://cuijiahua.com/blog/2017/11/ml_7_logistic_2.html

一、线性回归前置简介

1.1、Sigmoid函数

在这里插入图片描述
在这里插入图片描述
优点

  1. Sigmoid函数的输出映射在(0,1)之间,单调连续,输出范围有限,优化稳定,可以用作输出层。
  2. 求导容易。

缺点

  1. 由于其软饱和性,容易产生梯度消失,导致训练出现问题。
  2. 其输出并不是以0为中心的。

这 Sigmoid 函数作为激活函数,x 可以代表很多参数,例如:单个数字、矩阵
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
则 Sigmoid 函数就如下图所示:
在这里插入图片描述
其中:z是一个矩阵,θ是参数列向量(要求解的),x是样本列向量(给定的数据集)。θ^T表示θ的转置。

1.2、损失函数

根据sigmoid函数的特性,我们可以做出如下的假设:
在这里插入图片描述
在已知样本x和参数θ的情况下,样本x属性正样本(y=1)和负样本(y=0)的条件概率。理想状态下,根据上述公式,求出各个点的概率均为1,也就是完全分类都正确。

但是考虑到实际情况,样本点的概率越接近于1,其分类效果越好。比如一个样本属于正样本的概率为0.51,那么我们就可以说明这个样本属于正样本。另一个样本属于正样本的概率为0.99,那么我们也可以说明这个样本属于正样本。但是显然,第二个样本概率更高,更具说服力。我们可以把上述两个概率公式合二为一:
在这里插入图片描述
合并出来的Loss,我们称之为损失函数(Loss Function)。当y等于1时,(1-y)项(第二项)为0;当y等于0时,y项(第一项)为0。

为s了简化问题,我们对整个表达式求对数,(将指数问题对数化是处理数学问题常见的方法):
在这里插入图片描述
这个损失函数,是对于一个样本而言的。给定一个样本,我们就可以通过这个损失函数求出,样本所属类别的概率,而这个概率越大越好,所以也就是求解这个损失函数的最大值。既然概率出来了,那么最大似然估计也该出场了。假定样本与样本之间相互独立,那么整个样本集生成的概率即为所有样本生成概率的乘积,再将公式对数化,便可得到如下公式:
在这里插入图片描述
其中,m为样本的总数,y(i)表示第i个样本的类别,x(i)表示第i个样本,需要注意的是θ是多维向量,x(i)也是多维向量。

1.3、梯度上升算法

在这里插入图片描述

在我们用数学求解时,自然使用到求导 f’(x)=-2x+4,然后使其等于0,我们就可以得到最大值时的 x=2

但是真实环境中的函数不会像上面这么简单,就算求出了函数的导数,也很难精确计算出函数的极值。此时我们就可以用迭代的方法来做。就像爬坡一样,一点一点逼近极值。这种寻找最佳拟合参数的方法,就是最优化算法。爬坡这个动作用数学公式表达即为:
在这里插入图片描述
在这里插入图片描述编程实现:

# !/usr/bin/python
# -*- coding: utf-8 -*- 
# @Time : 2020/1/6 16:26 
# @Author : ljf
# @File : LOG_test1.py


def f_prime(x_old):  # f(x)的导数
    return -2 * x_old + 4


def Gradient_Ascent_test():
    """
    函数说明:梯度上升算法测试函数
    求函数f(x) = -x^2 + 4x的极大值
    Returns:
        无
    """
    x_old = -1  # 初始值,给一个小于x_new的值
    x_new = 0  # 梯度上升算法初始值,即从(0,0)开始
    alpha = 0.01  # 步长,也就是学习速率,控制更新的幅度
    presision = 0.00000001  # 精度,也就是更新阈值
    while abs(x_new - x_old) > presision:
        x_old = x_new
        x_new = x_old + alpha * f_prime(x_old)  # 上面提到的公式
    print(x_new)  # 打印最终求解的极值近似值


if __name__ == '__main__':
    Gradient_Ascent_test()
1.4、J(θ)的求导

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后就是梯度上升迭代公式。

二、示例

示例就是把两种点用直线分类,求这条直线。
在这里插入图片描述

1、数据准备

https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt

2、步骤

把数据文件下载下来。

  1. 加载数据,并初步处理
  2. 利用梯度上升迭代公式计算出每一列的权重
  3. 根据每列权重画出直线
3、改进

因为这个梯度上升迭代公式,每次修改权重时,必须每次全部遍历,这样就会耗费很多时间和资源。
所以有了改进,每次修改随机挑取一个向量进行计算。

4、代码
# !/usr/bin/python
# -*- coding: utf-8 -*- 
# @Time : 2020/1/6 21:17 
# @Author : ljf
# @File : LOG_test5.py
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt
import numpy as np
import random


def loadDataSet():
    """
    函数说明:加载数据
    Returns:
        dataMat:    数据列表
        labelMat:   标签列表
    """
    dataMat = []  # 创建数据列表
    labelMat = []  # 创建标签列表
    fr = open('testSet.txt')  # 打开文件
    for line in fr.readlines():  # 逐行读取
        lineArr = line.strip().split()  # 去回车,放入列表
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])  # 添加数据
        labelMat.append(int(lineArr[2]))  # 添加标签
    fr.close()  # 关闭文件
    return dataMat, labelMat  # 返回


def sigmoid(inX):
    """
    函数说明:sigmoid函数
    Args:
        inX: 数据
    Returns:
        sigmoid函数
    """
    return 1.0 / (1 + np.exp(-inX))


def gradAscent(dataMatIn, classLabels):
    """
    函数说明:梯度上升算法
    Args:
        dataMatIn:      数据集
        classLabels:    数据标签
    Returns:
        weights.getA(): 求得的权重数组(最优参数)
    """
    dataMatrix = np.mat(dataMatIn)  # 转换成numpy的mat
    labelMat = np.mat(classLabels).transpose()  # 转换成numpy的mat,并进行转置
    m, n = np.shape(dataMatrix)  # 返回dataMatrix的大小。m为行数,n为列数。
    alpha = 0.001  # 移动步长,也就是学习速率,控制更新的幅度。
    maxCycles = 500  # 最大迭代次数
    weights = np.ones((n, 1))
    for k in range(maxCycles):
        h = sigmoid(dataMatrix * weights)  # 梯度上升矢量化公式
        error = labelMat - h
        weights = weights + alpha * dataMatrix.transpose() * error
    return weights.getA()  # 将矩阵转换为数组,返回权重数组


def plotBestFit(weights):
    """
    函数说明:绘制数据集
    Args:
        weights:    权重参数数组
    Returns:
        无
    """
    dataMat, labelMat = loadDataSet()  # 加载数据集
    dataArr = np.array(dataMat)  # 转换成numpy的array数组
    n = np.shape(dataMat)[0]  # 数据个数
    xcord1 = []
    ycord1 = []  # 正样本
    xcord2 = []
    ycord2 = []  # 负样本
    for i in range(n):  # 根据数据集标签进行分类
        if int(labelMat[i]) == 1:
            xcord1.append(dataArr[i, 1])
            ycord1.append(dataArr[i, 2])  # 1为正样本
        else:
            xcord2.append(dataArr[i, 1])
            ycord2.append(dataArr[i, 2])  # 0为负样本
    fig = plt.figure()
    ax = fig.add_subplot(111)  # 添加subplot
    ax.scatter(xcord1, ycord1, s=20, c='red', marker='s', alpha=.5)  # 绘制正样本
    ax.scatter(xcord2, ycord2, s=20, c='green', alpha=.5)  # 绘制负样本
    x = np.arange(-3.0, 3.0, 0.1)
    y = (-weights[0] - weights[1] * x) / weights[2]
    ax.plot(x, y)
    plt.title('BestFit')  # 绘制title
    plt.xlabel('X1')
    plt.ylabel('X2')  # 绘制label
    plt.show()


def stocGradAscent1(dataMatrix, classLabels, numIter=150):
    """
    函数说明:改进的随机梯度上升算法
    Args:
        dataMatrix:     数据数组
        classLabels:    数据标签
        numIter:        迭代次数
    Returns:
        weights:        求得的回归系数数组(最优参数)
    """
    m, n = np.shape(dataMatrix)  # 返回dataMatrix的大小。m为行数,n为列数。
    weights = np.ones(n)  # 参数初始化
    for j in range(numIter):
        dataIndex = list(range(m))
        for i in range(m):
            alpha = 4 / (1.0 + j + i) + 0.01  # 降低alpha的大小,每次减小1/(j+i)。
            randIndex = int(random.uniform(0, len(dataIndex)))  # 随机选取样本
            h = sigmoid(sum(dataMatrix[dataIndex[randIndex]] * weights))  # 选择随机选取的一个样本,计算h
            error = classLabels[dataIndex[randIndex]] - h  # 计算误差
            weights = weights + alpha * error * dataMatrix[dataIndex[randIndex]]  # 更新回归系数
            del (dataIndex[randIndex])  # 删除已经使用的样本
    return weights  # 返回


if __name__ == '__main__':
    dataMat, labelMat = loadDataSet()
    weights = stocGradAscent1(np.array(dataMat), labelMat)
    print(weights)
    plotBestFit(weights)

三、总结

3.1、Logistic回归的一般过程
  • 收集数据:采用任意方法收集数据。
  • 准备数据:由于需要进行距离计算,因此要求数据类型为数值型。另外,结构化数据格式则最佳。
  • 分析数据:采用任意方法对数据进行分析。
  • 训练算法:大部分时间将用于训练,训练的目的是为了找到最佳的分类回归系数。
  • 测试算法:一旦训练步骤完成,分类将会很快。
  • 使用算法:首先,我们需要输入一些数据,并将其转换成对应的结构化数值;接着,基于训练好的回归系数,就可以对这些数值进行简单的回归计算,判定它们属于哪个类别;在这之后,我们就可以在输出的类别上做一些其他分析工作。
3.2、重要

梯度上升迭代公式

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
4S店客户管理小程序-毕业设计,基于微信小程序+SSM+MySql开发,源码+数据库+论文答辩+毕业论文+视频演示 社会的发展和科学技术的进步,互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。手机具有便利性,速度快,效率高,成本低等优点。 因此,构建符合自己要求的操作系统是非常有意义的。 本文从管理员、用户的功能要求出发,4S店客户管理系统中的功能模块主要是实现管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理,用户客户端:首页、车展、新闻头条、我的。门店客户端:首页、车展、新闻头条、我的经过认真细致的研究,精心准备和规划,最后测试成功,系统可以常使用。分析功能调整与4S店客户管理系统实现的实际需求相结合,讨论了微信开发者技术与后台结合java语言和MySQL数据库开发4S店客户管理系统的使用。 关键字:4S店客户管理系统小程序 微信开发者 Java技术 MySQL数据库 软件的功能: 1、开发实现4S店客户管理系统的整个系统程序; 2、管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理等。 3、用户客户端:首页、车展、新闻头条、我的 4、门店客户端:首页、车展、新闻头条、我的等相应操作; 5、基础数据管理:实现系统基本信息的添加、修改及删除等操作,并且根据需求进行交流信息的查看及回复相应操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值