Alors que l'on ne peut pas prouver un négatif avec un exemple. Je pense néanmoins qu'un exemple serait suggestif; et peut-être utile. Et cela montre comment on pourrait (tenter de) résoudre des problèmes similaires.
Dans le cas où
je veux faire des prédictions binaires, en utilisant des fonctionnalités qui sont des vecteurs binaires , une forêt aléatoire est un choix judicieux. Je suppose que cela répond à la deuxième partie de votre question: qu'est-ce qu'un bon algorithme?
Nous voulons bien pré-traiter les chaînes SHA256, en vecteurs binaires (booléens), chaque bit étant statistiquement indépendant, chaque bit est donc une bonne fonctionnalité. Cela fera donc de nos entrées 256 vecteurs booléens.
Démo
Voici une démonstration de la façon dont tout cela peut être réalisé à l'aide de la bibliothèque Julia DecisionTree.jl .
Vous pouvez copier coller le ci-dessous dans l'invite 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)
Résultats
Lorsque j’ai fait cela, je me suis entraîné sur 100 000 chaînes ASCII aléatoires d’une longueur maximale de 10 000. Voici les résultats que j'ai vus:
Former le modèle
julia> const model = build_forest(train_labels, train_feature_mat)
Ensemble of Decision Trees
Trees: 10
Avg Leaves: 16124.7
Avg Depth: 17.9
Précision d'ensemble d'entraînement:
julia> mean(apply_forest(model, train_feature_mat) .== train_labels)
0.95162
Précision de l'ensemble de test:
julia> mean(apply_forest(model, test_feature_mat) .== test_labels)
0.5016
Discussion
Donc, ce n'est fondamentalement rien. Nous sommes passés de 95% sur l'ensemble de formation, à un peu plus de 50% sur l'ensemble de test. Quelqu'un pourrait appliquer des tests d'hypothèses appropriés pour voir si nous pouvons rejeter l'
hypothèse nulle , mais je suis à peu près certain que nous ne le pouvons pas. C'est une infime amélioration par rapport au taux approximatif.
Cela suggère que cela ne peut pas être appris. Si vous êtes une forêt aléatoire, vous pourrez passer de bien aménagé à un taux approximatif. Les forêts aléatoires sont assez capables d'apprendre des intrants difficiles. S'il y avait quelque chose à apprendre, je m'attendrais à au moins quelques pour cent.
Vous pouvez jouer avec différentes fonctions de hachage en changeant le code. Ce qui pourrait être intéressant, j’ai obtenu les mêmes résultats lors de l’utilisation de la hash
fonction intégrée de julia (ce qui n’est pas une hsah sécurisée du point de vue cryptographique, mais qui reste un bon hachage, il est donc conseillé d’envoyer des chaînes similaires). J'ai aussi obtenu essentiellement les mêmes résultats pour CRC32c
.