【机器学习算法】逻辑回归算法总结
算法基础 . 2020/01/10发布 . shanyonggang_web . 我要评论 . 56阅读

逻辑回归算法看着有回归两个字,但是其属于分类算法的一种,不过其与我们之前的线性回归算法也有一定的关联,因此才会出现回归这两个字眼,逻辑回归常用于二分类问题,如:垃圾邮件分类、预判肿瘤属于良性还是恶性、预测某人的信用是否良好等,当然其也可以用作多分类问题,由于刚开始接触学习,所以先从简单的二分类问题出发,后续多分类问题可以类比学习。

本文参考B站上的机器学习视频,本节中的代码均放置在个人github上https://github.com/ShanYonggang/Machine__Learning/tree/master/Logistic_Regression

基本公式

逻辑回归主要是使用拟合的回归线对数据进行划分,如下图所示:

Logistic回归是分类方法,它利用的是Sigmoid函数阈值在[0,1]这个特性,Logistic本质上是一个基于条件概率的判别模型(Discriminative Model)。

首先介绍sigmoid函数,如下:

逻辑回归的代价函数为:

为避免出现过拟合,在逻辑回归中也会引入正则项:

同样使用梯度下降法进行最优化求解

代码实现

首先进行数据的读取及数据的可视化展示(散点图展示):

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from sklearn.metrics import classification_report
from sklearn import preprocessing
# 加载数据
data = open(r"F:\0_个人学习\3_数据分析与挖掘\4_机器学习\1_逻辑回归\logistic.txt").readlines()
x = []
y = []
for i in data:
    x_da = i.strip().split('\t')
    x.append([float(x_da[0]),float(x_da[1])])
    y.append(int(x_da[2]))
# 其中x,y分别为特征及分类标签值

# 数据是否需要标准化
scale = False

# 绘制特征散点分布图
def plot_data(x):
    x0 = []
    x1 = []
    y0 = []
    y1 = []
    for i in range(len(x)):
        if int(y[i]) == 0:
            x0.append(x[i][0])
            y0.append(x[i][1])
        else:
            x1.append(x[i][0])
            y1.append(x[i][1])
        # 画图
    scatter0 = plt.scatter(x0, y0, c='b', marker='o')
    scatter1 = plt.scatter(x1, y1, c='r', marker='x')
    #画图例
    plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best')
    
plot_data(x)
plt.show()

结果如下:

训练模型:

# 给样本添加偏置项(即添加常数项)
x_data = np.concatenate((np.ones((100,1)),x),axis=1)
print(x_data.shape)
y_data = np.array(y).reshape(-1,1)

# 梯度下降法计算

# sigmoid函数
def sigmoid_function(z):
    return 1/(1+np.exp(-z))

# 代价函数
def cost(xMat,yMat,ws):
    left = np.multiply(yMat, np.log(sigmoid_function(xMat*ws)))
    right = np.multiply(1-yMat, np.log(1-sigmoid_function(xMat*ws)))
    return np.sum(left+right)/(-len(xMat))

# 梯度下降算法
def grandAscent(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):
        # 计算h_theta_x的值
        h = sigmoid_function(xMat*ws)
        # 计算误差值
        ws_grad = xMat.T*(h - yMat)/m
        # 权值参数迭代
        ws = ws - lr*ws_grad 
        if i % 50 == 0:
            costList.append(cost(xMat,yMat,ws))
    return ws,costList

# 训练模型,得到权值和cost值的变化
ws,costList = grandAscent(x_data, y_data)

绘制决策边界

# 画图决策边界
plot_data(x)
x_test = [[-4],[3]]
y_test = (-ws[0] - x_test*ws[1])/ws[2]
plt.plot(x_test, y_test, 'k')
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_function(xMat*ws)]

predictions = predict(x_data, ws)

print(classification_report(y_data, predictions)

sklearn实现

前面读取数据和可视化展示与自己编写的相同,仅对训练模型进行编写:

model = LogisticRegression(solver='liblinear',max_iter=5000)
model.fit(x,np.array(y))
plot_data(x)
x_test = np.array([[-4],[3]])
y_test = (-model.intercept_ - x_test*model.coef_[0][0])/model.coef_[0][1]
plt.plot(x_test, y_test, 'k')
plt.show()

结果如下:

可以对比发现,其训练的模型相比之前争取率高了很多

名词说明

使用正确率、召回率、F值来评价训练模型的好坏,对这三个概念,可通过下面进行理解:


  • 有疑问请在下方评论区留言,我会尽快回复。
  • Email私信我: 511248513@qq.com 或添加博主 微信
本文作者:shanyonggang_web
发布时间:2020年1月10日 16:05
许可协议: 署名-非商业性使用 4.0 国际许可协议
知识共享许可协议     转载请保留原文链接及作者
正在加载今日诗词....
您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面的


登录 后回复

当前暂无评论,点击登录来做第一个吃螃蟹的人吧!