Py学习  »  机器学习算法

ClickHouse如何结合自家的GNDT算法库CatBoost来做机器学习

AI前线 • 8 年前 • 785 次点击  

作者|Altinity
译者|Liu Zhiyong
编辑|Cai Fangfang
AI 前线导读:ClickHouse 是俄罗斯第一大搜索引擎 Yandex 开发的列式储存数据库。据测试报告,这个列式储存数据库的性能大幅超越了很多商业 MPP 数据库软件,比如 Vertica(HP Vertica 成为 MPP 列式存储商业数据库的高性能代表,Facebook 就购买了 Vertica 数据用于用户行为分析。)、InfiniDB。2016 年 6 月 15 日,ClickHouse 由 Yandex 开源。2017 年 7 月 21 日,Yandex 开源了 CatBoost,这是一种支持类别特征,基于梯度提升决策树的机器学习方法。它是 MartixNet 算法的继承者。它能够在数据稀疏的情况下教机器学习。特别是在没有像视频、文本、图像这类感官性数据时,CatBoost 也能根据事务性数据或历史数据进行操作。CatBoost 采用了 Apache 许可证,它相较其他框架的最大优点是测试精准度高,而且只需少量调试,且性能良好。今天我们就来看看 Altinity 前几日撰写的教程 [^5],给我们演示了 ClickHouse 如何结合自家开源的 GBDT 算法库 CatBoost 来做机器学习。Altinity 是一家 ClickHouse 的服务供应商。

更多干货内容请关注微信公众号“AI 前线”,(ID:ai-front)

ClickHouse 非常灵活,可用于各种用例。现在最有意思的技术领域之一就是机器学习,而 ClickHouse 非常适合作为非常快速的数据源。几个月前,ClickHouse 团队实现了对机器学习算法的支持,这使得在 ClickHouse 数据上运行机器算法变得更容易、更快捷。他们从开源的 Yandex CatBoost^0 算法开始,但它可以在未来扩展到其他算法。在本文中,我们发布了关于如何使用 ClickHouse 来运行 CatBoost 模型的教程。

CatBoost

CatBoost 是最先进的开源梯度提升决策树算法库。

CatBoost 是由 Yandex 研究人员和工程师开发的,在公司内部广泛应用于排列任务、预测和提出建议。Yandex 称其是通用的,可以应用于广泛的领域和各种各样的问题。

CatBoost 与传统的梯度提升决策树有什么不同?

  • 精确性:在标准基准测试 [^2] 中引入竞争;

  • 健壮性:减少了对大量超参数调优的需求;

  • 易用性:提供了与 scikit 集成的 Python 接口,以及 R 和命令行接口;

  • 实用性:可直接地、以及可伸缩性地使用分类特征;

  • 可扩展性:允许指定自定义损失函数。

如需获取更详细的信息,请参阅 TechCrunch 发布的文章《Yandex 开源 CatBoost》[^1]。

CatBoost 结合 ClickHouse

现在让我们看看 CatBoost 如何结合 ClickHouse。本文其余部分转载自 GitHub 上的 clickhouse-presentations 项目提供的教程 ^6,ClickHouse 方面,由 Yandex 工程师 Nikolai Kochetov 负责此项目。那么让我们开始吧。

启动容器

本教程使用 Docker 容器。启动容器的命令如下:

$ sudo docker run -it -p 8888:8888 yandex/tutorial-catboost-clickhouse


结果,您可以通过 http://localhost:8888 来访问 Jupyter Notebook 中的 CatBoost 和 ClickHouse 教程:


  • kaggle_amazon_catboost.ipynb - 使用 Amazon Employee Access Challenge 数据的 CatBoost 功能演示。

  • catboost_with_clickhouse.ipynb - 在 ClickHouse(当前文档)中应用 CatBoost 模型。

VirtualBox 映像

可以使用 VirtualBox 映像 ^3 替代 Docker 容器。在启动后,可以在 http://localhost:8888 上使用相同的材料。

命令提示符

您需要使用命令提示符才能使用 ClickHouse。您可以使用 Docker 容器或 VirtualBox 映像中的命令提示符。另一个选项是使用 jupyter notebook 命令提示符。打开主页并选择 New→Terminal。所有其他命令都可以直接复制到终端窗口中。

使用 ClickHouse

ClickHouse 支持多种不同的接口,包括用于流行编程语言的 HTTP,JDBC,ODBC 和许多第三方库。但是,本教程是通过 TCP 使用本地客户端。

命令行界面

ClickHouse 服务器已经在 Docker 容器中运行。要连接到服务器,请键入以下命令:

$ clickhouse client --host 127.0.0.1

结果,ClickHouse 显示一个输入的邀请:

:)

尝试写一个“Hello,world!”查询:

:) SELECT 'Hello, world!'

如果一切正常,那就进入下一个步骤。

使用 ClickHouse 作为计算器

运行简单的计算查询:

:) SELECT 2 + 2 * 2
:) SELECT cos(pi() / 3)
:) SELECT pow(e(), pi())

system.numbers 表有一个单独的列,称为 number。该列存储从 0 开始的整数。我们来看前 10 个:

:) SELECT number FROM system.numbers LIMIT 10

现在计算前 100 个整数的平方和:

:) SELECT sum(pow(number, 2))
FROM 
(
    SELECT *
    FROM system.numbers 
    LIMIT 101
)

最后一个例子是使用 system.numbers 表中的子查询创建的。首先选择数字从 0 到 100 的单数列,然后计算平方,并使用求和聚合函数计算平方和。

创建一个表并插入数据

为训练样本创建一个表格:

:) CREATE TABLE amazon_train
(
    date Date MATERIALIZED today(), 
    ACTION UInt8, 
    RESOURCE UInt32, 
    MGR_ID UInt32, 
    ROLE_ROLLUP_1 UInt32, 
    ROLE_ROLLUP_2 UInt32, 
    ROLE_DEPTNAME UInt32, 
    ROLE_TITLE UInt32, 
    ROLE_FAMILY_DESC UInt32, 
    ROLE_FAMILY UInt32, 
    ROLE_CODE UInt32
)
ENGINE = MergeTree(date, date, 8192);

为了将数据插入到 ClickHouse 中,您需要使用 Linux 命令行。使用 Crtl+C 来退出 ClickHouse(或者,键入“quit”、“logout”、“exit”、“quit”、“q”或等价命令)。然后运行以下命令:

$ clickhouse client --host 127.0.0.1 --query 'INSERT INTO amazon_train FORMAT CSVWithNames' < ~/amazon/train.csv


检查数据是否被插入:

$ clickhouse client --host 0.0.0.0
:) SELECT count() FROM amazon_train

计算 ACTION 列的平均值:

:) SELECT avg(ACTION) FROM amazon_train
使用已训练的模型

用模型配置创建一个配置文件:


    
        
        catboost
        
        amazon
        
        /home/catboost/tutorial/catboost_model.bin
        
        0
    

ClickHouse 配置文件应该已经有这样的设置:

/home/catboost/models/*_model.xml


要验证一下,运行以下命令:

tail /etc/clickhouse-server/config.xml

让我们确保模型正在工作。计算表中前 10 行的预测值:

:) SELECT 
    modelEvaluate('amazon', 
                  RESOURCE,
                  MGR_ID,
                  ROLE_ROLLUP_1,
                  ROLE_ROLLUP_2,
                  ROLE_DEPTNAME,
                  ROLE_TITLE,
                  ROLE_FAMILY_DESC,
                  ROLE_FAMILY,
                  ROLE_CODE) > 0 AS prediction, 
    ACTION AS target
FROM amazon_train
LIMIT 10;

现在我们来预测一下概率:

:) SELECT 
    modelEvaluate('amazon', 
                  RESOURCE,
                  MGR_ID,
                  ROLE_ROLLUP_1,
                  ROLE_ROLLUP_2,
                  ROLE_DEPTNAME,
                  ROLE_TITLE,
                  ROLE_FAMILY_DESC,
                  ROLE_FAMILY,
                  ROLE_CODE) AS prediction,
    1\. / (1 + exp(-prediction)) AS probability, 
    ACTION AS target
FROM amazon_train
LIMIT 10;

计算样本上的 LogLoss:




    
:) SELECT -avg(tg * log(prob) + (1 - tg) * log(1 - prob)) AS logloss
FROM 
(
    SELECT 
        modelEvaluate('amazon', 
                      RESOURCE,
                      MGR_ID,
                      ROLE_ROLLUP_1,
                      ROLE_ROLLUP_2,
                      ROLE_DEPTNAME,
                      ROLE_TITLE,
                      ROLE_FAMILY_DESC,
                      ROLE_FAMILY,
                      ROLE_CODE) AS prediction,
        1\. / (1\. + exp(-prediction)) AS prob, 
        ACTION AS tg
    FROM amazon_train
);
与 CatBoost 集成

我们不需要为测试样本创建一个表,而是使用 catBoostPool 表函数。列描述在 /home/catboost/tutorial/amazon/test.cd 文件中,它看起来像这样:

0    DocId    id
1    Categ    RESOURCE
2    Categ    MGR_ID
3    Categ    ROLE_ROLLUP_1
4    Categ    ROLE_ROLLUP_2
5    Categ    ROLE_DEPTNAME
6    Categ    ROLE_TITLE
7    Categ    ROLE_FAMILY_DESC
8    Categ    ROLE_FAMILY
9    Categ    ROLE_CODE

看看从 catBoostPool 返回的临时表结构:

:) DESCRIBE TABLE catBoostPool('amazon/test.cd', 'amazon/test.tsv')

┌─name─────────────┬─type───┬─default_type─┬─default_expression─┐
│ Categ0           │ String │              │                    │
│ Categ1           │ String │              │                    │
│ Categ2           │ String │              │                    │
│ Categ3           │ String │              │                    │
│ Categ4           │ String │              │                    │
│ Categ5           │ String │              │                    │
│ Categ6           │ String │              │                    │
│ Categ7           │ String │              │                    │
│ Categ8           │ String │              │                    │
│ DocId            │ String │              │                    │
│ id               │ String │ ALIAS        │ DocId              │
│ RESOURCE         │ String │ ALIAS        │ Categ0             │
│ MGR_ID           │ String │ ALIAS        │ Categ1             │
│ ROLE_ROLLUP_1    │ String │ ALIAS        │ Categ2             │
│ ROLE_ROLLUP_2    │ String │ ALIAS        │ Categ3             │
│ ROLE_DEPTNAME    │ String │ ALIAS        │ Categ4             │
│ ROLE_TITLE       │ String │ ALIAS        │ Categ5             │
│ ROLE_FAMILY_DESC │ String │ ALIAS        │ Categ6             │
│ ROLE_FAMILY      │ String │ ALIAS        │ Categ7             │
│ ROLE_CODE        │ String │ ALIAS        │ Categ8             │
└──────────────────┴────────┴──────────────┴────────────────────┘

该表包含了列描述文件中的每个特性和别名的列。计算前 10 行的概率:

:) SELECT 
    id,
    modelEvaluate('amazon', *) AS prediction,
    1\. / (1\. + exp(-prediction)) AS probability
FROM catBoostPool('amazon/test.cd', 'amazon/test.tsv')
LIMIT 10;

在从 catBoostPool 读取数据时,可以使用 * 代替 modelEvaluate 的参数。计算测试样本的答案并将结果写入文件:

SELECT 
    toUInt32(id) AS Id, 
    1\. / (1 + exp(-modelEvaluate('amazon', *))) AS Action
FROM catBoostPool('amazon/test.cd', 'amazon/test.tsv') 
INTO OUTFILE 'submission.tsv'
FORMAT CSVWithNames;

在 Kaggle[^4] 上提交结果(您可以使用 jupyter notebook 界面从 Docker 容器中下载 submission.tsv)看看你在排行榜上排名如何?

[0]: CatBoost

https://tech.yandex.com/catboost/

[2]:CatBoost is an open-source gradient boosting library with categorical features support*

https://catboost.yandex/#benchmark

[1]:Yandex open sources CatBoost, a gradient boosting machine learning library

https://techcrunch.com/2017/07/18/yandex-open-sources-catboost-a-gradient-boosting-machine-learning-librar/

https://yadi.sk/d/htNTv2VK3Q9RQ7

[4]:Amazon.com - Employee Access Challenge

https://www.kaggle.com/c/amazon-employee-access-challenge/leaderboard

[5]:ClickHouse for Machine Learning

https://www.altinity.com/blog/2018/1/18/clickhouse-for-machine-learning

https://github.com/yandex/clickhouse-presentations/blob/master/tutorials/catboost_with_clickhouse_en.md


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/dC4WVUUIpF
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/5907