机器学习实战之python实现logistics算法

图片.png

logistics的理论知识,请参见下方博文:
Logistic回归原理及公式推导

import numpy as np
import matplotlib.pyplot as plt

def loadDataSet():#定义一个创建数据集函数
    dataMat = []
    labelMat = []
    fr = open('Ch05/testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        dataMat.append([1,float(lineArr[0]),float(lineArr[1])]) #这里因为原数据是二维的,只有x1和x2,为了方便后面的计算,引入一个x0,并全部赋值为1
        labelMat.append(int(lineArr[2]))#建立标签列
    fr.close()
    return dataMat,labelMat

def sigmoid(inx):#定义sigmoid函数
    return 1/(1+np.exp(-inx))

def gradAscent(dataMatIn,classLabels):
    dataMatrix = np.mat(dataMatIn)#100*3的矩阵
    labelMat = np.mat(classLabels).T#100*1的矩阵
    m,n = dataMatrix.shape
    alpha = 0.001
    maxCycles = 500
    weights = np.ones((n,1))#3*1,定义初始回归系数
    for k in range(maxCycles):#迭代调整回归系数
        h = sigmoid(dataMatrix*weights)#100*1的矩阵,利用回归系数计算样本预测值
        error = (labelMat - h)#100*1的矩阵,计算每个样本的误差(实际值-预测值)
        weights = weights + alpha*dataMatrix.T*error#3*1的矩阵,调整回归系数weights
        #dataMatrix.T是3*100的矩阵,error是100*1的矩阵,双方经过300次乘法相加,得到3*1的矩阵
    return weights#输出最终的回归系数

def plotBsetFit(wei):
    weights = wei.getA()#将矩阵转化为np.ndarry对象
    dataMat,labelMat = loadDataSet()
    dataArr = np.array(dataMat)
    n = dataArr.shape[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 = np.arange(-3,3,0.1)
    y = (-weights[0]-weights[1]*x)/weights[2]
    #这里,令sigmoid函数等于0,求出x1和x2的关系,即为要画的分割线
    ax.plot(x,y)
    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.show()
    
#以上梯度算法中,每次迭代都要遍历所有的数据,每次都有300次的乘法,如果数据量大,很容易
#累死,下面优化为随机梯度算法,即每次迭代只选择一个样本
    
def stocGradAscent0(dataMatrix,classLabels):
    m,n = dataMatrix.shape
    alpha = 0.01
    weights = np.ones((n,1))
    for i in range(m):
        h = sigmoid(sum(dataMatrix[i]*weights))
        error = classLabels[i] - h
        weights = weights + alpha*dataMatrix[i]*error
    return weights #注意,这里返回的weights是1*3的np.ndarry形式,不是矩阵形式
    #因此在调用画图函数时,需进行转换和转置
#调用画图函数可以看出,迭代效果没有全数据集迭代好,下面尝试对步长进行优化

def stocGradAscent1(dataMatrix,classLabels,numIter=150):
    m,n = dataMatrix.shape
    weights = np.ones((n,1))
    for j in range(numIter):#重复迭代全集样本
        dataIndex = list(range(m))
        for i in range(m):#随机迭代每一个样本
            alpha = 4/(1+j+i)+0.01 #s随着迭代调整步长
            randIndex = int(np.random.uniform(0,len(dataIndex)))#随机选择一个样本
            h = sigmoid(np.sum(dataMatrix[randIndex]*weights))
            error = classLabels[randIndex] - h
            weights = weights +alpha*dataMatrix[randIndex]*error
            del dataIndex[randIndex] 
    return weights
#画图,可以看出效果要比上个随机梯度好很多

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

def classifyVector(x,weights):#定义一个分类函数,利用sigmoid计算属于1的概率
    prob = sigmoid(np.sum(x*weights))
    if prob > 0.5:
        return 1
    else:
        return 0
    
def colicTest():
    frTrain = open('Ch05/horseColicTraining.txt')
    frTest = open('Ch05/horseColicTest.txt')
    trainingSet = []; trainlabels = []
    for i in frTrain.readlines():#加载训练数据
        ilist = i.strip().split('\t')
        trainingSet.append([float(x) for x in ilist[:-1]])
        trainlabels.append(float(ilist[-1]))  
    frTrain.close()
    
    trainWeights = stocGradAscent1(np.array(trainingSet),trainlabels,1000)
    #利用训练数据生成一组最优回归系数
    
    error = 0; numTest = 0
    for i in frTest.readlines():
        numTest += 1 
        ilist = i.strip().split('\t')
        pard = classifyVector(np.array([float(x) for x in ilist[:-1]]),trainWeights)
        #利用测试数据和最优回归系数,判定分类
        if int(pard) != int(ilist[-1]):
            error += 1
    frTest.close()
    errorRate = float(error)/numTest
    print('the error rate of this test is:%f'%errorRate)
    return errorRate

def multiTest():
    numTest = 10; errorSum = 0
    for i in range(numTest): #重复10次,求平均错误率
        errorSum += colicTest()
    print('after %d iterations the average error rate is:%f'%(numTest,errorSum/numTest))

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

推荐阅读更多精彩内容

  • “闭上双眼你会挂念谁,眼睛睁开身边竟是谁”,这是陈奕迅《人来人往》里面的一句歌词。以前听的时候,觉得很感伤,而今听...
    慕天涯阅读 611评论 0 2
  • 很多年前,高中历史老师在讲台上对我们说:大学文凭,会决定你毕业后十年的平台。高考即使是到坎,也得咬着牙迈过去。当时...
    先生文字工作坊阅读 312评论 1 1
  • 你的一个想法,可能因人而异,折射出千百种回应。 前不久日本出差,因为之前去过两次,时间间隔不是很大,自己没什么可买...
    夜心婉阅读 301评论 0 1
  • 工作以后,我依然把大多数周末消耗在家里。很少出去玩是一种状态,也是一种选择。毕竟我很难做出约邻居大爷大妈,或者并不...
    月清游阅读 410评论 1 1