简介
Mlpack是一个C++机器学习库,侧重于可扩展性、速度和易用性。它的目的是通过一个简单的、前后一致的API让新用户使用机器学习成为可能,同时利用C++语言特征为专家用户提供最好的性能和最大的灵活性。这些通过提供一系列命令行执行程序完成,就像使用一个黑箱,而且专家用户和研究者可以容易的更改一个模块化的C++ API的内部算法。
这种方法的结果就是Mlpack的性能大幅度超过其他竞争的机器学习库;在The BigLearning Workshop Paper 和The Benchmarks For Details查看细节。
Mlpack由全世界的贡献者开发。基于伯克利发行软件许可的第三个条款免费发行。(比1.0.12更老的版本基于GNU通用公共授权规定发行:LGPL,第3版。)
安装
Mlpack存储在许多Linux的发行版本中,所以在你的系统中使用程序包管理器可能更容易一些。例如:在Ubuntu上,你可以使用下面的命令安装Mlpack。
sudo apt-get install libmlpack-dev
如果Mlpack不能在你的系统的程序包管理器中使用,那么你可以按照下面的步骤编译和安装Mlpack源文件。
Mlpack使用CMake作为生成系统,允许几个灵活的生成配置选项。你可以查询大量的CMake教程得到更多的文件,但是这个教程应该足够让你在大多数Linux和类UNIX系统中(包括OS X)成功生成和安装Mlpack。如果你想在Windows操作系统中生成Mlpack,请看这里。
首先下载Mlpack。
当Mlpack的源文件完成解压,你可以创建一个生成目录。
cd mlpack-2.2.5
mkdir build
这个目录可以是任何名字,不仅仅是“Build”,但是“Build”足够了。
Mlpack依赖项
Mlpack依赖下面的库,它们需要被安装在系统中并有一些头文件出现。
Armadillo >=4.200.0(支持LAPACK(线性代数程序包))
Boost(Math_c99, Program_options, Serialization, Unit_test_framework, Heap, Spirit)>=1.49
在Ununtu和Debian中,你可以通过Apt获得所有这些依赖项:
dnf install boost-devel boost-test boost-program-options boost-math
armadillo-devel binutils-devel
配置CMake
运行CMake相当于使用Autotools运行./Configure。
如果你工作中使用Mlpack的Svn Trunk版本,且不带任何选项运行CMake,它将配置这个生成项目带有调试符号和分析信息:如果你工作中使用发行版本的Mlpack,不带任何选项运行CMake,它将配置这个生成项目不带调试符号和分析信息(为了速度)。
cd build
cmake../
你可以手动指定选项去编译或不编译调试信息和分析信息(也就是说尽可能快):
cd build
cmake-DDEBUG=OFF-DPROFILE=OFF../
Mlpack允许的全部选项为:
DEBUG=(ON/OFF): Compile With Debugging Symbols (Default ON In Svn Trunk, OFF In Releases)
PROFILE=(ON/OFF): Compile With Profiling Symbols (Default ON In Svn Trunk, OFF In Releases)
ARMA_EXTRA_DEBUG=(ON/OFF): Compile With Extra Armadillo Debugging Symbols (Default OFF)
BUILD_TESTS=(ON/OFF): Compile The Mlpack_test Program (Default ON)
BUILD_CLI_EXECUTABLES=(ON/OFF): Compile The Mlpack Command-Line Executables (I.E. Mlpack_knn, Mlpack_kfn, Mlpack_logistic_regression, Etc.) (Default ON)
TEST_VERBOSE=(ON/OFF): Run Test Cases In Mlpack_test With Verbose Output (Default OFF)
每个选项都可以被指定给带有‘-D’标记的CMake。其他工具也可以用于配置CMake,但是它们没有被记录在这里。
生成Mlpack
一旦CMake配置好,生成库就像打出‘Make’一样简单。这将生成所有库组件和‘Mlpack_test’。
$make
Scanning dependencies of target mlpack
[ 1%]Building CXX object
src/mlpack/CMakeFiles/mlpack.dir/core/optimizers/aug_lagrangian/aug_lagrangian_test_functions.cpp.o
<…>
如果你不想生成每一个库,可以指定你想生成的单个组件。
make mlpack_pca mlpack_knn mlpack_kfn
一个有趣的特殊组件是Mlpack_test,它是运行Mlpack的测试组件。你可以使用这个命令生成这个组件:
make mlpack_test
然后运行所有的测试组件或单个的测试组件:
bin/mlpack_test
bin/mlpack_test-tKNNTest
如果生成失败,而你不能找到为什么失败,在Github上注册一个账户,提交这个问题,Mlpack的开发人员将会尽快帮你解决,
或者在Irc.Freenode.Netm上的Mlpack的IRC中也可以找到Mlpack的帮助。
安装Mlpack
如果你想将Mlpack安装在/Usr/Include/Mlpack/、/Usr/Lib/和/Usr/Bin/中,当它生成后,确保你有Root权限(或向那两个目录的写入许可),然后简单的打出:
make install
现在你可以通过名字运行可执行程序;你可以使用-Lmlpack链接到Mlpack,Mlpack的头文件可以在目录/Usr/Include/Mlpack/中找到。
示例
最近邻搜索是一个常见的机器学习任务。在这个背景下 ,我们有一个查询数据集和一个参考数据集。对于在查询数据集中的每个点,我们希望知道参考数据集中距离给定查询点最近的K个点。
或者,如果查询和参考数据集是相同的,问题可以更简单的说明:对于每个数据集中的点,我们希望知道距离那个点最近的K个点。
Mlpack提供:
一个简单的命令行程序包运行最近邻搜索(和最远邻搜索)。
一个简单的C++接口用于完成最近邻搜索(和最远邻搜索)。
一个通用的、可扩展的和强大的C++类(邻域搜索)用于复杂算法。
命令行‘Mlpack_knn’
在Mlpack中完成最近邻搜索最简单的方式是使用Mlpack_knn程序包。这个程序将完成最近邻搜索,并将得到的邻近点放入一个文件,同时将对应的距离放入另一个文件。输出文件被整理为第一行对应第一个被查询点的最近邻点,第一列对应最近的点,以此类推。
下面是几个简单用法的例子(和输出结果)。由于使用了选项‘-V’,因此输出是给定的。更多关于每个选项的文档可以通过下面这个语句找到。
$mlpack_knn–help
一个数据集,5个最近邻点
mlpack_knn-rdataset.csv-nneighbors_out.csv-ddistances_out.csv-k5-v
[INFO]Loading’dataset.csv’asCSV data. Size is3x1000.
[INFO]Loaded reference data from’dataset.csv'(3×1000).
[INFO]Building reference tree…
[INFO]Tree built.
[INFO]Searching for5nearest neighbors with dual-tree kd-tree search…
[INFO]18412node combinations were scored.
[INFO]54543base cases were calculated.
[INFO]Search complete.
[INFO]Saving CSV data to’neighbors_out.csv’.
[INFO]Saving CSV data to’distances_out.csv’.
[INFO]
[INFO]Execution parameters:
[INFO] distances_file:distances_out.csv
[INFO] help:false
[INFO] info:””
[INFO] input_model_file:””
[INFO] k:5
[INFO] leaf_size:20
[INFO] naive:false
[INFO] neighbors_file:neighbors_out.csv
[INFO] output_model_file:””
[INFO] query_file:””
[INFO] random_basis:false
[INFO] reference_file:dataset.csv
[INFO] seed:0
[INFO] single_mode:false
[INFO] tree_type:kd
[INFO] verbose:true
[INFO] version:false
[INFO]
[INFO]Program timers:
[INFO] computing_neighbors:0.108968s
[INFO] loading_data:0.006495s
[INFO] saving_data:0.003843s
[INFO] total_time:0.126036s
[INFO] tree_building:0.003442s
在输出底部为每个不同的计算部分加入方便的程序计时器,同时也加入和仿真一起运行的参数。现在,如果我们看看结果文件:
$head neighbors_out.csv
862,344,224,43,885
703,499,805,639,450
867,472,972,380,601
397,319,277,443,323
840,827,865,38,438
732,876,751,492,616
563,222,569,985,940
361,97,928,437,79
547,695,419,961,716
982,113,689,843,634
$head distances_out.csv
5.986076164057e-02,7.664920518084e-02,1.116050961847e-01,1.155595474371e-01,1.169810085522e-01
7.532635022982e-02,1.012564715841e-01,1.127846944644e-01,1.209584396720e-01,1.216543647014e-01
7.659571546879e-02,1.014588981948e-01,1.025114621511e-01,1.128082429187e-01,1.131659758673e-01
2.079405647909e-02,4.710724516732e-02,7.597622408419e-02,9.171977778898e-02,1.037033340864e-01
7.082206779700e-02,9.002355499742e-02,1.044181406406e-01,1.093149568834e-01,1.139700558608e-01
5.688056488896e-02,9.478072514474e-02,1.085637706630e-01,1.114177921451e-01,1.139370265105e-01
7.882260880455e-02,9.454474078041e-02,9.724494179950e-02,1.023829575445e-01,1.066927013814e-01
7.005321598247e-02,9.131417221561e-02,9.498248889074e-02,9.897964162308e-02,1.121202216165e-01
5.295654132754e-02,5.509877761894e-02,8.108227366619e-02,9.785461174861e-02,1.043968140367e-01
3.992859920333e-02,4.471418646159e-02,7.346053904990e-02,9.181982339584e-02,9.843075910782e-02
所以对于第0点的最近邻点是第862点,距离是5.986076164057e-02。第二近邻点是第344点,距离是7.664920518084e-02。第5点的第三近邻点是第751点,距离是1.085637706630e-01。
查询和参考数据集,10个最近邻点
`mlpack_knn-qquery_dataset.csv-rreference_dataset.csv\
-nneighbors_out.csv-ddistances_out.csv-k10-v
[INFO]Loading’reference_dataset.csv’asCSV data. Size is3x1000.
[INFO]Loaded reference data from’reference_dataset.csv'(3×1000).
[INFO]Building reference tree…
[INFO]Tree built.
[INFO]Loading’query_dataset.csv’asCSV data. Size is3x50.
[INFO]Loaded query data from’query_dataset.csv'(3×50).
[INFO]Searching for10nearest neighbors with dual-tree kd-tree search…
[INFO]Building query tree…
[INFO]Tree built.
[INFO]Search complete.
[INFO]Saving CSV data to’neighbors_out.csv’.
[INFO]Saving CSV data to’distances_out.csv’.
[INFO]
[INFO]Execution parameters:
[INFO] distances_file:distances_out.csv
[INFO] help:false
[INFO] info:””
[INFO] input_model_file:””
[INFO] k:10
[INFO] leaf_size:20
[INFO] naive:false
[INFO] neighbors_file:neighbors_out.csv
[INFO] output_model_file:””
[INFO] query_file:query_dataset.csv
[INFO] random_basis:false
[INFO] reference_file:reference_dataset.csv
[INFO] seed:0
[INFO] single_mode:false
[INFO] tree_type:kd
[INFO] verbose:true
[INFO] version:false
[INFO]
[INFO]Program timers:
[INFO] computing_neighbors:0.022589s
[INFO] loading_data:0.003572s
[INFO] saving_data:0.000755s
[INFO] total_time:0.032197s
[INFO] tree_building:0.002590s一个数据集,3个最近邻点,15个点的大小$mlpack_knn-rdataset.csv-nneighbors_out.csv-ddistances_out.csv-k3-l15-v
[INFO]Loading’dataset.csv’asCSV data. Size is3x1000.
[INFO]Loaded reference data from’dataset.csv'(3×1000).
[INFO]Building reference tree…
[INFO]Tree built.
[INFO]Searching for3nearest neighbors with dual-tree kd-tree search…
[INFO]19692node combinations were scored.
[INFO]36263base cases were calculated.
[INFO]Search complete.
[INFO]Saving CSV data to’neighbors_out.csv’.
[INFO]Saving CSV data to’distances_out.csv’.
[INFO]
[INFO]Execution parameters:
[INFO] distances_file:distances_out.csv
[INFO] help:false
[INFO] info:””
[INFO] input_model_file:””
[INFO] k:3
[INFO] leaf_size:15
[INFO] naive:false
[INFO] neighbors_file:neighbors_out.csv
[INFO] output_model_file:””
[INFO] query_file:””
[INFO] random_basis:false
[INFO] reference_file:dataset.csv
[INFO] seed:0
[INFO] single_mode:false
[INFO] tree_type:kd
[INFO] verbose:true
[INFO] version:false
[INFO]
[INFO]Program timers:
[INFO] computing_neighbors:0.059020s
[INFO] loading_data:0.002791s
[INFO] saving_data:0.002369s
[INFO] total_time:0.069277s
[INFO] tree_building:0.002713s更多关于选项的文档可以使用‘-Help’选项找到。
‘KNN’类
具体来说,‘KNN’类是一个更扩展的邻域搜索类的类型定义,使用欧氏距离查询最近邻点。typedefNeighborSearch<NearestNeighborSort,metric::EuclideanDistance>
KNN;使用KNN类相当简单。首先,目标对象必须被构建并指定一个数据集。然后,运行方法,返回两个矩阵:一个是最近邻点的序号,一个是最近邻点的距离。以相同的结构输出–Neighbors_file和–Distances_file到命令行接口。下面给出几个KNN使用的几个例子。
单一数据集上的5个最近邻点#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
usingnamespacemlpack::neighbor;
// Our dataset matrix, which is column-major.
externarma::mat data;
KNNa(data);
// The matrices we will store output in.
arma::Mat<size_t>resultingNeighbors;
arma::mat resultingDistances;
a.Search(5,resultingNeighbors,resultingDistances);搜索的输出存储在ResultingNeighbors和ResultingDistances里面。
查询和参考数据集上的10个最近邻点#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
usingnamespacemlpack::neighbor;
// Our dataset matrices, which are column-major.
externarma::mat queryData,referenceData;
KNNa(referenceData);
// The matrices we will store output in.
arma::Mat<size_t>resultingNeighbors;
arma::mat resultingDistances;
a.Search(queryData,10,resultingNeighbors,resultingDistances);在数据集上自然(穷举)搜索6个最近邻点
这个例子使用时间度O(N^2)的自然搜索(不是树搜索)#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
usingnamespacemlpack::neighbor;
// Our dataset matrix, which is column-major.
externarma::mat dataset;
KNNa(dataset,true);
// The matrices we will store output in.
arma::Mat<size_t>resultingNeighbors;
arma::mat resultingDistances;
a.Search(6,resultingNeighbors,resultingDistances);不用说,自然搜索很慢。
扩展的‘NeighborSearch’类
NeighborSearch类是可扩展的,带有下列模板参数:template<
typenameSortPolicy=NearestNeighborSort,
typenameMetricType=mlpack::metric::EuclideanDistance,
typenameMatType=arma::mat,
template<typenameTreeMetricType,
typenameTreeStatType,
typenameTreeMatType>classTreeType=tree::KDTree,
template<typenameRuleType>classTraversalType=
TreeType<MetricType,NeighborSearchStat<SortPolicy>,
MatType>::templateDualTreeTraverser>
classNeighborSearch;通过为每个模板类选择不同的内容,可以创建任意的邻域搜索对象。注意,这些模板的每个参数都有默认值,所以不需要为每个参数赋值。
SortPolicy策略类
SortPolicy模板参数允许指定NeighborSearch对象将怎样确定被搜索的每个点。Mlpack::Neighbor::NearestNeighborSort类是一个被清楚记录的示例。一个定制的SortPolicy类必须完成和NearestNeighborSort类相同的方法。staticsize_t SortDistance(constarma::vec&list,doublenewDistance);
staticboolIsBetter(constdoublevalue,constdoubleref);
template<typenameTreeType>
staticdoubleBestNodeToNodeDistance(constTreeTypequeryNode,
constTreeTypereferenceNode);
template<typenameTreeType>
staticdoubleBestPointToNodeDistance(constarma::vec&queryPoint,
constTreeType*referenceNode);
staticconstdoubleWorstDistance();
staticconstdoubleBestDistance();Mlpack::Neighbor::FurthestNeighborSort类是用于创建‘KFN’类型定义类的另一个方法,和寻找最近邻点相反,它寻找最远邻点。
MetricType策略类
MetricType策略类允许邻域搜索发生在任意度量空间。Mlpack::Metric::LMetric是一个很好的示例实现。一个MetricType类必须提供下列功能:// Empty constructor is required.
MetricType();
// Compute the distance between two points.
template<typenameVecType>
doubleEvaluate(constVecType&a,constVecType&b);在内部,NeighborSearch类保存一个MetricType类的实例(它可以在构造函数中给定)。这对于像马氏距离这样必须存储状态(协方差矩阵)的度量是有用的(Mlpack::Metric::MahalanobisDistance)。因此,你可以写一个非静态MetricType类,无缝的使用它和NeighborSearch。
MatType策略类
MatType模板参数指定数据类型使用矩阵。这个类型必须实现和Armadillo矩阵相同的操作,标准选择是Arma::Mat和Arma::Sp_mat。
TreeType策略类
邻域搜索NeighborSearch类在用于搜索的树类型的选择上有很好的扩展。这个类型必须遵循典型的Mlpack TreeType策略。
典型的选择可能包含Mlpack::Tree::KDTree,Mlpack::Tree::BallTree,Mlpack::Tree::StandardCoverTree,Mlpack::Tree::RTree或Mlpack::Tree::RStarTree。制作你自己的树类型用来使用NeighborSearch是很容易的。更多细节请点击这里。
下面给出一个使用带有球树的NeighborSearch类的例子。// Construct a NeighborSearch object with ball bounds.
NeighborSearch<
NearestNeighborSort,
metric::EuclideanDistance,
arma::mat,
tree::BallTree
neighborSearch(dataset);TraverserType策略类
邻域搜索NeighborSearch类提供的最后一个模板参数是TraverserType类。它具有的策略是在单一树或者双树搜索模式下遍历树。默认情况下,它被设置为使用指定TreeType(成员TreeType::DualTreeTraverser)的默认遍历器。
这个类必须实现下面两种方法:// Instantiate with a given RuleType.
TraverserType(RuleType&rule);
// Traverse with two trees.
voidTraverse(TreeType&queryNode,TreeType&referenceNode);RuleType类用在遍历器中时提供下面的功能:// Evaluate the base case between two points.
doubleBaseCase(constsize_t queryIndex,constsize_t referenceIndex);
// Score the two nodes to see if they can be pruned, returning DBL_MAX if they
// can be pruned.
doubleScore(TreeType&queryNode,TreeType&referenceNode);`
注意任何指定的遍历器必须满足修剪双树遍历的定义,其在文章”Tree-Independent Dual-Tree Algorithms”中指定。
资源链接
命令行程序参考:Http://Mlpack.Org/Docs/Mlpack-2.2.5/Man.Html
官方网站:Http://Mlpack.Org/
开源地址:Https://Github.Com/Mlpack/Mlpack
原文;文章转载于:Www.Jobbole.Com/Members/Juliesh