mlpack支持多种数据和模型格式,可通过 mlpack::data::Load()函数在其命令行程序和使用mlpack的C ++程序中使用。
下面的示例代码片段使用C++将不同格式的数据加载到Armadillo矩阵对象(arma :: mat)或模型中。
using namespace mlpack;
arma::mat matrix1;
data::Load("dataset.csv", matrix1);
using namespace mlpack;
arma::mat matrix2;
data::Load("dataset.bin", matrix2);
using namespace mlpack;
arma::mat matrix3;
data::Load("dataset.h5", matrix3);
using namespace mlpack;
// ARFF loading is a little different, since sometimes mapping has to be done
// for string types.
arma::mat matrix4;
data::DatasetInfo datasetInfo;
data::Load("dataset.arff", matrix4, datasetInfo);
// The datasetInfo object now holds information about each dimension.
using namespace mlpack;
regression::LogisticRegression lr;
data::Load("model.bin", "logistic_regression_model", lr);
mlpack中的数据集在内部表示为稀疏或密集的数字矩阵(具体而言,表示为arma :: mat或arma :: sp_mat或类似名称)。这意味着从文件加载数据集时,必须将它们转换为合适的数字表示形式。因此,通常,磁盘上的数据集应仅包含数字功能,以便被mlpack成功加载。
mlpack可以加载的数据集类型与Armadillo可以加载的矩阵类型大致相同。但是,mlpack提供的加载功能仅支持加载密集数据集。 通过mlpack加载数据集时,将使用文件的扩展名来检测文件的类型。 mlpack支持以下文件类型:
mlpack加载的数据集应存储为一行表示一个点,一列表示一个维。因此,具有三个二维点$(0,1),(3,1)和(5,-5)的数据集将存储在csv文件中,如下所示:
0, 1
3, 1
5, -5
如前所述,对于命令行程序,在加载时会自动检测格式。 因此,可以通过多种方式加载数据集:
$ mlpack_logistic_regression -t dataset.csv -v
[INFO ] Loading ‘dataset.csv’ as CSV data. Size is 32 x 37749.
…
$ mlpack_logistic_regression -t dataset.txt -v
[INFO ] Loading ‘dataset.txt’ as raw ASCII formatted data. Size is 32 x 37749.
…
$ mlpack_logistic_regression -t dataset.h5 -v
[INFO ] Loading ‘dataset.h5’ as HDF5 data. Size is 32 x 37749.
…
同样,要保存的格式由给定文件名的扩展名检测。
编写C++时,mlpack::data::Load()和mlpack::data::Save()函数分别用于加载和保存数据集。 这些功能应优于内置Armadillo.load()和.save()函数。
mlpack中的矩阵以列为主,这意味着每一列应对应于数据集中的一个点,而每一行应对应于一个维;这与数据在文件中的存储方式不一致。 因此,在加载和保存期间需要转置(transposition)。 mlpack::data::Load()和mlpack::data::Save()函数自动执行此操作(除非另行指定),这就是为什么它们比Armadillo函数更受青睐的原因。
要从文件加载矩阵,函数调用非常简单。 创建矩阵对象后,可以加载数据:
arma::mat dataset; // The data will be loaded into this matrix.
mlpack::data::Load("dataset.csv", dataset);
保存矩阵同样简单。 下面的代码生成一个3维10点的随机矩阵,并将其保存为HDF5文件。
// 3 dimensions (rows), with 10 points (columns).
arma::mat dataset = arma::randu<arma::mat>(3, 10);
mlpack::data::Save("dataset.h5", dataset);
与命令行程序一样,将从文件扩展名中自动检测要加载的数据类型。
如前所述,目前尚不支持在mlpack中加载稀疏矩阵。要将稀疏矩阵与mlpack代码一起使用,您将必须编写C++程序而不是使用任何命令行工具,因为命令行工具都在内部使用密集数据集。(有一个例外:mlpack_cf程序,用于协同过滤,会加载稀疏坐标列表。)
另外,mlpack::data::Load()函数不支持加载任何稀疏格式。因此最好的办法是使用未记录的Armadillo功能加载坐标列表。 假设您有一个坐标列表文件,如下所示:
$ cat cl.csv
0 0 0.332
1 3 3.126
4 4 1.333
这表示具有三个非零元素的5x5矩阵。 我们可以使用Armadillo加载它:
arma::sp_mat matrix;
matrix.load("cl.csv", arma::coord_ascii);
matrix = matrix.t(); // We must transpose after load!
如果坐标列表是以行为主的格式(即:如果矩阵中的每一行代表一个点,而每一列代表一个维度),则加载后需要进行转置。 确保与mlpack方法一起使用的矩阵的点作为列,维度作为行!
在某些情况下,将数据不仅表示为数字矩阵而且还表示为分类数据(即具有数字但无序类别的数据)很有用。该支持对于例如支持分类特征的决策树和其他模型很有用。
在某些机器学习情况下,例如决策树,可以使用分类数据。 分类数据可能看起来像这样(CSV格式):
0, 1, “true”, 3
5, -2, “false”, 5
2, 2, “true”, 4
3, -1, “true”, 3
4, 4, “not sure”, 0
0, 7, “false”, 6
在上面的示例中,第三维(值“ true”,“ false”和“不确定”)是分类的数据。mlpack可以加载和使用此数据,但是字符串必须映射为数字,因为mlpack中的所有数据集均由Armadillo矩阵对象表示。
从mlpack命令行程序的角度来看,这种支持是透明的。mlpack会尝试加载数据文件,并且如果它检测到文件中非数字的条目,则会将它们映射为数字,然后为每个维度打印映射数(mappings)。例如,如果我们在上面的数据集(存储为dataset.csv)上运行mlpack_hoeffding_tree程序(支持分类数据),则在加载期间会收到以下输出:
$ mlpack_hoeffding_tree -t dataset.csv -l dataset.labels.csv -v
[INFO ] Loading ‘dataset.csv’ as CSV data. Size is 6 x 4.
[INFO ] 0 mappings in dimension 0.
[INFO ] 0 mappings in dimension 1.
[INFO ] 3 mappings in dimension 2.
[INFO ] 0 mappings in dimension 3.
…
当前,只有mlpack_hoeffding_tree程序支持加载分类数据,这也是唯一支持加载ARFF数据集的程序。
在编写C ++时,加载分类数据要稍微麻烦一些:必须保留从字符串到整数的映射。 这就是mlpack::data::DatasetInfo类的作用,该类存储这些映射,并且可以使用它们并加载和节省时间来应用和取消这些映射。
当使用分类数据加载数据集时,应使用带有mlpack::data::DatasetInfo对象的mlpack::data::Load()进行重载。 下面是一个示例:
arma::mat dataset; // Load into this matrix.
mlpack::data::DatasetInfo info; // Store information about dataset in this.
// Load the ARFF dataset.
mlpack::data::Load("dataset.arff", dataset, info);
加载完成后,info对象将保存有关加载数据集所需映射的信息。可以再使用该DatasetInfo对象来加载具有相同映射的另一个数据集。例如,当同时加载训练集和测试集时,并且对于分类特征,从字符串到整数的映射必须相同。下面给出一个例子:
arma::mat trainingData; // Load training data into this matrix.
mlpack::data::DatasetInfo info; // This will store the mappings.
// Load the training data, and create the mappings in the 'info' object.
mlpack::data::Load("training_data.arff", trainingData, info);
// Load the test data, but re-use the 'info' object with the already initialized
// mappings. This means that the same mappings will be applied to the test set.
mlpack::data::Load("test_data.arff", trainingData, info);
保存数据时,使用与加载时相同的DatasetInfo对象,以便正确地解映射。下面的示例演示了此功能:它将加载数据集,将所有非分类要素加1,然后使用与加载时相同的DatasetInfo保存数据集。
arma::mat dataset; // Load data into this matrix.
mlpack::data::DatasetInfo info; // This will store the mappings.
// Load the dataset.
mlpack::data::Load("dataset.tsv", dataset, info);
// Loop over all features, and add 1 to all non-categorical features.
for (size_t i = 0; i < info.Dimensionality(); ++i)
{
// The Type() function returns whether or not the data is numeric or
// categorical.
if (info.Type(i) != mlpack::data::Datatype::categorical)
dataset.row(i) += 1.0;
}
// Save the modified dataset using the same DatasetInfo.
mlpack::data::Save("dataset-new.tsv", dataset, info);
DatasetInfo还有更多用法。
通过使用boost::serialization,mlpack可以轻松加载和保存机器学习模型。 这些模型当前可以以三种格式保存:
$ mlpack_logistic_regression -t training_dataset.tsv -l training_labels.txt
> -M model.xml
许多mlpack命令行程序都通过–input_model_file(-m)和–output_model_file(-M)选项支持加载和保存模型。 有关更多信息,请参见每个程序的文档(可通过将–help作为参数来访问)。
mlpack内部使用boost :: serialization库来执行模型的加载和保存,并提供mlpack :: data :: Load()和mlpack :: data :: Save()的便利重载来加载和保存这些模型。
为了序列化,一个类必须实现该方法:
template<typename Archive>
void serialize(Archive& ar, const unsigned int version);
如果要保存的类型实现了serialize()方法,则使用mlpack::data::Load()和mlpack::data::Save()类很容易:只需使用文件名(对象的名称)调用任一函数保存,以及对象本身。例如,下面的示例创建一个mlpack::math::Range对象,并将其保存为range.txt。 然后,该范围从文件加载到另一个mlpack::math::Range对象。
// Create range and save it.
mlpack::math::Range r(0.0, 5.0);
mlpack::data::Save("range.txt", "range", r);
// Load into new range.
mlpack::math::Range newRange;
mlpack::data::Load("range.txt", "range", newRange);
加载适当的类型很重要;例如,如果你保存一个mlpack::regression::LogisticRegression对象并尝试将其作为mlpack::math::Range对象加载,则加载将失败并且将引发异常。(当该对象另存为二进制文件(.bin)时,加载可能不会失败,而是加载损坏的数据,这甚至可能更糟!)