机器学习——logistic回归

目录

一、logistic回归的概念

1.线性模型与回归

 2.Logistic回归:

3.Sigmoid函数

4.logistic的优缺点:

二、Logistic实现

1.logistic实现一般过程:

2.收集读取数据集并绘制图像

3.用Sigmoid函数寻找边界和参数

4.利用梯度下降算法优化

5.分析数据:画出决策边界

三、课外实验:从疝气病症状预测病马的死亡率

1.准备数据:处理数据中的缺失值

 2.利用梯度上升进行分类

 3.小结


一、logistic回归的概念

1.线性模型与回归

线性模型一般模式:

回归: 

    现有一些数据点,我们用 一条直线对这些点进行拟合,该线称为最佳拟合直线,这个拟合过程就称作回归。

 2.Logistic回归:

    Logistic回归(logistic regression)是统计学习中的经典分类方法,属于对数线性模型,所以也被称为对数几率回归。这里要注意,虽然带有回归的字眼,但是该模型是一种分类算法,Logistic回归是一种线性分类器,针对的是线性可分问题。利用logistic回归进行分类的主要思想是:根据现有的数据对分类边界线建立回归公式,以此进行分类。
 

    利用Logistic 回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的 “回归”一词源于最佳拟合,表示要找到最佳拟合参数集。 训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化算法。

    Logistic回归来做分类问题,我们想要的函数应该是,能接受所有的输入然后预测出类别。例如,在两个类的情况下,上述函数输出0或1。例如海维塞德阶跃函数 (Heaviside step function),也称为单位阶跃函数。

    单位跃函数的问题在于: 该函数在跳跃点上从0瞬间跳跃到1(不连续、不可微),这个瞬间跳跃过程有时很难处理。

3.Sigmoid函数

    但是在数学上,Sigmoid函数可以可以解决这个问题。Sigmoid函数具体的计算公式如下:

    下图给出了Sigmoid函数在不同坐标尺度下的两条曲线图。当x为0时,Sigmoid函数值为0.5。 随着x的增大,对应的Sigmoid值将逼近于1;而随着x的减小,Sigmoid值将逼近于0。如果横坐标 刻度足够大,Sigmoid函数看起来很像一个阶跃函数。

    所以,为了实现Logistic回归分类,我们可以在每个特征上都乘以一个回归系数,然后把 所有的结果值相加,将这个总和代入Sigmoid函数中,进而得到一个范围在0~1之间的数值。任何大于0.5的数据被分入1类,小于0.5即被归入0类。所以,Logistic回归也可以被看成是一种概率估计。

4.logistic的优缺点:

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

二、Logistic实现

1.logistic实现一般过程:

收集数据:任何方式 
准备数据:由于要计算距离,因此要求数据都是数值型的,另外结构化数据格式最佳。 
分析数据:采用任一方是对数据进行分析 
训练算法:大部分时间将用于训练,训练的目的为了找到最佳的分类回归系数 
测试算法:一旦训练步骤完成,分类将会很快 
使用算法:首先,我们需要输入一些数据,并将其转化成对应的结构化数值;接着基于训练好的回归系数就可以对这些数值进行简单的回归计算,判定它们属于哪一类别;在这之后,我们就可以在输出的类别上做一些其他的分析工作。

2.收集读取数据集并绘制图像

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
 
path='D:\machine learning\logdata1.txt'

data=pd.read_csv(path,names=['Exam1','Exam2','Accepted'])
data.head()
 
#数据可视化
fig,ax=plt.subplots()
ax.scatter(data[data['Accepted'] == 0]['Exam1'], data[data['Accepted'] == 0]['Exam2'], c='r', marker='x', label='y=0')
ax.scatter(data[data['Accepted'] == 1]['Exam1'], data[data['Accepted'] == 1]['Exam2'], c='b', marker='o', label='y=1')
ax.legend()
ax.set_xlabel('exam1')
ax.set_ylabel('exam2')
plt.show()
 
def get_Xy(data):
    # 在第一列插入1
    data.insert(0, 'ones', 1)
    # 取除最后一列以外的列
    X_ = data.iloc[:, 0:-1]
    # 取特征值
    X = X_.values
    # 取最后一列
    y_ = data.iloc[:, -1]
    y = y_.values.reshape(len(y_), 1)
    return X, y
 
X,y=get_Xy(data)

 

3.用Sigmoid函数寻找边界和参数

#损失函数
def sigmoid(z):
    return 1/(1+np.exp(-z))
 
def costFunction(X,y,theta):
    A=sigmoid(X@theta)
    
    first=y * np.log(A)
    second =(1-y)*np.log(1-A)
    #样本的累加
    return -np.sum(first+second)/len(X)
 
theta=np.zeros((3,1))
theta.shape

#输出损失函数
cost_init=costFunction(X,y,theta)
print(cost_init)

 

4.利用梯度下降算法优化

#梯度下降
def gradientDescent(X, y, theta, alpha, iters):
    m = len(X)
    costs = []
    for i in range(iters):
        A = sigmoid(X @ theta)
        # X.T:X的转置
        theta = theta - (alpha / m) * X.T @ (A - y)
        cost = costFunction(X, y, theta)
        costs.append(cost)
        if i % 1000 == 0:
             print(cost)
    return costs, theta
alpha=0.004
iters=200000
costs, theta_final = gradientDescent(X, y, theta, alpha, iters)
print(costs)
 
def predict(X, theta):
    prob = sigmoid(X @ theta)
    return [1 if x >= 0.5 else 0 for x in prob]
 
 
print(predict(X, theta_final))
 
y_ = np.array(predict(X, theta_final))
print(y_)
y_pre = y_.reshape(len(y_), 1)

 

5.分析数据:画出决策边界

# 求取均值
acc = np.mean(y_pre == y)
print(acc)
print('-----------------------6.决策边界-------------------------------------')
# 决策边界就是Xθ=0的时候
coef1 = - theta_final[0, 0] / theta_final[2, 0]
coef2 = - theta_final[1, 0] / theta_final[2, 0]
x = np.linspace(20, 100, 100)
f = coef1 + coef2 * x
fig, ax = plt.subplots()
ax.scatter(data[data['Accepted'] == 0]['Exam1'], data[data['Accepted'] == 0]['Exam2'], c='r', marker='x', label='y=0')
ax.scatter(data[data['Accepted'] == 1]['Exam1'], data[data['Accepted'] == 1]['Exam2'], c='b', marker='o', label='y=1')
ax.legend()
ax.set_xlabel('exam1')
ax.set_ylabel('exam2')
ax.plot(x, f, c='g')
plt.show()

    不知道bug在哪,没有直线,和网上别人的比对了一下不知道代码错在哪,也可能是我没太看明白。

三、课外实验:从疝气病症状预测病马的死亡率

1.准备数据:处理数据中的缺失值

病马数据存放在文件夹中

 2.利用梯度上升进行分类

# 分类函数
def classifyVector(inX, weights):
    prob = sigmoid(sum(inX * weights))   # 计算sigmoid值
    if prob > 0.5:                       # 概率大于0.5,返回分类结果1.0
        return 1.0
    else:                                # 概率小于等于0.5,返回分类结果0.0
        return 0.0

ef colicTest1():
    # 读取测试集和训练集,并对数据进行格式化处理
    frTrain = open('D:\machine learning\horseColicTraining.txt')      # 读取训练集文件
    frTest = open('D:\machine learning\horseColicTest.txt')           # 读取测试集文件
    trainingSet = []                              # 创建数据列表
    trainingLabels = []                           # 创建标签列表
    for line in frTrain.readlines():              # 按行读取
        currLine = line.strip().split('\t')       # 分隔
        lineArr = []
        for i in range(21):
            lineArr.append(float(currLine[i]))
        trainingSet.append(lineArr)
        trainingLabels.append(float(currLine[21]))
 
    # 使用改进的随即上升梯度训练
    trainWeights =  gradAscent(array(trainingSet), trainingLabels)
    errorCount = 0                                # 错误数
    numTestVec = 0.0
    for line in frTest.readlines():               # 遍历每行数据
        numTestVec += 1.0                         # 测试集数量加1
        currLine = line.strip().split('\t')
        lineArr = []
        for i in range(21):
            lineArr.append(float(currLine[i]))
        if int(classifyVector(array(lineArr), trainWeights)) != int(currLine[21]):
            errorCount += 1                        # 预测结果与真值不一致,错误数加1
    errorRate = (float(errorCount) / numTestVec)   # 计算错误率
    print("测试的错误率为: %f" % errorRate)
    return errorRate

# 求结果的平均值
def multiTest():
    numTests = 10
    errorSum = 0.0
    for k in range(numTests):
        errorSum += colicTest1()
    print("在 %d 迭代之后, 平均错误率为: %f" % (numTests, errorSum / float(numTests)))

 3.小结

    本次实验过程,遇到了好几个小问题,比如绘图的时候,拟合曲线不显示的问题,没有注意到x,y的维度问题,导致卡在绘图上半天。

    而logistic回归的目的是寻找一个非线性函数Sigmoid的最佳拟合参数,求解过程可以由最优化算法完成。
 

参考资料:

[1]: 《机器学习实战》Peter Harrington 著

[2]:实验参考

 

 

 


 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值