Chociaż nie da się udowodnić negatywem na przykładzie. Nadal uważam, że przykład byłby sugestywny; i być może przydatne. I pokazuje, jak można (próbować) rozwiązać podobne problemy.
W przypadku,
gdy chcę tworzyć prognozy binarne, używając funkcji, które są wektorami binarnymi , losowy las jest dobrym wyborem. Myślę, że tego rodzaju odpowiedzi stanowią drugą część twojego pytania: co to jest dobry algorytm.
Chcemy wstępnie przetworzyć łańcuchy SHA256 na wektory binarne (boolowskie), ponieważ każdy bit jest statystycznie niezależny, a zatem każdy bit jest dobrą cechą. Dzięki temu nasze wejściowe 256-elementowe wektory boolowskie.
Próbny
Oto demonstracja tego, jak można to wszystko zrobić przy użyciu biblioteki Julia DecisionTree.jl .
Możesz skopiować wklej poniżej do monitu 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)
Wyniki
Kiedy to zrobiłem, trenowałem na 100 000 losowych ciągów ASCII o długości do 10 000. Oto wyniki, które zobaczyłem:
Trenuj model
julia> const model = build_forest(train_labels, train_feature_mat)
Ensemble of Decision Trees
Trees: 10
Avg Leaves: 16124.7
Avg Depth: 17.9
Dokładność zestawu treningowego:
julia> mean(apply_forest(model, train_feature_mat) .== train_labels)
0.95162
Dokładność zestawu testowego:
julia> mean(apply_forest(model, test_feature_mat) .== test_labels)
0.5016
Dyskusja
Więc to w zasadzie nic. Przeszliśmy z 95% na zestawie treningowym do niewiele ponad 50% na zestawie testowym. Ktoś mógłby zastosować odpowiednie testy hipotez, aby sprawdzić, czy możemy odrzucić
hipotezę zerową , ale jestem pewien, że nie możemy. Jest to niewielka poprawa w stosunku do współczynnika zgadywania.
To sugeruje, że nie można się tego nauczyć. Jeśli losowy las, możesz przejść od dobrze dopasowanego do trafiania tylko w liczbę trafień. Losowe lasy są w stanie nauczyć się trudnych danych wejściowych. Gdyby było coś do nauczenia, oczekiwałbym co najmniej kilku procent.
Możesz bawić się różnymi funkcjami skrótu, zmieniając kod. Co może być interesujące, otrzymałem w zasadzie takie same wyniki, gdy hash
używałem Julii we wbudowanej funkcji (która nie jest bezpieczną kryptograficznie hsah, ale nadal jest dobrym hashem, więc rzeczywiście powinna wysyłać podobne ciągi znaków osobno). Mam też w zasadzie te same wyniki CRC32c
.