🛡️

Juliaで遊ぶセキュリティエンジニアのための機械学習

2023/12/16に公開

アドベントカレンダーらしいです.ということでJuliaについて最初に書きます.

Juliaについて

一応,まだまだ市民権を獲得できていないJuliaという言語の特徴を簡単に[2]から引用しておきます.

・Rubyのように動的
・Cのように速い
・Pythonのように書きやすい
・MATLABのように直感的な数式表現ができる
・Lispのように真のマクロやコンパイル言語に似た洗練された型システムを持つ

やったこと(概要)

セキュリティエンジニアのための機械学習という本があります.
https://www.amazon.co.jp/セキュリティエンジニアのための機械学習-―AI技術によるサイバーセキュリティ対策入門-Chiheb-Chebbi/dp/4873119073

Pythonで実装されているこの本の内容をJuliaに一部書き換えてみただけです.
記事一通り書き終えてからの謝罪になりますが,セキュリティについて詳しく書いているわけでも,機械学習のアルゴリズムについて詳しく書いているわけでも,Juliaの言語特性について詳しく書いているわけでもないです.魔法剣士状態です.すみません.

実施に至った経緯

・アドベントカレンダーの期日までに何とか形にはできそう
・Julia書かなすぎて分厚いJulia本2冊も買ってたのに積読状態
とかとか

環境

Julia 1.8.1
Jupyterlab上で実施
Windows10

フィッシングサイト検出器

ソーシャルエンジニアリング手法の一つであり,誰でも聞いたことがある「フィッシング」.

結局人間が1番脆弱なんだよなぁ みつを

フィッシングサイトか否かを分類してみます.

データセット

UCI Machine Learning Repositoryのフィッシングサイトのデータを使います.ただし書籍用のgithubにcsvが用意されているので,そちらをダウンロードします.

#データ取得
cm = @cmd "curl -OL https://github.com/oreilly-japan/ml-security-jp/raw/master/ch02/dataset.csv"
run(cm)

データの中身は以下.


#モジュール
using CSV
using DataFrames
using Statistics

#データを読み込む
data = CSV.read("dataset.csv",DataFrame)

このコードをJupyterLab上で打ち込むと上記のように表示されます.
1列目~30列目が特徴量,31列目がフィッシングサイトか否かの2値になっているデータだそうです.
特徴量は,フィッシングサイトにありがちな特徴「ドメイン名ではなくIPアドレスを使っているか」が入っているそうです.
フィッシングサイトにありがちな特徴があることを知らなかったです…

ロジスティック回帰

書籍内容と同じく,ロジスティック回帰を用いてフィッシングサイトの分類をします.

書籍ではscikit-learnを使っているので,Juliaでもscikit-learnを使ってみます.

using ScikitLearn

データをいじっていきます.

#xが特徴量,yが出力
x = data[:,1:end-1]
y = data[:,end]



Juliaのscikit-learnでは本書記載のtrain_test_splitを見つけることが最初できなかったため,愚直に以下で分割します.
ちなみにCrossValidation.train_test_split~で出来そうでした.
Θはバックスラッシュthetaと打ち込んでtabキーで表示できます.

using Random
# 全母数
N = length(y)

#ランダムに8:2に分割
θ = Int(floor(N*0.8))
Shuffle_Index = shuffle(1:N)
n1 = Shuffle_Index[1:θ]
n2 = Shuffle_Index[θ+1:end]


#学習データ,テストデータセット
x_train = Array(x[n1,:])
y_train = Array(y[n1])
x_test = Array(x[n2,:])
y_test = Array(y[n2])



ではでは,実際に学習させていきます.
@sk_importはPython版のscikit-learnからモデルを引っ張ってきているマクロらしいです.

@sk_import linear_model: LogisticRegression
#モデル作成
classifier = LogisticRegression(solver="lbfgs")
#学習
classifier.fit(x_train,y_train)



テストデータから予測
ŷはyバックスラッシュhatと打ち込んでtabキーを押すと表現できます.

#予測= classifier.predict(x_test)



Juliaのscikit-learnでは本書記載のaccuracy_scoreが見当たらない,正確には見つける気力がなかったため,愚直に以下で正解率を求めました.
".=="はブロードキャストです.

accuracy = 100 * count(y_test.==)/length(y_test)

90パーセント以上でした!
意外にフィッシングサイトって予測しやすいんですね…

書籍同様にK分割交差検証もしておきます.
μはバックスラッシュmuと入力しtabキーで表現できます.

score = CrossValidation.cross_val_score(classifier,x_train,y_train,cv=5)
μ = mean(score)
print("score is $μ")


とりあえず92%出ました.

書籍だとこの後はハイパラのチューニングがあったのですが,92%で満足したためハイパラチューニングは飛ばして同じデータに対して決定木で分類します.
混同行列とか指標を使うべきだと講義でも習ったのですが…
決定木のところでも書籍だとハイパラチューニングしてるんですが飛ばします…

決定木

決定木については,別モジュールを使いモデルを定義します.引数指定はしていません.

using DecisionTree
model = DecisionTree.DecisionTreeClassifier()



早速学習していきます.

fit!(model,x_train,y_train)



学習完了したら結果を見てみませう
ŷ₁はyバックスラッシュhatと打ち込んでtabキーを押し,バックスラッシュ_1と打ち込んでtabキーを押すと表現できます.

ŷ₁ = predict(model,x_test)
accuracy = 100 * count(y_test.==ŷ₁)/length(y_test)


96%……
怪しいレベル…

ロジスティック回帰同様にK分割交差検証しておきます.

score = CrossValidation.cross_val_score(model,x_train,y_train,cv=5)= mean(score)
print("score is $ȳ")


95%,もはや96%でした.
書籍でも正答率95%くらいでしたので,間違ってはいなさそうですね

感想

・Juliaで遊べる機械学習モジュールについて少しだけ知れた.今まで深層学習系しか触れたことなかったから良かった
・フィッシングサイトを機械学習使って予測可能な場合があることを知れた
・今回はPythonとの実行速度の比較もしておらず,下手したら内部でPycallしているかもしれないため,Juliaをあえて使うメリットが見えにくいが,μとかŷみたいなJuliaの直感的な数式表現が出来るポイントは含めることが出来たのでヨシ!
・セキュリティの内容ではなく,浅く機械学習やってみたの話になってしまった!(しかも学生時代の講義でちょっと触った手法だから詳しくない手法)

参考

[1] Chiheb Chebbi(著)、新井 悠、一瀬 小夜、黒米 祐馬(訳)(2021).『セキュリティエンジニアのための機械学習 ―AI技術によるサイバーセキュリティ対策入門』. オライリー・ジャパン
[2] 後藤 俊介(2023). 『実践Julia入門』. 技術評論社

GitHubで編集を提案

Discussion