ExpressionEstimator 类

定义

此估算器将用户提供的表达式 (指定为字符串) 应用于输入列值,以生成新的输出列值。

public sealed class ExpressionEstimator : Microsoft.ML.IEstimator<Microsoft.ML.Transforms.ExpressionTransformer>
type ExpressionEstimator = class
    interface IEstimator<ExpressionTransformer>
Public NotInheritable Class ExpressionEstimator
Implements IEstimator(Of ExpressionTransformer)
继承
ExpressionEstimator
实现

注解

估算器特征

此估算器是否需要查看数据来训练其参数?
输入列数据类型 float、double、int、long、bool 或 text。
输出列数据类型 可以是 float、double、int、long、bool 或 text,具体取决于表达式。

生成的 ExpressionTransformer 将创建一个新列,该列在输出列名称参数中指定,其中表达式应用于输入值。 最多一个输入列可以是 VectorDataViewType 类型,当输入包含向量列时,表达式将单独根据向量的每个元素进行计算,以创建长度与该输入相同的向量输出。

表达式语言

表达式估算器的语言应该适用于广泛的用户。 它与一些流行语言有许多相似之处。 它区分大小写,支持多种类型,并具有一组丰富的运算符和函数。 它是纯功能,从某种意义上说,在语言中没有可变值或可变操作。 它不具有也不需要任何异常机制,而是在正常值不合适时生成 NA 值。 它是静态类型化,但所有类型都由编译器推断。

语法

lambda 的语法由一个参数列表组成,后跟冒号 (:) 或箭头 (=>) 后跟表达式。 参数列表可以是单个标识符,也可以是用括号括起来的一个或多个标识符的逗号分隔列表。

Lambda:

  • parameter-list expression
  • parameter-list => expression

parameter-list:

  • identifier
  • (参数名称)

parameter-name:

  • identifier
  • identifier parameter-name

表达式可以使用参数、文本、运算符、with-expression 和函数。

文本

  • 布尔文本为 true 和 false。
  • 整数文本可以是十进制或十六进制 (例如0x1234ABCD) 。 它们可以用 you 或 U 作为后缀,表示 unsigned,以及 l 或 L,指示 long (Int64) 。 你或 U 的使用很少见,只会影响某些 32 位十六进制值的提升,从而确定常量是被视为负 Int32 值还是正 Int64 值。
  • 浮点文本使用标准语法,包括指数表示法 (123.45e-37) 。 它们可以以 f 或 F 为后缀,表示单精度,或 d 或 D,表示双精度。 与 C# 不同,浮点文本的默认精度为单精度。 若要指定双精度,请追加 d 或 D。
  • 文本文本用双引号括起来,并支持标准转义机制。

运算符

下表按先行顺序列出了表达式语言的运算符。 除非另有说明,否则二元运算符保持关联性, (如果任一操作数值为 NA,则结果为 NA) 。 通常,整数值的溢出会产生 NA,而浮点值的溢出会产生无穷大。

“运算符” 含义 Arity 注释
​? : 条件 三元 表达式条件? value1 :如果 condition 为 true,则 value2 解析为 value1;如果 condition 为 false,则解析为 value2。 条件必须是布尔值,而 value1 和 value2 必须是兼容的类型。
​?? 合并 二 进 制 表达式 x ?? 如果 x 不是 NA,则 y 解析为 x,否则解析为 y。 操作数必须同时为 Single 或 Doubles。 此运算符是右结合运算符。
| |或 logical 或 二 进 制 操作数和结果为布尔值。 如果一个操作数为 true,则结果为 true,否则为 false。
&& 和 逻辑 和 二 进 制 操作数和结果为布尔值。 如果一个操作数为 false,则结果为 false,否则为 true。
​==, =
!=, <>
<, <=
>, >=
equals
不等于
小于等于
大于等于
多个 - 比较运算符是多重运算符,这意味着它们可以应用于两个或更多个操作数。 例如,如果 a、b 和 c 具有相同的值,则 a == b == c 的结果为 true。 不相等运算符要求所有操作数都是不同的,因此 1 != 2 != 1 为 false。 若要测试 x 是否为非负值但小于 10,请使用 0 <= x < 10。 无需写入 0 <= x && x < 10,这样做也不会执行。 同一行中列出的运算符可以组合在单个表达式中,因此 > b >= c 是合法的,但 < b >= c 不是。
- 等于和不等于适用于任何操作数类型,而有序运算符需要数值操作数。
​+ - 加法和减法 二 进 制 使用 NA 传播进行数值加法和减法。
​* / % 乘法、除法和模数 二 进 制 数值乘法、除法和 NA 传播的模数。
​- ! not 数值求反和逻辑非 这些运算符是一元前缀运算符、需要数值操作数的求反 ( ) ,而不是 (!) 需要布尔操作数。
​^ 权力 二 进 制 这是右关联指数。 它需要数值操作数。 对于整数操作数,0^0 生成 1。
​( ) parenthetical grouping 标准含义。

With 表达式

with-expression 的语法为:

with-expression:

  • 使用 ( assignment-list ; 表达式 )

assignment-list:

  • 分配
  • assignment assignment-list

分配:

  • 标识符 = 表达式

with-expression 引入了一个或多个命名值。 例如,以下表达式将 celcius 温度转换为华氏度,然后根据华氏度太低还是过高生成消息。

c => with(f = c * 9 / 5 + 32 ; f < 60 ? "Too Cold!" : f > 90 ? "Too Hot!" : "Just Right!")

一个赋值的表达式可以引用以前赋值引入的标识符,如此示例中返回 -1、0 或 1 而不是消息:

c : with(f = c * 9 / 5 + 32, cold = f < 60, hot = f > 90 ; -float(cold) + float(hot))

如上所述,当在较大的表达式中多次需要表达式值时,with-expression 非常有用。 处理复杂或重要的常量时,它也很有用:

    ticks => with(
        ticksPerSecond = 10000000L,
        ticksPerHour = ticksPerSecond \* 3600,
        ticksPerDay = ticksPerHour \* 24,
        day = ticks / ticksPerDay,
        dayEpoch = 1 ;
        (day + dayEpoch) % 7)

这从理想化公历) 的标准 .Net DateTime epoch (01/01/0001 以来, (Int64) 的周期数来计算星期几。 工作分配用于秒内的刻度数、一小时的刻度数、一年的刻度数以及纪元的星期几。 对于此示例,我们希望将星期日映射到零,因此,由于纪元是星期一,因此我们将 dayEpoch 设置为 1。 如果纪元已更改,或者我们想将一周中的另一天映射到零,只需更改 dayEpoch。 请注意,ticksPerSecond 定义为 10000000L,使其成为 Int64 值 (8 字节整数) 。 如果没有 L 后缀,ticksPerDay 将溢出 Int32 的范围。

函数

表达式转换支持许多有用的函数。

下表列出了可以接受任何类型的操作数的常规一元函数。

名字 意义 评论
isna 测试 na 返回一个布尔值,该值指示操作数是否为 NA 值。
na 值 返回与操作数相同类型的 NA 值, (float 或 double) 。 请注意,这不会评估操作数,它仅使用操作数来确定要返回的 NA 的类型,并且该确定发生在编译时。
默认 默认值 返回与操作数类型相同的默认值。 例如,若要将 NA 值映射到默认值,请使用 x ?? 默认 (x) 。 请注意,这不会评估操作数,它仅使用操作数来确定要返回的默认值的类型,并且确定在编译时进行。 对于数值类型,默认值为零。 对于布尔值,默认值为 false。 对于文本,默认值为空。

下表中列出了一元转换函数。 NA 操作数生成 NA,如果类型不支持 NA,则引发。 不成功或溢出的转换也会导致 NA 或异常。 这种情况最常见的情况是从使用标准转换分析的文本进行转换时。 从浮点 (值或双) 浮点值转换为 int32 或 Int64) (整数值时,转换将执行截断操作, (向零) 舍入。

名字 意义 评论
Bool 转换为布尔值 操作数必须是文本或布尔值。
Int 转换为 Int32 输入可以是任何类型的。
转换为 Int64 输入可以是任何类型的。
single,float 转换为 Single 输入可以是任何类型的。
转换为 Double 输入可以是任何类型的。
文本 转换为 文本 输入可以是任何类型的。 这会生成默认文本表示形式。

下表列出了需要数值操作数的一元函数。 结果类型与操作数类型相同。 NA 操作数值生成 NA。

名字 意义 评论
Abs 绝对值 生成操作数的绝对值。
标志 符号 (-1、0、1) 生成 -1、0 或 1,具体取决于操作数是负数、零还是正数。

下表中列出了需要数值操作数的二进制函数。 当操作数类型不同时,操作数将提升为适当的类型。 结果类型与提升的操作数类型相同。 NA 操作数值生成 NA。

名字 意义 评论
min 最低 生成操作数的最小值。
麦克斯 最大值 生成最大操作数。

下表列出了需要浮点操作数的一元函数。 结果类型与操作数类型相同。 Overflow 产生无穷大。 无效的输入值会生成 NA。

名字 意义 评论
sqrt 平方根 负操作数生成 NA。
trunc,truncate 截断为整数 向零舍入到最接近的整数值。
地板 地板 向负无穷大舍入到最接近的整数值。
ceil, ceiling 天花板 向正无穷大舍入到最接近的整数值。
无偏差舍入 舍入到最接近的整数值。 当操作数介于两个整数值之间时,这会产生偶数整数。
exp 指数 将 e 引发到操作数。
ln, log 对数 生成自然 (底 e) 对数。 还有一个两个操作数版本的日志,用于使用不同的基。
deg, degrees 弧度到度 从弧度到度数的映射。
rad、弧度 度到弧度 从度到弧度映射。
sin,sind 正弦 采用角度的正弦值。 sin 函数假定操作数以弧度为单位,而 sind 函数假定操作数以度为单位。
cos、cosd 余弦 采用角度的余弦值。 cos 函数假定操作数以弧度为单位,而 cosd 函数假定操作数以度为单位。
tan,tand 切线 采用角度的正切值。 tan 函数假定操作数以弧度为单位,而 tand 函数假定操作数以度为单位。
sinh 双曲正弦值 取其操作数的双曲正弦值。
cosh 双曲余弦值 取其操作数的双曲余弦值。
tanh 双曲正切 获取其操作数的双曲正切值。
asin 反正弦值 取其操作数的反正弦值。
acos 反余弦值 取其操作数的反余弦值。
atan 逆切 获取其操作数的反切值。

下表列出了需要浮点操作数的二进制函数。 当操作数类型不同时,操作数将提升为适当的类型。 结果类型与提升的操作数类型相同。 NA 操作数值生成 NA。

名字 意义 评论
日志 给定基数的对数 第二个操作数是基数。 第一个是取其对数的值。
atan2、atanyx 确定角度 从给定的 y 和 x 值确定 -pi 和 pi 之间的角度。 请注意,y 是第一个操作数。

下表中列出了文本函数。

名字 意义 评论
len (x) 文本长度 操作数必须是文本。 结果是指示操作数长度的 I4。 如果操作数为 NA,则结果为 NA。
下 (x) ,高 (x) 小写或大写 将文本映射到小写或大写。
左 (x、k) 、右 (x、k) 第一个操作数必须是文本,第二个操作数必须是 Int32。 如果第二个操作数为负数,则会将其视为距文本末尾的偏移量。 然后,将此调整后的索引固定到 0 到 len (x) 。 结果是结果位置左侧或右侧的字符。
中 (x、a、b) 第一个操作数必须是文本,另外两个操作数必须是 Int32。 索引的转换方式与左函数和右函数的转换方式相同:负值被视为距文本末尾的偏移量;这些调整后的索引被固定到 0 到 len (x) 。 第二个固定索引也在下面固定到第一个固定索引。 结果是这两个固定索引之间的字符。
concat (x1、x2、...、xn) 串联 这接受任意数量的操作数 (包括零) 。 所有操作数必须是文本。 结果是按顺序连接所有操作数。

方法

Fit(IDataView)

此估算器将用户提供的表达式 (指定为字符串) 应用于输入列值,以生成新的输出列值。

GetOutputSchema(SchemaShape)

此估算器将用户提供的表达式 (指定为字符串) 应用于输入列值,以生成新的输出列值。

扩展方法

AppendCacheCheckpoint<TTrans>(IEstimator<TTrans>, IHostEnvironment)

将“缓存检查点”追加到估算器链。 这将确保针对缓存的数据训练下游估算器。 在采用多个数据传递的培训师之前设置缓存检查点会很有帮助。

WithOnFitDelegate<TTransformer>(IEstimator<TTransformer>, Action<TTransformer>)

给定估算器后,返回一个包装对象,该对象在调用委托后 Fit(IDataView) 将调用委托。 估算器通常必须返回有关适合的内容的信息,这就是方法返回特定类型对象(而不仅仅是常规 ITransformer对象)的原因Fit(IDataView)。 但是,同时, IEstimator<TTransformer> 通常会形成包含许多对象的管道,因此,我们可能需要通过 EstimatorChain<TLastTransformer> 生成一个估算器链,其中,要获取转换器的估算器埋在此链中的某个位置。 对于这种情况,我们可以通过此方法附加一个委托,该委托将在调用拟合后调用。

适用于

另请参阅