机器学习实战 第五章 logistic回归

机器学习实战 第五章 logistic回归

二值型输出分类器。

5.1 基于logistic回归和sigmoid函数的分类

一个很有意思的阶跃函数叫做海维赛德阶跃函数,英文是heaviside step function,我原本以为这会是个人名——海维赛德,结果一看英文heaviside,这个意思难道不是一边重?因为一边重,所以一边就被压成了0,另一边就是1.

sigmoid:

def sigmoid(inX):
    return 1.0/(1+exp(-inX));

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

sigmoid函数的输入相对来说简单,就是一个数值,然后对其进行计算。之所以将原来的大量计算进行简化,成为了一个数,我认为其中原因如下:1.label是二值,所以其最后进行判断相对简单,通过sigmoid函数。2.对于其进行参数的调整,主要是为了能够进行区分性的度量,参数可以看作是对于每一个维度上的大小的度量。所以经过参数放缩之后,第一个作用就是能够对于原来的数据进行放缩,第二个就是选取出主要的影响因素。

5.2.1 梯度上升法

这其中有个梗,怎么就突然从梯度变成了对于参数的处理了呢。

梯度实际上就是在每个变量上面的变化量的大小。变化大的就多来点儿,变化小的就少来点儿。这样一种类似于贪心的策略能够保证尽快的达到最大或者最小值点。

而用梯度来对于原始的参数w进行更改我认为是这样的原因,求偏导实际上就是对于w进行一个判断,到底哪个w变化最大,那么这最后的偏导启示就是输入,输入的数值越大,那么偏导也就越大,这意味着影响也就越大。

梯度上升算法是w+偏导,而下降时w-偏导。感觉这个梗得理解一下。因为虽然说是这么计算,似乎是因为符号上能够说通。

5.2.2 训练算法:使用梯度上升找到最佳参数

    def loadDataSet():
        dataMat = [];labelMat = [];
        fr = open('testSet.txt');
        for line in fr.readlines():
            lineArr = line.strip().split();
            dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])]);
            labelMat.append(int(lineArr[2]));
        return dataMat,labelMat;

这样可以看出来,对于其来说,变量有两个,分别是lineArr[0]和lineArr[1],第一个1.0,是为了给一个bias用的,为1.0永不改变。label标签就是lineArr[3]了。

    def gradAscent(dataMatIn,classLabels):
        dataMatrix = mat(dataMatIn);
        labelMat = mat(classLabels).transpose();
        m,n = shape(dataMatrix);
        learning_rate = 0.001
        maxCycles = 500;
        weights = ones((n,1));
        for k in range(maxCycles):
            h = sigmoid(dataMatrix*weights)
            error = label - h;
            weights = weights + learning_rate * dataMatrix.transpose() * error
        return weights

这里面其实梯度可以这样来计算,首先是一个m*n(n=3)的矩阵,weights是3*1的矩阵,这是在正向计算的时候,然后在反向梯度下降进行更新的时候,是用的transpose,这个其实就是梯度了,因为对于w来说,计算是很简单的向量的乘法,因此其逐元素的梯度也就是输入的矩阵。

5.2.3 分析数据:画出决策边界

    def 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,3,0.1);
        y = (-weights[0]-weights[1]*x)/weights[2];
        ax.plot(x,y);
        plt.xlabel('X1');plt.ylabel('X2');
        plt.show();

其实就是画一画边界线就好了

5.2.4 训练算法:随机梯度上升

    def stocGradAscent0(dataMatrix,classLabels):
        m,n = shape(dataMatrix);
        learning_rate = 0.001
        weights = ones(n);
        for i in range(m):
            h = sigmoid(dataMatrix[i]*weights);
            error = classLabels[i] - h;
            weights = weights + learning_rate * error * dataMatrix[i];
        return weights

在这个算法中,是对于单个样本逐个进行计算。

    def stocGradAscent1(dataMatrix,classLabels,maxIter = 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;
                tmp = int(random.uniform(0,len(dataIndex)));
                randIndex = dataIndex(tmp);
                h = sigmoid(dataMatrix[randIndex]*weights);
                error = classLabels[randIndex];
                weights = weights + learning_rate * error * dataMatrix[randIndex];
                del dataIndex[tmp];
        return weights

在这个算法中的主要修改就是使得每一轮对于数据的处理都能够实现随机。

5.3 从疝气病症预测病马的死亡率

数据集:http://archive.ics.uci.edu/ml/datasets/Horse+Colic

    def colicTest():
        frTrain = open('/Users/yangzhaohui/Desktop/horse_data/training.txt');
        frTest = open('/Users/yangzhaohui/Desktop/horse_data/testing.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,1);
        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(classifuVector(array(lineArr),trainWeights))!=int(currLine[21]):
                errorCount += 1;
            errorRate = (float(errorCount)/numTestVec);
            print("the error rate of this test is: %f" % errorRate)
            return errorRate


    def multiTest():
        numTests = 10;
        errorSum = 0.0;
        for k in range(numTests):
            errorSum += colicTest()
            print("after %d iterations the averate error rate is : %f"%(numTests,errorSum/float(numTests));

这段代码我就是敲进去熟悉了一下,没有运行。主要是因为1:数据和现在的不一样,要稍作修改,但是思路已经知道了,尤其是对于确实数据如何去进行补充,在这个例子中是补充成0或者去掉 2.我饿了,要去吃饭了。


感觉这本书中的代码风格不大一样,感觉不是一个人写出来的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值