干货|机器学习算法相关的数据结构

拥有机器学习技能是不够的。你还须要良好的数据结构的工做知识。学习更多,并解决一些问题。算法

所以,你已经决定再也不使用固定的算法并开始编写本身的机器学习方法。也许你已经有了一种新的集群数据的新方法,或者你可能对你最喜欢的统计分类包的局限性感到失望。编程

不管哪一种状况,你对数据结构和算法的了解越多,在代码编写时就越容易。我不认为机器学习中使用的数据结构与其余软件开发领域的数据结构有很大的不一样。然而,因为许多问题的规模和难度,对基础知识的掌握很是重要。数组

另外,因为机器学习是一个数学性很是强的领域,咱们应该记住,数据结构是如何被用来解决数学问题的,以及它们是如何以本身的方式来处理数学问题的。有两种方法能够对数据结构进行分类:经过它们的实现和它们的操做。数据结构

经过实现,我指的是它们的编程方式和实际存储模式的具体细节。它们的外观并无如何实现更重要。对于按操做或抽象数据类型分类的数据结构来讲,状况偏偏相反——它们的外观和操做比实现方式更重要,事实上,它们一般可使用许多不一样的内部表示来实现。机器学习

数组数据结构和算法

当我说基本数组是机器学习中最重要的数据结构时,我并非在开玩笑。这个实用的类型比你想象的要多。数组很是重要,由于它们被用于线性代数——这是你可使用的最有用和最强大的数学工具。编程语言

所以,最多见的类型分别是一个和二维的类型,分别对应于向量和矩阵,但偶尔会遇到三个或四维的数组,它们要么用于更高级别的张量,要么为前者的组示例。函数

在进行矩阵运算时,你将不得不从使人眼花缭乱的各类库、数据类型、甚至语言中进行选择。许多科学编程语言,如Matlab,交互式数据语言(IDL),以及带有Numpy扩展的Python,主要是为处理向量和矩阵而设计的。工具

但这些数据结构的优势是,即便在更通用的编程语言中,实现向量和矩阵在metal很简单,假设语言中有任何Fortran DNA。考虑矩阵向量乘法的平移:学习

使用C++:

for (int i=0; i<n; i++) { y[i]=0; for (int j=0; j<n; j++) y[i]+=a[i][j]*x[j]}

在大多数状况下,数组能够在运行时分配到固定大小,或者能够计算可靠的上限。在那些须要数组无限扩展的状况下,可使用可扩展数组,例如C ++标准模板库(STL)中的vector类。Matlab中的规则数组具备类似的可扩展性,可扩展数组是整个Python语言的基础。

在这个数据结构中,有两个元数据与实际数据值一块儿存储。 这些是分配给数据结构的存储空间量和阵列的实际大小。一旦数组大小超过存储空间,将分配一个新空间,该空间的大小是其大小的两倍,将值复制到其中,并删除旧数组。

这有一个O(n)操做,其中n是数组的大小,但因为它只是偶尔发生,因此添加一个新值到实际结束的时间实际上被分配到常量时间O(1)。这是一个很是灵活的数据结构,具备快速的平均插入和快速访问。

可扩展数组很是适合组成其余更复杂的数据结构并使其可扩展。例如,要存储稀疏矩阵,能够在结尾添加任意数量的新元素,而后按位置对其进行排序以更快地定位。稍后详述!稀疏矩阵可用于文本分类问题。

链表

链表由几个分开分配的节点组成。每一个节点都包含一个数据值和一个指向列表中下一个节点的指针。插入在不变的时间是很是有效的,可是访问一个值很慢,而且一般须要扫描大部分列表。

链表很容易拼接并分开。有许多变化——例如,能够在头部或尾部进行插入;该列表能够是双连接的,而且有许多相似的数据结构基于相同的原则。

主要是,我发现链表可用于解析不肯定长度的列表。 以后,它们能够转换为固定长度的阵列以便快速访问。出于这个缘由,我使用了一个连接列表类,其中包含一个转换为数组的方法。

二叉树

二叉树与链表类似,只不过每一个节点都有两个指向后续节点的指针而不是一个。左侧孩子的值老是小于父节点的值,而父节点的值又小于右侧孩子的值。所以,二叉树中的数据会自动排序。O(log n)的平均插入和访问都是有效的。像连接列表同样,它们很容易转换为数组,这是树状排序的基础。

平衡树

若是数据已经排序,二叉树在O(n)最差的状况下效率较低,由于数据将被线性排列,就好像它是一个链表。虽然二叉树中的排序受到限制,但它毫不是惟一的,而且能够根据插入的顺序以相同的列表排列许多不一样的配置。

为了使其更加平衡,能够将一些转换应用于树。自平衡树会自动执行这些操做,以保持访问和插入的最佳平均值。

机器学习中广泛存在的问题是找到最接近某一特定点的邻居。这个问题是NN算法所须要的。KD树是一种二叉树,它提供了一种有效的解决方案。

堆是另外一个层次结构,相似于树的有序数据结构,它具备垂直排序,而不是水平排序。这种排序适用于层次结构,但不适用于整个层次:父节点老是大于它的子节点,可是更高级别的节点并不必定比下面的节点要大。

插入和检索都是经过升级来执行的。元素首先插入到最高可用位置。而后将其与其父母进行比较并提高,直至达到正确的等级。为了从堆中去掉一个元素,两个孩子中较大的一个被提高到缺失的位置,而后这两个孩子中较大的一个被提高,如此等等,直到每个都变成正确的等级。

一般状况下,顶部的最高排名值将从堆中取出,以便对列表进行排序。 与树不一样,大多数堆只是简单地存储在数组中,元素之间的关系只是隐含的。

堆栈

一个堆栈被定义为“先进后出”。一个元素被压入堆栈的顶部,覆盖前一个元素。顶部的元素必须先弹出才能访问任何其余元素。

堆栈主要用于解析语法和实现计算机语言。

在许多机器学习应用程序中,领域特定语言(DSL)是完美的解决方案。例如,libAGF库使用递归控制语言将二进制分类通常化到多类。特殊字符用于重复前面的选项,可是因为语言是递归的,因此必须从相同的层次或更高的层次上选择该选项。这是由堆栈实现的。

队列

队列被定义为“先入先出”。想一想银行柜员面前的队伍(对于咱们这些年纪还大的人来讲,还记得在网上银行出现以前的一段时间)。队列在实时编程中很是有用,所以程序能够维护要处理的做业列表。

考虑一个记录运动员分段时间的应用程序。你输入bib号码,而后按回车键,但你要作的时候,后面的运动员也经过了。因此你输入的是最近接近运动员的bib号码列表,而后按下一个单独的键来注册队列中的下一个。

集合

一个集合包含一个非重复元素的无序列表。若是添加已经在集合中的元素,则不会有任何更改。因为机器学习的许多数学知识都与集合有关,因此它们是很是有用的数据结构。

关联数组

在关联数组中,有两种类型的数据成对存储:密钥及其相关值。 数据结构本质上是关系型的:数值由其键来解决。因为大部分训练数据也是关系型的,这种类型的数据结构彷佛很是适合于机器学习问题。在实践中,它的用处不大,部分缘由是大多数关联数组只是一维的,而机器学习数据一般是多维的。

关联数组适用于构建字典。假设你正在构建一个DSL,想要存储一个函数和变量列表,而且须要区分这二者。

sin =函数。

var = 变量。

exp =函数。

x =变量。

sqrt =函数。

a =变量。

在“sqrt”查询数组将返回“函数”。

自定义数据结构

当你处理更多问题时,你确定会遇到标准配方框不包含最佳结构的那些问题。你将须要设计本身的数据结构。考虑一个多类分类器,它归纳了一个二元分类器来处理具备两个以上类的分类问题。一个明显的解决方案是平分:递归地将类分红两组。但分层解决方案并非解决多类的惟一方法,你可使用相似于二叉树的方法来组织二进制分类器。考虑几个分区,而后用它们同时解决全部类的几率。

最通用的解决方案将二者结合起来,所以每一个分层分区不须要是二进制的,而是能够经过非分层多类分类器来解决。这是在libAGF库中采用的方法。

更复杂的数据结构也能够由基本结构组成。考虑一个稀疏矩阵类。在稀疏矩阵中,大多数元素都是零,而且只存储非零元素。咱们能够将每一个元素的位置和值存储为一个三元组,并将它们的列表存储在一个可扩展数组中。

结论

数据结构自己偶尔也颇有趣。令它们真正有趣的是它们能够解决的各类问题。对于大多数工做,我使用了许多基本的固定长度数组。我主要使用更复杂的数据结构来使程序在运行和与外部界面交互方面更加流畅,而且更加便于用户使用。不像之前的Fortran程序那样,为了改变网格大小,我不得不忍受一个接近半小时的编译周期(我实际上在这样的程序上工做过!)。

即便你没法想出一个应用程序,我仍然认为知道诸如栈和队列之类的东西是件好事。你永远不知道何时会派上用场。真正复杂的人工智能应用程序可能会使用定向和无向图,它们只是树和链表的通常化。若是你没法应对后者,你将如何创建起像前者那样的东西?

问题

若是你想本身练习和实现ML算法的数据结构,请尝试解决下面的一些问题:

将矩阵向量乘法代码片断封装到名为matrix_times_vector的子例程中。设计子例程的调用语法。使用struct,typedef或class,将矢量和矩阵分别封装到一对称为vect和matrix的抽象类型中。为这些类型设计一个API。在网上找到至少三个以上的库。

下载并安装LIBSVM库。考虑方法Kernel :: k_function在“svm.cpp”的第316行。用于保存向量的数据结构有哪些优缺点?在LIBSVM库中,如何重构内核函数的计算?文中描述的哪些数据结构是抽象类型?你可使用什么内部表示/数据结构来实现抽象数据类型?上面的列表中是否有未包含的内容?

使用二叉树,设计一个关联数组。

在LIBSVM中考虑向量类型。如何用它来表示一个稀疏矩阵?与上面描述的稀疏矩阵类进行对比。看看完整的类型。每一个表明的优势和缺点是什么?实现一个treesort和一个堆排序。如今使用相同的数据结构来查找前k个元素。什么常见的机器学习算法适合这种状况?用你喜欢的语言实现你最喜欢的数据结构。

原文:https://dzone.com/articles/data-structures-related-to-machine-learning-algori?spm=a2c4e.11153959.blogcont517112.16.6cdb3706CSMuov

End

相关文章
相关标签/搜索