机器学习--logistics(代码片段)

zhengyinboke zhengyinboke     2023-03-21     602

关键词:

摘要

1. Logistic回归分类

2. 梯度下降法

3. 代码实现与解释

 

Logistic回归

逻辑斯特回归(logistic regression)是一种非常经典的分类方法。其用到的分类函数一般为Sigmoid函数,其函数形式为:

 技术图片

 

其图形表示如下:

技术图片

 

从图中我们可以看到,当z=0时,函数值为0.5。随着z值的增加,对应的函数值将逼近于1;随着z值的减小,函数值将逼近于0。

因此为了实现logistic回归,对于样本,我们可以在每个特征上乘以一个回归系数,然后将所有的结果值相加,将总和带入sigmoid函数中,进而得到一个范围在0~1之间的数值。大于0.5的数据被分到1类,小于0.5的即被分到0类。

 

二分类问题

对于Logistic回归中的二分类问题,当我们给定数据样本x时,其被分到1类和0类的条件概率分别为:

技术图片

 

其中,

技术图片

 

那么上式就可改写为:

技术图片

 

我们现在需要做的,就是怎么来确定模型中的参数w呢?

模型参数估计

在Logistic回归参数学习中,对于给定的训练数据集T={(x1,y1),(x2,y2),...(xN,yN)},我们用极大似然估计法估计模型参数w,从而得到logistic回归模型。

技术图片

 

 

当我们对L(w)求得极大值,也就得到了参数w的估计值。

这样,问题就变成了以对数似然估计为目标函数的最优化问题。而我们解决这个问题我们一般采用梯度下降法和拟牛顿法。

 

多分类问题

当然,上述的logistic模型同样可以推广到多分类问题。设Y的取值为{1,2,3,...K},那么回归模型即为:

技术图片

梯度下降法

梯度下降法可以解决上面对于参数w的优化问题。

梯度下降法是一种迭代算法,通过选取适当的初始值,不断迭代,对参数值不断更新,进行目标函数的极小化,直到收敛。由于负梯度方向是函数值减小最快的方向,所以在迭代的每一步,我们向负梯度方向更新参数值,从而减小函数值。

梯度算法的迭代公式为:

 技术图片

 

其中:

技术图片

 

同理,梯度上升法,就是向梯度方向移动,以求得函数的极大值

随机梯度下降法

在实现梯度下降法时,我们发现在进行梯度下降法的回归系数更新时需要遍历整个数据集,如果样本或者特征过多的话,这种方法计算复杂度太高。

有一种改进的方法,就是一次我们只随机用一个样本点来更新回归系数,那么该方法就叫做随机梯度下降法。

这两种算法在下面的代码部分都有实现,读者可以自行参考。

 

求解回归系数w的方法除了上面提到的梯度下降法,还有拟牛顿法,想要详细了解的同学可以见《统计学习方法》附录B。

 

上面一部分,我们系统地从分类函数讲到怎么确定优化目标函数,再到怎么解优化目标函数。

至此我们就完成了Logistic回归原理部分的学习。下面是代码部分。

 

代码实现

1.回归梯度上升优化算法

程序清单:

 1 from numpy import *
 2 # 打开文本文件函数
 3 def loadDataSet():
 4     dataMat=[];labelMat=[]
 5     # 打开文本文件
 6     fr=open(testSet.txt)
 7     # 逐行读取
 8     for line in fr.readlines():
 9         # 对文本进行处理,处理为一个列表
10         lineArr=line.strip().split()
11         # 加到dataMat中,并把第一个值设为1.0
12         dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])
13         # 求得类别标签
14         labelMat.append(int(lineArr[2]))
15     print(len(labelMat))
16     return dataMat,labelMat
17 
18 # 利用sigmoid函数进行计算
19 def sigmoid(inX):
20     return 1.0/(1+exp(-inX))
21 
22 # 梯度上升算法
23 # dataMatIn里存放的是特征,但是第一列都为1.0,实际上为100*3的矩阵
24 # classLabels里存放的是类别标签,1*100的行向量
25     
26 def gradAscent(dataMatIn,classLabels):
27     # 转换为Numpy矩阵类型
28     dataMatrix=mat(dataMatIn)
29     # 转化为矩阵类型并求转置
30     labelMat=mat(classLabels).transpose()
31     # 求得矩阵大小
32     m,n=shape(dataMatrix)
33     # alpha是目标移动的步长
34     alpha=0.01
35     # 设置迭代次数
36     maxCycle=500
37     # 权重初始化为1
38     weights=ones((n,1))
39     for k in range(maxCycle):
40         # 注意,这里h是一个m*1的列向量
41         h=sigmoid(dataMatrix*weights)
42         # 求得误差
43         error=(labelMat-h)
44         # 更新权重
45         weights = weights+alpha*dataMatrix.transpose()*error
46     return weights

2.画出数据集最佳拟合直线

程序清单:

 1 # 作图
 2 def plotBestFit():
 3     import matplotlib.pyplot as plt
 4     dataMat,labelMat=loadDataSet()
 5     weights = gradAscent(dataMat,labelMat)
 6     dataArr=array(dataMat)
 7     # 得到数据的样本数
 8     n=shape(dataArr)[0]
 9     xcord1=[];ycord1=[]
10     xcord2=[];ycord2=[]
11     # 将样本分成两类,放到列表中
12     for i in range(n):
13         if int(labelMat[i])==1:
14             xcord1.append(dataArr[i,1]);ycord1.append(dataArr[i,2])
15         else:
16             xcord2.append(dataArr[i,1]);ycord2.append(dataArr[i,2])
17     fig=plt.figure()
18     ax=fig.add_subplot(111)
19     # 两个种类用不同的颜色表示
20     ax.scatter(xcord1,ycord1,s=30,c=red,marker=s)
21     ax.scatter(xcord2,ycord2,s=30,c=green)
22     # 标注X轴的范围与步长
23     x=arange(-4.0,4.0,0.1)
24     #x = mat(x)
25     # 表示出分界线的方程
26     y=(-weights[0]-weights[1]*x)/weights[2]
27     print(y.shape)
28     ax.plot(x,y.transpose())
29     # 坐标名称
30     plt.xlabel(X1);plt.ylabel(X2)
31     plt.show()
32     
33 plotBestFit()

3.随机梯度上升算法

程序清单:

def stocGradAscent(dataMatrix,classLabels):
    #为便于计算,转为Numpy数组
    dataMat=array(dataMatrix)
    获取数据集的行数和列数
    m,n=shape(dataMatrix)
    #初始化权值向量各个参数为1.0
    weights=ones(n)
    #设置步长为0.01
    alpha=0.01
    #循环m次,每次选取数据集一个样本更新参数
    for i in range(m):
        #计算当前样本的sigmoid函数值
        h=sigmoid(dataMatrix[i]+weights)
        #计算当前样本的残差(代替梯度)
        error=(classLabels[i]-h)
        #更新权值参数
        weights=weights+alpha*error*dataMatrix[i]
    return weights

 


4.改进的随机梯度上升算法

我们知道,评判一个优化算法的优劣的可靠方法是看其是否收敛,也就是说参数的值是否达到稳定值。此外,当参数值接近稳定时,仍然可能会出现一些小的周期性的波动。这种情况发生的原因是样本集中存在一些不能正确分类的样本点(数据集并非线性可分),所以这些点在每次迭代时会引发系数的剧烈改变,造成周期性的波动。显然我们希望算法能够避免来回波动,从而收敛到某个值,并且收敛速度也要足够快。

程序清单:

def stocGradAscent1(dataMatrix,classLabels,numIter=150):
    #将数据集列表转为Numpy数组
    #dataMat=array(dataMatrix)
    #获取数据集的行数和列数
    m,n=shape(dataMat)
    #初始化权值参数向量每个维度均为1
    weights=ones(n)
    #循环每次迭代次数
    for j in range(numIter):
        #获取数据集行下标列表
        dataIndex = list(range(m))
        #print(dataIndex)
        #遍历行列表
        for i in range(m):
            #每次更新参数时设置动态的步长,且为保证多次迭代后对新数据仍然具有一定影响
            #添加了固定步长0.1
            alpha=4/(1.0+j+i)+0.1
            #随机获取样本
            randomIndex=int(random.uniform(0,len(dataIndex)))
            #计算当前sigmoid函数值
            h=sigmoid(sum(dataMat[randomIndex]*weights))
            #计算权值更新
            #***********************************************
            error=classLabels[randomIndex]-h
            weights=array(weights)+alpha*error*array(dataMat[randomIndex])
            #***********************************************
            #选取该样本后,将该样本下标删除,确保每次迭代时只使用一次
            del (dataIndex[randomIndex])
    return weights 
stocGradAscent1(dataMat,labelMat,numIter=150)

5.用Logistic回归进行分类

程序清单:

#sigmoid()分类函数
def classifyVector(inX,weights):
    prob=sigmoid(sum(inX*weights))
    # 值如果大于0.5,归为1.0类
    if(prob>0.5):return 1.0
    else:return 0.0


def colicTest():
    # 打开训练集合
    frTrain=open(rC:UsersAdministratorDesktopMliA
                MLiA_SourceCodemachinelearninginactionCh05                  horseColicTraining.txt)
    # 打开测试集合
    frTest=open(rC:UsersAdministratorDesktopMliA
                MLiA_SourceCodemachinelearninginactionCh05horseColicTest.txt)
    # 初始化训练集和标签的列表
    trainingSet=[]
    trainingLabels=[]
    for line in frTrain.readlines():
        # 对训练集的数据格式化处理
        currLine=line.strip().split(	)
        lineArr=[]
        for i in range(21):
            # 将每一行的特征数据放到lineArr中
            lineArr.append(float(currLine[i]))
        # 再将lineArr作为列表放到trainingSet中
        trainingSet.append(lineArr)
        # 将标签放到trainingLabels中
        trainingLabels.append(float(currLine[21]))
    # 得到训练集的权重
    trainWeights=stocGraAscent1(array(trainingSet),trainingLabels,500)
    errorCount=0;numTestVec=0.0
    # 对测试集进行测试
    for line in frTest.readlines():
        # 计算测试集的个数
        numTestVec+=1.0
        # 对测试数据进行格式化处理
        currLine=line.strip().split(	)
        lineArr=[]
        for i in range(21):
            lineArr.append(float(currLine[i]))
        # 如果学习出来的结果和真实结果不一致,则错误数加一
        if(int(classifyVector(array(lineArr),trainWeights))!=int(currLine[21])):
            errorCount+=1
        # 计算错误率
        errorRate=(float(errorCount)/numTestVec)
        print(the error rate of this test is %f%errorRate)
        return errorRate
# 调用colicTest()函数多次,计算错误率的平均值
def multiTest():
    numTests=10
    errorSum=0.0
    for k in range(numTests):
        errorSum+=colicTest()
    print(after %d iterations the arrange error rate is:%f
            % (numTests,errorSum/float(numTests)))

 


吴恩达深度学习笔记(代码片段)

...础知识1.数据类型2.学习次序3.常用符号4.二分分类(logistics)5.梯度下降法6.导数和流程图(略)7.logistics中的梯度下降7.向量化的必要性8.向量化的logistics总结前言学习的第一天一、监督学习常见应用输入输出应用... 查看详情

吴恩达深度学习笔记(代码片段)

...础知识1.数据类型2.学习次序3.常用符号4.二分分类(logistics)5.梯度下降法6.导数和流程图(略)7.logistics中的梯度下降7.向量化的必要性8.向量化的logistics总结前言学习的第一天一、监督学习常见应用输入输出应用... 查看详情

机器学习logistic分类回归算法(二元分类&多元分类)(代码片段)

...创作者。该文章收录专栏✨—机器学习—✨【机器学习】logistics分类一、线性回归能用于分类吗?二、二元分类2.1假设函数2.1.1案例一2.1.2例子二2.2拟合logistic回归参数θi\\theta_iθi​三、 查看详情

《机器学习实战》-机器学习基础(代码片段)

目录机器学习基础什么是机器学习机器学习应用场景海量数据机器学习的重要性机器学习的基本术语监督学习和非监督学习监督学习:supervisedlearning非监督学习:unsupervisedlearning机器学习工具介绍Python非PythonNumPy函数库基础测试Nu... 查看详情

logistics_day05:kudu入门使用(代码片段)

stypora-copy-images-to:imgtypora-root-url:./Logistics_Day05:Kudu入门使用01-[复习]-上次课程内容回顾主要讲解:业务服务器部署数据库及数据实时采集、大数据服务器如何使用CM部署CDH架构。1)、物流系统Logistics:数据存储Oracle数据库中,使... 查看详情

note_logistics_day06(代码片段)

stypora-copy-images-to:imgtypora-root-url:./Logistics_Day04:Kudu入门使用01-[复习]-上次课程内容回顾​主要讲解:Kudu存储引擎,类似HBase数据库,属于HBase和HDFS折中产品,既能够随机数据读写,又支持批量数据加载分析。1、物流项目ETL流程 ... 查看详情

logistics_day15:clickhouse存储引擎(代码片段)

Logistics_Day15:ClickHouse存储引擎01-[复习]-上次课程内容回顾主要讲解ClickHouse数据库(属于实时OLAP分析数据库),基本入门使用。1)、OLAP分析需求以及技术选项对比Hive(MapReduce、Tez、Spark)、Presto、Impala、SparkSQLKylin(Hive,预计... 查看详情

pythonipython:机器学习片段(代码片段)

查看详情

logistics_day17:自定义外部数据源clickhouse(代码片段)

Logistics_Day17:自定义外部数据源ClickHouse01-[复习]-上次课程内容回顾上次课程2个方面内容:ClickHouseJDBCClientAPI编写Java代码,使用JDBC方式查询ClickHouse表数据,类似MySQLJDBC查询获取连接Connection、创建PreparedStatement和结果数据集ResultSe... 查看详情

机器学习基础教程笔记---机器学习概述(代码片段)

目录机器学习概述1.1人工智能概述1.1.1机器学习与人工智能、深度学习1.1.2机器学习、深度学习能做些什么1.1.3人工智能阶段课程安排1.2什么是机器学习1.2.1定义1.2.2解释1.2.3数据集构成1.3机器学习算法分类学习目标分析1.2中的例子... 查看详情

markdown机器学习(代码片段)

查看详情

text机器学习(代码片段)

查看详情

python机器学习有用的代码片段(代码片段)

查看详情

维护订单交货单各种文本标准功能(代码片段)

"NewlongtextCONCATENATEis_logistics_info-dymb"打印模板编码is_logistics_info-dymb_t"打印模板名称is_logistics_info-sjmc"商家名称is_logistics_info-cnckmc"菜鸟仓库名称is_logistics_info-shdz"收货地址(省-市-区-县-详细地址)is_logistics_info- 查看详情

python机器学习笔记(代码片段)

Python机器学习笔记一机器学习概述1.1人工智能概述1.1.1机器学习与人工智能、深度学习关系机器学习和人工智能、深度学习的关系机器学习是人工智能的一个实现途径深度学习是机器学习的一个方法发展而来达特茅斯会议(Da... 查看详情

python机器学习笔记(代码片段)

Python机器学习笔记一机器学习概述1.1人工智能概述1.1.1机器学习与人工智能、深度学习关系机器学习和人工智能、深度学习的关系机器学习是人工智能的一个实现途径深度学习是机器学习的一个方法发展而来达特茅斯会议(Da... 查看详情

机器学习介绍(代码片段)

机器学习Sitara机器学习工具包通过在所有Sitara设备(仅Arm、Arm+专用硬件加速器)上启用机器学习推理,将机器学习推向了最前沿。它是作为TI的处理器SDKLinux的一部分提供的,可以免费下载和使用。今天的Sitara... 查看详情

机器学习介绍(代码片段)

机器学习Sitara机器学习工具包通过在所有Sitara设备(仅Arm、Arm+专用硬件加速器)上启用机器学习推理,将机器学习推向了最前沿。它是作为TI的处理器SDKLinux的一部分提供的,可以免费下载和使用。今天的Sitara... 查看详情