Пока нельзя доказать отрицание на примере. Тем не менее, я чувствую, что пример был бы наводящим на размышления; и, возможно, полезно. И это показывает, как можно (пытаться) решить подобные проблемы.
В случае, когда
я хочу делать двоичные предсказания, используя функции, которые являются двоичными векторами , случайный лес является хорошим выбором. Я думаю, что такого рода ответы на вторую часть вашего вопроса: что такое хороший алгоритм.
Мы хотим предварительно обработать строки SHA256 в двоичные (булевы) векторы, поскольку каждый бит статистически независим, поэтому каждый бит является хорошей особенностью. Так что это сделает наши входные данные 256-элементными логическими векторами.
демонстрация
Вот демонстрация того, как все это можно сделать с помощью библиотеки Julia DecisionTree.jl .
Вы можете скопировать вставить ниже в подсказку Джулии.
using SHA
using DecisionTree
using Statistics: mean
using Random: randstring
const maxlen=10_000 # longest string (document) to be hashed.
gen_plaintext(x) = gen_plaintext(Val{x}())
gen_plaintext(::Val{true}) = "1" * randstring(rand(0:maxlen-1))
gen_plaintext(::Val{false}) = randstring(rand(1:maxlen))
bitvector(x) = BitVector(digits(x, base=2, pad=8sizeof(x)))
bitvector(x::AbstractVector) = reduce(vcat, bitvector.(x))
function gen_observation(class)
plaintext = gen_plaintext(class)
obs = bitvector(sha256(plaintext))
obs
end
function feature_mat(obs)
convert(Array, reduce(hcat, obs)')
end
########################################
const train_labels = rand(Bool, 100_000)
const train_obs = gen_observation.(train_labels)
const train_feature_mat = feature_mat(train_obs)
const test_labels = rand(Bool, 100_000)
const test_obs = gen_observation.(test_labels)
const test_feature_mat = feature_mat(test_obs)
# Train the model
const model = build_forest(train_labels, train_feature_mat)
@show model
#Training Set accuracy:
@show mean(apply_forest(model, train_feature_mat) .== train_labels)
#Test Set accuracy:
@show mean(apply_forest(model, test_feature_mat) .== test_labels)
Полученные результаты
Когда я это сделал, тренировался на 100 000 случайных ASCII-строк длиной до 10000. Вот результаты, которые я видел:
Тренируй модель
julia> const model = build_forest(train_labels, train_feature_mat)
Ensemble of Decision Trees
Trees: 10
Avg Leaves: 16124.7
Avg Depth: 17.9
Точность тренировочного набора:
julia> mean(apply_forest(model, train_feature_mat) .== train_labels)
0.95162
Точность тестового набора:
julia> mean(apply_forest(model, test_feature_mat) .== test_labels)
0.5016
обсуждение
Так что это в принципе ничего. Мы прошли с 95% на тренировочном наборе до чуть более 50% на тестовом наборе. Кто-то может применить надлежащие проверки гипотез, чтобы увидеть, можем ли мы отвергнуть нулевую
гипотезу, но я почти уверен, что мы не сможем. Это небольшое улучшение по сравнению с вероятностью угадывания.
Это говорит о том, что этому нельзя научиться. Если Случайный Лес, может перейти от хорошо приспособленного к поражению только вероятности. Случайные леса довольно способны к изучению сложных входных данных. Если бы было чему поучиться, я бы ожидал как минимум несколько процентов.
Вы можете поиграть с различными хэш-функциями, изменив код. Что может быть интересно Я получил в основном те же результаты при использовании встроенной hash
функции julia (которая не является криптографически защищенной hsah, но все же является хорошим хэшем, поэтому действительно должна посылать подобные строки отдельно). Я также получил в основном те же результаты для CRC32c
.