logistic回归

假设一个二维坐标平面上,有许多的点,这些点有两个特征,一个是x1,另一个是x2。将这两个特征表示在坐标轴上,横坐标表示特征x1,纵坐标表示特征x2。平面上所有的点,都可以根据它的这两个特征的取值大小,来唯一地在坐标平面上画出来。


假设这个坐标平面上的所有点可以被一条直线划分为两类,一类叫做0,一类叫做1.

分类函数叫做sigmoid函数。将平面上这些点的两个特征相应的值作为sm函数的输入,sm函数就能够准确地将这个点划分为类0或者类1.


sm函数的输入更为精确的表达是:

这是一个由平面上的点的数个特征的值构成的表达式,在点原有的n个特征上,再加上一个常数特征x0=1,之后在这n+1个特征前面乘上各自的系数,并求和,

之后将和带入sm函数,sm函数自然就会将这个点进行分类。(在本例中,点只有2个特征)。用来分类的系数矩阵w0,w1,w2……wn,叫做权重矩阵。对于平面上任意线性可分的数据点,可以找到最合适的用来的分类的权重矩阵,这个权重矩阵非常重要。


这个权重矩阵,可以采用梯度下降法的方法来计算出来,梯度下降法的两个公式如下:



w和theta表示同样地概念,是权重系数。两式后面一个部分都是表示函数  f  的梯度,上面两式就是工程数学中很著名的,求函数F=0的解的一种方法,该方法叫做梯度下降法。

在我们这个项目之中,函数F有特定的含义,就是误差函数,就是数据真实的类别Y和模拟计算出来的类别H之间的差异。当误差函数f =0,其w就是本数据集最适合的权重。


Logistic回归梯度上升优化算法-python代码:

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

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

def gradAscent(dataMatIn, classLabels):
    dataMatrix = mat(dataMatIn)             convert to NumPy matrix//就是前面提取的每行的前两个特征的数据,这里将之转换为矩阵
    labelMat = mat(classLabels).transpose() convert to NumPy matrix将标签转换为矩阵,并转置
    m,n = shape(dataMatrix)
    alpha = 0.001
    maxCycles = 500                         #迭代次数
    weights = ones((n,1))   // 初始化权重矩阵的值,将他们全部初始化为1
    for k in range(maxCycles):              #heavy on matrix operations循环500次
        h = sigmoid(dataMatrix*weights)     #matrix mult将所有样本的特征值矩阵和权重矩阵相乘,就得到了sm函数的输入,就是利用已知的权重,初步算出来的模拟值,这个值只是模拟的,需要和真实的标签值做对比,并得出它和标签中的真正值得差异。假如差异很小,那么说明权重很对,加入差异很大,那么就要修改权重;这是一个100*1的矩阵,100表示样本的个数
        error = (labelMat - h)              #vector subtraction误差函数,将真实的类别与模拟出来的类别进行对比。误差函数是一个列向量
        weights = weights + alpha * dataMatrix.transpose()* error #matrix mult 梯度上升公式,学习率、特征值矩阵,误差函数
    return weights                          #返回值为[w0,w1,w2]

分析数据:画出决策边界

** 画出数据集和Logistic回归最佳拟合直线的函数 **

def plotBestFit(weights):              #此处weights即为上面求出的[w0,w1,w2]
   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://假如这个样本是类别1,那么就将这个样本的两个坐标值都存入到cord1之中;假如这个样本类别是0,就将之存到cord2中
           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] # 0=w0x0+w1x1+w2x2 (x0=1) 此处x=x1;y=x2;z=0是sm 函数的阶跃点,因而z=0这根直线就是这个样本的分界线。
   ax.plot(x, y)
   plt.xlabel('X1'); plt.ylabel('X2');
   plt.show() 

训练算法:随机梯度上升

改进算法,一次仅用一个样本点来更新回归系数——在线学习算法

** 随机梯度上升算法 **

def stocGradAscent0(dataMatrix, classLabels):
    m,n = shape(dataMatrix)//m是样本的个数
    alpha = 0.01
    weights = ones(n)   #initialize to all ones
    for i in range(m)://选取其中的某个样本
        h = sigmoid(sum(dataMatrix[i]*weights))//这是第i个样本的z值,这是一个标量
        error = classLabels[i] - h//将这个样本的真正分类减去它的预测分类H,得到只针对这个样本的误差值,这也是一个标量。
        weights = weights + alpha * error * dataMatrix[i]//只用这一个样本的数据跟新权重矩阵。
    return weights//一次只用一个样本的数据更新权重矩阵,那么全部都样本循环下来之后,权重矩阵就被更新了m=100次。

改进的随机梯度上升算法

def stocGradAscent1(dataMatrix, classLabels, numIter=150):
m,n = shape(dataMatrix)
weights = ones(n)   #initialize to all ones
for j in range(numIter)://设置迭代的次数,j表示每一次的迭代
    dataIndex = range(m)//得到[0,1……99],同时也能确定样本的个数
    for i in range(m):对于其中的每个样本
        alpha = 4/(1.0+j+i)+0.0001    #apha decreases with iteration, does not 每个样本在计算的时候,学习率都不一样
        randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant从所有的样本之中,随机算出一个样本
        h = sigmoid(sum(dataMatrix[randIndex]*weights))//计算这个样本的分类结果
        error = classLabels[randIndex] - h//计算这个样本分类的误差
        weights = weights + alpha * error * dataMatrix[randIndex]//用这个样本来更新权重
        del(dataIndex[randIndex])//删掉这个被用过的样本,然后下次更新的时候,就从剩下的样本之中选择随机一个样本来更新权重。直到一次循环,所有的100个样本都被用来更新权重过。
return weights//返回权重

z=ω0x0+ω1x1+ω2x2+...+ωnxn

z=ω0x0+ω1x1+ω2x2+...+ωnxn z=ω0x0+ω1x1+ω2x2+...+ωnxn

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值