codecov Platform Swift Version PRs Welcome Ubuntu MacOS

适用于 Swift 的 XGBoost

XGBoost 系统库 提供的绑定。此软件包旨在模仿 XGBoost Python 绑定,同时利用 Swift 和 C 兼容性的强大功能。因此,某些事情的行为会有所不同,但应该为您提供对 XGBoost 的最大灵活性。

请查看

安装

系统库依赖

Linux

从源码安装 XGBoost

git clone https://github.com/dmlc/xgboost
cd xgboost
git checkout tags/v1.1.1
git submodule update --init --recursive
mkdir build
cd build
cmake ..
make
make install
ldconfig

或者您可以使用提供的安装脚本

./install.sh

macOS

您可以像在 Linux 上一样构建和安装,或者直接使用 brew

brew install xgboost
注意

在 1.1.1 版本之前,XGBoost 没有创建 pkg-config。 此问题已通过 PR Add pkgconfig to cmake #5744 修复。

如果您由于某种原因使用旧版本,您可能需要在构建时指定 XGBoost 库的路径,例如

swift build -Xcc -I/usr/local/include -Xlinker -L/usr/local/lib

或者手动创建 pkg-config 文件。 例如,对于 macOS 10.15XGBoost 1.1.0,其内容是

prefix=/usr/local/Cellar/xgboost/1.1.0
exec_prefix=${prefix}/bin
libdir=${prefix}/lib
includedir=${prefix}/include

Name: xgboost
Description: XGBoost machine learning libarary.
Version: 1.1.0
Cflags: -I${includedir}
Libs: -L${libdir} -lxgboost

需要放置在 /usr/local/lib/pkgconfig/xgboost.pc

软件包

在您的 Package.swift 中添加依赖项

.package(url: "https://github.com/kongzii/SwiftXGBoost.git", from: "0.0.0"),

导入 Swifty XGBoost

import XGBoost

或直接导入 C 库

import CXGBoost

BoosterDMatrix 类都暴露了指向底层 C 代码的指针,因此您可以直接利用 C-API 进行更高级的用法。

由于该库仍在不断发展,因此更新之间可能会有不兼容的更改,1.0.0 之前的版本不遵循 语义化版本控制。如果您不想担心更新您的软件包,请使用确切的版本。

.package(url: "https://github.com/kongzii/SwiftXGBoost.git", .exact("0.1.0")),

Python 兼容性

DMatrix 可以像在 Python 中一样从 numpy 数组创建

let pandas = Python.import("pandas")
let dataFrame = pandas.read_csv("data.csv")
let data = try DMatrix(
    name: "training",
    from: dataFrame.values
)

并且 swift 数组可以转换回 numpy

let predicted = try booster.predict(
    from: validationData
)

let compare = pandas.DataFrame([
    "Label lower bound": yLowerBound[validIndex],
    "Label upper bound": yUpperBound[validIndex],
    "Prediced": predicted.makeNumpyArray(),
])

print(compare)

这要归功于 PythonKit。 有关更详细的用法和已知问题的解决方法,请查看示例

TensorFlow 兼容性

Swift4TensorFlow 是 Google 的一个很棒的项目。 如果您正在使用 S4TF swift 工具链之一,您可以将其功能与 XGBoost 直接结合使用。

let tensor = Tensor<Float>(shape: TensorShape([2, 3]), scalars: [1, 2, 3, 4, 5, 6])
let data = try DMatrix(name: "training", from: tensor)

注意

Swift4TensorFlow 工具链附带预安装的 PythonKit,并且当使用带有额外 PythonKit 依赖项的软件包时,您可能会遇到问题。 如果是这样,请添加带有 -tensorflow 后缀的软件包版本,其中 PythonKit 依赖项已被删除。

.package(url: "https://github.com/kongzii/SwiftXGBoost.git", .exact("0.7.0-tensorflow")),

这个bug是已知的,希望很快得到解决。

示例

更多示例可以在 Examples 目录 中找到,并在 docker 中运行

docker-compose run swiftxgboost swift run exampleName

或在主机上运行

swift run exampleName

基本功能

import XGBoost

// Register your own callback function for log(info) messages
try XGBoost.registerLogCallback {
    print("Swifty log:", String(cString: $0!))
}

// Create some random features and labels
let randomArray = (0 ..< 1000).map { _ in Float.random(in: 0 ..< 2) }
let labels = (0 ..< 100).map { _ in Float([0, 1].randomElement()!) }

// Initialize data, DMatrixHandle in the background
let data = try DMatrix(
    name: "data",
    from: randomArray,
    shape: Shape(100, 10),
    label: labels,
    threads: 1
)

// Slice array into train and test
let train = try data.slice(indexes: 0 ..< 90, newName: "train")
let test = try data.slice(indexes: 90 ..< 100, newName: "test")

// Parameters for Booster, check https://docs.xgboost.com.cn/en/latest/parameter.html
let parameters = [
    Parameter("verbosity", "2"),
    Parameter("seed", "0"),
]

// Create Booster model, `with` data will be cached
let booster = try Booster(
    with: [train, test],
    parameters: parameters
)

// Train booster, optionally provide callback functions called before and after each iteration
try booster.train(
    iterations: 10,
    trainingData: train,
    evaluationData: [train, test]
)

// Predict from test data
let predictions = try booster.predict(from: test)

// Save
try booster.save(to: "model.xgboost")

开发

文档

使用 Jazzy 生成文档。

您可以使用以下命令在本地生成文档

make documentation

当合并到 master 分支时,Github 页面将自动更新。

测试

在可能的情况下,Swift 实现通过 PythonKit 针对 Python 中的参考实现进行测试。 例如,测试 score 方法的 scoreEmptyFeatureMapTest

let pyFMap = [String: Int](pyXgboost.get_score(
    fmap: "", importance_type: "weight"))!
let (fMap, _) = try booster.score(featureMap: "", importance: .weight)

XCTAssertEqual(fMap, pyFMap)

本地运行

在 ubuntu 上使用 docker

docker-compose run test 

在主机上

swift test

代码格式

使用 SwiftFormat 进行代码格式化。

make format