逻辑回归算法原理及其python实现

1.逻辑回归原理

1.决策边界

在这里插入图片描述
梯度下降要做的就是在使损失函数尽量小的情况下求的一组Θ

2.损失函数

这里只给出了损失函数的梯度下降求解,之所以使用对数损失,其实是一个极大似然估计的参数估计问题
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为何此处损失函数要用对数损失?
https://www.jianshu.com/p/b6bb6c035d8c

2.线性逻辑回归python实现

数据集展示

from matplotlib import pyplot as plt
import numpy as np

# 载入数据
data = np.genfromtxt("LR-testSet.csv", delimiter=",")
x_data = data[:, :-1]
y_data = data[:, -1]

def plot():
    x0 = []
    x1 = []
    y0 = []
    y1 = []
    # 切分不同类别的数据
    for i in range(len(x_data)):
        if y_data[i] == 0:
            x0.append(x_data[i, 0])
            y0.append(x_data[i, 1])
        else:
            x1.append(x_data[i, 0])
            y1.append(x_data[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()
plt.show()

在这里插入图片描述
逻辑回归

# 数据处理,添加偏置项
x_data = data[:,:-1]
y_data = data[:,-1,np.newaxis]

print(np.mat(x_data).shape) # (100, 2)
print(np.mat(y_data).shape) # (100, 1)

# 给样本添加偏置项
# x0=1 x1 x2
x_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
print(x_data.shape) # (100, 3)

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

# 损失函数
def cost(xMat, yMat, ws):
    # y*log(h(x))
    left = np.multiply(yMat, np.log(sigmoid(xMat*ws)))
    # (1-y)*log(h(x))
    right = np.multiply(1 - yMat, np.log(1 - sigmoid(xMat*ws)))
    return np.sum(left + right) / -(len(xMat))

# 梯度下降
def gradAscent(xArr, yArr):
    xArr = preprocessing.StandardScaler().fit_transform(xArr)
    xMat = np.mat(xArr)
    yMat = np.mat(yArr)
    
    lr = 0.001
    epochs = 10000
    costList = []
    # 计算数据行列数
    # 行代表数据个数,列代表权值个数
    m,n = np.shape(xMat)
    # 初始化权值 (3,1) Θ1 Θ2 Θ3
    ws = np.mat(np.ones((n,1)))
    
    for i in range(epochs+1):             
        # xMat和weights矩阵相乘 (100,3)*(3,1)=(100,1)
        h = sigmoid(xMat*ws)   
        # 计算误差   (3,100)*(100,1)=(3,1) 得到Θ1 Θ2 Θ3的梯度
        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 = gradAscent(x_data, y_data)
print(ws)
# [[ 1.        ]
#  [ 0.30816757]
#  [-1.76171512]]

# 预测
def predict(x_data, ws):
    x_data = preprocessing.StandardScaler().fit_transform(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)
print(classification_report(y_data, predictions))

#               precision    recall  f1-score   support

#          0.0       0.92      1.00      0.96        47
#          1.0       1.00      0.92      0.96        53

#     accuracy                           0.96       100
#    macro avg       0.96      0.96      0.96       100
# weighted avg       0.96      0.96      0.96       100

3.非线性逻辑回归python实现

数据集展示

import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report
from sklearn import preprocessing
from sklearn.preprocessing import PolynomialFeatures

# 载入数据
data = np.genfromtxt("LR-testSet2.txt", delimiter=",")
x_data = data[:,:-1]
y_data = data[:,-1,np.newaxis]
    
def plot():
    x0 = []
    x1 = []
    y0 = []
    y1 = []
    # 切分不同类别的数据
    for i in range(len(x_data)):
        if y_data[i]==0:
            x0.append(x_data[i,0])
            y0.append(x_data[i,1])
        else:
            x1.append(x_data[i,0])
            y1.append(x_data[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()
plt.show()

在这里插入图片描述

# 定义多项式回归,degree的值可以调节多项式的特征
poly_reg  = PolynomialFeatures(degree=3) 
# 特征处理
x_poly = poly_reg.fit_transform(x_data)
print(x_poly.shape) # (118,10)
# x0=1 x1 x2 x1^2 x1x2 x2^2 x1^3 x1^2*x2 x2^2*x1 x2^3

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

# 损失函数
def cost(xMat, yMat, ws):
    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):
    xArr = preprocessing.StandardScaler().fit_transform(xArr)
    xMat = np.mat(xArr)
    yMat = np.mat(yArr)
    
    lr = 0.03
    epochs = 50000
    costList = []
    # 计算数据列数,有几列就有几个权值
    m,n = np.shape(xMat)
    # 初始化权值 (10,1) Θ1 Θ2...Θ10
    ws = np.mat(np.ones((n,1)))
   
    for i in range(epochs+1):             
        # xMat和weights矩阵相乘 (118,10)*(10,1)=(118,1)
        h = sigmoid(xMat*ws)
        # 计算误差 (10,118)*(118,1)=(10,1) 得到Θ1 Θ2...Θ10的梯度
        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 = gradAscent(x_poly, y_data)
print(ws)
# [[ 4.16787292]
#  [ 2.72213524]
#  [ 4.55120018]
#  [-9.76109006]
#  [-5.34880198]
#  [-8.51458023]
#  [-0.55950401]
#  [-1.55418165]
#  [-0.75929829]
#  [-2.88573877]]

# 预测
def predict(x_data, ws):
    x_data = preprocessing.StandardScaler().fit_transform(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_poly, ws)
print(classification_report(y_data, predictions))

#               precision    recall  f1-score   support

#          0.0       0.89      0.83      0.86        60
#          1.0       0.84      0.90      0.87        58

#     accuracy                           0.86       118
#    macro avg       0.87      0.86      0.86       118
# weighted avg       0.87      0.86      0.86       118
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值