AAAMLP-Chapter-1: Supervised vs unsupervised learning

141 阅读5分钟

在处理机器学习问题时,通常有两大类数据:

  • 监督数据,带有一个或多个标签。

  • 无监督数据,不含目标变量。

监督学习通常比无监督学习简单,那些需要我们预测某个数值的问题通常是监督学习。

例如,在给定历史房价序列上预测房价,数据中包含周围是否有医院、学校或商场、最近地铁站的距离等。

相似地,假如有一组猫猫狗狗图片,提前给定哪些图内容是猫、哪些图内容是狗,然后让我们构造模型预测输入图片的内容是猫还是狗,这类问题被认为是监督问题。

如图 1 所示,每行数据对应一个目标值,该行通常被称为样本点 Sample,该目标值通常被称为 Target 或 Label;目标值可以是数值也可以是类别名称;每列表示不同特征值。

图中展示了 10 个样本,每个样本有 10 个特征值和 1 个目标值。如果目标值是类别名称,则该问题被称为分类问题。如果目标值是数值,该问题被称为回归问题。

因此,监督学习可以划分为两类:

  • 分类,预测类别,如猫、狗。

  • 回归,预测数值,如房价。

需要注意的是,有时候我们在分类问题中计算回归,这取决于计算时用到的度量值类型。

另一类机器学习问题是无监督学习,无监督数据集通常不含有目标值,在解决此类问题时难度更大。

假如你在金融公司工作,处理信用卡和转账业务,每秒都有一大批新数据。现在的问题是,如何将每笔交易标记为有效、真实的交易或欺诈,原始数据中没有关于交易真实或欺诈的信息,这类问题即为无监督问题。

为解决无监督问题,需要思考数据可被分为几类。分类 Clustering 是解决无监督问题的方法之一,但需记得,除此之外还有其他方法。

对于欺诈检测问题,数据可以分为两类(欺诈、真实)。在类别数量已知的情况下,可使用聚类算法处理无监督学习问题。

图 2 中数据分为两类,深色表示欺诈交易,浅色表示真实交易,然而这些类别信息在聚类操作之前是未知的,使用聚类算法后,才能辨别该类别信息。

对于无监督学习,我们可以使用许多分解技术 Decomposition Techniques,如 Principal Component Analysis (PCA)、t-Distributed Stochastic Neighbour Embedding (t-SNE) 等。

处理无监督算法的结果时,往往需要进行人工推断和启发式规则处理。

通常在人们刚接触数据科学或机器学习时,要从经典数据集上进行监督学习,如 Titanic、Iris 数据集。

在 Titanic 数据集上,基于幸存者的船票类型、性别、年龄等特征,预测幸存概率。在 Iris 数据集上,基于花萼和花瓣的长宽,预测鸢尾花的类别。

无监督学习数据集可能是客户分类数据集,例如,电商或超市顾客的访问数据,需将顾客分为不同类别。

通常可以将监督数据集转换为无监督数据集,并通过绘制图片来查看细节。

例如,对于 MNIST 数据集,该数据集包含手写数字图片和对应的数字值,用于监督学习任务,预测输入图片中的数字。

该数据集可以很方便的转为无监督版本,并绘图显示。通过对 MNIST 数据集做 t-SNE 分解,将数据降到两维,可以将其绘制到散点图上,观察其划分特征。

实现代码如下,首先导入依赖库。

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn import datasets, manifold

我们使用 matplotlibseaborn 绘图,用 numpy 构建数组,用 pandas 做数组变换,用 scikit-learn 执行 t-SNE 算法。

执行导入之后,下载数据。

data = datasets.fetch_openml(
    'mnist_784',
    version=1,
    return_X_y=True
)
pixel_values, targets = data
targets = targets.astype(int)

在代码里,通过 sklearn 的 datasets 模块下载数据,得到一组像素和一组目标值,目标值原始类型为 string,这里将其转换为 int。

pixel_values 是 2 维数组,形状为 70000x784,表示有 70000 个图片,每个图片有 784 个像素点,即将 28x28 图片的像素值按行展平到长度为 784 的数组。

可以通过以下代码,从数据集中取出一个样本的像素数字,将其恢复为 28x28 的图片格式,然后做可视化显示。

single_img = pixel_values.to_numpy()[1, :].reshape(28, 28)
plt.imshow(single_img, cmap='gray')

下边是最重要的一步,创建数据的 t-SNE 变换,为便于可视化,我们只将其分解到两个维度。

tsne = manifold.TSNE(n_components=2, random_state=42)
transformed_data = tsne.fit_transform(
    pixel_values.to_numpy()[:3000, :]
)

tsne_df = pd.DataFrame(
    np.column_stack((transformed_data, targets[:3000])),
    columns=['x', 'y', 'targets']
)
tsne_df.loc[:, 'targets'] = tsne_df.targets.astype(int)

然后,使用 seaborn 和 matplotlib 绘制分解后到数据,结果将如图 4 所示。

grid = sns.FacetGrid(tsne_df, hue='targets')
grid.map(plt.scatter, 'x', 'y').add_legend()

这是可视化无监督数据的一种方式,也可以使用 k-means 聚类。一个在心里不断出现的问题是,如何确定聚类的最优数量?这个问题没有固定答案,需要通过交叉验证的方法算出这个最优数量。

MNIST 是一个监督分类问题,我们将其转换为无监督学习问题,尝试通过聚类方法获取类别划分,似乎 t-SNE 分解后的结果质量还不错。