网站首页 > 技术文章 正文
“经典”机器学习算法通常要求训练数据集采用两个矩阵的格式——一个带样本的矩阵和一个带目标的数组。然而,如何处理观测没有固定长度的数据集呢?
考虑以下情况。您有一个文件数据集,其中每个文件包含一个观察,并且您事先不知道每个文件的长度。不可能将每个文件“flatten”为数字向量,并将这些向量提供给训练算法,因为它们的长度不匹配。我们如何“normalize”观测,使我们能够将它们连接到矩阵中?
在这篇文章中,我将讨论Wrist-Worn Accelerometer数据集(https://archive.ics.uci.edu/ml/datasets/Dataset+for+ADL+Recognition+with+Wrist-worn+Accelerometer),它具有各种长度观测的特征。我将展示如何应用K-Means聚类和随机森林分类器将数据集分类为具有固定长度特征向量的任何其他数据集。
数据集概述
Wrist-Worn Accelerometer数据集代表一组具有3维加速度计测量值的文件。每个文件属于14个类中的一个。每个类代表由加速度计腕带的佩戴者执行的单个动作,例如,步行,饮酒,进食等。总共有839个观测值。
以下直方图显示,通常,每个数据集的文件具有不同数量的记录。例如,我们有26个文件,270个测量值,6个文件,417个记录,依此类推。直方图包括并不代表所有可能的长度,即,存在具有不同观察数量的文件。
我们的目标是将这一堆文件转换为数字矩阵和目标数组,我们可以将其传递到机器学习分类器中。
k - means聚类
为了直观了解K-Means算法如何帮助我们将数据集的观测数据规范化,让我们考虑以下图片:
该图显示了从这个 scikit-learn documentation snippet中获取的手写数字数据的聚类过程的结果。蓝色的点表示数据集的投影到二维空间中使用PCA算法,红色的点在聚类过程中被推断出来。
从图像上可以看出,聚类过程可以被看作是一种原始的连续的连续的平面,形成了一层不均匀的多边形,而这些多边形的数量是由我们指定的,而我们选择的是k -均值算法。
如果我们用最近的(关于欧几里得距离)红点替换每个蓝点,我们就得到了原始点数组的离散表示。因此,不管我们的观测结果如何,它们都被固定大小的质心阵列所取代。
现在情况变得更加清楚了。我们有一个文件(通常)有任意数量的带有观察的行。然后,我们将聚类过程应用到这些观测中。K-Means算法返回一个簇质心数组。我们将这些数组连接到一个固定大小的向量中。从原理上讲,可以用下图来表示该过程:
当我们完成每个文件的过程时,我们将拥有一个具有固定行数和列数的常用数值数据集,并且可以应用任何合适的机器学习算法。
决策树和随机森林
决策树是表示为分析数据集的递归分区的分类器。从数学上讲,它表示一个函数,该函数将属性值的向量作为输入,并返回一个“决策”——一个输出值。树通过对给定的观察属性执行一系列测试来做出决定。树中的每个内部节点都对应于对观察值的一个属性的值的测试,节点的分支被标记为属性的可能值。树中的每个叶节点都指定一个函数要返回的值。
决策树是非常直观的数据分类技术,它“询问”数据集观察组的是 - 否问题,并根据这些“答案”做出决定。但是,这种技术存在一个缺点:决策树对您正在训练它们的数据非常敏感。采用原始数据集的各种训练子集,您可能会获得不同的树,并且它们的准确性可能会有很大差异。此外,单个树预测精度通常不会太高。
如何缓解这些问题呢?其中一个可能的解决方案是构建几棵树并平均预测。这个结果的理论基础来自关于弱学习者的定理。这个想法是,如果你有一个 比一个随机的分类器更好的分类器(比如,在执行二进制分类任务时比均匀硬币要好一点),那么拥有足够数量的这种弱分类器将能够预测类几乎完美准确。
严格地说,为了应用该定理,数据集样本应该是独立且相同分布的随机变量的要求,并且样本来自的分布不应该变化很大。然而,如果每个分类器的训练过程与其他分类器的训练过程略有不同,这种方法在实践中的效果相当好。
将一组弱学习者加入单个强学习者的想法可以应用于任何分类器,而不仅仅应用于决策树。在将这种方法应用于一组树时,强学习者称为随机森林。
现在,当数据集准备就绪并且选择了分类器时,是时候将所有内容连接在一起并构建数据分类管道。
The Pipeline
在使用优秀的scikit-learn库时,构建应该在单个机器上运行的数据分类管道是一个非常简单的过程。唯一需要注意的是我们数据集的特定属性,需要应用预处理技术。
因此,我们只需要读取数据集文件并在库的类之上创建几个thin wrappers。下面的Python代码段显示了如何实现这一点:
"""
Wrist-Worn Accelerometer Dataset using scikit-learn.
"""
import re
from os import listdir
from os.path import exists, join, basename, isdir
import numpy as np
from sklearn.pipeline import make_pipeline
from sklearn.base import TransformerMixin, clone
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.cluster import KMeans
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
class AccelerometerDatasetReader:
"""
A class intended to read the accelerometer dataset and parse their names
to extract observations classes.
"""
FILE_REGEX = re.compile('^Accelerometer-([\d-]+)-(\w+)-(\w\d+).txt