700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 机器学习实战(四)逻辑回归LR(Logistic Regression)

机器学习实战(四)逻辑回归LR(Logistic Regression)

时间:2019-02-04 18:15:22

相关推荐

机器学习实战(四)逻辑回归LR(Logistic Regression)

目录

0.前言

1. Sigmoid函数

2.梯度上升与梯度下降

3.梯度下降法(Gradient descent)

4.梯度上升法(Gradient ascent)

5.梯度下降/上升法的数学推导

6.随机梯度下降/上升法(Stochastic gradient descent/ascent)

7.实战案例

7.1. 简单案例

7.2. 病马死亡率案例

学习完机器学习实战的逻辑回归,简单的做个笔记。文中部分描述属于个人消化后的理解,仅供参考。

本篇综合了先前的文章,如有不理解,可参考:

吴恩达机器学习(二)多元线性回归

吴恩达机器学习(四)逻辑回归

吴恩达机器学习(五)正则化

吴恩达机器学习(十五)大规模机器学习

所有代码和数据可以访问我的 github

如果这篇文章对你有一点小小的帮助,请给个关注喔~我会非常开心的~

0.前言

逻辑回归(Logistic Regression)是一种基于最优化思想的二分类监督学习算法。

其主要思想是根据现有数据对分类边界线建立回归公式,以此分类

其目的是寻找一个非线性函数的最佳拟合参数,求解过程可以通过最优化算法完成。

优点:计算代价不高,易于理解和实现缺点:容易造成欠拟合,分类精度不高适用数据类型:数值型和标称型数据

1. Sigmoid函数

线性回归中,对数据进行拟合,是在每个特征上都乘以一个回归系数,然后把所有结果再相加,即,向量化即。

逻辑回归中,再将带入函数,可得到属于范围的一个数值,若大于则属于正类,若小于则反之。

函数的定义如下:

函数的图像如下:

综合上述,整体公式表示为:

2.梯度上升与梯度下降

梯度:某一函数在该点处的方向导数沿该方向取得最大值,即在该点变化率(斜率)最大。

梯度上升法:寻找某函数的最大值,沿着该函数的梯度方向寻找梯度下降法:寻找某函数的最小值,沿着该函数的梯度方向寻找

梯度符号记为,的梯度可表示为,对各个方向求偏导数:

如下图所示,求最小值,可采用梯度下降法:

梯度下降:,当在最小值左边时,导数为负数,向右移;当在最小值右边时,导数为正数,向左移。

如下图所示,求最大值,可采用梯度上升法:

梯度上升:,当在最小值左边时,导数为正数,向右移;当在最小值右边时,导数为负数,向左移。

3.梯度下降法(Gradient descent)

梯度下降法的代价函数如下定义:

代价函数是指,函数值越大,付出的代价越大,即精度越差。

第二项是正则化项,是为了防止过拟合而设定,先忽略这项。

第一项是所有样本计算结果的求平均,若,则取,若,则取。

由上图易得,时,若越接近代价越大,时,若越接近代价越大。

为了降低代价函数,可采取梯度下降法,定义如下:

4.梯度上升法(Gradient ascent)

梯度上升法求解逻辑回归参数,和梯度下降法求解参数原理是一样的。

只是在梯度上升法中,定义如下:

与梯度下降法只相差一个负号,所以是求解最大值,采用梯度上升法:

5.梯度下降/上升法的数学推导

以梯度上升法为例子,不考虑正则化项:

对三项分别计算:

综合三项可得:

综上所述,在梯度上升法中:

6.随机梯度下降/上升法(Stochastic gradient descent/ascent)

以随机梯度下降法为例子,随机梯度下降法是对梯度下降法的改进。

梯度下降法中,每次更新参数都需要遍历整个数据集,又称作 Batch gradient descent 。

随机梯度下降法中,每次更新参数只随机选择一个样本点,通过每次更新参数的迭代而选择不同的样本点。

算法流程如下:

随机梯度下降/上升法是一个在线算法,可以在新数据来临的时候直接更新参数,而不用遍历整个数据集。

7.实战案例

以下将展示书中案例的代码段,所有代码和数据可以在github中下载:

7.1. 简单案例

# coding:utf-8from numpy import *import matplotlib.pyplot as plt"""简单案例"""# sigmoid函数def sigmoid(inX):return 1.0 / (1 + exp(-inX))# 梯度上升求解J(\theta)# Batch gradient ascentdef gradAscent(dataMatIn, classLabels):# 转换为矩阵dataMatrix = mat(dataMatIn)# 转换为矩阵后转置,表示为列向量labelMat = mat(classLabels).transpose()m, n = shape(dataMatrix)alpha = 0.001maxCycles = 500# \theta 表示为列向量weights = ones((n, 1))# 梯度上升迭代for k in range(maxCycles):h = sigmoid(dataMatrix * weights)error = (labelMat - h)weights = weights + alpha * dataMatrix.transpose() * errorreturn weights# 加载数据集def loadDataSet():dataMat = []labelMat = []fr = open('testSet.txt')for line in fr.readlines():# 去除头尾空字符,按照空格分割字符串lineArr = line.strip().split()# 添加偏置位 w_0(\theta_0) 相乘的 x_0 = 1.0dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])labelMat.append(int(lineArr[2]))return dataMat, labelMat# 画出数据的分界线def plotBestFit(weights):dataMat, labelMat = loadDataSet()dataArr = array(dataMat)n = shape(dataArr)[0]xcord1 = []ycord1 = []xcord2 = []ycord2 = []# 遍历每一条数据,根据类别将x1, x2分别插入不同的List中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 = array(arange(-3.0, 3.0, 0.1))# x=x1, y=x2 表示的是 w0x0+w1x1+w2x2 = 0 的直线y = (-weights[0] - weights[1] * x) / weights[2]ax.plot(x, y)plt.xlabel('X1')plt.ylabel('X2')plt.show()if __name__ == '__main__':dataArr, labelMat = loadDataSet()weights = gradAscent(dataArr, labelMat)# getA():# 将矩阵转换为ndarrayplotBestFit(weights.getA())

7.2. 病马死亡率案例

# coding:utf-8from numpy import *"""病马死亡率案例"""# sigmoid函数def sigmoid(inX):return 1.0 / (1 + exp(-inX))# 随机梯度上升# stochastic gradient ascentdef stocGradAscent0(dataMatrix, classLabels):m, n = shape(dataMatrix)alpha = 0.01weights = ones(n)# 遍历每一个数据for i in range(m):# 数组对应元素相乘再相加h = sigmoid(sum(dataMatrix[i] * weights))error = classLabels[i] - hweights = weights + alpha * error * dataMatrix[i]return weights# 改进后的随机梯度上升# 学习率随迭代次数减少# 随机选择样本def stocGradAscent1(dataMatrix, classLabels, numIter=150):m, n = shape(dataMatrix)weights = ones(n)for j in range(numIter):dataIndex = list(range(m))for i in range(m):# 学习率降低alpha = 4 / (1.0 + j + i) + 0.0001randIndex = int(random.uniform(0, len(dataIndex)))h = sigmoid(sum(dataMatrix[dataIndex[randIndex]] * weights))error = classLabels[dataIndex[randIndex]] - hweights = weights + alpha * error * dataMatrix[dataIndex[randIndex]]del (dataIndex[randIndex])return weights# 分类函数def classifyVector(inX, weights):prob = sigmoid(sum(inX * weights))if prob > 0.5:return 1else:return 0# 构件逻辑回归分类器,进行分类测试def colicTest():frTrain = open('horseColicTraining.txt')frTest = open('horseColicTest.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, 1000)correctCount = 0numTestVec = 0.0# 遍历测试集for line in frTest.readlines():numTestVec += 1.0currLine = line.strip().split('\t')lineArr = []for i in range(21):lineArr.append(float(currLine[i]))if int(classifyVector(array(lineArr), trainWeights)) == int(currLine[21]):correctCount += 1accuracy = (float(correctCount) / numTestVec)print("the accuracy of this test is: %f" % accuracy)return accuracy# 多次测试分类器def multiTest():numTests = 10correctSum = 0.0for k in range(numTests):correctSum += colicTest()print("after %d iterations the average accuracy is: %f" % (numTests, correctSum / float(numTests)))if __name__ == '__main__':multiTest()

如果这篇文章对你有一点小小的帮助,请给个关注喔~我会非常开心的~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。