李宏毅机器学习 Machine_Learning_2019_Task 4_Part II
学习目标
学习逻辑回归 Logistic Regression 算法
- 线性回归
- 正则化(回顾前期Task2)
- 岭回归与Lasso回归(回顾前期Task2)
- 逻辑回归
- 学习逻辑回归与线性回归之间的区别以及 Logistic Regression 梯度下降 (结合对比线性回归的梯度下降法)
- 线性回归是输入到输出的线性变换,其计算的是具体的值,拟合能力有一定限制性,而逻辑回归通过阈值判断的方法,引入了非线性因素,可以处理分类问题(二分类 or 多分类问题);
- 线性回归模型是分析一个变量与另一个变量 or 多个变量(指自变量)之间关系强度的方法,而逻辑回归模型只输出数据点在一个 or 另一个类别中的“概率”,而不是常规数值,同时逻辑回归中的因变量与自变量的对数概率具有线性关系;
- 线性回归的目标值是(−∞, +∞),而逻辑回归的输出一般为(0, 1);
- 逻辑“回归” 是 一种 “分类”模型,其本质是在线性回归的基础上,引入了一个逻辑函数(比如,Sigmoid函数,把y的值从线性回归的(−∞, +∞)限制到了(0, 1)的范围) or 激活函数,用来估计某事件发生的“可能性”(该可能性指的是特征值的加权求和)。换言之,逻辑回归解决的是分类问题,而不是回归问题(对于初学者,估计很难接受这一事实);
梯度下降可视化
RSS指的是点与线之间差异的平方和,该值代表了点与线的距离大小,而梯度下降就是要找出RSS的最小值.
- 推导 Sigmoid 函数公式,理解逻辑回归分类器
不同参数对Logistic分布的影响( 来源于维基百科)
可以看到μ影响的是中心对称点的位置,γ越小中心点附近增长的速度越快,而Sigmoid是一种非线性变换函数,即Logistic分布的γ=1,μ=0的特殊形式(具体推导请回顾Task1)
学习多样本的向量计算
- 基于实例的算法 or 基于记忆的学习
- k近邻(kNN)
- 学习向量量化
- 局部加权学习
- 理解向量化的优点 (One-hot 编码)
- 比较循环与向量化之间的区别
学习 Softmax 激活函数(后续补充)
- Softmax 原理
- Softmax 损失函数
- Softmax 梯度下降
学以致用(继续修改和完善)
-
手动获取数据,基于得到的数据实现 Logistic Regression 逻辑回归算法
''' @Date:Created on May 25, 2019 @Manual Coding:Logistic Regression @Description:手动获取数据,基于得到的数据实现 Logistic Regression 逻辑回归算法 @Author: 追风者 ''' from numpy import * 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): # 转换为NumPy矩阵 dataMatrix = mat(dataMatIn) labelMat = mat(classLabels).transpose() m,n = shape(dataMatrix) alpha = 0.001 maxCycles = 500 weights = ones((n,1)) for k in range(maxCycles): # 矩阵相乘 h = sigmoid(dataMatrix*weights) # 向量减法 error = (labelMat - h) weights = weights + alpha * dataMatrix.transpose() * error return weights 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: 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] ax.plot(x, y) plt.xlabel('X1'); plt.ylabel('X2'); plt.show() def stocGradAscent0(dataMatrix, classLabels): m,n = shape(dataMatrix) alpha = 0.01 # 初始化为1 weights = ones(n) for i in range(m): h = sigmoid(sum(dataMatrix[i]*weights)) error = classLabels[i] - h weights = 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 = range(m) for i in range(m): # apha随着迭代次数的增加而减少,但不能到达0 alpha = 4/(1.0+j+i)+0.0001 randIndex = int(random.uniform(0,len(dataIndex))) h = sigmoid(sum(dataMatrix[randIndex]*weights)) error = classLabels[randIndex] - h weights = weights + alpha * error * dataMatrix[randIndex] del(dataIndex[randIndex]) # 存在问题 return weights def classifyVector(inX, weights): prob = sigmoid(sum(inX*weights)) if prob > 0.5: return 1.0 else: return 0.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) errorCount = 0; numTestVec = 0.0 for line in frTest.readlines(): numTestVec += 1.0 currLine = line.strip().split('\t') lineArr =[] for i in range(21): lineArr.append(float(currLine[i])) if int(classifyVector(array(lineArr), trainWeights))!= int(currLine[21]): errorCount += 1 errorRate = (float(errorCount)/numTestVec) print("the error rate of this test is: %f" % errorRate) return errorRate def multiTest(): numTests = 10; errorSum=0.0 for k in range(numTests): errorSum += colicTest() print("after %d iterations the average error rate is: %f" % (numTests, errorSum/float(numTests)))
数学基础(基础巩固与复习)
- 链式求导法则
- 基础概率与统计知识
- 矩阵乘法与矩阵求导