前几天使用后sklearn实现了逻辑回归,这里用纯python实现逻辑回归.

首先,我们定义一个sigmoid函数

def sigmoid(inX): #sigmoid函数

return 1.0/(1+exp(-inX))

这里使用梯度上升进行逻辑回归

#梯度上升求最优参数

def gradAscent(dataMat, labelMat):

dataMatrix=mat(dataMat) #将读取的数据转换为矩阵

classLabels=mat(labelMat).transpose() #将读取的数据转换为矩阵

m,n = shape(dataMatrix)

alpha = 0.001 #设置梯度的阀值,该值越大梯度上升幅度越大

maxCycles = 500 #设置迭代的次数,一般看实际数据进行设定,有些可能200次就够了

weights = ones((n,1)) #设置初始的参数,并都赋默认值为1。注意这里权重以矩阵形式表示三个参数。

for k in range(maxCycles):

h = sigmoid(dataMatrix * weights)

error = (classLabels - h) #求导后差值

weights = weights + alpha * dataMatrix.transpose()* error #迭代更新权重

return weights

代码里的error与weights已经再上面的公式中可以体现。

考虑到当数据量比较大时,如果每次迭代都选择全量数据进行计算,计算量会非常大。所以采用每次迭代中一次只选择其中的一行数据进行更新权重。

def stocGradAscent0(dataMat, labelMat):

dataMatrix=mat(dataMat)

classLabels=labelMat

m,n=shape(dataMatrix)

alpha=0.01

maxCycles = 500

weights=ones((n,1))

for k in range(maxCycles):

for i in range(m): #遍历计算每一行

h = sigmoid(sum(dataMatrix[i] * weights))

error = classLabels[i] - h

weights = weights + alpha * error * dataMatrix[i].transpose()

return weights

对方法进一步进行改进,在每次迭代中随机选择样本来更新权重,并且随迭代次数增加,权重变化越小。

def stocGradAscent1(dataMat, labelMat):

dataMatrix=mat(dataMat)

classLabels=labelMat

m,n=shape(dataMatrix)

weights=ones((n,1))

maxCycles=500

for j in range(maxCycles): #迭代

dataIndex=[i for i in range(m)]

for i in range(m): #随机遍历每一行

alpha=4/(1+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].transpose()

del(dataIndex[randIndex]) #去除已经抽取的样本

return weights

三种方法得到了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()

下面是三种方法得到的weights的结果

gradAscent迭代500次后得到的weights

gradAscent迭代500次后得到的weights可视化分类

stocGradAscent0迭代500次后得到的weights

stocGradAscent0迭代500次后得到的weights可视化分类

stocGradAscent1迭代500次后得到的weights

stocGradAscent1迭代500次后得到的weights可视化分类

可以看到,这三种方法发挥的weights存在细微差别,但基本都已经使用逻辑回归对数据进行了分类。

实际上,得到的weights就是特征的权值,这里我们将样本数据进行向量化,约定训练数据的矩阵形式如下,x的每一行为一条训练样本,而每一列为不同的特称取值

逻辑回归的优缺点

优点:

速度快,适合二分类问题

简单易于理解,直接看到各个特征的权重

能容易地更新模型吸收新的数据

缺点:

对数据和场景的适应能力有局限性,不如决策树算法适应性那么强

样本数据集,可以复制下来,保存为testSet.txt

-0.017612 14.053064 0

-1.395634 4.662541 1

-0.752157 6.538620 0

-1.322371 7.152853 0

0.423363 11.054677 0

0.406704 7.067335 1

0.667394 12.741452 0

-2.460150 6.866805 1

0.569411 9.548755 0

-0.026632 10.427743 0

0.850433 6.920334 1

1.347183 13.175500 0

1.176813 3.167020 1

-1.781871 9.097953 0

-0.566606 5.749003 1

0.931635 1.589505 1

-0.024205 6.151823 1

-0.036453 2.690988 1

-0.196949 0.444165 1

1.014459 5.754399 1

1.985298 3.230619 1

-1.693453 -0.557540 1

-0.576525 11.778922 0

-0.346811 -1.678730 1

-2.124484 2.672471 1

1.217916 9.597015 0

-0.733928 9.098687 0

-3.642001 -1.618087 1

0.315985 3.523953 1

1.416614 9.619232 0

-0.386323 3.989286 1

0.556921 8.294984 1

1.224863 11.587360 0

-1.347803 -2.406051 1

1.196604 4.951851 1

0.275221 9.543647 0

0.470575 9.332488 0

-1.889567 9.542662 0

-1.527893 12.150579 0

-1.185247 11.309318 0

-0.445678 3.297303 1

1.042222 6.105155 1

-0.618787 10.320986 0

1.152083 0.548467 1

0.828534 2.676045 1

-1.237728 10.549033 0

-0.683565 -2.166125 1

0.229456 5.921938 1

-0.959885 11.555336 0

0.492911 10.993324 0

0.184992 8.721488 0

-0.355715 10.325976 0

-0.397822 8.058397 0

0.824839 13.730343 0

1.507278 5.027866 1

0.099671 6.835839 1

-0.344008 10.717485 0

1.785928 7.718645 1

-0.918801 11.560217 0

-0.364009 4.747300 1

-0.841722 4.119083 1

0.490426 1.960539 1

-0.007194 9.075792 0

0.356107 12.447863 0

0.342578 12.281162 0

-0.810823 -1.466018 1

2.530777 6.476801 1

1.296683 11.607559 0

0.475487 12.040035 0

-0.783277 11.009725 0

0.074798 11.023650 0

-1.337472 0.468339 1

-0.102781 13.763651 0

-0.147324 2.874846 1

0.518389 9.887035 0

1.015399 7.571882 0

-1.658086 -0.027255 1

1.319944 2.171228 1

2.056216 5.019981 1

-0.851633 4.375691 1

-1.510047 6.061992 0

-1.076637 -3.181888 1

1.821096 10.283990 0

3.010150 8.401766 1

-1.099458 1.688274 1

-0.834872 -1.733869 1

-0.846637 3.849075 1

1.400102 12.628781 0

1.752842 5.468166 1

0.078557 0.059736 1

0.089392 -0.715300 1

1.825662 12.693808 0

0.197445 9.744638 0

0.126117 0.922311 1

-0.679797 1.220530 1

0.677983 2.556666 1

0.761349 10.693862 0

-2.168791 0.143632 1

1.388610 9.341997 0

0.317029 14.739025 0

参考资料:

python实现逻辑回归三种方法_纯Python实现逻辑回归相关推荐

  1. python打印菱形三种方法_用python打印菱形的实操方法和代码

    python怎么打印菱形?下面给大家带来三种方法: 第一种 rows = int(input('请输入菱形边长:\n')) row = 1 while row <= rows: col = 1 ...

  2. python猴子吃桃三种解法_【Python】【demo实验22】【练习实例】【猴子吃桃问题】...

    原题: 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个.以后每天早上都吃了前一天剩下的一半零一个.到第10天早上想再吃时,见只 ...

  3. python实时监控文件目录_教你三种方法,用 Python实时监控文件

    原标题:教你三种方法,用 Python实时监控文件 在业务稳定性要求比较高的情况下,运维为能及时发现问题,有时需要对应用程序的日志进行实时分析,当符合某个条件时就立刻报警,而不是被动等待出问题后去解决 ...

  4. python可以播放音乐吗_详解python播放音频的三种方法

    第一种 使用pygame模块 pygame.mixer.init() pygame.mixer.music.load(self.wav_file) pygame.mixer.music.set_vol ...

  5. python调用cmd命令释放端口_详解python调用cmd命令三种方法

    目前我使用到的python中执行cmd的方式有三种 使用os.system("cmd") 该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码, ...

  6. 测试Python下载图片的三种方法

    简 介: 通过Python软件包对网络URL图片链接进行下载,可以加快后期处理.本文测试了urllib, request两个软件包对图片进行下载效果.如果图片原网页有了防止下载机制,是无法下载图片. ...

  7. python学习音频-详解python播放音频的三种方法

    第一种 使用pygame模块 pygame.mixer.init() pygame.mixer.music.load(self.wav_file) pygame.mixer.music.set_vol ...

  8. Python创建多线程的三种方法

    Python创建多线程的三种方法 thread模块函数式创建线程 继承threading类创建多线程 threading模块函数式创建线程 使用总结 thread模块函数式创建线程 调用thread模 ...

  9. python求平方根的三种方法

    python求平方根的三种方法 题干描述 题目解答 题干描述 没啥好说的qwq,求根号下x,并舍弃小数部分,只保留整数 题目解答 方法一:不多bb,直接0.5次方(这应该是最没有营养的解法,面试官估计 ...

最新文章

  1. Spring xml 注入静态变量
  2. 基于Android Studio搭建hello world工程
  3. 【转】 GetProcAddress()用法
  4. eclipse下使用git插件上传代码至github
  5. c语言学生成绩查询课设报告,C语言课设报告(学生考试成绩查询程序)【荐】.doc...
  6. 第四十五期:程序员未来干什么?做架构还是做管理?
  7. 【faster rcnn 实现via的自动框人】使用detectron2中faster rcnn 算法生成人的坐标,将坐标导入via(VGG Image Annotator)中,实现自动框选出人的区域
  8. 计算机应用技术面试的礼仪和技巧,远程复试下,这些面试礼仪一定要注意!
  9. 【转】Rhythm Of The Rain 雨的旋律
  10. java hashmap
  11. Maven学习总结(35)——Maven项目错误 JAX-RS (REST Web Services) 2.0 can not be installed问题
  12. linux打印设备树,Linux 设备树(Device Tree)(转载)
  13. 计算机网络实验一:网线制作
  14. 编写程序计算交错序列_求给定精度的简单交错序列部分和
  15. 魅族春晚广告耗尽预算?继续约陌陌
  16. 花瓣搜索编辑网站的方法
  17. 完成 B1 轮融资后,掌上糖医下一步要做 AI 智能诊疗平台
  18. 新能源汽车行业资讯-2022-9-11
  19. 用友2018秋招Java笔试题(三)
  20. Mathematica12 免费安装教程

热门文章

  1. haimianjie工作日记:2023年6月
  2. icepak计算机机箱热仿真,ANSYS Icepak电子散热基础教程
  3. java短信验证码登录功能设计与实现
  4. 二维码在会议签到中的高效应用
  5. 南城故事---一招教会你怎样清理微信(安卓端)。
  6. 获取实时股票行情数据
  7. 无领导群面如何精准得分?
  8. 教程 | ROS中将urdf转为sdf制作模型包
  9. eval与json转换
  10. 全网首个tk网络音乐播放器!支持歌词滚动!你看我吊不?