Logistic应用于二分类

来源:互联网 发布:windows自带数据库 编辑:程序博客网 时间:2024/05/18 03:53

回归方程

z=w0x0+w1x1+w2x2+w3x3+...wnxn
=wTx
表示两个向量对应元素的相乘
x是分类器的输入特征
w是我们需要求的最佳参数

算法过程

每个回归系数初始化为1
重复R次:
。。。计算整个数据的梯度
。。。使alpha*grandient更新回归系数向量
。。。返回回归系数

Sigmoid

在由于是二分类问题,需要对上面求得z进行判断,判断其所在的类别,我们用到的是Sigmoid,公式如下:
σ(z)=11+ez
这里写图片描述
该函数具有很好的性质:
z很大时候,函数值趋向于1
z很小时候,函数值趋向于0
根据这个特性可用于二分类分体
z=w0x0+w1x1+w2x2+w3x3+...wnxn
=wTx
对上面的回归方程:
σ(z)=σ(wTx)=11+ewTx
对给定的x,上式的值越趋向于1,认为是1类的可能性越大,越趋近0,则认为是0类的可能性越大,Sigmoid函数给了分类的一个很好的界限。

梯度上升法

参见梯度下降法
梯度上升法和梯度下降法只是在迭代公式中的正负号的差别。
上面的梯度下降法中很详细的讲了梯度下降法,随机梯度下降法和增量梯度下降法,但是写的有点乱。
我们发现对σ(z)求导后的结果是σ(z)(1σ(z)
根据梯度上升法至于要求出w既可以对给定的样本,判断其所在的类别
hw(x)=σ(z)=σ(wTx)

P(y=1|x;w)=hw(x)

P(y=0|x;w)=1hw(x)

P(y|x;w)=(hw(x))y(1hw(x))1y

若假设有m个训练样本,根据极大似然估计
L(W)=P(Y|X;W)=i=mi=1P(y(i)|x(i);w)

=i=mi=1(hw(x(i)))y(i)(1hw(x(i)))1y(i)
取对数

logL(W)=i=mi=1y(i)loghw(x(i))+i=mi=1(1y(i))log(1hw(x(i)))

为了求出W=(w0,w1,w2,...,wm)

logL(W)中的某个wj求导得到;mi=1(y(i)hw(x(i)))x(i)j

wj

wj=wj+α(mi=1(y(i)hw(x(i))))x(i)j
这个是增量梯度上升法
注意:
1.这里的迭代只是求出了wj,只是一个而已,求出所有的要分别迭代n+1
2.x(i)是第i个样本数据,是个向量,有n个元素,n+1W中元素的个数
3.(y(i)hw(x(i))),第i个样本的误差
4.mi=1(y(i)hw(x(i)))x(i)j,可以理解为:所有每个样本的误差与样本特征乘积的和。
5.α是学习率
6.这个与上次讲的梯度下降法的求导后的结果有点不一样,这里是对的,这个我求导好多次的,要求所有的误差与特征乘积的和。为了与梯度下降法的迭代公式一样,每次可知求一个样本的误差。

wj=wj+α((y(i)hw(x(i))))x(i)j
这个是普通的梯度上升法
为了提高速度可以,随机的抽取样本x(i),这个就是随机梯度上升法

Python程序

程序中有两个数据集,第一个只是用来简单的测试,第二个数据集是疝气病预测马死亡的预测
程序中注释很详细,不对程序再过多说明

# -*- coding: utf-8 -*-from numpy import *import operatorfrom os import listdirdef loadDataSet():    dataMat=[]    labelMat=[]    # 打开txt文件    fr = open('testSet.txt')    # readData中保存了所有的数据行    readData = fr.readlines()    # 利用正则,每行数据以 \t 划分开的    # 返回的结果是list    for line in readData:        lineArr = line.strip().split("\t")        dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])        labelMat.append(int(lineArr[2]))    return dataMat,labelMatdef sigmoid(intX):    # sigmoid 函数    return 1.0/(1+exp(-intX))def gradAscent(dataMatIn,classLabels):    # 梯度上升法    DataMatrix = mat(dataMatIn)    labelMat = mat(classLabels).transpose()    m,n = shape(DataMatrix)    # alpha 学习率    alpha = 0.001     maxCycles = 500    weight = ones((n,1))    # 下面计算都是按照矩阵方式    # 1.计算sigmoid函数,也就是根据当前的weight,判断类别    # 2.计算误差    # 3.更新权值 对w_i,只是计算了自己的误差,误差大,更新权值w_i相对越大    # 4.迭代到达最大次数结束     for k in range(maxCycles):        h= sigmoid(DataMatrix*weight)        error = (labelMat - h)        weight = weight  + alpha * DataMatrix.transpose()*error    return weightdef plotBestFit(weights):    import matplotlib.pyplot as plt    dataMat,labelMat = loadDataSet()    dataArr = array(dataMat)    n = shape(dataArr)[0]    xcord1 = [];ycord1=[]    xcord2 = [];ycord2=[]    for i in range(n):        if(int(labelMat[i])==1):            xcord1.append(dataArr[i,1])            ycord1.append(dataArr[i,2])        else:            xcord2.append(dataArr[i,1])            ycord2.append(dataArr[i,2])    fig = plt.figure()    ax = fig.add_subplot(111)    ax.scatter(xcord1,ycord1,s=30,c='red',marker='s')    ax.scatter(xcord2,ycord2,s=30,c='green')    x = arange(-3.0,3.0,0.1)    y = (-weights[0]-weights[1]*x)/weights[2]    ax.plot(x,y)    plt.xlabel('X1');plt.ylabel('X2')    plt.show()def runTest():    dataArr,labelMat = loadDataSet()    weights = gradAscent(dataArr,labelMat)    plotBestFit(weights.getA())def stocGradAscent0(dataMatrix,classLabels):    # 随机梯度上升法    m,n=shape(dataMatrix)    alpha = 0.01    weights = ones(n)    # 选取前m个样本更新权值    # 每次对所有的weights 更新的权值一样     for i in range(m):        h = sigmoid(sum(dataMatrix[i]*weights))        error = classLabels[i] - h        weights = weights + alpha*error * dataMatrix[i]    return weightsdef runTest1():    dataArr,labelMat = loadDataSet()    weights = stocGradAscent0(array(dataArr),labelMat)    plotBestFit(weights)def stocGradAscent1(dataMatrix,classLabels,numIter=150):    # 改进的随机梯度上升法    m,n=shape(dataMatrix)    weights = ones(n)    # 随机的选取样本,计算误差,更新权值    # 这里的alpha 也根据迭代次数更新大小,    for j in range(numIter):        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(dataMatrix[randIndex]*weights))            error = classLabels[randIndex] - h             weights = weights + alpha* error* dataMatrix[randIndex]            del(dataIndex[randIndex])    return weightsdef runTest2():    dataArr,labelMat = loadDataSet()    weights = stocGradAscent1(array(dataArr),labelMat)    plotBestFit(weights)def classifyVector(intX,weights):    prob = sigmoid(sum(intX*weights))    if prob>0.5: return 1.0     else: return 0.0 def 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[i]))    trainWeights = stocGradAscent1(array(trainingSet),trainingLabels,500)    errorCount = 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 mulitTest():    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))
1 0
原创粉丝点击