亦菲喊你来学机器学习(9) --逻辑回归实现手写数字识别

2024-08-23 15:04

本文主要是介绍亦菲喊你来学机器学习(9) --逻辑回归实现手写数字识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 逻辑回归
  • 实现手写数字识别
    • 训练模型
    • 测试模型
  • 总结

逻辑回归

逻辑回归(Logistic Regression)虽然是一种广泛使用的分类算法,但它通常更适用于二分类问题。然而,通过一些策略(如一对多分类,也称为OvR或One-vs-Rest),逻辑回归也可以被扩展到多分类问题,如手写数字识别(通常是0到9的10个类别)。

本篇我们就来尝试一下如何通过逻辑回归来实现手写数字识别

  1. 训练模型
  2. 测试模型

实现手写数字识别

训练模型

  1. 收集数据

在这里插入图片描述

  1. 读取图片

使用opencv处理图片,将图片的像素数值读取进来,并返回的是一个三维(高,宽,颜色)numpy数组:

 pip install opencv-python==3.4.11.45
import cv2
img = cv2.imread("digits.png")
  1. 转为灰度图

将图片转化为灰度图,从而让三维数组变成二位的数组:

grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  1. 处理图片信息

对图片进行处理:将其先垂直切分(横向)成50份,再将每一份水平切分(竖向)成100份,这样我们的每份图片的像素值都为20*20(训练的图片比较规范)共500个,比如:

在这里插入图片描述

import numpy as np
img_info = [np.hsplit(row,100) for row in np.vsplit(grey,50)]
  1. 装进array数组

将切分的每一份图片像素数据都装进array数组中:

x = np.array(img_info)
  1. 分隔训练集与测试集

将数据竖着分隔一半,一半作为训练集,一般作为测试集:

train_x = x[:,:50]
test_x = x[:,50:100]
  1. 调整数据结构

由于我们最后要将数据放在逻辑回归模型中训练,我们得将数据结构调整为适合逻辑回归算法训练的结构,那么我们就来改变每份图片数组的维度:reshape:

new_train_x = train_x.reshape(-1,400).astype(np.float32)
new_test_x = test_x.reshape(-1,400).astype(np.float32)
  1. Z-score标准化

逻辑回归算法进行手写数字识别时,对数据进行标准化是为了提高优化算法的收敛速度、提升模型的预测性能,并避免潜在的数值问题。将数据都进行表示话,避免参数的影响:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
fin_train = scaler.fit_transform(new_train_x)
fin_test = scaler.fit_transform(new_test_x)
  1. 分配标签

我们训练着那么多的数据,却没有给他们具体的类别标签(图像的实际值),因为我们之前的图像处理都是在寻找图像特征,但是并没有给他们一个具体对应的类别,只有空荡荡的特征,无法分类,所以我们得给切分的每份图片打上它们对应的标签:

k = np.arange(10)
train_y = np.repeat(k,250)
test_y = np.repeat(k,250)
train_y = train_y.ravel()
  1. 交叉验证

在逻辑回归的算法中,逻辑模型的参数中,有一参数为正则化强度C,越小的数值表示越强的正则化。我们要进行调参数,看看哪个惩罚因子最为合适,使模型拟合效果更好:

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score#交叉验证选择较优的惩罚因子
scores = []
c_param_range = [0.01,0.1,1,10,100] #参数:一般常用的惩罚因子for i in c_param_range:lr = LogisticRegression(C = i,penalty='l2',solver='lbfgs',max_iter=1000,random_state=0)# C表示正则化强度,越小的数值表示越强的正则化。防止过拟合score = cross_val_score(lr,fin_train,train_y,cv=10,scoring='recall_macro')#交叉验证,将模型和数据集传入,对其进行划分,每份轮流作为测试集来测试模型。返回一个列表对象score_mean = sum(score)/len(score)scores.append(score_mean)
c_choose = c_parma[np.argmax(scores)] #argmax取出最大值的索引位置
  1. 训练模型
lr_model = LogisticRegression(C = c_choose,max_iter=1000,random_state=0)
lr_model.fit(fin_train,train_y)

测试模型

  1. 先用训练数据再次进入模型测试,查看他本身的模型训练效果怎么样:
from sklearn import metrics
train_predict = lr_model.predict(fin_train)
print(metrics.classification_report(train_y,train_predict))  #查看混淆矩阵
-------------------------------precision    recall  f1-score   support0       0.99      1.00      0.99       2501       0.98      1.00      0.99       2502       1.00      0.98      0.99       2503       0.98      0.98      0.98       2504       1.00      1.00      1.00       2505       0.98      0.98      0.98       2506       0.99      1.00      1.00       2507       0.98      0.99      0.98       2508       0.98      0.99      0.99       2509       0.99      0.97      0.98       250accuracy                           0.99      2500macro avg       0.99      0.99      0.99      2500
weighted avg       0.99      0.99      0.99      2500
  1. 再用分割的测试集来测试模型:
test_predict = lr_model.predict(fin_test)
print(metrics.classification_report(test_y,test_predict))
---------------------------precision    recall  f1-score   support0       0.95      0.96      0.95       2501       0.94      0.96      0.95       2502       0.88      0.86      0.87       2503       0.90      0.86      0.88       2504       0.92      0.84      0.88       2505       0.84      0.90      0.87       2506       0.92      0.95      0.93       2507       0.89      0.93      0.91       2508       0.89      0.84      0.86       2509       0.83      0.86      0.85       250accuracy                           0.90      2500macro avg       0.90      0.90      0.89      2500
weighted avg       0.90      0.90      0.89      2500

到这为止!!我们就训练好一个关于手写数字识别的逻辑回归模型啦!!

总结

本篇介绍了如何用逻辑回归算法实现手写数字识别:

  1. 逻辑回归更适合二分类算法,但是也可以通过一些策略,扩展到多分类问题。
  2. 注意要将读取的数据进行标准化操作,灰度图图片数据相差过大。
  3. 学会调整参数,优化模型,比如本篇在交叉验证中找寻最优的惩罚因子。

这篇关于亦菲喊你来学机器学习(9) --逻辑回归实现手写数字识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099719

相关文章

springboot filter实现请求响应全链路拦截

《springbootfilter实现请求响应全链路拦截》这篇文章主要为大家详细介绍了SpringBoot如何结合Filter同时拦截请求和响应,从而实现​​日志采集自动化,感兴趣的小伙伴可以跟随小... 目录一、为什么你需要这个过滤器?​​​二、核心实现:一个Filter搞定双向数据流​​​​三、完整代码

SpringBoot利用@Validated注解优雅实现参数校验

《SpringBoot利用@Validated注解优雅实现参数校验》在开发Web应用时,用户输入的合法性校验是保障系统稳定性的基础,​SpringBoot的@Validated注解提供了一种更优雅的解... 目录​一、为什么需要参数校验二、Validated 的核心用法​1. 基础校验2. php分组校验3

Python实现AVIF图片与其他图片格式间的批量转换

《Python实现AVIF图片与其他图片格式间的批量转换》这篇文章主要为大家详细介绍了如何使用Pillow库实现AVIF与其他格式的相互转换,即将AVIF转换为常见的格式,比如JPG或PNG,需要的小... 目录环境配置1.将单个 AVIF 图片转换为 JPG 和 PNG2.批量转换目录下所有 AVIF 图

Pydantic中model_validator的实现

《Pydantic中model_validator的实现》本文主要介绍了Pydantic中model_validator的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录引言基础知识创建 Pydantic 模型使用 model_validator 装饰器高级用法mo

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

Redis分片集群的实现

《Redis分片集群的实现》Redis分片集群是一种将Redis数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性,本文主要介绍了Redis分片集群的实现,具有一定的参考价值,感兴趣的可以了解一... 目录1. Redis Cluster的核心概念哈希槽(Hash Slots)主从复制与故障转移2.

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文