一、数据集分析
该手写数据为Sklearn内置数据集,导入数据集:
from sklearn.datasets import load_digits
1.1 数据集规格
- 1797个样本,每个样本包括8*8像素的图像和一个[0, 9]整数的标签
- 数据集data中,每一个样本均有64个数据位float64型。
- 关于手写数字识别问题:通过训练一个8x8 的手写数字图片中每个像素点不同的灰度值,来判定数字,是一个分类问题.
内置文件来自作者的解说:
"""Load and return the digits dataset (classification).
Each datapoint is a 8x8 image of a digit.
================= ==============
Classes 10
Samples per class ~180
Samples total 1797
Dimensionality 64
Features integers 0-16
================= ==============
This is a copy of the test set of the UCI ML hand-written digits datasets
https://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits
Read more in the :ref:`User Guide <digits_dataset>`.
Parameters
----------
n_class : int, default=10
The number of classes to return. Between 0 and 10.
return_X_y : bool, default=False
If True, returns ``(data, target)`` instead of a Bunch object.
See below for more information about the `data` and `target` object.
.. versionadded:: 0.18
as_frame : bool, default=False
If True, the data is a pandas DataFrame including columns with
appropriate dtypes (numeric). The target is
a pandas DataFrame or Series depending on the number of target columns.
If `return_X_y` is True, then (`data`, `target`) will be pandas
DataFrames or Series as described below.
.. versionadded:: 0.23
Returns
-------
data : :class:`~sklearn.utils.Bunch`
Dictionary-like object, with the following attributes.
data : {ndarray, dataframe} of shape (1797, 64)
The flattened data matrix. If `as_frame=True`, `data` will be
a pandas DataFrame.
target: {ndarray, Series} of shape (1797,)
The classification target. If `as_frame=True`, `target` will be
a pandas Series.
feature_names: list
The names of the dataset columns.
target_names: list
The names of target classes.
.. versionadded:: 0.20
frame: DataFrame of shape (1797, 65)
Only present when `as_frame=True`. DataFrame with `data` and
`target`.
.. versionadded:: 0.23
images: {ndarray} of shape (1797, 8, 8)
The raw image data.
DESCR: str
The full description of the dataset.
(data, target) : tuple if ``return_X_y`` is True
A tuple of two ndarrays by default. The first contains a 2D ndarray of
shape (1797, 64) with each row representing one sample and each column
representing the features. The second ndarray of shape (1797) contains
the target samples. If `as_frame=True`, both arrays are pandas objects,
i.e. `X` a dataframe and `y` a series.
.. versionadded:: 0.18
Examples
--------
To load the data and visualize the images::
>>> from sklearn.datasets import load_digits
>>> digits = load_digits()
>>> print(digits.data.shape)
(1797, 64)
>>> import matplotlib.pyplot as plt
>>> plt.gray()
>>> plt.matshow(digits.images[0])
<...>
>>> plt.show()
"""
翻译(翻译的一言难尽,将就一下吧):
“”“加载并返回数字数据集(分类)。每个数据点都是一个数字的 8x8 图像。 ==============类 每类 10 个样本 ~180 个样本 共 1797 维 64 特征 整数 0-16 ============== 这是 UCI ML 手写数字数据集测试集的副本 https:archive.ics.uci.edumldatasetsOptical+Recognition+of+Handwritten+Digits
在 :ref:'用户指南<digits_dataset>中阅读更多内容'.参数 ----------
n_class : int, default=10 要返回的类数。介于 0 和 10 之间。
return_X_y : bool, default=False 如果为 True,则返回 ''(data, target)'' 而不是 Bunch 对象。有关“data”和“target”对象的详细信息,请参阅下文。
as_frame : bool, default=False ,如果为 True,则数据是 pandas DataFrame,其中包含具有适当 dtypes (numeric) 的列。目标是 pandas DataFrame 或 Series,具体取决于目标列的数量。如果 'return_X_y' 为 True,则 ('data', 'target') 将是 pandas DataFrames 或 Series,如下所述。
返回-------数据: :class:'~sklearn.utils.Bunch' 类似字典的对象,具有以下属性。
data : {ndarray, dataframe} of shape (1797, 64) 扁平化的数据矩阵。如果 'as_frame=True',则 'data' 将是一个 pandas DataFrame。
target: {ndarray, Series} of shape (1797,) 分类目标。如果 'as_frame=True',则 'target' 将是pandas Series。
feature_names:list 数据集列的名称。
target_names:列出目标类的名称。
frame: shape(1797, 65)的DataFrame,仅当'as_frame=True'时才出现。带有“data”和“target”的 DataFrame。
images: {ndarray} of shape (1797, 8, 8) 原始图像数据。
DESCR: str 数据集的完整描述。
(data, target) : tuple if ''return_X_y'' is True 默认情况下,两个 ndarrays 的元组。第一个包含形状 (1797, 64) 的 2D ndarray,每行代表一个样本,每列代表特征。形状 (1797) 的第二个 ndarray 包含目标样本。如果 'as_frame=True',则两个数组都是 pandas 对象,即 'X' 是数据帧,“y”是序列
1.2 加载数据
# 获取数据集数据和标签
datas = load_digits()
X_data = datas.data
y_data = datas.target
1.3 展示数据集中前十个数据
代码:
from matplotlib import pyplot as plt
# 展示前十个数据的图像
fig, ax = plt.subplots(
nrows=2,
ncols=5,
sharex=True,
sharey=True, )
ax = ax.flatten()
for i in range(10):
ax[i].imshow(datas.data[i].reshape((8, 8)), cmap='Greys', interpolation='nearest')
plt.show()
图像:
二、数据处理
2.1 划分数据集
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.3)
三、建立模型
3.1 逻辑回归
3.1.1 LogisticRegression()主要参数
penalty:指定正则化的参数可选为 "l1", “l2” 默认为 “l2”. 注意: l1 正则化会将部分参数压缩到 0 ,而 l2 正则化不会让参数取到 0 只会无线接近C:大于 0 的浮点数。 C 越小对损失函数的惩罚越重multi_class:告知模型要处理的分类问题是二分类还是多分类。 默认为 “ovr” (二分类) “multinational”: 表示处理多分类问题,在solver="liblinear" 时不可用 “auto” : 表示让模型自动判断分类类型solver:指定求解方式
3.2 建立逻辑回归模型
# 建立逻辑回归模型
model = LogisticRegression(max_iter=10000, random_state=42, multi_class='multinomial')
# 训练模型
model.fit(X_train, y_train)
四、模型评估
4.1 十折交叉验证
十折交叉验证是将训练集分割成10个子样本,一个单独的子样本被保留作为验证模型的数据,其他9个样本用来训练。交叉验证重复10次,每个子样本验证一次,平均10次的结果或者使用其它结合方式,最终得到一个单一估测。这个方法的优势在于,同时重复运用随机产生的子样本进行训练和验证,每次的结果验证一次,10次交叉验证是最常用的。
scores = cross_val_score(model, X_train, y_train, cv=10) # 十折交叉验证
k = 0
for i in scores:
k += i
print("十折交叉验证平均值:", k / 10)
print(f"十折交叉验证:{scores}\n")
结果:
4.2 错误率
y_pred = model.predict(X_test)
error_rate = model.score(X_test, y_test)
print(f"错误率:{error_rate}\n")
print(f"测试集预测值:{y_pred}\n")
结果:
五、源码
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_digits
from sklearn.model_selection import cross_val_score, train_test_split
from matplotlib import pyplot as plt
# 获取数据集数据和标签
datas = load_digits()
X_data = datas.data
y_data = datas.target
# 展示前十个数据的图像
fig, ax = plt.subplots(
nrows=2,
ncols=5,
sharex=True,
sharey=True, )
ax = ax.flatten()
for i in range(10):
ax[i].imshow(datas.data[i].reshape((8, 8)), cmap='Greys', interpolation='nearest')
plt.show()
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.3)
# 建立逻辑回归模型
model = LogisticRegression(max_iter=10000, random_state=42, multi_class='multinomial')
scores = cross_val_score(model, X_train, y_train, cv=10) # 十折交叉验证
k = 0
for i in scores:
k += i
print("十折交叉验证平均值:", k / 10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
error_rate = model.score(X_test, y_test)
print(f"十折交叉验证:{scores}\n")
print(f"错误率:{error_rate}\n")
print(f"测试集预测值:{y_pred}\n")