C++中的机器学习库教程

591 阅读6分钟

C++中的机器学习库

我们学习了从头开始实现算法,并强调了为什么我们应该使用C++来进行机器学习的原因。在这篇文章中,我们将接着介绍如何用机器学习算法实现它们。

我们在C++中创建了机器学习模型,这不仅很麻烦,而且错过了机器学习中包含的大部分内容。

库能够重复使用代码来解决问题。如今,常见问题的解决方案都是以库和包的形式出现的,这些库和包都经过了全面的测试和优化。

这些代码可能是由专家或爱好者实现的。这使人们不必每次都 "重新发明轮子",特别是在严格的期限内工作或学习时。

C++编程语言提供了可用于机器学习的库。在这篇文章中,我们将研究SHARKMLPACK库,并利用它们在机器学习中的功能。

前提条件

  • 对机器学习模型和算法的理解。
  • 对面向对象编程概念的理解。
  • 对机器学习模型和算法的理解。

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。

  1. git clone https://github.com/Shark-ML/Shark.git
  2. cd shark
  3. mkdir build
  4. cd build ..
  5. cmake ..
  6. 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值。这就是应该有的样子。

demo.

这两个.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有一些非常有用的库,它们应该被安装到系统中。

这些库是

  1. Boost
  2. Armadillo
  3. 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

如何进行编译

  1. 包括相关的头文件,例如,让我们说,对于K-means,头文件将是。
#include <mlpack/methods/kmeans/kmeans.hpp>
#include <armadillo>
  1. 与下面的库链接,进行编译。
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。库是为项目部署机器学习算法的一种更简单、更快速的方式。

每个库的文档中都有很多帮助。如果你被卡住了,你也可以阅读文档以获得详细的帮助。如果你需要帮助,你也可以给我发邮件寻求帮助。