参考《机器学习实战》

利用Logistic回归进行分类的主要思想:

根据现有数据对分类边界线建立回归公式,以此进行分类。

分类借助的Sigmoid函数:

Sigmoid函数图:

Sigmoid函数的作用:

将所有特征都乘上一个回归系数,然后将所有结果值相加,将这个总和代入Sigmoid函数中,进而得到一个0~1之间的数值。任何大于0.5的数据被分1类,小于0.5分入0类。

综上,Sigmoid的输入可以记为z:

所以向量w即是我们要通过最优化方法找的系数。

w向量的求解:

1)、梯度上升法(思想:沿函数梯度方向找函数最大值)

梯度上升法伪代码:

更新w系数的细节实现代码:

要注意的是,作者在这里dataMatrix的特征矢量维度比实际特征矢量多了一维。作者使用的数据是二维[x1,x2],而程序中增加了一维[x0=1,x1,x2].奇怪的是x0加在了最前面的位置,而不是最后的位置。此外,上图中画红线处的公式作者未给出由来,网上搜索了下,找到一篇博文,写得还不错。这里帖上点简要概述:

具体过程如下:(参考:http://blog.csdn.net/yangliuy/article/details/18504921?reload

参数概率方程:

其中x为训练特征,y为x对应的类,θ为待估计参数

利用上式中y只取0或1的特点,刚好可以表示为:

似然函数:(这里就是Logistic Regression的目标函数,原书中并未指明,所以如果不网上找logistic的资料区先前学过机器学习,很无法理解书中的做法的)

对数似然函数:

所以极大似然估计:

从而得到梯度上升法的递归公式:

这里也就是上面的图中,我画红线处公式的由来了。

这里再上传下自己写的代码(未优化的logistic算法),代码中的数据来源仍是《机器学习实战》一书提供的数据:

#-*- coding:cp936 -*-
import numpy as np
import matplotlib.pyplot as plt class Log_REG():
def __init__(self):
self._closed=False def loadData(self, dataFile='testSet.txt'):
f_file = open(dataFile)
lines = f_file.readlines()
line_data = lines[0].strip().split()
self.num_feature = len(line_data) - 1
self.xData = np.zeros((len(lines), self.num_feature + 1))
self.label = np.zeros((len(lines), 1))
self.num_label = len(lines)
line_cnt = 0
for iLine in lines:
line_data = iLine.strip().split()
for i in range(self.num_feature):
self.xData[line_cnt][i] = float(line_data[i])
self.xData[line_cnt][self.num_feature] = 1
self.label[line_cnt] = float(line_data[-1])
line_cnt+=1 def _sigmoid(self, z):
return 1.0 / (1 + np.exp(-z)) def gradAscendClass(self):
maxIter = 500
self.omiga = np.ones((1, self.num_feature+1))
xDataMat = np.matrix(self.xData)
alpha = 0.01
self.omiga_record=[]
for i in range(maxIter):
h = self._sigmoid(self.omiga * xDataMat.transpose()) # 矩阵乘
error = self.label - h.transpose()
self.omiga = self.omiga + alpha * (xDataMat.transpose()*error).transpose()
self.omiga_record.append(self.omiga)
if np.sum(np.abs(error)) < self.num_label * 0.05:
print "error very low",i
break def stochasticGradAscend(self):
pass
# maxIter = 150
# self.omiga = np.ones((1,self.num_feature+1))
# for def plotResult(self):
self._close()
if self.num_feature != 2:
print "Only plot data with 2 features!"
return
label0x = []
label0y = []
label1x = []
label1y = []
for i in range(self.num_label):
if int(self.label[i]) == 1:
label1x.append(self.xData[i][0])
label1y.append(self.xData[i][1])
else:
label0x.append(self.xData[i][0])
label0y.append(self.xData[i][1])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(label0x, label0y, c='b',marker='o')
ax.scatter(label1x, label1y, c='r',marker='s') minx = min(min(label0x),min(label1x))
maxx = max(max(label0x),max(label1x))
wx = np.arange(minx,maxx,0.1)
wy = (-self.omiga[0,2]-self.omiga[0,0]*wx)/self.omiga[0,1]
ax.plot(wx,wy) def plotIteration(self):
self._close()
iterTimes = len(self.omiga_record)
w0=[i[0][0,0] for i in self.omiga_record]
w1=[i[0][0,1] for i in self.omiga_record]
w2=[i[0][0,2] for i in self.omiga_record]
fig = plt.figure()
ax1 = fig.add_subplot(3,1,1)
ax1.plot(range(iterTimes),w0,c='b')#,marker='*')
plt.xlabel('w0')
ax2 = fig.add_subplot(3,1,2)
ax2.plot(range(iterTimes),w1,c='r')#,marker='s')
plt.xlabel('w1')
ax3 = fig.add_subplot(3,1,3)
ax3.plot(range(iterTimes),w2,c='g')#,marker='o')
plt.xlabel('w2') def show(self):
plt.show() def _close(self):
pass if __name__ =='__main__':
testclass = Log_REG()
testclass.loadData()
testclass.gradAscendClass()
testclass.plotResult() testclass.plotIteration()
testclass.show()

显示结果:

分类结果

分类参数收敛结果

梯度上升(或下降)算法的改进:

当数据量很大时,上述梯度上升算法每次迭代都要对所有数据进行处理,会造成计算量异常庞大。解决的方法是引入随机梯度的思想。

随机梯度下降的基本原理是:不直接计算梯度的精确值,而是用梯度的无偏估计g(w)来代替梯度:

实际操作时,随机地选取单个数据而非整个数据集参与迭代,详细的原理推导可参见:http://www.52ml.net/2024.html

改进的随机梯度上升法:

def stochasticGradAscend2(self):
maxIter = 150
self.omiga = np.ones((1,self.num_feature+1))
self.omiga_record=[] for j in range(maxIter):
randRange = range(self.xData.shape[0])
for i in range(self.xData.shape[0]):
alpha = 4/(1.0+i+j)+0.01
randIndex = int(random.uniform(0,len(randRange)-1))
index = randRange[randIndex]
h = self._sigmoid(np.matrix(self.omiga)[0]*np.matrix(self.xData[index,:]).transpose())
error = self.label[index]-h self.omiga = self.omiga+alpha*error*self.xData[index,:]
self.omiga_record.append(np.matrix(self.omiga))
del(randRange[randIndex])

从上图可以看出,改进后的随机梯度算法收敛很快,上图只对所有数据做150次迭代。

参考文献:

http://blog.csdn.net/yangliuy/article/details/18504921?reload

随机梯度:http://www.52ml.net/2024.html

机器学习——Logistic回归的更多相关文章

  1. 机器学习——Logistic回归

    1.基于Logistic回归和Sigmoid函数的分类 2.基于最优化方法的最佳回归系数确定 2.1 梯度上升法 参考:机器学习--梯度下降算法 2.2 训练算法:使用梯度上升找到最佳参数 Logis ...

  2. 机器学习——logistic回归,鸢尾花数据集预测,数据可视化

    0.鸢尾花数据集 鸢尾花数据集作为入门经典数据集.Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理.Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集.数据集包含150个数 ...

  3. 机器学习--Logistic回归

    logistic回归 很多时候我们需要基于一些样本数据去预测某个事件是否发生,如预测某事件成功与失败,某人当选总统是否成功等. 这个时候我们希望得到的结果是 bool型的,即 true or fals ...

  4. coursera机器学习-logistic回归,正则化

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  5. 机器学习 Logistic 回归

    Logistic regression 适用于二分分类的算法,用于估计某事物的可能性. logistic分布表达式 $ F(x) = P(X<=x)=\frac{1}{1+e^{\frac{-( ...

  6. 机器学习-- Logistic回归 Logistic Regression

    转载自:http://blog.csdn.net/linuxcumt/article/details/8572746 1.假设随Tumor Size变化,预测病人的肿瘤是恶性(malignant)还是 ...

  7. 吴恩达-机器学习+Logistic回归分类方案

  8. 机器学习简易入门(四)- logistic回归

    摘要:使用logistic回归来预测某个人的入学申请是否会被接受 声明:(本文的内容非原创,但经过本人翻译和总结而来,转载请注明出处) 本文内容来源:https://www.dataquest.io/ ...

  9. 机器学习(4)之Logistic回归

    机器学习(4)之Logistic回归 1. 算法推导 与之前学过的梯度下降等不同,Logistic回归是一类分类问题,而前者是回归问题.回归问题中,尝试预测的变量y是连续的变量,而在分类问题中,y是一 ...

随机推荐

  1. ios开发--高德地图SDK使用简介

    高德LBS开放平台将高德最专业的定位.地图.搜索.导航等能力,以API.SDK等形式向广大开发者免费开放.本章节我们来简单学习一下如何使用它的定位及地图SDK. 一.相关框架及环境配置 地图SDK 对 ...

  2. 64位下好神奇啊(增加了PatchGuard技术保护自己,SSDT是相对地址,参数通过寄存器与rdi来传递)

    近期可能会有一个64位平台的驱动开发任务,找了些资料,对64位平台下的驱动开发略知一二了,好神奇. 一.在64位系统下,有一项PatchGuard技术,它是微软为了防止自己的代码被Patch,进而影响 ...

  3. Android:PopupWindow简单弹窗改进版

    Android:PopupWindow简单弹窗 继续上一节的内容,改进一下,目标是点击菜单后把菜单收缩回去并且切换内容,我使用的是PopupWindow+RadioGroup public class ...

  4. ubuntu服务器/home/分区替换3T硬盘

    一,关机,将硬盘连接到主机. 二,开机 1,查看/dev/ 是否有多余的sdb 注,sda,sdb可以直接看做一整块硬盘. 而sda1,sda2即sda硬盘上的分区. 2,执行fdisk –l,确保添 ...

  5. ifdebug

    #if DEBUG 首先,大小写不能写错. 其次,解决方案配置设为:Debug,才会执行该语句,如果在条件里面搭配Debug.Assert等,效果甚佳.而如果要设置为Release模式,就不会执行条件 ...

  6. NDK(12)Jni常用函数

    参考官方文档 http://docs.oracle.com/javase/7/docs/technotes/guides/jni/ http://docs.oracle.com/javase/7/do ...

  7. 分解成3NF保持函数依赖且为无损连接的算法

    分解成3NF保持函数依赖且为无损连接的算法: 1.根据分解成3NF的保持函数依赖的分解算法(http://www.cnblogs.com/bewolf/p/4443919.html),得到分解结果ρ ...

  8. MyEclipse中使用JUnit进行单元测试

    1. 下载JUnit的jar文件,下载地址在这里 2. 在MyEclipse中新建一个要测试的项目HelloJUnit 3. 添加一个要测试的类HelloJUnit,代码如下,注意需要先建packag ...

  9. UVa 10341 (二分求根) Solve It

    很水的一道题,因为你发现这个函数是单调递减的,所以二分法求出函数的根即可. #include <cstdio> #include <cmath> //using namespa ...

  10. UVa 12716 (GCD == XOR) GCD XOR

    题意: 问整数n以内,有多少对整数a.b满足(1≤b≤a)且gcd(a, b) = xor(a, b) 分析: gcd和xor看起来风马牛不相及的运算,居然有一个比较"神奇"的结论 ...