首页 > 其他分享 >机器学习--Logistic 回归*

机器学习--Logistic 回归*

时间:2022-12-08 09:22:55浏览次数:37  
标签:inputs 机器 -- labels weights Logistic np data def

机器学习--Logistic 回归

Logistic回归简介

Logistic回归是一种十分常见的分类模型,是的严格来说这是一个分类模型,之所以叫做回归也是由于历史原因。不同于线性回归中对于参数的推导,我们在这里运用的方式不再是最小二乘法,而是极大似然估计。

优点:计算代价不高,易于理解和实现。 缺点:容易欠拟合,分类精度可能不高。 适用数据类型:数值型和标称型数据。

本章将以以下几个方面入手

算法原理

基于最优化方法的最佳回归系数确定

Sigmoid函数的输入记为z,由下面公式得出:

MommyTalk1670459796718

接下来,我们将学习优化算法,使得分类器更加准确

梯度上升法

梯度上升法基于的思想是:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。如果梯度记为▽,则函数f(x,y)的梯度由下式表示:

20180728112918619

v2-5cb3137cc2353debb7d695f3b062bee1_r

上图梯度上升算法沿梯度方向移动了一步。可以看到,梯度算子总是指向函数值增长最快的方向。这里所说的是移动方向,而未提到移动量的大小。该量值称为步长,记做 α 。用向量来表示的话,梯度上升算法的迭代公式如下:

MommyTalk1670460592613

准备数据

此次数据集来自《机器学习实战》,如下

-0.017612   14.053064   0  
-1.395634   4.662541    1  
-0.752157   6.538620 0  
-1.322371   7.152853    0  
0.423363 11.054677   0  
0.406704    7.067335    1  
0.667394    12.741452   0  
-2.460150   6.866805    1  
0.569411    9.548755    0  
-0.026632   10.427743   0  
0.850433    6.920334    1  
1.347183    13.175500   0  
1.176813    3.167020    1  
-1.781871   9.097953    0  
-0.566606   5.749003    1  
0.931635    1.589505    1  
-0.024205   6.151823    1  
-0.036453   2.690988    1  
-0.196949   0.444165    1  
1.014459    5.754399    1  
1.985298    3.230619    1  
-1.693453   -0.557540   1  
-0.576525   11.778922   0  
-0.346811   -1.678730   1  
-2.124484   2.672471    1  
1.217916    9.597015    0  
-0.733928   9.098687    0  
-3.642001   -1.618087   1  
0.315985    3.523953    1  
1.416614    9.619232    0  
-0.386323   3.989286    1  
0.556921    8.294984    1  
1.224863    11.587360   0  
-1.347803   -2.406051   1  
1.196604    4.951851    1  
0.275221    9.543647    0  
0.470575    9.332488    0  
-1.889567   9.542662    0  
-1.527893   12.150579   0  
-1.185247   11.309318   0  
-0.445678   3.297303    1  
1.042222    6.105155    1  
-0.618787   10.320986   0  
1.152083    0.548467    1  
0.828534    2.676045    1  
-1.237728   10.549033   0  
-0.683565   -2.166125   1  
0.229456    5.921938    1  
-0.959885   11.555336   0  
0.492911    10.993324   0  
0.184992    8.721488    0  
-0.355715   10.325976   0  
-0.397822   8.058397    0  
0.824839    13.730343   0  
1.507278    5.027866    1  
0.099671    6.835839    1  
-0.344008   10.717485   0  
1.785928    7.718645    1  
-0.918801   11.560217   0  
-0.364009   4.747300    1  
-0.841722   4.119083    1  
0.490426    1.960539    1  
-0.007194   9.075792    0  
0.356107    12.447863   0  
0.342578    12.281162   0  
-0.810823   -1.466018   1  
2.530777    6.476801    1  
1.296683    11.607559   0  
0.475487    12.040035   0  
-0.783277   11.009725   0  
0.074798    11.023650   0  
-1.337472   0.468339    1  
-0.102781   13.763651   0  
-0.147324   2.874846    1  
0.518389    9.887035    0  
1.015399    7.571882    0  
-1.658086   -0.027255   1  
1.319944    2.171228    1  
2.056216    5.019981    1  
-0.851633   4.375691    1  
-1.510047   6.061992    0  
-1.076637   -3.181888   1  
1.821096    10.283990   0  
3.010150    8.401766    1  
-1.099458   1.688274    1  
-0.834872   -1.733869   1  
-0.846637   3.849075    1  
1.400102    12.628781   0  
1.752842    5.468166    1  
0.078557    0.059736    1  
0.089392    -0.715300   1  
1.825662    12.693808   0  
0.197445    9.744638    0  
0.126117    0.922311    1  
-0.679797   1.220530    1  
0.677983    2.556666    1  
0.761349    10.693862   0  
-2.168791   0.143632    1  
1.388610    9.341997    0  
0.317029    14.739025   0 

由于需要进行距离计算,因此要求数据类型为数值型,另外,结构化数据格式更佳

分析数据

采用合适的方式对数据进行分析(比如可视化、数据的简单处理等)

def dataloader(data_path):

    with open(data_path, 'r', encoding='utf-8') as f:
        #读取文件中全部内容
        data_info = f.readlines()
        # strip()移除字符串首尾特定字符
        # lambda匿名函数,此出lambda:输入x,返回x.strip().split('\t')
        # map将后者每一个输入到前者
        data_list = list(map(lambda x: x.strip().split(), data_info))
    data=np.array(data_list,dtype=np.float)
        # y=w0+w1*x1+w2*x2
        # 插入一列1.,做偏移量
    data = np.insert(data, 0, 1., axis=1)
    X = data[:,:3]
    label = data[:,3]
    return X,label

训练算法

大部分时间用于训练,训练的目的是为了找到最佳的分类回归系数

def sigmoid(x):
    return 1./(np.exp(-x)+1)

def gradAscent(inputs,labels,num_epoch,lr):
    weights=np.ones((inputs.shape[1],1))
    inputs = np.mat(inputs)  # convert to NumPy matrix  获得输入数据并将其转换为Numpy矩阵数据类型
    labels = np.mat(labels).transpose()  # convert to NumPy matrix 获得输入数据并将其转换为Numpy矩阵数据类型
    for epoch in range(num_epoch):
        pred=sigmoid(inputs*weights) #(100,3)*(3,1)
        loss=(labels-pred)
        weights=weights+lr*inputs.transpose()*loss
    return weights

模型测试

Figure_1

总结

1.本次实验验证了梯度上升算法,学到了最优化问题的一种解决方案

2.logistic回归不仅在机器学习上有广泛的运用,在深度学习里,也十分有名

3.提高性能可以有多种方法,比如增加训练次数,更换learning_rate,等等

最后全部代码如下

import numpy as np

import matplotlib.pyplot as plt
import os
#显示为小数,而不是以e为底的
np.set_printoptions(suppress=True)
def dataloader(data_path):

    with open(data_path, 'r', encoding='utf-8') as f:
        #读取文件中全部内容
        data_info = f.readlines()
        # strip()移除字符串首尾特定字符
        # lambda匿名函数,此出lambda:输入x,返回x.strip().split('\t')
        # map将后者每一个输入到前者
        data_list = list(map(lambda x: x.strip().split(), data_info))
    data=np.array(data_list,dtype=np.float)
        # y=w0+w1*x1+w2*x2
        # 插入一列1.,做偏移量
    data = np.insert(data, 0, 1., axis=1)
    X = data[:,:3]
    label = data[:,3]
    return X,label

def sigmoid(x):
    return 1./(np.exp(-x)+1)

def gradAscent(inputs,labels,num_epoch,lr):
    weights=np.ones((inputs.shape[1],1))
    inputs = np.mat(inputs)  # convert to NumPy matrix  获得输入数据并将其转换为Numpy矩阵数据类型
    labels = np.mat(labels).transpose()  # convert to NumPy matrix 获得输入数据并将其转换为Numpy矩阵数据类型
    for epoch in range(num_epoch):
        pred=sigmoid(inputs*weights) #(100,3)*(3,1)
        loss=(labels-pred)
        weights=weights+lr*inputs.transpose()*loss
    return weights


# 画出数据集和Logistic回归最佳拟合直线
def plot_best_fit(weights,inputs,labels):
    # 画点
    dataMat, labelMat = inputs,labels
    dataArr = np.array(dataMat)
    n = np.shape(dataArr)[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])
        else:
            xcord2.append(dataArr[i, 1])
            ycord2.append(dataArr[i, 2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    ax.scatter(xcord2, ycord2, s=30, c='green')

    # 画线
    x = np.arange(-3.0, 3.0, 0.1)
    # y = (0.48 * x + 4.12414) / (0.616)
    y = (-weights[0] - weights[1]*x )/ weights[2]
    y = np.array(y).squeeze()
    ax.plot(x, y)
    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.show()  # 显示
if __name__=="__main__":
    
    data_path="./file/logistic_data.txt"
    x,labels=dataloader(data_path)
    weights=gradAscent(x,labels,100,0.001)
    plot_best_fit(weights,x,labels)



标签:inputs,机器,--,labels,weights,Logistic,np,data,def
From: https://www.cnblogs.com/danchegg/p/16965172.html

相关文章