Chap 2 Logistic Regression

  • 预习
  • 决策边界
  • 预测函数
  • 代价函数
  • 模型的求解
  • 梯度下降法
  • sklearn


预习

  • 逻辑回归用于分类问题
  • 决策边界
  • 逻辑回归的预测函数

关于sigmoid函数

Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。在信息科学中,由于其单增以及反函数单增等性质,Sigmoid函数常被用作神经网络的激活函数,将变量映射到0,1之间。

sigmoid函数也叫Logistic函数,用于隐层神经元输出,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,可以用来做二分类。

Logistic生长模型 python_逻辑回归

Logistic生长模型 python_逻辑回归_02

值域Logistic生长模型 python_代价函数_03

Logistic生长模型 python_Logistic生长模型 python_04

  • 逻辑回归的代价函数(求min)

分类模型的性能评估

  • 混淆矩阵
  • 准确率、正确率、召回率
  • F-score
  • ROC&AUC

决策边界

Logistic生长模型 python_代价函数_05
Logistic生长模型 python_逻辑回归_06

线性可分的
非线性可分的:引入高次项

建模:找出决策边界的系数Logistic生长模型 python_逻辑回归_07
模型Logistic生长模型 python_Logistic生长模型 python_08,样本Logistic生长模型 python_机器学习_09,真实值Logistic生长模型 python_python_10
Logistic生长模型 python_逻辑回归_11
找出一组Logistic生长模型 python_逻辑回归_07使得n维向量Logistic生长模型 python_python_13降维成一维Logistic生长模型 python_机器学习_09
Logistic生长模型 python_python_15为一类,Logistic生长模型 python_python_16为另一类。

预测函数

Logistic生长模型 python_python_17,其中Logistic生长模型 python_Logistic生长模型 python_18函数是sigmoid函数
Logistic生长模型 python_python_19

Logistic生长模型 python_代价函数_20

表示分类为Logistic生长模型 python_Logistic生长模型 python_21的概率

Logistic生长模型 python_python_22,归为1类的概率大于0.5

Logistic生长模型 python_Logistic生长模型 python_23

代价函数

Logistic生长模型 python_机器学习_24


Logistic生长模型 python_机器学习_25


Logistic生长模型 python_代价函数_26

Logistic生长模型 python_代价函数_27

代价函数形式的推导:

Logistic生长模型 python_python_28

模型的求解

梯度下降法

import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report #用于评估模型的性能
from sklearn import preprocessing #用于数据标准化预处理
scale = False  # 数据是否需要标准化

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

def plot():
    x1_0 = []
    x2_0 = []
    x1_1 = []
    x2_1 = []
    # 切分不同类别的数据
    for i in range(len(x_data)):
        if y_data[i]==0:
            x1_0.append(x_data[i,0])
            x2_0.append(x_data[i,1])
        else:
            x1_1.append(x_data[i,0])
            x2_1.append(x_data[i,1])
    # 画图
    scatter0 = plt.scatter(x1_0, x2_0, c='b', marker='o')
    scatter1 = plt.scatter(x1_1, x2_1, c='r', marker='x')
    #画图例
    plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best') #loc表示图例的位置
    
plot()
plt.show()

# 数据处理,添加偏置项
print(x_data.shape)
print(y_data.shape)
print(np.mat(x_data).shape)
print(np.mat(y_data).shape)
# 给样本添加偏置项
X_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
print(X_data)
print(X_data.shape)
y_data = data[:,-1,np.newaxis]
print(y_data.shape)

def sigmoid(x):
    return 1.0/(1+np.exp(-x))
def cost(xMat, yMat, ws):   #计算代价
    left = np.multiply(yMat, np.log(sigmoid(xMat*ws))) # multiply表示矩阵按对应位置相乘
    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):   #迭代10001次,最后一次i=10000       
        # xMat和weights矩阵相乘
        h = sigmoid(xMat*ws)    #xMat:(100,3); ws:(3,1); h:(100,1)
        # 计算误差
        ws_grad = xMat.T*(h - yMat)/m  # xMat.T: (3,100) ;  h - yMat:(100,1);  ws_grad:(3,1)
        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)

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')   #k:black
    plt.show()

# 画图 loss值的变化
x = np.linspace(0,10000,201)
print(x)
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)
y_data = data[:,-1]
print(y_data)
print(predictions)
print(classification_report(y_data, predictions))

sklearn

import numpy as np
from sklearn.metrics import classification_report
from sklearn import preprocessing
from sklearn import linear_model
# 数据是否需要标准化
scale = False

# 载入数据
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()

logistic = linear_model.LogisticRegression()
logistic.fit(x_data, y_data)

if scale == False:
    # 画图决策边界
    plot()
    x_test = np.array([[-4],[3]])
    print(logistic.coef_)
    y_test = (-logistic.intercept_ - x_test*logistic.coef_[0][0])/logistic.coef_[0][1]
    plt.plot(x_test, y_test, 'k')
    plt.show()

predictions = logistic.predict(x_data)
print(classification_report(y_data, predictions))