使用Sklearn中的逻辑回归(LogisticRegression)对手写数字(load

一、数据集分析

该手写数据为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 `.
        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:'用户指南中阅读更多内容'.参数 ----------

            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")