Logistic回归

来源:互联网 发布:共产主义社会 知乎 编辑:程序博客网 时间:2024/05/28 17:04

假设我们现在有一些数据点,我们用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程称作回归。利用Logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的“回归”一词源于最佳拟合,表示要找到最佳拟合参数集。训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化算法。

1.1 基于Logistic回归和Sigmoid函数的分类
我们想要的函数应该是,能接受所有的输入然后预测出类别。例如,在两个类的情况下,上述函数输出0与1,这就是Sigmoid函数,具体的计算公式如下:Δ(z)=11+ez 当x为0时,Sigmoid函数值为0.5.随着x的增大,对应的Sigmoid值将逼近于0。因此,为了实现Logistic回归分类器,我们可以在每个特征上都乘以一个回归系数,然后把所有的结果值相加,将这个总和代入Sigmoid函数中,进而得到一个范围在0~1之间的数值。任何大于0.5的数据被分入1类,小于0.5即被归入0类。所以Logistic回归也可以被看成是一种概率估计。

1.2 基于最优化方法的最佳回归系数确定

1.2.1 梯度上升法
梯度上升法基于的思想是:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。梯度算子总是指向函数值增长最快的方向。这里所说的是移动方向,而未提到移动量的大小。该量值称为步长,记做α。用向量来表示的话,梯度上升算法的迭代公式如下:ω=ω+αf(ω) 该公式将一直被迭代执行,直至达到某个停止条件为止,比如迭代次数达到某个指定值或算法达到某个可以允许的误差范围。

1.2.2 随机梯度上升
梯度上升算法在每次更新回归系数时都需要遍历整个数据集,该方法在处理100个左右的数据集时尚可,但如果有数十亿样本或成千上万的特征,那么该方法的计算复杂度就太高了。一种改进方法是一次仅用一个样本点来更新回归系数,该方法称为随机梯度上升算法。由于可以在新的样本到来时对分类器进行增量式更新,因而随机梯度上升算法是一个在线学习算法。与在线学习相对应,一次处理所有的数据被称作是批处理。

程序清单1-1 改进的随机梯度上升算法

def stocGradAscent1(dataMatrix,classLabels,numIter = 150):    m,n = shape(dataMatrix)    weights = ones(n)    for j in range(numIter):        dataIndex = range(m)        for i in range(m):            alpha = 4/(1.0+j+i)+0.01            randIndex = int(random.uniform(0,len(dataIndex)))            h = sigmoid(sum(dataMatrix[randIndex]*weights))            error = classLabels[randIndex]-h            weights =weights + alpha * error * dataMatrix[randIndex]            del(dataIndex[randIndex])    return weights

1.3 示例:从疝气病症预测病马的死亡率
将原始数据经过缺失处理得到两个文件:horseColicTraining.txt和horseColicTest.txt。下面看看运行Logistic回归的分类效果。

程序清单1-2 Logistic回归分类函数

def sigmoid(inX):    return 1.0/(1+exp(-inX))def classifyVector(inX,weights):    prob = sigmoid(sum(inX*weights))    if prob > 0.5:        return 1.0    else:        return 0.0def colicTest():    frTrain = open('horseColicTraining.txt')    frTest = open('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 = stocGradAscent1(array(trainingSet),trainingLabels,500)    errorCount = 0.0; numTestVec = 0.0    for line in frTest.readlines():        numTestVec += 1.0        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    errorRate = (float(errorCount)/numTestVec)    print "the error rate of this test is: %f"%errorRate    return errorRatedef multiTest():    numTests = 10;errorSum = 0.0    for k in range(numTests):        errorSum += colicTest()    print "after %d iterations the average error rate is:%f" %(numTests,errorSum/float(numTests))

最后一个函数是multiTest(),其功能是调用函数colicTest()10次并求结果的平均值。

0 0
原创粉丝点击