[Python3] 机器学习 ——(二)Scikit-Learn简介

2023-05-16

文章目录

    • 二、Scikit-Learn简介
      • (一)Scikit-Learn的数据表示
        • 1. 数据表
        • 2. 特征矩阵
        • 3. 目标数组
      • (二)Scikit-Learn的评估器API
        • 1. API基础知识
        • 2. 有监督学习示例:简单线性回归
        • 3. 有监督学习示例:鸢尾花数据分类
        • 4. 无监督学习示例:鸢尾花数据降维
        • 5. 无监督学习示例:鸢尾花数据聚类
      • (三)应用:手写数字探索
        • 1. 加载并可视化手写数字
        • 2. 无监督学习:降维
        • 3. 数字分类


[ sklearn version: 0.23.0 ]


二、Scikit-Learn简介

Scikit-Learn为各种常用机器学习算法提供了高效版本。

(一)Scikit-Learn的数据表示

机器学习是从数据创建模型的学问,因此首先需要了解怎样表示数据爱你让计算机理解。Scikit-Learn认为数据表示(data representation)最好的方法就是用数据表的形式。

1. 数据表

基本的数据表就是二维网格数据,其中的每一行表示数据集中的每个样本(samples),而列表示构成每个样本的相关特征(features)。

# 鸢尾花数据集
import pandas as pd
iris = pd.read_csv('./seaborn-data-master/iris.csv')
iris.head()

在这里插入图片描述

  • 每行数据表示每朵被观察的鸢尾花,行数表示数据集中记录的鸢尾花总述。一般会将这个矩阵的行称为样本,行数记为 n_samples,每列数据表示每个样本某个特征的量化值,列数记为 n_features
  • 数据集: mwaskom/seaborn-data - GitHub

2. 特征矩阵

这个表格布局通过二维数组或矩阵的形式将信息清晰地表达出来,通常把这类矩阵称为特征矩阵(features matrix)。

特征矩阵通常被简记为变量X。它是维度为[n_samples, n_features]二维矩阵,通常可以用NumPy数组或Pandas的DataFrame来表示,不过Scikit-Learn也支持SciPy的稀疏矩阵。

样本(每一行)通常是指数据集中的每个对象(任何可以通过一组量化方法进行测量的实体)。

特征(每一列)通常是指每个样本都具有的某种量化观测值。一般情况下,特征都是实数,但有时也可能是布尔类型或离散值。

3. 目标数组

除了特征矩阵 X 之外,还需要一个标签目标数组,通常简记为y

目标数组一般是一维数组,其长度就是样本总数n_samples,通常都用一维的NumPy数组或Pandas的Series表示。

目标数组可以是连续的数值类型,也可以是离散的类型/标签。

有些Scikit-Learn的评估器可以处理具有多目标值的二维[n_samples, n_targets]目标数组,文中基本上只涉及常见一维目标数组问题。

如何区分目标数组的特征与特征矩阵中的特征列,一直是个问题。目标数组的特征通常是我们希望从数据中预测的量化结果,借用统计学的术语,y就是因变量。

  • 以鸢尾花数据集为例,我们需要通过其他测量值来建立模型,预测花的品种(species),species列就可以看成是目标数组
%matplotlib inline
import seaborn as sns
sns.set()
sns.pairplot(iris, hue='species', height=1.5)

在这里插入图片描述

抽取特殊矩阵和目标数组

# 从DataFrame中抽取特征矩阵和目标数组
X_iris = iris.drop('species', axis=1)
X_iris.shape 	# (150, 4)
X_iris

在这里插入图片描述

y_iris = iris['species']
y_iris.shape 	# (150,)
y_iris

在这里插入图片描述

(二)Scikit-Learn的评估器API

Scikit-Learn API主要遵照以下设计原则:

  • 统一性:所有对象使用共同接口连接一组方法和统一的文档
  • 内省:所有参数值都是公共属性
  • 限制对象层级:只有算法可以用Python类表示。数据集都用标准数据类型(NumPy数组、Pandas DataFrame、SciPy稀疏矩阵)表示,参数名称用标准的Python字符串
  • 函数组合:许多机器学习任务都可以用一串基本算法实现,Scikit-Learn尽力支持这种可能
  • 明智的默认值:当模型需要用户设置参数时,Scikit-Learn预先定义适当的默认值

Scikit-Learn中的所有机器学习算法都是通过评估器API实现的,它为各种机器学习应用提供了统一的接口

1. API基础知识

Scikit-Learn评估器API的常用步骤如下:

  1. 通过从Scikit-Learn中导入适当的评估器类,选择模型类
  2. 用合适的数值对模型类进行实例化,配置模型超参数(hyperparameter)
  3. 整理数据,获取特征矩阵和目标数组
  4. 调用模型实例的fit()方法对数据进行拟合
  5. 对新数据应用模型:
    – 在有监督学习模型中,通常使用predict()方法预测新数据的标签
    – 在无监督学习模型中,通常使用transform()predict()方法转换或推断数据的性质

2. 有监督学习示例:简单线性回归

演示一个简单线性回归的建模步骤:最常见的任务就是为散点数据集 ( x , y ) (x,y) (x,y)拟合一条直线

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

rng = np.random.RandomState(42)
x = 10 * rng.rand(50)
y = 2 * x - 1 + rng.randn(50)
plt.scatter(x, y)

(1) 选择模型类

在Scikit-Learn中,每个模型类都是一个Python类。

# 计算一个简单线性回归模型
from sklearn.linear_model import LinearRegression
  • 更多线性模型:sklearn.linear_model - scikit-learn 0.23.0 documentation

(2) 选择模型超参数

注意:模型类与模型实例不同

当我们选择模型类之后,还有许多参数需要配置。根据不同模型的不同情况,你可能需要回答一下问题:

  • 我们想要拟合偏移量(即直线的截距)吗?
  • 我们需要对模型进行归一化处理吗?
  • 我们需要对特征进行预处理以提高模型灵活性吗?
  • 我们打算在模型中使用哪种正则化类型?
  • 我们打算使用多少模型组件(model component)?

有一些重要的参数必须在选择模型类时确定好。这些参数通常被称为超参数,即在模型拟合数据之前必须被确定的参数。

在Scikit-Learn中,通常在模型初始化阶段选择超参数。

# 对于示例,可以实例化LinearRegression类
# 并用fit_intercept超参数设置是否想要拟合直线的截距
model = LinearRegression(fit_intercept=True)
model
# LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)

注意:对模型进行实例化仅仅是存储了超参数的值。我们还没有将模型应用到数据上:Scikit-Learn的API对选择模型将模型应用到数据区别得很清晰。

(3) 将数据整理成特征矩阵和目标数组

Scikit-Learn的数据表示方法(需要二维特征矩阵和一维目标数组)。

虽然我们的目标数组已经有了y(长度为n_samples的数组),但还需要将数据x整理成[n_samples, n_features]的形式。

# 示例中,可以对一维数组进行简单的维度变换
X = x[:, np.newaxis]
X.shape 	# (50, 1)

(4) 用模型拟合数据

现在就可以将模型应用到数据上了,这一步通过模型的fit()方法即可完成。

fit()命令会在模型内部大量运算,运算结果将存储在模型属性中,供用户使用。

model.fit(X, y)
# LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)

在Scikit-Learn中,所有通过fit()方法获得的模型参数都带一条下划线。

# 例如,在线回归模型中,模型参数如下
model.coef_ 		# array([1.9776566])
model.intercept_ 	# -0.9033107255311164
  • model.coef_model.intercept_两个参数分别表示对样本数据拟合直线的斜率和截距
  • 与前面样本数据的定义(斜率2,截距-1)进行比对,发现拟合结果与样本非常接近

模型参数的不确定性是机器学习经常遇到的问题。一般情况下,Scikit-Learn不会为用户提供直接从模型参数获得结论的工具,与其将模型桉树解释为机器学习问题,不如说它更像统计建模问题。机器学习的重点并不是模型的预见性。

(5) 预测新数据的标签

模型预测出来后,有监督机器学习的主要任务就变成了对不属于训练集的新数据进行预测。

在Scikit-Learn中,用predict()方法进行预测

# 新数据是特征矩阵的x坐标值,需要用模型预测出目标数组的y轴坐标
xfit = np.linspace(-1, 11)
# 先将x值转换成[n_samples, n_features]的特征矩阵形式,之后将其输入到模型中
Xfit = xfit[:, np.newaxis]
yfit = model.predict(Xfit)
# 最后把原始数据和拟合结果可视化
plt.scatter(x, y)
plt.plot(xfit, yfit)

在这里插入图片描述

3. 有监督学习示例:鸢尾花数据分类

示例问题:如何为鸢尾花数据集建立模型,先用一部分数据进行㜕,再用模型预测出其他样本的标签?

我们将使用高斯朴素贝叶斯(Gaussian naive Bayes)方法完成。

这个方法假设每个特征中属于每一类的观测值都符合高斯分布。因为高斯朴素贝叶斯分类高斯朴素贝叶斯方法速度很快,而且不需要选择超参数,所以通常很适合作为初步分类手段,在借助更复杂的模型进行优化之前使用。

由于需要用模型之前没有接触过的数据评估它的训练效果,因此得现将数据分割成训练集(training set)和测试集(testing set)。使用train_test_split函数

from sklearn.model_selection import train_test_split
Xtrain, Xtest, ytrain, ytest = train_test_split(X_iris, y_iris, random_state=1)

整理好数据后,用模型预测标签

from sklearn.naive_bayes import GaussianNB 	# 1.选择模型类
model = GaussianNB() 						# 2.初始化模型
model.fit(Xtrain, ytrain) 					# 3.用模型拟合数据
y_model = model.predict(Xtest) 				# 4.对新数据进行预测

最后用accuracy_score工具验证模型预测结果的准确率(预测的所有结果中,正确结果占总预测样本数的比例)

from sklearn.metrics import accuracy_score
accuracy_score(ytest, y_model) 				# 输出:0.9736842105263158
  • 准确率高达97%,表明即使是简单的分类算法也可以有效学习这个数据集

4. 无监督学习示例:鸢尾花数据降维

无监督学习问题:对鸢尾花数据集进行降维,以便能更方便地对数据进行可视化。(鸢尾花数据集由四个维度构成,即每个样本都有四个维度。)

降维的任务是要找到一个可以保留数据本质特征的低维矩阵来表示高维数据。降维通常用于辅助数据可视化的工作(用二维数据画图比用四维甚至更高维的数据画图更方便)

以下将使用主成分分析(principle component analysis, PCA)方法,是一种快速线性降维技术。将用模型返回两个主成分,也就是用二维数据表示鸢尾花的四维数据。

from sklearn.decomposition import PCA 	# 1.选择模型类
model = PCA(n_components=2) 			# 2.设置超参数,初始化模型
model.fit(X_iris) 						# 3.拟合数据(注意这里不用y变量)
X_2D = model.transform(X_iris) 			# 4.将数据转换为二维

可视化结果:快速处理方法就是先将二维数据插入到鸢尾花的DataFrame中,然后用Seaborn的lmplot方法画图

iris['PCA1'] = X_2D[:, 0]
iris['PCA2'] = X_2D[:, 1]
sns.lmplot('PCA1', 'PCA2', hue='species', data=iris, fit_reg=False)

在这里插入图片描述

  • 从二维数据表示图可以看出,虽然PCA算法不知道花的种类标签,但不同种类的花被很清晰区分开,这表明用一种比较简单的分类方法就能有效学习这份数据集

5. 无监督学习示例:鸢尾花数据聚类

聚类算法是要对没有任何标签的数据集进行分组。

此处使用聚类方法之高斯混合模型(Gaussian mixture model, GMM),GMM模型试图将数据构造成若干服从高斯分布的概率密度函数簇。

拟合高斯混合模型:

from sklearn.mixture import GaussianMixture 	# 1.选择模型类
model = GaussianMixture(n_components=3,
                        covariance_type='full') # 2.设置超参数,初始化模型
model.fit(X_iris) 								# 3.拟合数据(注意不需要y变量)
y_gmm = model.predict(X_iris) 					# 4.确定簇标签

将簇标签添加到鸢尾花的DataFrame中,并用Seaborn画出结果

iris['cluster'] = y_gmm
sns.lmplot('PCA1', 'PCA2', data=iris, hue='species',
           col='cluster', fit_reg=False)

在这里插入图片描述

  • 根据簇数量对数据进行分割,就会清洗地看出GMM算法的训练效果:setosa(山鸢尾花)类的花在簇0中被完美地区分出来,唯一的遗憾是第三幅图中versicolor(变色鸢尾花)和virginical(维吉尼亚鸢尾花)还有一点混淆。这就说明,由于每种花的特征差异很大,我们也可以通过简单的聚类算法自动识别出不同种类的花。
  • 这种算法还可以探索观察样本之间的关联性

(三)应用:手写数字探索

挑战一个光学字符识别问题:手写数字识别。这个问题包括图像中字符的定位和识别两部分。

1. 加载并可视化手写数字

用Scikit-Learn的数据获取接口加载数据并简单统计:

from sklearn.datasets import load_digits
digits = load_digits()
digits.images.shape 	# 输出:(1797, 8, 8)
# 图像数据是一个三维矩阵:共有1797个样本,每张图像都是8像素*8像素。

# 对前100张图进行可视化
import matplotlib.pyplot as plt

fig, axes = plt.subplots(10, 10, figsize=(8, 8),
                         subplot_kw={'xticks': [], 'yticks': []},
                         gridspec_kw=dict(hspace=0.2, wspace=0.1))

for i, ax in enumerate(axes.flat):
    ax.imshow(digits.images[i], cmap='binary', interpolation='nearest')
    ax.text(0.05, 0.05, str(digits.target[i]),
            transform=ax.transAxes, color='green')

为了在Scikit-Learn中使用数据,需要一个维度为[n_samples, n_features]的二维特征矩阵,可以将每个样本图像的所有像素都作为特征,也就是将每个数字的8像素*8像素平铺成长度为64的一维数组。另外还需要一个目标数组,用来表示每个数字的真实值(标签)。

# 这两份数据已经在手写数字数据集的data与target属性中,可直接使用
X = digits.data
X.shape 		# 输出:(1797, 64)

y = digits.target
y.shape 		# 输出:(1797,)
# 一共有1797个样本和64个特征

2. 无监督学习:降维

需要借助无监督学习方法将维度降到二维,通过流形学习算法中的Isomap算法对数据进行降维:

from sklearn.manifold import Isomap
iso = Isomap(n_components=2)
iso.fit(digits.data)
data_projected = iso.transform(digits.data)
data_projected.shape 	# 输出:(1797, 2)

# 数据已投影到二维,将二维数据可视化
plt.scatter(data_projected[:, 0], data_projected[:, 1], c=digits.target,
            edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('nipy_spectral', 10))
plt.colorbar(label='digit label', ticks=range(10))
plt.clim(-0.5, 9.5)

在这里插入图片描述

  • 图像呈现了很直观的效果,可以看出数字在64维空间中的分离(可识别)程度。
  • 如,在参数空间中,数字0(黑色)和1(紫色)基本不会重叠。
  • 从图中发现,数字1、4、7有点混淆

3. 数字分类

需要找到一个分类算法,对手写数字进行分类。

# 将数据分成训练集和测试集
Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, random_state=0)

# 用高斯朴素贝叶斯模型来拟合
from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(Xtrain, ytrain)
y_model = model.predict(Xtest)

# 已完成模型预测,用模型在训练集中的正确识别样本量与总训练样本连进行对比,获得模型的准确率
from sklearn.metrics import accuracy_score
accuracy_score(ytest, y_model) 	# 输出:0.8333333333333334
  • 可以看出,通过一个简单的模型,数字识别率就可以高达80%,但仅依靠这个指标,无法知道模型哪里做得不够好,解决这个问题的办法就是用混淆矩阵(confusion matrix)
# 用Scikit-Learn计算混淆矩阵,并用Seaborn可视化
from sklearn.metrics import confusion_matrix

mat = confusion_matrix(ytest, y_model)

sns.heatmap(mat, square=True, annot=True, cbar=True)
plt.xlabel('predicted value')
plt.ylabel('true value')

在这里插入图片描述

  • 从图中可以看出,误判的主要原因在于许多数字2被误判成数字1或8。

另一种显示模型特征的直观方式是将样本画出来,然后把预测标签放在左下角,用绿色表示预测正确,红色表示预测错误

fig, axes = plt.subplots(10, 10, figsize=(8, 8),
                         subplot_kw={'xticks':[], 'yticks':[]},
                         gridspec_kw=dict(hspace=0.1, wspace=0.1))

test_images = Xtest.reshape(-1, 8, 8)

for i, ax in enumerate(axes.flat):
    ax.imshow(test_images[i], cmap='binary', interpolation='nearest')
    ax.text(0.05, 0.05, str(y_model[i]),
            transform=ax.transAxes,
            color='green' if (ytest[i] == y_model[i]) else 'red')

在这里插入图片描述

  • 通过观察这部分样本数据,能知道模型哪里的学习不够好。
  • 如果希望分类准确率达到80%以上,可能需要借助更加复杂的算法,如支持向量机、随机森林或其他分类算法。

机器学习相关阅读:

[Python3] 机器学习 ——(一)机器学习简介


总结自《Python数据科学手册》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[Python3] 机器学习 ——(二)Scikit-Learn简介 的相关文章

  • Linux 权能综述

    为了执行权限检查 xff0c 传统的 UNIX 实现区分两种类型的进程 xff1a 特权进程 xff08 其有效用户 ID 为0 xff0c 称为超级用户或 root xff09 xff0c 和非特权用户 xff08 其有效 UID 非0
  • EGL Context 创建

    继续 EGL context 创建的分析 eglInitialize 来看 EGL10 eglInitialize 的实现 com google android gles jni EGLImpl 中 xff0c 这个方法的实现如下 xff1

随机推荐

  • 【嵌入式】如何使用JLINK RTT打印log日志

    没有串口的情况下可以使用JLINK的RTT即 Real Time Transfer功能 RTT的工作原理大致就是在内存里面创建一个RTT控制块RTT Control Block xff0c 即SEGGER RTT CB结构体 这个结构体里面
  • Android R Settings搜索框功能流程

    Settings 搜索是调用的 SettingsIntelligence 应用的 SearchActivity xff0c 路径 xff1a android packages apps SettingsIntelligence 流程图如下
  • Android R 系统编译时 Lint 工具检查问题记录

    Android R上面对于系统api的修改变更有了新的检查方式 xff0c 对于代码静态检查变得更严格了 xff0c 代码中类型或是参数有些必须要添加 64 NonNull 等注释 xff0c 否则编译不过 编译报错日志大致如下 See t
  • Android 长时间待机后系统概率性无声

    之前一个高通平台项目出现这种问题 xff0c 查看log xff0c 发现出现异常的时候 xff0c 系统 audioserver 挂了 xff0c 导致 audioserver 挂了log 02 24 10 12 46 724 1041
  • 安卓更改app中状态栏和底部手机导航栏背景颜色

    相应的属性 xff1a 在res目录下的values文件夹中有一个styles xml文件 xff0c 它定义了一些安卓应用的布局样式 xff0c 如是否显示默认的actionbar xff1a span class token opera
  • 3.2多纹理效果的像素着色器

    3 2 多纹理效果的像素着色器 下面是像素着色器的代码 xff0c 该代码存储于 ps txt 中 xff0c 该像素着色器根据输入的两套纹理坐标对对应的纹理贴图进行采样 xff0c 根据一定比例 Scalar 混合后输出像素颜色 全局变量
  • 3.3应用程序

    3 3 应用程序 程序中我们首先创建一个四边形 xff0c 然后使用像素着色器进行纹理混合后对其进行渲染 下面是应用程序代码 xff1a 顶点格式定义 struct CUSTOMVERTEX 定点位置坐标 float x y z 两套纹理坐
  • ITK——5. 利用ITK自身的多线程加速filter计算

    文章目录 1 ITK多线程简介 1 1 平台多线程 1 1 1 基本内容 1 1 2 Intel的TBB 1 2 典型例子 执行原理 1 3 5 X版本之后的变动 1 4 ITK多线程整体认识 1 4 1 基本内容 1 4 2 过滤器级别的
  • 4.HLSL Effect(效果框架)

    4 HLSL Effect xff08 效果框架 xff09 进行到这里 xff0c 读者可能会觉得使用着色器多少有些繁琐 xff0c Effect xff08 效果框架 xff09 被提出以解决这些问题 作为一种方法 xff0c Effe
  • 4.2用Effect实现多纹理化效果

    4 2 用 Effect 实现多纹理化效果 前面我们介绍了一个使用像素着色器实现的多纹理化 xff0c 这里用 Effect 框架重新给于实现 xff0c 读者可以比较两者之间的异同 xff0c 体会 Effect 框架给我们带来了哪些方面
  • HLSL初级教程-结语,参考资料

    结语 至此 xff0c HLSL 初级内容介绍完毕 xff0c 相信读者已经对 HLSL 着色器 Effect 等概念有了比较深入的理解 xff0c 并且掌握了 HLSL 编程的基本方法 xff0c 文章中裁去了对 HLSL 语法等细节的讨
  • Unity 3D网页游戏 Demo 展示

    2011 年 xff0c 网页 3D 这一网游开发新趋势逐渐浮出水面 xff0c Unity 作为浏览器及移动设备 3D 引擎领域的佼佼者 xff0c 在国内开始崭露头角 我们团队也完成了首款 Unity Demo 的第一个版本 Demo
  • 用Ogre实现无缝地图

    用 Ogre 实现无缝地图 1 7 版本之前 xff0c 如果想用 Ogre 内建的地形系统实现一个像样的无缝地图 xff0c 恐怕要闹到抓狂 所幸 sinbad 在 1 7 为 Ogre 加入了全新的地形组件 xff0c 它囊括了一个地形
  • 一劳永逸地解决寻路问题

    一劳永逸地解决寻路问题 作者 xff1a PaulT 译者 xff1a trcj 原文 xff1a http www ai blog net archives 000152 html 通常我都会尽量避免对业内游戏产品或开发者们评头论足 但这
  • 口吐莲花

    久不更新blog xff0c 优狗 进展尚可 xff0c 新项目又开 xff0c 忙里偷闲想写点东西 xff0c 一时竟无从下笔 xff0c 以往那种花几天甚至几星期整理一篇技术文章的机会恐怕越来越少了 六月份 优狗 团队新入数名成员 xf
  • Unity3D运行时刻资源管理

    Unity运行时刻资源管理 Asset Bundles 制作 xff1a BuildPipeline BuildAssetBundle 加载 xff1a AssetBundle Load 卸载 xff1a AssetBundle Unloa
  • Unity3D页游《坦克英雄》发布!

    坦克英雄 是一款主打PVP的射击类3D竞技页游 xff0c 它基于Unity引擎 xff0c 以二战坦克为题材 xff0c 既保留了射击类游戏的操作性 xff0c 又缓和了其与页游载体看似相悖的剧烈节奏 xff0c 目前游戏的核心玩法及主体
  • vnc批量登录,8个步骤带你了解Windows中vnc批量登录

    VNC系统由客户端 xff0c 服务端 xff0c 和一个协议组成 服务端目的是分享其所运行的屏幕 xff0c 服务端被动的允许客户端控制它 IIS7服务器管理工具里面的VNC功能可以说是使用感非常棒的 它可以批量打开链接 当然 xff0c
  • mac系统手册(帮助/说明)

    文章目录 1 mac自带的帮助文档2 Mac使用技巧 xff08 提示 xff09 2 1 聚焦搜索2 2 截图 xff08 录制屏幕 xff09 2 3 调出右键菜单2 4 快速查看 xff08 空格预览gif动画 xff09 2 5 翻
  • [Python3] 机器学习 ——(二)Scikit-Learn简介

    文章目录 二 Scikit Learn简介 xff08 一 xff09 Scikit Learn的数据表示1 数据表2 特征矩阵3 目标数组 xff08 二 xff09 Scikit Learn的评估器API1 API基础知识2 有监督学习