回归系列之逻辑回归

逻辑回归是回归系列中一个分类模型,而且是一个二分类模型。逻辑回归模型简单但应用广泛,本文从模型介绍、适用场景以及优缺点等几个方面介绍下。

模型介绍

介绍模型之前, 先了解一个数学函数:sigmoid 函数

sigmoid函数

其函数图像如下:

sigmoid函数曲线图

sigmoid函数值在【0,1】之间, 在离x较远的地方, 函数值无限接近0或者1。逻辑回归就是利用sigmoid的这个性质构建。

利用函数sigmoid构建的逻辑回归的概率函数:


P(y=1 | x; θ) 表示分类结果为1的概率, θT * X表示参数向量与自变量X的点积, 作为sigmoid函数的输入, 得到一个【0,1】之间的值。作为分类模型, 做如下定义:

Paste_Image.png

其中y*是分类结果, 当P(y=1 | x; θ) 大于0.5, 分类结果为1;小于0.5, 分类结果为0.
通俗点说:利用sigmoid函数的特殊数学性质, 将θT * X结果映射到【0,1】的一个概率值,设定一个概率阈值(不一定非是0.5),大于这个阈值分类为1, 小于则分类为0.

模型参数

模型参数的求解方法之一:采用最大似然估计的对数形式(对数是单调函数, 求解参数的最大值,函数的对数和函数求出的最大解是一样的)构建函数, 再利用前面介绍的梯度下降来求解。

逻辑回归似然函数的对数形式

梯度下降求解对数似然函数:


得到参数的迭代公式:


模型的适用场景

用于分类场景, 尤其是因变量是二分类, 比如垃圾邮件判断(是/否垃圾邮件),是否患某种疾病(是/否), 广告是否点击等场景。

模型的优缺点

缺点:
逻辑回归需要大样本量,因为最大似然估计在低样本量的情况下不如最小二乘法有效。
防止过拟合和欠拟合,应该让模型构建的变量是显著的。
对模型中自变量多重共线性较为敏感,需要对自变量进行相关性分析,剔除线性相关的变量。

优点:
模型更简单,好理解,实现起来,特别是大规模线性分类时比较方便

模型实践

参考机器学习实践书中逻辑回归章节, 实现判断马是否得疝气病案例。
采用随机梯度下降方法求取weights, 分测试集和训练集对逻辑回归模型进行测试。
有两个值得注意的点:
1.随机梯度下降函数stocGradAscent中,weights更新会加上循环

for i in range(m)

不是很明白为啥, 加上以后计算量和批量梯度差不多。尝试去掉这个循环, 但误差变得不稳定, 有的次数误差达到0.5+。如果不去掉, 基本保持在0.3+以内。

  1. stocGradAscent函数中alpha的更新

alpha = 4 / (1.0 + i + j ) + 0.01
alpha不是一个固定的值, 而是随着数据下标i, 迭代次数j的变大, 而变小。对比测试, 发现能有效地让weights更稳定,不会再小区域内来回波动。 尚不知为何这样设置alpha的更新策略, 后续学习。

#coding=utf-8

import numpy as np
from numpy import *
#sigmoid函数定义
def sigmoid(inX):
    return 1.0/(1+exp(-inX))

#以概率0.5为阈值, 大于0.5判断类型为1,否则为0
def classifyBySigmoid(xVectors, wVectors):
    p = sigmoid(sum(xVectors*wVectors))
    if p > 0.5:
        return 1
    else:
        return 0

#读取文本数据
def readDatasetFromFile(path, labelIndex):
    data_file = open(path)
    
    dataSet = []
    dataLabel = []
    for line in data_file.readlines():
        currLine = line.strip().split('\t')
        lineArr = []
        for i in range(21):
            lineArr.append(float(currLine[i]))
        dataSet.append(lineArr)
        dataLabel.append(float(currLine[labelIndex]))
    return dataSet, dataLabel

# 随机梯度上升函数
# dataMatrix X自变量向量集合
# classLabels Y因变量向量,逻辑回归中是0或者1的集合
# numIters 迭代次数
def stocGradAscent(dataMatrix, classLabels, numIters=150):
    m,n = shape(dataMatrix)
    
    weights = ones(n)
    
    for j in range(numIters):
        dataIndex = range(m)
        #随机梯度算法, 可以去除这个循环?加上和批量梯度下降相比,计算量貌似没有降低
        for i in range(m):
            alpha = 4 / (1.0 + i + j ) + 0.01
            randIndex = int(random.uniform(0, len(dataIndex)))
            h = sigmoid(sum(weights * dataMatrix[randIndex]))
            error = classLabels[randIndex] - h
            weights = weights + alpha * error * dataMatrix[randIndex]
            del(dataIndex[randIndex])
    return weights

def logisticTrain():
    trainingSet = []
    trainingLabel = []
    testSet = []
    testLabel = []
        
    trainSet, trainLabel = readDatasetFromFile("../../../data/lr/horseColicTraining.txt", 21)
    testSet, testLabel = readDatasetFromFile("../../../data/lr/horseColicTest.txt", 21)

    weights = stocGradAscent(array(trainSet), trainLabel, 500)
    errorNo = 0
    totalNo = 0
    for i in range(len(testSet)):
        totalNo += 1
        tempLabel = classifyBySigmoid(array(testSet[i]), weights)
        if (tempLabel != testLabel[i]):
            errorNo += 1
    errorRate = float(errorNo) / totalNo
    print "the error rate of test set: " + str(errorRate)
    return errorRate
        
if __name__ == '__main__':
    error_sum = 0.0
    for i in range(10):
        error_sum += logisticTrain()
    print "the 10 iterations the average error rate is : " + str(error_sum / 10)

PS:简书貌似不可以传数据附件,贴出机器学习实战的下载地址, 解压后第5章可以找到相关代码和数据。
https://manning-content.s3.amazonaws.com/download/3/29c6e49-7df6-4909-ad1d-18640b3c8aa9/MLiA_SourceCode.zip

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容