Si bien uno no puede probar un negativo con un ejemplo. Todavía siento que un ejemplo sería sugestivo; y quizás útil. Y muestra cómo uno (intentaría) resolver problemas similares.
En el caso de
que quiera hacer predicciones binarias, utilizando características que son vectores binarios , un bosque aleatorio es una opción sólida. Supongo que este tipo de respuestas responde a la segunda parte de su pregunta: ¿qué es un buen algoritmo?
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. Entonces eso hará que nuestras entradas sean 256 elementos booleanos.
Manifestación
Aquí hay una demostración de cómo se puede hacer todo usando la biblioteca Julia DecisionTree.jl .
Puede copiar pegar el siguiente en el indicador 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, me entrené en 100,000 cadenas ASCII aleatorias de hasta 10,000. Aquí están los resultados que vi:
Entrenar a la 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
Exactitud del conjunto de prueba:
julia> mean(apply_forest(model, test_feature_mat) .== test_labels)
0.5016
Discusión
Entonces 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
hipótesis nula , pero estoy bastante seguro de que no podemos. Es una pequeña mejora sobre la tasa de conjetura.
Eso sugiere que no se puede aprender. Si se trata de un bosque aleatorio, puede pasar de estar bien ajustado a golpear solo la tasa de conjetura. Los bosques aleatorios son bastante capaces de aprender entradas difíciles. Si hubiera algo que aprender, esperaría al menos un pequeño porcentaje.
Puedes jugar con diferentes funciones hash cambiando el código. Lo que podría ser interesante, obtuve básicamente los mismos resultados cuando utilicé el julia en la hash
función incorporada (que no es una hsah criptográficamente segura, pero aún así es un buen hash, por lo que debería enviar cadenas similares). También obtuve básicamente los mismos resultados para CRC32c
.