logistic回归

来源:互联网 发布:知乎 自己拍婚纱照 编辑:程序博客网 时间:2024/06/05 21:51

回归就是对已知公式的未知参数进行估计。比如已知公式是y=a∗x+by=a∗x+b,未知参数是a和b,利用多真实的(x,y)训练数据对a和b的取值去自动估计。估计的方法是在给定训练样本点和已知的公式后,对于一个或多个未知参数,机器会自动枚举参数的所有可能取值,直到找到那个最符合样本点分布的参数(或参数组合)。

何为logistic回归呢,他是用来干嘛的?
Logistic regression (逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性。之前在经典之作《数学之美》中也看到了它用于广告预测,也就是根据某广告被用户点击的可能性,把最可能被用户点击的广告摆在用户能看到的地方,然后叫他“你点我啊!”用户点了,你就有钱收了。这就是为什么我们的电脑现在广告泛滥的原因了。
Logistic regression可以用来回归,也可以用来分类,主要是二分类。还记得上几节讲的支持向量机SVM吗?它就是个二分类的例如,它可以将两个不同类别的样本给分开,思想是找到最能区分它们的那个分类超平面。但当你给一个新的样本给它,它能够给你的只有一个答案,你这个样本是正类还是负类。例如你问SVM,某个女生是否喜欢你,它只会回答你喜欢或者不喜欢。这对我们来说,显得太粗鲁了,要不希望,要不绝望,这都不利于身心健康。那如果它可以告诉我,她很喜欢、有一点喜欢、不怎么喜欢或者一点都不喜欢,你想都不用想了等等,告诉你她有49%的几率喜欢你,总比直接说她不喜欢你,来得温柔。而且还提供了额外的信息,她来到你的身边你有多少希望,你得再努力多少倍,知己知彼百战百胜,哈哈。Logistic regression就是这么温柔的,它给我们提供的就是你的这个样本属于正类的可能性是多少。

一、logistic分布:
X是连续随机变量,其中X~logistic分布,则:
分布函数和密度函数公式
对应的图形如下图所示,分布函数F(x)图形是一条S曲线(sigmoid curve),该点以(u,1/2)中心对称。密度函数与正态分布函数很像啊?有何关系?
密度函数和分布函数曲线

二、logistic回归模型

首先要知道LR分类器,即Logistic Regression Classifier,在分类情形下,经过学习后的LR分类器是一组权值这里写图片描述,当测试样本的数据输入时,这组权值与测试数据按照线性加和得到这里写图片描述.这里这里写图片描述是每个样本的个特征。之后按照sigmoid函数的形式求出

这里写图片描述

由于sigmoid函数的定义域为(-INF,INF),值域为(0,1),因此最基本的LR分类器适合对两类目标进行分类。

所以Logistic回归最关键的问题就是研究如何求得这组权值这里写图片描述,其中w0=b.

二项logistic回归模型是如下的条件概率分布:
这里写图片描述
这里要理解为什么是这样?我们认为x~logistic分布,则样本x对应的类标签y取得1的概率等于其带入sigmoid函数得到的值,我们这儿是要学习得到加权值w,b,来满足已知样本和类标签,即训练数据集这里写图片描述
故可以用极大似然估计法来估计模型参数。

何为极大似然估计呢?
利用已知的样本结果,反推最有可能(最大概率)导致这样结果的参数值。要理解似然函数的意义,以及为什么要让似然函数最大?
从最大似然到EM算法浅解

三、模型参数估计
假设我们有n个独立的训练样本{(x1, y1) ,(x2, y2),…, (xn, yn)},y={0, 1}。那每一个观察到的样本(xi, yi)出现的概率是:
这里写图片描述

那我们的整个样本集,也就是n个独立的样本出现的似然函数为(因为每个样本都是独立的,所以n个样本出现的概率就是他们各自出现的概率相乘):
这里写图片描述
那最大似然法就是求模型中使得似然函数最大的系数取值w*。这个最大似然就是我们的代价函数(cost function)了。
我们先变换下L(w):取自然对数
这里写图片描述

接下来就是使L(w)最大,用梯度下降/上升法求解加权值这里写图片描述

四、梯度上升确定回归系数
激动人心的代码就要来了!
本算法的主要思想根据logistic回归的sigmoid函数来将函数值映射到有限的空间内,sigmoid函数的取值范围是0~1,从而可以把数据按照0和1分为两类。在算法中,首先要初始化所有的w权值为1,每次计算一次误差并根据误差调整w权值的大小。
根据梯度上升,梯度上升算法是按照上升最快的方向不断移动
这里写图片描述

###使用梯度上升找到最佳参数import numpyfrom numpy.core.fromnumeric import shapefrom numpy.core.multiarray import array, arangefrom numpy.matlib import onesfrom numpy.matrixlib.defmatrix import matimport matplotlib.pyplot as pltdef loadDataSet():    with open("logistic_test.txt",'r')as fr:        for line in fr.readlines():            lineArr = line.strip().split()  ###strip:Return a copy of the string S with leading and trailing whitespace removed.  spilt():list of strings            dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])            labelMat.append(int(lineArr[2]))        return dataMat, labelMatdef sigmoid(inX):    return 1.0 / (1 + numpy.exp(-inX))def gradAscent(dataMat, classLabels, alpha,maxIter):  ### opts is optimize option include step and maximum number of iterations    dataMatrix = mat(dataMat)  ### mat()函数将数组转化为矩阵    labelMat = mat(classLabels).transpose()  ### 行向量转换为列向量,transpose()表示转置矩阵    numsimples, numfeatures = shape(dataMatrix)  ###(列数,行数)numsimples 表示样本,numfeatures表示特征数    weights = numpy.ones((numfeatures,1))    for k in range(maxIter):        h = sigmoid(dataMatrix * weights)        error = (labelMat - h)        weights += alpha * dataMatrix.transpose() * error  ##这里需要好好理解,与推导的结果不太一样    return weightsdef show(weights):    dataMat,labelMat = loadDataSet()    dataArr = array(dataMat)    n = shape(dataArr)[0]  ###样本个数   ###(列数,行数)    min_x = min(dataMat[1])    max_x = max(dataMat[1])    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='blue', marker='s')    ax.scatter(xcord1, ycord1, s=30, c='red')    x = numpy.arange(min_x, max_x, 0.1)        ##Return evenly spaced values within a given interval.    y = (-weights[0] - weights[1] * x) / weights[2]   ### w0 +w1*x +w2*x2 = 0    ax.plot(x, y)    plt.xlabel('X1')    plt.ylabel('X2')    plt.show()if __name__ =='__main__':    dataMat= []    labelMat = []    dataMat,labelMat = loadDataSet()    weights = gradAscent(dataMat,labelMat,0.001,300)    show(weights)
0 0
原创粉丝点击