evalMLMethod
使用已拟合的回归模型进行预测时,可使用 evalMLMethod 函数。请参阅 linearRegression 中的链接。
stochasticLinearRegression
stochasticLinearRegression 聚合函数实现了基于线性模型和 MSE 损失函数的随机梯度下降方法。使用 evalMLMethod 对新数据进行预测。
stochasticLogisticRegression
stochasticLogisticRegression 聚合函数实现了用于二元分类问题的随机梯度下降方法。使用 evalMLMethod 对新数据进行预测。
naiveBayesClassifier
使用带有 n-gram 和拉普拉斯平滑的朴素贝叶斯模型对输入文本进行分类。该模型必须先在 ClickHouse 中配置后方可使用。
语法
naiveBayesClassifier(model_name, input_text);参数
model_name— 预配置模型的名称。String 该模型必须在 ClickHouse 的配置文件中定义 (见下文) 。input_text— 要分类的文本。String 输入会完全按原样处理 (保留大小写和标点) 。
返回值
- 预测类别 ID,以无符号整数表示。UInt32 类别 ID 对应于模型构建时定义的类别。
示例
使用语言检测模型对文本进行分类:
SELECT naiveBayesClassifier('language', 'How are you?');┌─naiveBayesClassifier('language', 'How are you?')─┐
│ 0 │
└──────────────────────────────────────────────────┘结果 0 可能表示英语,而 1 可能表示法语——具体类别含义取决于你的训练数据。
实现细节
算法 使用朴素贝叶斯分类算法,并结合 拉普拉斯平滑 处理未见过的 n-gram;n-gram 概率的计算方法参考了这份资料。
主要特性
- 支持任意长度的 n-gram
- 三种标记化模式:
byte:基于原始字节进行处理。每个字节都是一个标记。codepoint:基于从 UTF‑8 解码得到的 Unicode 标量值进行处理。每个码点都是一个标记。token:按连续的 Unicode 空白字符 (正则\s+) 拆分。标记是非空白的子字符串;如果与标点符号相邻,标点符号也会被视为该标记的一部分 (例如,"you?" 是一个标记) 。
模型配置
你可以在这里找到用于创建语言检测朴素贝叶斯模型的示例源代码。
此外,这里还提供了示例模型及其对应的配置文件。
下面是 ClickHouse 中朴素贝叶斯模型的一个示例配置:
<clickhouse>
<nb_models>
<model>
<name>sentiment</name>
<path>/etc/clickhouse-server/config.d/sentiment.bin</path>
<n>2</n>
<mode>token</mode>
<alpha>1.0</alpha>
<priors>
<prior>
<class>0</class>
<value>0.6</value>
</prior>
<prior>
<class>1</class>
<value>0.4</value>
</prior>
</priors>
</model>
</nb_models>
</clickhouse>配置参数
| 参数 | 说明 | 示例 | 默认值 |
|---|---|---|---|
| name | 唯一模型标识符 | language_detection |
必填 |
| path | 模型二进制文件的完整路径 | /etc/clickhouse-server/config.d/language_detection.bin |
必填 |
| mode | 标记化方式: - byte:字节序列- codepoint:Unicode 字符- token:标记 |
token |
必填 |
| n | N-gram 大小 (token 模式) :- 1=单个词- 2=词对- 3=三个词一组 |
2 |
必填 |
| alpha | 分类时使用的 拉普拉斯平滑 系数,用于处理模型中未出现的 n-grams | 0.5 |
1.0 |
| priors | 类别概率 (属于某一类别的文档占比) | 类别 0 占 60%,类别 1 占 40% | 均匀分布 |
模型训练指南
文件格式
在可读性较高的格式中,对于 n=1 且 token 模式,模型可能如下所示:
<class_id> <n-gram> <count>
0 excellent 15
1 refund 28当 n=3 且为 codepoint 模式时,可能如下所示:
<class_id> <n-gram> <count>
0 exc 15
1 ref 28ClickHouse 不会直接使用人类可读格式;必须先将其转换为下文所述的二进制格式。
二进制格式详情 每个存储的 n-gram 格式如下:
- 4 字节
class_id(UInt,小端序) - 4 字节
n-gram字节长度 (UInt,小端序) - 原始
n-gram字节 - 4 字节
count(UInt,小端序)
预处理要求
在根据文档语料库创建模型之前,必须先按照指定的 mode 和 n 对文档进行预处理,以提取 n-gram。以下步骤概述了预处理过程:
-
根据标记化模式,在每个文档的开头和结尾添加边界标记:
- Byte:
0x01(起始) ,0xFF(结束) - Codepoint:
U+10FFFE(起始) ,U+10FFFF(结束) - Token:
<s>(起始) ,</s>(结束)
注意: 文档开头和结尾各添加
(n - 1)个标记。 - Byte:
-
token模式下n=3的示例:- 文档:
"ClickHouse is fast" - 处理结果:
<s> <s> ClickHouse is fast </s> </s> - 生成的三元组:
<s> <s> ClickHouse<s> ClickHouse isClickHouse is fastis fast </s>fast </s> </s>
- 文档:
为简化 byte 和 codepoint 模式下的模型创建,可先将文档标记化为标记 (byte 模式下为 byte 列表,codepoint 模式下为 codepoint 列表) 。然后,在文档开头添加 n - 1 个起始标记,在文档末尾添加 n - 1 个结束标记。最后,生成 n-grams 并将其写入序列化文件。
evalMLMethod
引入版本:v20.1.0
将训练好的机器学习模型应用于输入特征,生成预测结果。
语法
evalMLMethod(model, x1[, x2, ...])参数
model— 训练后的机器学习模型。AggregateFunctionStatex1, x2, ...— 用于预测的特征值。Float*或(U)Int*
返回值
返回基于训练后模型的预测值。Float64
示例
使用示例
CREATE TABLE trips (pickup_datetime DateTime('UTC'), trip_distance Float64, total_amount Float64) ENGINE = Memory;
-- A fare of 3, plus 2.5 for every unit of distance.
INSERT INTO trips
SELECT toDateTime('2020-01-01 00:00:00', 'UTC') + number * 60, number % 10 + 1, 2.5 * (number % 10 + 1) + 3
FROM numbers(1000);
-- One model per year of the data.
CREATE TABLE models ENGINE = Memory AS
SELECT
toYear(pickup_datetime) AS year,
stochasticLinearRegressionState(0.01, 0.0, 10, 'SGD')(total_amount, trip_distance) AS model
FROM trips
GROUP BY year;
SELECT
trip_distance,
round(evalMLMethod(model, trip_distance), 2) AS predicted,
total_amount
FROM trips
LEFT JOIN models ON year = toYear(pickup_datetime)
ORDER BY pickup_datetime
LIMIT 5┌─trip_distance─┬─predicted─┬─total_amount─┐
│ 1 │ 4.05 │ 5.5 │
│ 2 │ 6.79 │ 8 │
│ 3 │ 9.53 │ 10.5 │
│ 4 │ 12.28 │ 13 │
│ 5 │ 15.02 │ 15.5 │
└───────────────┴───────────┴──────────────┘naiveBayesClassifier
引入版本:v25.11.0
使用 NAIVE_BAYES 字典对输入文本进行分类。返回与 dictGet(dictionary_name, class_attribute, input_text) 相同的预测类别值,其中 class_attribute 是在字典 布局 中配置的类别标签属性名称。与 dictGet 不同,返回结果的类型始终为 UInt32,而不是类别属性的声明类型;并且 input_text 必须是 String (不进行键类型转换) 。
语法
naiveBayesClassifier(dictionary_name, input_text)参数
返回值
预测的类别 ID。UInt32
示例
文本分类
-- A dictionary built from the token counts of two classes: 0 for a positive review, 1 for a negative one.
CREATE TABLE review_tokens (ngram String, class_id UInt32, count UInt64) ENGINE = Memory;
INSERT INTO review_tokens VALUES ('good', 0, 5), ('great', 0, 4), ('excellent', 0, 3), ('bad', 1, 5), ('awful', 1, 4), ('terrible', 1, 3);
CREATE DICTIONARY sentiment (ngram String, class_id UInt32 DEFAULT 0, count UInt64 DEFAULT 0)
PRIMARY KEY ngram
SOURCE(CLICKHOUSE(TABLE 'review_tokens'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token'))
LIFETIME(0);
SELECT naiveBayesClassifier('sentiment', 'a good and great film') AS class_id;┌─class_id─┐
│ 0 │
└──────────┘naiveBayesClassifierWithAllProbs
引入版本:v26.7.0
使用 NAIVE_BAYES 字典对输入文本进行分类,并返回所有类别及其对应的概率,按概率从高到低排列。
语法
naiveBayesClassifierWithAllProbs(dictionary_name, input_text)参数
返回值
由 (class_id, probability) Tuple 组成的数组,按概率从高到低排序。Array(Tuple(UInt32, Float64))
示例
所有类别的概率
-- A dictionary built from the token counts of two classes: 0 for a positive review, 1 for a negative one.
CREATE TABLE review_tokens (ngram String, class_id UInt32, count UInt64) ENGINE = Memory;
INSERT INTO review_tokens VALUES ('good', 0, 5), ('great', 0, 4), ('excellent', 0, 3), ('bad', 1, 5), ('awful', 1, 4), ('terrible', 1, 3);
CREATE DICTIONARY sentiment (ngram String, class_id UInt32 DEFAULT 0, count UInt64 DEFAULT 0)
PRIMARY KEY ngram
SOURCE(CLICKHOUSE(TABLE 'review_tokens'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token'))
LIFETIME(0);
SELECT arrayMap(p -> (p.1, round(p.2, 4)), naiveBayesClassifierWithAllProbs('sentiment', 'a good and great film')) AS predictions;┌─predictions─────────────┐
│ [(0,0.9677),(1,0.0323)] │
└─────────────────────────┘naiveBayesClassifierWithProb
引入版本:v26.7.0
使用 NAIVE_BAYES 字典对输入文本进行分类,并返回预测类别及其概率。
语法
naiveBayesClassifierWithProb(dictionary_name, input_text)参数
返回值
(class_id, probability) 组成的 Tuple。 Tuple(UInt32, Float64)
示例
输出分类及其概率
-- A dictionary built from the token counts of two classes: 0 for a positive review, 1 for a negative one.
CREATE TABLE review_tokens (ngram String, class_id UInt32, count UInt64) ENGINE = Memory;
INSERT INTO review_tokens VALUES ('good', 0, 5), ('great', 0, 4), ('excellent', 0, 3), ('bad', 1, 5), ('awful', 1, 4), ('terrible', 1, 3);
CREATE DICTIONARY sentiment (ngram String, class_id UInt32 DEFAULT 0, count UInt64 DEFAULT 0)
PRIMARY KEY ngram
SOURCE(CLICKHOUSE(TABLE 'review_tokens'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token'))
LIFETIME(0);
WITH naiveBayesClassifierWithProb('sentiment', 'a good and great film') AS p
SELECT (p.1, round(p.2, 4)) AS prediction;┌─prediction─┐
│ (0,0.9677) │
└────────────┘