本文主要是介绍亦菲喊你来学机器学习(9) --逻辑回归实现手写数字识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 逻辑回归
- 实现手写数字识别
- 训练模型
- 测试模型
- 总结
逻辑回归
逻辑回归(Logistic Regression)虽然是一种广泛使用的分类算法,但它通常更适用于二分类问题。然而,通过一些策略(如一对多分类,也称为OvR或One-vs-Rest),逻辑回归也可以被扩展到多分类问题,如手写数字识别(通常是0到9的10个类别)。
本篇我们就来尝试一下如何通过逻辑回归来实现手写数字识别:
- 训练模型
- 测试模型
实现手写数字识别
训练模型
- 收集数据
- 读取图片
使用opencv处理图片,将图片的像素数值读取进来,并返回的是一个三维(高,宽,颜色)numpy数组:
pip install opencv-python==3.4.11.45
import cv2
img = cv2.imread("digits.png")
- 转为灰度图
将图片转化为灰度图,从而让三维数组变成二位的数组:
grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
- 处理图片信息
对图片进行处理:将其先垂直切分(横向)成50份,再将每一份水平切分(竖向)成100份,这样我们的每份图片的像素值都为20*20(训练的图片比较规范)共500个,比如:
import numpy as np
img_info = [np.hsplit(row,100) for row in np.vsplit(grey,50)]
- 装进array数组
将切分的每一份图片像素数据都装进array数组中:
x = np.array(img_info)
- 分隔训练集与测试集
将数据竖着分隔一半,一半作为训练集,一般作为测试集:
train_x = x[:,:50]
test_x = x[:,50:100]
- 调整数据结构
由于我们最后要将数据放在逻辑回归模型中训练,我们得将数据结构调整为适合逻辑回归算法训练的结构,那么我们就来改变每份图片数组的维度:reshape:
new_train_x = train_x.reshape(-1,400).astype(np.float32)
new_test_x = test_x.reshape(-1,400).astype(np.float32)
- 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)
- 分配标签
我们训练着那么多的数据,却没有给他们具体的类别标签(图像的实际值),因为我们之前的图像处理都是在寻找图像特征,但是并没有给他们一个具体对应的类别,只有空荡荡的特征,无法分类,所以我们得给切分的每份图片打上它们对应的标签:
k = np.arange(10)
train_y = np.repeat(k,250)
test_y = np.repeat(k,250)
train_y = train_y.ravel()
- 交叉验证
在逻辑回归的算法中,逻辑模型的参数中,有一参数为正则化强度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取出最大值的索引位置
- 训练模型
lr_model = LogisticRegression(C = c_choose,max_iter=1000,random_state=0)
lr_model.fit(fin_train,train_y)
测试模型
- 先用训练数据再次进入模型测试,查看他本身的模型训练效果怎么样:
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
- 再用分割的测试集来测试模型:
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
到这为止!!我们就训练好一个关于手写数字识别的逻辑回归模型啦!!
总结
本篇介绍了如何用逻辑回归算法实现手写数字识别:
- 逻辑回归更适合二分类算法,但是也可以通过一些策略,扩展到多分类问题。
- 注意要将读取的数据进行标准化操作,灰度图图片数据相差过大。
- 学会调整参数,优化模型,比如本篇在交叉验证中找寻最优的惩罚因子。
这篇关于亦菲喊你来学机器学习(9) --逻辑回归实现手写数字识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!