• 逻辑回归---梯度下降法


    前言:

    线性关系主要解决一类事物的特点,而逻辑回归注重于解决分类问题,试图寻找多种事物的边界所在,因此掌握逻辑回归是十分必要的!

    正文:

    #老朋友
    import matplotlib.pyplot as plt
    import numpy as np
    #做模型评估的,正确率,召回率等
    from sklearn.metrics import classification_report
    #数据是否需要标准化,可以做也可以不做
    from sklearn import preprocessing
    #False代表不做,True代表做
    #做标准化会使数据变得更加准确更加平滑,推荐做
    scale = True
    
    #载入数据
    data = np.genfromtxt("LR-testSet.csv",delimiter = ",")
    #切分数据,从第1列到最后一列但不包括最后一列
    x_data = data[:,:-1]
    #最后一列
    y_data = data[:,-1]
    #定义画图函数
    def plot():
        x0 = []
        x1 = []
        y0 = []
        y1 = []
        #切分不同类别的数据
        #有多少数据,循环多少次
        for i in range(len(x_data)):
            #如果数据属于y=0这个类别
            if y_data[i] == 0:
                #把每行第一个数据送给x0
                x0.append(x_data[i,0])
                #把每行第二个数据送给y0
                y0.append(x_data[i,1])
            #如果这个数据属于y=1这个类别
            else:
                #把每行第一个数据送给x0
                x1.append(x_data[i,0])
                #把每行第二个数据送给y0
                y1.append(x_data[i,1])
        #开始画图
        #把属于0的点画成点
        scatter0 = plt.scatter(x0,y0,c = 'b',marker = 'o')
        #把属于1的点画成叉
        scatter1 = plt.scatter(x1,y1,c = 'r',marker = 'x')
        #画图例
        #handles表示你要画图例的数据,labels是图例的名称,loc=‘best’表示自动适配
        plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best')
    plot()
    plt.show()
    

    执行效果如下:
    在这里插入图片描述

    #数据处理,添加偏置项
    x_data = data[:,:-1]
    #这里注意要给y_data增加维度,让他也变成二维数据来适配函数mat
    y_data = data[:,-1,np.newaxis]
    
    print(np.mat(x_data).shape)
    print(np.mat(y_data).shape)
    #给样本添加偏置项
    #concatenate函数可以改变axis的值来进行数据拼接
    #axis的值为0时,不改变列数,将数据向下拼接
    #axis的值为1时,不改变行数,将数据向右拼接
    X_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
    print(X_data.shape)
    

    打印出来的data格式如下:
    在这里插入图片描述

    #预测函数
    def sigmoid(x):
        return 1.0/(1+np.exp(-x))
     
    #代价函数
    def cost(xMat,yMat,ws):
        #函数multiply是按位相乘
        left = np.multiply(yMat,np.log(sigmoid(xMat*ws)))
        right = np.multiply(1-yMat,np.log(1-sigmoid(xMat*ws)))
        #返回公式
        return np.sum(left + right) / -(len(xMat))
        
     def gradAscent(xArr,yArr):
        if scale == True:
            xArr = preprocessing.scale(xArr)
        #将数据变成矩阵形式
        xMat = np.mat(xArr)
        yMat = np.mat(yArr)
        #定义学习率
        lr = 0.001
        #定义循环次数
        epochs = 10000
        #将代价函数的值定义在一个列表
        costList = []
        #计算数据的行列数
        #行代表数据个数,列代表权值个数
        m,n = np.shape(xMat)
        #初始化权值
        ws = np.mat(np.ones((n,1)))
        
        for i in range(epochs+1):
            #xMat和weights矩阵相乘
            h = sigmoid(xMat*ws)
            #计算误差
            #给xMat的矩阵进行转置,才能进行正常的矩阵乘法
            #h-yMat的格式是100*1,xMat.T的矩阵的格式是3*100
            ws_grad = xMat.T*(h-yMat)/m
            #更新ws的值
            ws = ws-lr*ws_grad
            #循环每进行50次,就将更新好的代价函数值代入
            if i%50 == 0:
                costList.append(cost(xMat,yMat,ws))
        return ws,costList
    
    #训练模型,得到权值和cost值的变换
    #注意这里的X_data是大写字母
    ws,costList = gradAscent(X_data,y_data)
    print(ws)
    

    训练后的权值如下:
    在这里插入图片描述

    #不进行数据标准化时
    if scale == False:
        #画图决策边界
        plot()
        x_test = [[-4],[3]]
        y_test = (-ws[0]-x_test*ws[1])/ws[2]
        plt.plot(x_test,y_test,'k')
        plt.show()
    
    #画图 loss值的变化
    #定义图像范围
    x = np.linspace(0,10000,201)
    #给图像起名贴标签
    plt.plot(x,costList,c = 'r')
    plt.title('Train')
    plt.xlabel('epochs')
    plt.ylabel('Cost')
    plt.show()
    

    图片展示如下:
    在这里插入图片描述

    #预测
    def predict(x_data,ws):
        if scale == True:
            x_data = preprocessing.scale(x_data)
        xMat = np.mat(x_data)
        ws = np.mat(ws)
        return [1 if x>=0.5 else 0 for x in sigmoid(xMat*ws)]
    predictions = predict(X_data,ws)
    #classification_report计算准确率,召回率
    print(classification_report(y_data,predictions))
    

    三种率运算如下:
    在这里插入图片描述

    总结:

    可以看出工作量很高,检查很频繁,容易报错,尤其要求对参数格式的转化,期待sklearn库能使工作变得轻松愉悦!

  • 相关阅读:
    无向连通图求割边+缩点+LCA
    poj 1417(并查集+简单dp)
    java系统时间的调用和格式转换
    Delphi程序的主题(Theme)设置
    分块读取Blob字段数据(Oracle)
    Delphi xe5 编译报environment.proj错误的解决
    DataSnap服务器从xe2升级到xe5报错的处理
    分块读取Blob字段数据(MSSQL)
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
  • 原文地址:https://www.cnblogs.com/lqk0216/p/12360186.html
Copyright © 2020-2023  润新知