C++机器学习库介绍
作者|ALAKH SETHI
编译|VK
来源|Analytics Vidhya
介绍
我喜欢使⽤C++。C++是我学习过的第⼀种编程语⾔,我喜欢在机器学习中使⽤它。
我在之前写过关于构建机器学习模型的⽂章。我收到了⼀个回复,问我C++有没有机器学习的库?
这是个公平的问题。像Python和R这样的语⾔有⼤量的包和库来满⾜不同的机器学习任务。那么C++有没有这样的产品呢?
是的,是的!在本⽂中,我将重点介绍两个这样的C++库,我们也将看到它们都可以运⾏。
⽬录
1. 为什么我们要使⽤机器学习库?
2. C++中的机器学习库
1. SHARK 图书馆
2. MLPACK库
为什么我们要使⽤机器学习库?
这是很多新来者都会遇到的问题。库在机器学习中的重要性是什么?让我试着在这⼀节解释⼀下。
⽐如说,经验丰富的专业⼈⼠和⾏业⽼⼿已经付出了艰⾟的努⼒,并想出了解决问题的办法。你更愿意使⽤它,还是愿意花⼏个⼩时从头开始重新创建相同的东西?后⼀种⽅法通常没有什么意义,尤其是当你在DDL前的⼯作或学习。
我们的机器学习社区最⼤的优点是已经有很多解决⽅案以库和包的形式存在。其他⼀些⼈,从专家到爱好者,已经做了艰苦的⼯作,并将解决⽅案很好地打包在⼀个库中。
这些机器学习库是有效的和优化的,它们经过了多个⽤例的彻底测试。依靠这些库,我们的学习能⼒和编写代码,⽆论是在C++或Python,都是如此的简单和直观。
C++中的机器学习库
在本节中,我们将介绍C+中两个最流⾏的机器学习库:
1. SHARK库
2. MLPACK库
让我们逐⼀查看并查看他们的C++代码。
1.SHARK库
Shark是⼀个快速的模块库,它对监督学习算法(如线性回归、神经⽹络、聚类、k-means等)提供了强⼤的⽀持。它还包括线性代数和数值优化的功能。这些是在执⾏机器学习任务时⾮常重要的关键数学函数。
我们将⾸先了解如何安装Shark并设置环境。然后我们将⽤Shark实现线性回归。
安装Shark和安装环境(Linux)
Shark依赖于Boost和cmake。幸运的是,可以使⽤以下命令安装所有依赖项:
sudo apt-get install cmake cmake-curses-gui libatlas-base-dev libboost-all-dev
要安装Shark,请在终端中逐⾏运⾏以下命令:
gitt clone github/Shark-ML/Shark.git (you can download the zip file and extract as well)
cd Shark
mkdir build
cd build
cmake ..
make
使⽤Shark编译程序
包括相关的头⽂件。假设我们要实现线性回归,那么额外的头⽂件包括:
⽤Shark编译程序
包括相关的头⽂件。假设我们要实现线性回归,那么包含的额外头⽂件是:
#include <shark/ObjectiveFunctions/Loss/SquaredLoss.h>
#include <shark/Algorithms/Trainers/LinearRegression.h>
要编译,我们需要链接到以下库:
-std=c++11 -lboost_serialization -lshark -lcblas
⽤Shark实现线性回归
初始化阶段
我们将从包含线性回归的库和头函数开始:
#include <bits/stdc++.h> //所有c++标准库的头⽂件
#include <shark/Data/Csv.h> //导⼊csv数据的头⽂件
#include <shark/ObjectiveFunctions/Loss/SquaredLoss.h> //⽤于实现平⽅损失函数的头⽂件
#include <shark/Algorithms/Trainers/LinearRegression.h>// 实现线性回归的头⽂件
接下来是数据集。我已经创建了两个CSV⽂件。这个输⼊.csv⽂件包含x值和标签.csv⽂件包含y值。以下是数据的快照:
⾸先,我们将制作⽤于存储CSV⽂件中的值的数据容器:
Data<RealVector> inputs; //存储x值的容器
Data<RealVector> labels; //存储y值的容器
接下来,我们需要导⼊它们。Shark提供了⼀个很好的导⼊CSV函数,我们指定了要初始化的数据容器,以及CSV的路径⽂件的位置:
importCSV(inputs, "input.csv"); // 通过指定csv的路径将值存储在特定的容器中
importCSV(labels, "label.csv");
然后,我们需要实例化⼀个回归数据集类型。现在,这只是⼀个⼀般的回归对象,我们在构造函数中要做的是传递我们的输⼊以及数据的标签。
接下来,我们需要训练线性回归模型。我们怎么做呢?我们需要实例化⼀个训练器,并定义⼀个线性模型:
RegressionDataset data(inputs, labels);
LinearRegression trainer;// 线性回归模型训练器
LinearModel<> model; // 线性模型
训练阶段
接下来是我们实际训练模型的关键步骤。在这⾥,trainer有⼀个名为train的成员函数。我们⽤函数训练这个模型
//训练模型
预测阶段
最后,输出模型参数:
// 显⽰模型参数
cout << "intercept: " << model.offset() << endl;
cout << "matrix: " << model.matrix() << endl;
线性模型有⼀个名为offset的成员函数,输出最佳拟合线的截距。接下来,我们输出⼀个矩阵。
我们通过最⼩化最⼩平⽅来计算最佳拟合线,也就是最⼩化平⽅损失。
幸运的是,模型允许我们输出这些信息。Shark库⾮常有助于说明模型的适⽤性:
SquaredLoss<> loss;  //初始化square loss对象
Data<RealVector> prediction = model(data.inputs());  //根据数据输⼊预测
cout << "squared loss: " << loss(data.labels(), prediction) << endl; // 最后我们计算损失
⾸先,我们需要初始化⼀个平⽅损失对象,然后我们需要实例化⼀个数据容器。然后,根据系统的输⼊计算预测,然后我们只需通过传递标签和预测值来计算输出损失。
最后,我们需要编译。在终端中,键⼊以下命令(确保正确设置了⽬录):
g++ -o lr linear_regression.cpp -std=c++11 -lboost_serialization -lshark -lcblas
⼀旦编译,它就会创建⼀个lr对象。现在只需运⾏程序。我们得到的结果是:
b : [1](-0.749091)
A :[1,1]((2.00731))
Loss: 7.83109
b的值离0有点远,但这是因为标签中存在噪声。乘数的值接近于2,与数据⾮常相似。这就是如何使⽤c++中的Shark库来构建线性回归模型!
MLPACK C++库
mlpack是⼀个⽤c++编写的快速灵活的机器学习库。它的⽬标是提供快速和可扩展的机器学习算法的实现。mlpack可以将这些算法作为简单的命令⾏程序、或绑定Python、Julia和c++,然后可以将这些类集成到更⼤规模的机器学习解决⽅案中。
我们将⾸先了解如何安装mlpack和环境。然后我们将使⽤mlpack实现k-means算法。
安装mlpack和安装环境(Linux)
mlpack依赖于以下库,这些库需要安装在系统上:
Armadillo >= 8.400.0 (with LAPACK support)
Boost (math_c99, program_options, serialization, unit_test_framework, heap, spirit) >= 1.49
ensmallen >= 2.10.0
在Ubuntu和Debian中,你可以通过apt获得所有这些依赖项:
sudo apt-get install libboost-math-dev libboost-program-options-dev libboost-test-dev libboost-serialization-dev binutils-dev python-pandas python-numpy cython python-setuptools 现在所有依赖项都已安装在系统中,可以直接运⾏以下命令来⽣成和安装mlpack:
wget
tar -xvzpf mlpack-3.2.
mkdir mlpack-3.2.2/build && cd mlpack-3.2.2/build
cmake ../
make -j4 # The -j is the number of cores you want to use for a build
sudo make install
在许多Linux系统上,mlpack默认安装为/usr/local/lib,你可能需要设置LD_LIBRARY_PATH环境变量:
export LD_LIBRARY_PATH=/usr/local/lib
上⾯的说明是获取、构建和安装mlpack的最简单⽅法。
⽤mlpack编译程序
在你的程序中设置相关的头⽂件(实现k-means):
#include <mlpack/methods/kmeans/kmeans.hpp>
#include <armadillo>
要编译,我们需要链接以下库:
std=c++11 -larmadillo -lmlpack -lboost_serialization
⽤mlpack实现K-Means
K-means是⼀个基于质⼼的算法,或者是⼀个基于距离的算法,在这⾥我们计算距离以将⼀个点分配给⼀个簇。在K-Means中,每个簇都与⼀个质⼼相关联。
K-Means算法的主要⽬标是最⼩化点与它们各⾃的簇质⼼之间的距离之和。
K-means是⼀个有效的迭代过程,我们希望将数据分割成特定的簇。⾸先,我们指定⼀些初始质⼼,所以这些质⼼是完全随机的。
接下来,对于每个数据点,我们到最近的质⼼。然后我们将数据点指定给那个质⼼。所以每个质⼼代表⼀个类。⼀旦我们把所有的数据点分配给每个质⼼,我们就会计算出这些质⼼的平均值。
这⾥,我们将使⽤C++中的MLPACK库来实现k-均值。
初始化阶段
我们将⾸先导⼊k-means的库和头函数:
#include <bits/stdc++.h>
#include <mlpack/methods/kmeans/kmeans.hpp>
#include <armadillo>
Using namespace std;
接下来,我们将创建⼀些基本变量来设置簇的数量、程序的维度、样本的数量以及我们要执⾏的最⼤迭代次数。因为K-均值是⼀个迭代过程。
int k = 2; //簇的数量
int dim = 2;//维度
int samples = 50;
int max_iter = 10;//最⼤迭代次数
接下来,我们将创建数据。所以这是我们第⼀次使⽤Armadillo库。我们将创建⼀个映射类,它实际上是⼀个数据容器:
arma::mat data(dim, samples, arma::fill::zeros);
这个mat类,我们给它2维,50个样本,它初始化所有这些数据值为0。
接下来,我们将向这个数据类分配⼀些随机数据,然后在其上有效地运⾏K-means。我将在位置1 1周围创建25个点,我们可以通过有效地说每个
数据点是1 1或者在X = 1,y = 1的位置。然后我们要为这25个数据点中的每⼀个加⼀些随机噪声。
// 创建数据
int i = 0;
for(; i < samples / 2; ++i)
numpy库需要安装吗{
}
for(; i < samples; ++i)
{
}
这⾥,对于从0到25的i,基本位置是X = 1,y = 1,然后我们要添加⼀定数量的维度为2的随机噪声。然后我们对点x=2,y=3做同样的操作。我们的数据已经准备好了!是时候进⼊训练阶段了。
训练阶段
⾸先,我们实例化⼀个arma mat⾏类型来保存簇,然后实例化⼀个arma mat来保存质⼼:
//对数据进⾏聚类
arma::Row<size_t> clusters;
arma::mat centroids;
现在,我们需要实例化K-means类:
mlpack::kmeans::KMeans<> mlpack_kmeans(max_iter);
我们实例化了K-means类,并指定了传递给构造函数的最⼤迭代次数。现在,我们可以进⾏聚类了。
我们将调⽤这个K-means类的Cluster成员函数。我们需要传⼊数据、簇的数量,然后还要传⼊簇对象和质⼼对象。
mlpack_kmeans.Cluster(data, k, clusters, centroids);
现在,这个Cluster函数将使⽤指定数量的簇对这个数据运⾏K-means
⽣成结果
我们可以使⽤centroids.print函数简单地显⽰结果。这将给出质⼼的位置:
centroids.print("Centroids:");
接下来,我们需要编译。在终端中,键⼊以下命令(再次确认⽬录设置正确):
g++ k_means.cpp -o kmeans_test -O3 -std=c++11 -larmadillo -lmlpack -lboost_serialization && ./kmeans_test
⼀旦编译,它就会创建⼀个kmeans对象。现在只需运⾏程序。我们得到的结果是:
Centroids:
0.9497  1.9625
0.9689  3.0652
结尾
在本⽂中,我们看到了两个流⾏的机器学习库,它们帮助我们在c++中实现机器学习模型。