Python实现逻辑斯蒂回归

本实验室根据两次考试成绩与是否通过的数据,通过logistic回归,最后获得一个分类器。

逻辑斯蒂回归

导入数据

import numpy as np

def loaddata(file, delimeter):

#以delimeter为分隔符导入file数据

data = np.loadtxt(file, delimiter=delimeter)

print('Dimensions: ',data.shape)

# 打印数据前6行

print(data[1:6,:])

return(data)

data = loaddata('data1.txt', ',')

结果为:

Dimensions: (100, 3)

[[30.28671077 43.89499752 0. ]

[35.84740877 72.90219803 0. ]

[60.18259939 86.3085521 1. ]

[79.03273605 75.34437644 1. ]

[45.08327748 56.31637178 0. ]]

可以看见data的数据结构为一个100*3的矩阵,第一列为exam1的成绩,第二列为exam2的成绩,第三列为是否最终通过(0为否,1为是)。

# 作图显示数据分布

import matplotlib.pyplot as plt

def plotData(data, label_x, label_y, label_pos, label_neg, axes=None):

# 获得正负样本的下标(即哪些是正样本,哪些是负样本)

neg = data[:,2] == 0

pos = data[:,2] == 1

if axes == None:

axes = plt.gca()

axes.scatter(data[pos][:,0], data[pos][:,1], marker='+', c='k', s=60, linewidth=2, label=label_pos)

axes.scatter(data[neg][:,0], data[neg][:,1], c='y', s=60, label=label_neg)

axes.set_xlabel(label_x)

axes.set_ylabel(label_y)

axes.legend(frameon= True, fancybox = True)

plotData(data, 'Exam 1 score', 'Exam 2 score', 'Pass', 'Fail')

读取数据作为X与y向量:

X = np.c_[np.ones((data.shape[0],1)), data[:,0:2]]

y = np.c_[data[:,2]]

则X为:

1 34.6237 78.0247

1 30.2867 43.895

1 35.8474 72.9022

1 60.1826 86.3086

1 79.0327 75.3444

1 45.0833 56.3164

1 61.1067 96.5114

1 75.0247 46.554

1 76.0988 87.4206

1 84.4328 43.5334......

y为:

0

0

0

1

1

0

1

1

1

1......

逻辑斯蒂回归

逻辑斯蒂回归函数设为为:

# 定义sigmoid函数

def sigmoid(z):

return(1 / (1 + np.exp(-z)))

损失函数为:

向量化的损失函数(矩阵形式):

# 定义损失函数

def costFunction(theta, X, y):

m = y.size

# 此处h为一个列向量

h = sigmoid(X.dot(theta))

J = -1.0*(1.0/m)*(np.log(h).T.dot(y)+np.log(1-h).T.dot(1-y))

return J[0]

# 初始化theta为0向量

initial_theta = np.zeros(X.shape[1])

# 此时逻辑斯蒂回归的损失函数值为

cost = costFunction(initial_theta, X, y)

print('Cost:\n', cost)

Cost:

0.6931471805599452

求偏导(梯度)

向量化的偏导(梯度)

# 求梯度

def gradient(theta, X, y):

m = y.size

# 此处h为一100*1的列向量

h = sigmoid(X.dot(theta.reshape(-1,1)))

# grad为一个3*100的矩阵

grad =(1.0/m)*X.T.dot(h-y)

return(grad.flatten())

#此时逻辑斯蒂函数在初始化theta处在Θ0、Θ1、Θ2处的梯度分别为:

grad = gradient(initial_theta, X, y)

print('Grad:\n', grad)

Grad:

[ -0.1 -12.00921659 -11.26284221]

最小化损失函数

# 计算损失函数得最小值。

from scipy.optimize import minimize

# 规定最大迭代次数为400次

res = minimize(costFunction, initial_theta, args=(X,y), jac=gradient, options={'maxiter':400})

res

# minimize()返回的格式是固定的,fun为costFunction函数迭代求得的最小值,hess_inv和jac分别为求得最小值时海森矩阵和雅克比矩阵的值,小写字母x为当costFunction函数最小时函数的解,在costFunction中即为theta的解。即计算损失函数最小时theta的值为[-25.16133284, 0.2062317 , 0.2014716 ]。

Out[17]:

fun: 0.20349770158944375

hess_inv: array([[ 3.31474479e+03, -2.63892205e+01, -2.70237122e+01],

[ -2.63892205e+01, 2.23869433e-01, 2.02682332e-01],

[ -2.70237122e+01, 2.02682332e-01, 2.35335117e-01]])

jac: array([ -9.52476821e-09, -9.31921318e-07, -2.82608930e-07])

message: 'Optimization terminated successfully.'

nfev: 31

nit: 23

njev: 31

status: 0

success: True

x: array([-25.16133284, 0.2062317 , 0.2014716 ])

即损失函数最小时theta的值:

theta = res.x.T

theta

Out[20]: array([-25.16133284, 0.2062317 , 0.2014716 ])

咱们来看看考试1得分45,考试2得分85的同学通过概率有多高

sigmoid(np.array([1,45,85]).dot(theta))

Out[22]: 0.77629072405889421

即考试1得分45,考试2得分85的同学通过概率约为0.7763。

画出决策边界

# 标注考试1得分45,考试2得分85的同学

plt.scatter(45, 85, s=60, c='r', marker='v', label='(45, 85)')

# plotData为之前定义的画分类点的函数

plotData(data, 'Exam 1 score', 'Exam 2 score', 'Admitted', 'Not admitted')

# 生成网格数据

x1_min, x1_max = X[:,1].min(), X[:,1].max(),

x2_min, x2_max = X[:,2].min(), X[:,2].max(),

xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))

# 计算h的值

h = sigmoid(np.c_[np.ones((xx1.ravel().shape[0],1)), xx1.ravel(), xx2.ravel()].dot(res.x))

h = h.reshape(xx1.shape)

# 作等高线,可理解为在这条线上h值为0.5

plt.contour(xx1, xx2, h, [0.5], linewidths=1, colors='b')

加正则化项的逻辑斯蒂回归

导入数据

data2 = loaddata('data2.txt', ',')

data2的格式为:

Dimensions: (118, 3)

[[-0.092742 0.68494 1. ]

[-0.21371 0.69225 1. ]

[-0.375 0.50219 1. ]

[-0.51325 0.46564 1. ]

[-0.52477 0.2098 1. ]]

作分布图

y = np.c_[data2[:,2]]

X = data2[:,0:2]

plotData(data2, 'Microchip Test 1', 'Microchip Test 2', 'y = 1', 'y = 0')

在上一个逻辑回归试验中,我们把sigmoid函数(即这里的g函数)设置的为简单的一次多项式。

在这个逻辑回归实验里,因为样本的分布比较复杂,可以采用多次多项式来代替ΘTX。这里取最高六次项。

取高阶多项式放入sigmoid函数进行模拟

from sklearn.preprocessing import PolynomialFeatures

# 生成一个六次多项式

poly = PolynomialFeatures(6)

# XX为生成的六次项的数据

XX = poly.fit_transform(data2[:,0:2])

# 六次项后有28个特征值了。即,之前我们只有两个特征值x1、x2,取六次项多项式后我们会有x1、x2、x1^2、x2^2、x1*x2、x1^2*x2、……,总共28项。

XX.shape

Out[12]: (118, 28)

正则化

因为取得的多项式最高项为6次,容易发生过拟合情况。将损失函数采取“正则化”处理,引入惩罚项。

正则化后损失函数:

向量化的损失函数(矩阵形式):

# 定义损失函数

def costFunctionReg(theta,reg ,XX, y):

m = y.size

h = sigmoid(XX.dot(theta))

J = -1.0*(1.0/m)*(np.log(h).T.dot(y)+np.log(1-h).T.dot(1-y)) +(reg/(2.0*m))*np.sum(np.square(theta[1:]))

if np.isnan(J[0]):

return(np.inf)

return(J[0])

与之对应的偏导(梯度):

向量化的偏导(梯度):

注意,我们另外自己加的参数 θ0 不需要被正则化

# 定义正则化损失函数的偏导

def gradientReg(theta, reg, XX, y):

m = y.size

h = sigmoid(XX.dot(theta.reshape(-1,1)))

grad = (1.0/m)*XX.T.dot(h-y) + (reg/m)*np.r_[[[0]],theta[1:].reshape(-1,1)]

return(grad.flatten())

设初始化theta为0向量,计算此时初始损失值

initial_theta = np.zeros(XX.shape[1])

costFunctionReg(initial_theta, 1, XX, y)

Out[9]: 0.69314718055994529

画出决策边界

定义预测函数,用来统计准确率。分类的阈值定为0.5,即计算的h(x)>0.5则分到1类(即通过),h(x)<0.5则分到0类(即不通过):

def predict(theta, X, threshold=0.5):

h = sigmoid(X.dot(theta.T)) >= threshold

# 返回的h值只会有两种,1或0

return(h.astype('int'))

决策边界,咱们分别来看看正则化系数lambda太大太小分别会出现什么情况Lambda = 0 : 就是没有正则化,这样的话,就过拟合咯

Lambda = 1 : 这才是正确的打开方式

Lambda = 100 : 卧槽,正则化项太激进,导致基本就没拟合出决策边界

fig, axes = plt.subplots(1,3, sharey = True, figsize=(17,5))

# 分别取lambda为0、1、100

for i, C in enumerate([0.0, 1.0, 100.0]):

# 最优化 costFunctionReg

res2 = minimize(costFunctionReg, initial_theta, args=(C, XX, y), jac=gradientReg, options={'maxiter':3000})

# 准确率

accuracy = 100.0*sum(predict(res2.x, XX) == y.ravel())/y.size

# 对X,y的散列绘图

plotData(data2, 'Microchip Test 1', 'Microchip Test 2', 'y = 1', 'y = 0', axes.flatten()[i])

# 画出决策边界

x1_min, x1_max = X[:,0].min(), X[:,0].max(),

x2_min, x2_max = X[:,1].min(), X[:,1].max(),

xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))

h = sigmoid(poly.fit_transform(np.c_[xx1.ravel(), xx2.ravel()]).dot(res2.x))

h = h.reshape(xx1.shape)

axes.flatten()[i].contour(xx1, xx2, h, [0.5], linewidths=1, colors='g');

axes.flatten()[i].set_title('Train accuracy {}% with Lambda = {}'.format(np.round(accuracy, decimals=2), C))

python做逻辑斯蒂二分类_Python实现逻辑斯蒂回归相关推荐

  1. 用python制作二维码_用python做一个可视化生成二维码的工具

    用python做一个可视化生成二维码的工具 环境 pip install gooey pip install MyQR 源代码 from gooey import GooeyParser,Gooey ...

  2. 基于python的垃圾邮件分类_python实现贝叶斯推断——垃圾邮件分类

    理论 理论强推阮一峰大神的个人网站 1.贝叶斯推断及其互联网应用(一):定理简介 2.贝叶斯推断及其互联网应用(二):过滤垃圾邮件 非常简明易懂,然后我下面的代码就是实现上面过滤垃圾邮件算法的. 前期 ...

  3. python做的游戏可以导出吗_Python for RenderDoc批量导出模型和贴图

    故事背景: 美术那里有需求,需要别人游戏的模型,来借鉴一下,问我是否有工具可以一键导出模型.我就搜索了一下RenderDoc批量导出图片,结果搜到了用C++改RenderDoc源码的文章.让Rende ...

  4. python做一副54扑克牌发牌_python模拟实现分发扑克牌

    本文实例为大家分享了python分发扑克牌的具体代码,供大家参考,具体内容如下 52张扑克牌发个4个玩家,每人13张. 要求: 自动生成一幅扑克牌组:洗牌:发牌到玩家手中:将玩家手中扑克牌按花色大小整 ...

  5. python 将三维数据转为二维_python 二维矩阵转三维矩阵示例

    如下所示: >>> import numpy as np >>> a = np.arange(12).reshape(3,4) >>> a arr ...

  6. lightgbm实战-二分类问题(贝叶斯优化下调参方法)

    # use bayes_opt from sklearn.datasets import make_classification from sklearn.ensemble import Random ...

  7. python 将三维数据转为二维_python将三维数组展开成二维数组的实现

    这篇文章尝试用"曲线救国"的方法来解决二维数组叠加成三维数组的问题. 但天道有轮回,苍天绕过谁.好不容易把数组叠加在一块儿了,新的需求又出现了:将三维数组展开成二维数组.有借有还, ...

  8. python做定时任务的方式及优缺点_python BlockingScheduler定时任务及其他方式的实现...

    本文介绍了python BlockingScheduler定时任务及其他方式的实现,具体如下: #BlockingScheduler定时任务 from apscheduler.schedulers.b ...

  9. python做系统查人的信息_Python综合项目之员工信息查询

    #!/usr/bin/env python # -*- coding: utf-8 -*- import re from db import db_handle ​ ​ # 查询接口 def sele ...

最新文章

  1. 【错误记录】Android Gradle 配置报错 ( gradle.properties 配置到 BuildConfig 中需要注意类型转换 | 位置: 类 BuildConfig )
  2. 数据挖掘导论读书笔记3--分类
  3. 怎么判断间隙过渡过盈配合_尺寸公差配合与装配方法
  4. JavaScript基础11-day13【正则表达式(量词、语法、转义字符、元字符)、DOM(节点、事件)、图片切换】
  5. maven profile实现多环境构建 (单项目多套配置)
  6. jQueryEasyUI框架 - panel 选项卡高度自适应
  7. Android多媒体整体架构图
  8. 关于SSM项目中配置文件的一些心得
  9. 什么是防抖和节流?有什么区别?如何实现?
  10. Python基础学习----异常
  11. 【蓝桥杯单片机进阶强化-01】PCF8591的基本原理与A/D转换应用
  12. Landsat系列卫星遥感影像数据USGS中批量下载多张图像的方法
  13. 英语基础-英语的动词变化
  14. win10怎么在开机时自动连接拨号上网
  15. 【跨域】 关于跨域的一些知识整合
  16. 小学计算机教学打字,怎么快速学拼音打字-小学生如何更快的学习拼音
  17. ide模式ahci模式_IDE的完整形式是什么?
  18. 计算机系统崩溃了怎么办,电脑系统崩溃开不了机怎么办
  19. python 求x的 n次方
  20. qq浏览器HTML5在哪,qq浏览器wifi助手功能在哪里?

热门文章

  1. java矩阵addall_为什么Collections.addAll()比arrays.addAll()性能好?
  2. DEDE fck编辑器插件 图片排版 自动排版 繁简转换
  3. c语言标志符由什么组成,C语言的标识符由什么组成
  4. Front-end Internal error: Failed to analyze declaration .kts运行报错问题,创建kotlin script运行报错
  5. dlp数据防泄漏(dlp数据防泄漏系统可以监控个人电脑吗)
  6. java 框架用来做什么_Java框架(一)——什么是框架?
  7. 真正的3D桌面!以后的Windows会是这样的?
  8. 深入浅出CChart 每日一课——第十九课 人往高处走,屌丝逆袭白富美之VS2010
  9. 小米平板2怎么样卡刷开发版启用root权限
  10. HeadFirst设计模式-模板方法模式