前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于Logistic回归和Sigmoid函数的分类(一)

基于Logistic回归和Sigmoid函数的分类(一)

作者头像
用户6021899
发布2019-08-14 17:00:13
2.1K0
发布2019-08-14 17:00:13
举报
  • 线性回归

假设现有一些二维数据点,我们用一条线(直线或者曲线)对这些点进行拟合,这个拟合的过程就称作回归。如果用直线拟合,就是线性回归。

在多维空间下线性回归的公式为:

z = w0*x0+w1*x1+w2*x2+···+wn*xn。其中w0~wn为回归系数,

x0~ xn为各坐标值。

用矩阵的写法则为:

  • Logistic 函数

Logistic函数是一类函数的集合,其定义为:

其中,x0为x值的中点,L为函数曲线的最大值,k为函数曲线的曲率

  • Sigmoid 函数

Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。它可以将实数域映射到(0,1),并且单调递增。其函数由下列公式定义:

其导数为:

可以看出,Sigmoid 函数是Logistic函数的一个特例。

Sigmoid函数常用做神经网络的激活函数。它也可以用于Logistic回归分类。我们在每一个特征上乘以一个回归系数然后求和:

再将结果代入Sigmoid函数中,h =S(z), 进而得到一个范围在0~1之间的数值。假如我们的分类问题的结果只有两个类别,则可以将大于等于0.5的归入1类,小于0.5即被归入0类(即z >0 归入1类,z<0 归入0类)。

确定了分类器的函数形式之后,现在的问题变成了:最优的回归系数(矩阵W)是多少?

  • 梯度下降算法求最优回归系数

本例的数据集保存在文本文件中:

首先导入数据集,注意,代码里额外添加了一个常数特征x0=1,和w0乘得到截距w0。

代码语言:javascript
复制
from numpy import *
def loadDataSet():
    dataMat = []; labelMat = []
    fr = open('testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        ##添加一个常数特征x0=1,和w0乘得到截距,z = w0 + w1*x1+w2*x2
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])#
        labelMat.append(int(lineArr[2]))
    return dataMat,labelMat

定义Sigmoid函数:

代码语言:javascript
复制
def sigmoid(inX):
    return 1.0/(1+exp(-inX))

再用梯度下降算法求权重系数:

代码语言:javascript
复制
def gradDescend(dataMatIn, classLabels):
    dataMatrix = mat(dataMatIn) #mx3  #转换成100x3矩阵(3个特征,含常数特征)
    labelMat = mat(classLabels).transpose() #转换成mx1矩阵 
    m,n = shape(dataMatrix) #m=100, n=
    alpha = 0.001 #步长
    maxCycles = 500 #最大迭代步数
    weights = ones((n,1))#初始化权重可以全部设置为1
    for k in range(maxCycles):              #heavy on matrix operations
        h = sigmoid(dataMatrix*weights)     #matrix mult, h shape is m x1
        error = h - labelMat             #误差,shape mx1
        #梯度下降算法的变种
        weights -=  alpha * dataMatrix.transpose() *error#matrix mult (  3xm x mx1 -> 3x1)
    #print("error = ", error)
    return weights # 3x1

求得权重weights(w0,w1, w2 =weights)之后,根据判别临界条件: w0*x0 +w1* x1 + w2*x2 = 0 ,

即 w0 + w1*X + w2*Y =0 可得到分类所用直线的方程为:

Y = -(w0 + w1*X)/ w2

最后用matplotlab 把数据点和分类的边界线画出来。

可以看到,错判的点数很少。当然,这和数据集的数据点分布有关。只有当数据集基本线性可分时,用本例的线性回归分类算法才能得到较好的效果。

代码语言:javascript
复制
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:# label =0
            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', label ="class 1")
    ax.scatter(xcord2, ycord2, s=30, c='green',label ="class 0")

    #画出分类所用的线
    x = arange(-4.0, 4.0, 0.1)
    w0, w1, w2 = weights
    y = (0 - w0 - w1*x) / w2
    #x= x.reshape(1,-1)
    ax.plot(x, y,label ="判别线")
    plt.xlabel('X1'); plt.ylabel('X2');
    ax.legend()
    plt.title("梯度下降算法+ Logistic回归 示例")
    plt.show()
    
    
dataArr, labelMat = loadDataSet()
weights = gradDescend(dataArr, labelMat)
print(weights)
plotBestFit(weights)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档