Aunque no se puede demostrar una negativa con un ejemplo. Aun así, creo que un ejemplo sería sugerente; y quizás útil. Y muestra cómo uno podría (intentar) resolver problemas similares.
En el caso de Quiero hacer predicciones binarias, utilizando características que son vectores binarios , un Bosque Aleatorio es una opción sólida. Supongo que esto responde a la segunda parte de tu pregunta: cuál es un buen algoritmo.
Bien queremos preprocesar las cadenas SHA256, en vectores binarios (booleanos), ya que cada bit es estadísticamente independiente, por lo que cada bit es una buena característica. Así que eso hará que nuestras entradas sean vectores booleanos de 256 elementos.
Demo
Aquí hay una demostración de cómo se puede hacer todo esto usando la Julia DecisionTree.jl biblioteca.
Puedes copiar y pegar lo siguiente en el prompt de julia.
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)
Resultados
Cuando hice esto, entrenando en 100.000 cadenas ASCII aleatorias de longitud hasta 10.000. Estos son los resultados que vi:
Entrenar el modelo
julia> const model = build_forest(train_labels, train_feature_mat)
Ensemble of Decision Trees
Trees: 10
Avg Leaves: 16124.7
Avg Depth: 17.9
Precisión del conjunto de entrenamiento:
julia> mean(apply_forest(model, train_feature_mat) .== train_labels)
0.95162
Precisión del conjunto de pruebas:
julia> mean(apply_forest(model, test_feature_mat) .== test_labels)
0.5016
Discusión
Así que eso es básicamente nada. Pasamos del 95% en el conjunto de entrenamiento, a apenas más del 50% en el conjunto de prueba. Alguien podría aplicar pruebas de hipótesis adecuadas, para ver si podemos rechazar la nula
hipótesis, pero estoy bastante seguro de que no podemos. Es una pequeña mejora con respecto a la tasa de adivinación.
Eso sugiere que no se puede aprender. Si un Bosque Aleatorio, puede pasar de estar bien ajustado a acertar sólo la tasa de adivinación. Los Bosques Aleatorios son bastante capaces de aprender entradas difíciles. Si hubiera algo que aprender, esperaría al menos un porcentaje.
Puedes jugar con diferentes funciones hash cambiando el código. Lo que podría ser interesante Obtuve básicamente los mismos resultados al usar el julia in built hash
(que no es un hsah criptográficamente seguro, pero sigue siendo un buen hash, por lo que debería separar cadenas similares). También obtuve básicamente los mismos resultados para CRC32c
.