C++中的机器学习库
我们学习了从头开始实现算法,并强调了为什么我们应该使用C++来进行机器学习的原因。在这篇文章中,我们将接着介绍如何用机器学习算法实现它们。
我们在C++中创建了机器学习模型,这不仅很麻烦,而且错过了机器学习中包含的大部分内容。
库能够重复使用代码来解决问题。如今,常见问题的解决方案都是以库和包的形式出现的,这些库和包都经过了全面的测试和优化。
这些代码可能是由专家或爱好者实现的。这使人们不必每次都 "重新发明轮子",特别是在严格的期限内工作或学习时。
C++编程语言提供了可用于机器学习的库。在这篇文章中,我们将研究SHARK和MLPACK库,并利用它们在机器学习中的功能。
前提条件
- 对机器学习模型和算法的理解。
- 对面向对象编程概念的理解。
- 对机器学习模型和算法的理解。
1.Shark库
Shark是一个非常快速的基于模块的库,支持监督学习算法,如聚类、线性回归、神经网络和K-means。
安装Shark并设置环境
我将为基于Linux的操作系统做这件事。对于Windows用户来说,你可以安装Linux的Windows子系统,据此你就可以把Linux操作系统作为Windows程序来运行。
shark库的依赖性是Boost和Cmake。在你的终端上键入以下命令来安装所有的依赖项。
sudo apt-get install cmake cmake-curses-gui libatlas-base-dev libboost-all-dev
依次输入下面的命令,就可以安装Shark。
git clone https://github.com/Shark-ML/Shark.gitcd sharkmkdir buildcd build ..cmake ..make
如何编译程序
为了能够用Shark编译程序,你需要在应用机器学习时包括你的特定用例所需的头文件。比方说,对于线性回归,你需要包括以下额外的头文件。
#include <shark/ObjectiveFunction/Loss/Squaredloss.h>
#include <shark/Algorithms/Trainers/LinearRegression.h>
你需要与以下库链接,以便进行编译。
-std=c++11 -lboost_serialization-lshark-lcblas
实现线性回归
初始化数据
包括用于线性回归的头文件和库。
#include <bits/stdc++.h> //header file for all basic c++ libraries
#include <shark/Data/Csv.h> //header file for importing data in csv format
#include <shark/ObjectiveFunctions/Loss/SquaredLoss.h> //to implement squared loss function
#include <shark/Algorithms/Trainers/LinearRegression.h>
现在我们需要一个数据集。我已经包含了两个.csv文件。independent.csv文件包括x值,dependent.csv文件包括y值。这就是应该有的样子。
.
这两个.csv文件可以在我的GitHubrepo上找到。接下来,创建一个容器来保存csv文件的数据。
Data<RealVector> independent; //store the independent values
Data<RealVector> dependent;//store the dependent values
我们现在需要将数据导入我们的容器。Shark有一个importCSV 功能。
它的使用格式如下。
importCSV(datacontainer, "filelocation")
对于我们的例子,它将是。
importCSV(independent, "independent.csv"); // storing the values in specific container by specifying the path of csv
importCSV(dependent, "dependent.csv");
实例化一个回归数据集类型,并在数据的构造函数中传递我们的独立和依赖。此后,通过实例化一个训练器来训练线性回归模型并定义一个线性模型。
RegressionDataset data(independent, dependent);
LinearRegression trainer;// trainer for linear regression model
LinearModel<> model; // linear model
训练模型
这就是我们训练模型的方法。训练器有一个叫做train的成员。该成员训练模型并为其寻找参数。
trainer.train(model, data)
预测
我们来输出模型的参数
// show model parameters
cout << "intercept: " << model.offset() << endl;
cout << "matrix: " << model.matrix() << endl;
线性模型的偏移成员函数输出最佳拟合线的截距。我们还输出一个矩阵而不是一个乘数,因为模型不一定是线性的。
它可以被泛化。最小化损失的平方,得到最佳拟合线。幸运的是,该模型允许我们显示所有这些信息。
我们的首要任务是初始化一个squared loss ,然后实例化一个数据容器,我们将称之为predicted 。预测值是根据送入系统的自变量计算出来的,然后我们输出损失,损失是通过传递因变量值和预测值得到的。
SquaredLoss<> loss; //initializing square loss object
Data<RealVector> predicted = model(data.independent()); //predicted is calculated based on the independent variables fed into the system.
cout << "squared loss: " << loss(data.dependent(), predicted) << 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离零有点远。乘数的值相当接近于2,因此与数据相似。恭喜你,你已经使用Shark C++库建立了一个线性回归模型。
2.ML包库
mlpack有一些非常有用的库,它们应该被安装到系统中。
这些库是
- Boost
- Armadillo
- Ensmallen。
安装ML包和设置环境
在你的终端上键入以下命令,一次性安装所有的依赖项。
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.2.tar.gz
- mkdir mlpack-3.2.2/build && cd mlpack-3.2.2/build
- cmake .../
- make -j4
- sudo make install
如何进行编译
- 包括相关的头文件,例如,让我们说,对于K-means,头文件将是。
#include <mlpack/methods/kmeans/kmeans.hpp>
#include <armadillo>
- 与下面的库链接,进行编译。
std=c++11 -larmadillo -lmlpack -lboost_serialization
K-means的实现
要跟上这一部分,你需要对K-means这种机器学习算法有一个正确的理解。K-means将相似的事物分组为群组。我们将"n" 观察结果分组到"k" 集群中。
k是由分析者预先确定的。实际的应用领域包括三角测量犯罪高发区,客户分析,以及公共交通分析。你可以阅读这篇文章来深入了解k-means算法。
初始化
包括实现k-means的相关库和头文件。
比如说。
#include <bits/stdc++.h>
#include <mlpack/methods/kmeans/kmeans.hpp> #include <armadillo> using namespace std;
现在,让我们设置我们程序的聚类、样本、维度的数量以及我们希望的迭代次数,因为k-means是一种迭代算法。
int c = 2; //number of clusters
int dim = 2;//dimension of our program
int samples = 50; int iter = 10;//maximum number of iterations
接下来,我们创建数据。这就是我们利用Armadillo库的地方。我们创建一个数据容器,它是一个地图类。
arma::mat data(dim, samples, arma::fill::zeros)
我们给mat类的维度大小为2,50个样本,我们将它们全部初始化为0。下一步是给这个类分配一些随机数据,我们将在上面运行k-means算法。
我们将在位置[1,1]周围创建25个点,具体做法是:每个数据点都在位置[1,1],然后为每个点添加随机噪声。这在下面的代码中已经实现。
int i = 0; for(; i < samples / 2; ++i) { data.col(i) = arma::vec({1, 1}) + 0.25*arma::randn<arma::vec>(dim); } for(; i < samples; ++i) { data.col(i) = arma::vec({2, 3}) + 0.25*arma::randn<arma::vec>(dim); }
恭喜你!现在数据已经准备好进行训练了。
训练
我们需要创建一个arma行类型来保存聚类,然后创建一个arma矩阵类型来保存中心点。
arma::Row<size_t> clusters;
arma::mat centroids;
之后,我们将实例化k-means类,并指定迭代次数,这是通过构造函数完成的。
mlpack::kmeans::KMeans<> mlpack_kmeans(max_iter);
为了进行聚类,我们将调用k-means类中名为cluster的成员函数。在这个成员函数中,我们传递数据、若干个簇、中心点对象和簇的对象。
Cluster函数在这些数据上运行k-means算法,并初始化簇和中心点对象。
mlpack_kmeans.Cluster(data, k, clusters, centroids);
显示结果
我们使用包含在中心点对象中的print函数来显示结果。
centroids.print("Centroids:");
最后,使用下面的命令在终端上编译整个代码,创建一个k-means对象,我们可以从中推导出有意义的结论。
g++ k_means.cpp -o kmeans_test -O3 -std=c++11 -larmadillo -lmlpack -lboost_serialization && ./kmeans_test
结果显示在下面,就这样了。
Centroids: 0.9497 1.9625 0.9689 3.0652
结论
总之,我们了解了一些有用的C++库,以及如何用机器学习算法实现它们。我们探索的两个流行的库是Shark和ML Pack。库是为项目部署机器学习算法的一种更简单、更快速的方式。
每个库的文档中都有很多帮助。如果你被卡住了,你也可以阅读文档以获得详细的帮助。如果你需要帮助,你也可以给我发邮件寻求帮助。