Прямое унитарное кодирование с OneHotArrays.jl
Категориальные переменные (такие как true
, false
или cat
, dog
) часто кодируются в форме «один из k» или прямой унитарной форме. OneHotArrays.jl предоставляет функцию onehot
, упрощающую эту задачу.
julia> using OneHotArrays
julia> onehot(:b, [:a, :b, :c])
3-element OneHotVector(::UInt32) with eltype Bool:
⋅
1
⋅
julia> onehot(:c, [:a, :b, :c])
3-element OneHotVector(::UInt32) with eltype Bool:
⋅
⋅
1
Существует также функция onecold
, которая является обратной для функции onehot
. Вместо логических значений ей можно также передать массив чисел. В этом случае она выполняет операцию наподобие argmax
, возвращая метку, наиболее соответствующую по весу.
julia> onecold(ans, [:a, :b, :c])
:c
julia> onecold([true, false, false], [:a, :b, :c])
:a
julia> onecold([0.3, 0.2, 0.5], [:a, :b, :c])
:c
В случае со сразу несколькими выборками onehotbatch
создает пакет (матрицу) прямых унитарных векторов, а onecold
обрабатывает матрицы как пакеты.
julia> using OneHotArrays
julia> onehotbatch([:b, :a, :b], [:a, :b, :c])
3×3 OneHotMatrix(::Vector{UInt32}) with eltype Bool:
⋅ 1 ⋅
1 ⋅ 1
⋅ ⋅ ⋅
julia> onecold(ans, [:a, :b, :c])
3-element Vector{Symbol}:
:b
:a
:b
Обратите внимание, что эти операции возвращают OneHotVector
и OneHotMatrix
, а не Array
. Векторы OneHotVector
похожи на обычные векторы, но позволяют избежать лишних затрат, которые возникают при использовании целочисленных индексов напрямую. Например, при умножении матрицы на прямой унитарный вектор на внутреннем уровне просто создается срез соответствующей строки матрицы.
Список функций
#
OneHotArrays.onehot
— Function
onehot(x, labels, [default])
Возвращает вектор OneHotVector
, который примерно соответствует разреженному представлению x .== labels
.
Вместо сохранения, например, Vector{Bool}
, в нем сохраняется индекс первого вхождения x
в labels
. Если x
отсутствует в метках, то либо возвращается onehot(default, labels)
, либо выдается ошибка, если значение по умолчанию не задано.
См. также описание функции onehotbatch
, которая применяется сразу ко многим x
, и функции onecold
, которая является обратной для обеих этих функций, а также общей функцией для argmax
.
Примеры
julia> β = onehot(:b, (:a, :b, :c))
3-element OneHotVector(::UInt32) with eltype Bool:
⋅
1
⋅
julia> αβγ = (onehot(0, 0:2), β, onehot(:z, [:a, :b, :c], :c)) # использует значение по умолчанию
(Bool[1, 0, 0], Bool[0, 1, 0], Bool[0, 0, 1])
julia> hcat(αβγ...) # сохраняет разреженность
3×3 OneHotMatrix(::Vector{UInt32}) with eltype Bool:
1 ⋅ ⋅
⋅ 1 ⋅
⋅ ⋅ 1
#
OneHotArrays.onecold
— Function
onecold(y::AbstractArray, labels = 1:size(y,1))
Операция, которая является примерно обратной для onehot
или onehotbatch
: Находит индекс самого большого элемента в y
или каждого столбца в y
и ищет его в labels
.
Если метки labels
не заданы, по умолчанию ими являются целые числа 1:size(y,1)
— это та же операция, что и argmax(y, dims=1)
, но иногда тип возвращаемого значения иной.
Примеры
julia> onecold([false, true, false])
2
julia> onecold([0.3, 0.2, 0.5], (:a, :b, :c))
:c
julia> onecold([ 1 0 0 1 0 1 0 1 0 0 1
0 1 0 0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 ], 'a':'e') |> String
"abeacadabea"
#
OneHotArrays.onehotbatch
— Function
onehotbatch(xs, labels, [default])
Возвращает матрицу OneHotMatrix
, в которой k
-й столбец — onehot(xs[k], labels)
. Это разреженная матрица, в которой хранится лишь вектор Vector{UInt32}
с индексами ненулевых элементов.
Если один из входных элементов в xs
не найден в labels
, то столбец имеет вид onehot(default, labels)
при заданном значении default
; в противном случае выдается ошибка.
Если в xs
больше измерений (N = ndims(xs) > 1
), то результатом будет массив AbstractArray{Bool, N+1}
, который является прямым унитарным по первому измерению, то есть result[:, k...] == onehot(xs[k...], labels)
.
Обратите внимание, что xs
может быть любым итерируемым объектом, например строкой, и что использование кортежа для labels
зачастую ускоряет создание, по крайней мере если классов менее 32.
Примеры
julia> oh = onehotbatch("abracadabra", 'a':'e', 'e')
5×11 OneHotMatrix(::Vector{UInt32}) with eltype Bool:
1 ⋅ ⋅ 1 ⋅ 1 ⋅ 1 ⋅ ⋅ 1
⋅ 1 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 1 ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 1 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 1 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ 1 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 1 ⋅
julia> reshape(1:15, 3, 5) * oh # данное умножение матриц будет выполняться эффективно
3×11 Matrix{Int64}:
1 4 13 1 7 1 10 1 4 13 1
2 5 14 2 8 2 11 2 5 14 2
3 6 15 3 9 3 12 3 6 15 3
#
OneHotArrays.OneHotArray
— Type
OneHotArray{T, N, M, I} <: AbstractArray{Bool, M}
OneHotArray(indices, L)
Прямой унитарный M
-мерный массив с L
метками (то есть size(A, 1) == L
и sum(A, dims=1) == 1
), хранящийся как компактный N == M-1
-мерный массив индексов.
Обычно создается с помощью onehot
и onehotbatch
. Параметр I
— это тип базового объекта для хранения, а T
— тип его элементов.
#
OneHotArrays.OneHotMatrix
— Type
OneHotMatrix{T, I} = OneHotArray{T, 1, 2, I}
OneHotMatrix(indices, L)
Прямая унитарная матрица (с L
метками), обычно создаваемая с помощью onehotbatch
. Хранится эффективно как вектор индексов типа I
и типом элементов T
.