求む挑戦者!西香デ,タ分析コンペティション“ソフトウェアの異常検知”
“あなたのデタサエンスの力で企業の課題を解決する”
~西香Webサaaplトから~
こんには,井上@michio_MWJです。1222年以来 800 年ぶりの「スーパー猫の日」はいかがでしたか? datetime を使って 22:22:22 の記念をされた方もいらっしゃいましたね(笑)私は既に寝落ていました··。
さて,今回は西香さんとの共同企画”ソフトウェアの異常検知のご紹介とベンチマ,クコ,ドの解説です。今日(2/25)からはじまるこのコンペ。ソフトウェアの安定的な稼働の為に異常を早く確実に検知すべく,ログデータをもとにしたシステムの健全性状態予測に挑戦します。
~2022/3/22 追記~
コ,ド解説のYouTube生活を実施しました!
Matlabラ词典センス提供中!
どなたでも参加できますし使用ルは問いません。が!!MATLABの無料ラaapl . exeセンスも工具箱もりもりで提供しておりますので,これを機に新しい工具箱の味見がてらぜひ参加してみてください。(注:学生コンテストとの記載がありますがどなたでも利用可能です)
ラ@ @センスに申し込む際のステップは申し込みガ@ @ドにまめました。実際に利用いただけるまで申請から少し時間がかかりますのでまずは申請を済ませておくことをおススメいたします。
コンテスト概要
コンペの詳細·登録は”ソフトウェアの異常検知から行ってください。
- 分析課題:ソフトウェアの異常検知
- 参加締切:2022年 4 月 26 日
- 賞金総額:25万円
Matlabをメaapl . exeンに使って参加頂いた方には順位に応じてMatlab特別賞をお贈りします。
デ,タは操作系统やWebLogic Serverより観測されるCPUやメモリの利用率など。それらを説明変数にしてソフトウェア(MATLABじゃないよ)の異常を予測するというシンプルな設定。与えられた多くの時系列デ,タをどう料理するかが問われます。
ベンチマ,ク解析
ここでは学習デ,タの一部を使ってデ,タの読み込みから予測モデルの学習までを実施してみます。スクリプト自体はペ,ジ下部のボタンからdlできますし,使用するデ,タと一緒にMATLAB驱动器でも公開しています。MathWorksアカウントと関連ライセンスがあればMATLAB在线で実行してみることもできます。
今回,学習用データセットとして与えられているtrain.csvは1.8 GBと多少大きいので,このコードでは一部を取り出したtrainIphost17.csvを使用します。変数hostが" lphost17 "のデ,タだけを抽出しています。読み込むデ,タをtrain.csvに置き換えてもそのまま機能するはずです。
使用する工具箱
デ,タの読み込み
datadir =“实际上”;%ファescルの保存場所
Filepath = fullfile(datadir,“trainlphost17.csv”);
Ds =数据存储
170変数が認識されていますね。問題なく読み込めそうです。预览で冒頭の8行だけ確認してみます。
预览(ds)
时间戳、主机异常,流程など170個の変数が確認できますね。readallを使って一気に読み込んでみます。
Matfilepath = fullfile(datadir,“trainData_lphost17.mat”);
如果存在(matfilepath“文件”)
负载(matfilepath“trainData”);
其他的
trainData = readall(ds);
% matファescルからの読み込みの方が速いので保存しておく
保存(matfilepath,“trainData”);
结束
主机と进程がデタ元のラベルの様なのでこれらの種類を確認します。
独特的(trainData.process)
独特的(trainData.host)
このデータでは主机はlphost17のみ,そして过程はwls1とwls2です。正常か異常のラベルが异常という変数で,今回の目的変数ですね。ラベルの数を汇总関数で見ておきます。
汇总(trainData.Anomaly)
異常デタ(异常= 1)。データ元は主机/过程で特定できますが,2変数だと不便なのでデータ元を表す変数起源を作っておきます。それぞれカテゴリ変数に変換しておきます。
trainData。origin = categorical(string(trainData.host) + string(trainData.process));
trainData。宿主= categorical(trainData.host);
trainData。过程= categorical(trainData.process);
時系列の確認
ここでは主机/进程毎にデタ,特に時刻デタをチェックします。パッと見たところ時刻データはきれいに並んでいるようですが,时间戳の最大,最小,時間間隔を念のため確認します。
%グルプ要約の計算
Gstats = groupsummary(trainData,[“主机”,“过程”), {“马克斯”,“最小值”,...
@ (x){独特(diff (x))}},“时间戳”)
デ,タ数はwls1/wls2ともに大体同じ。計測開始·終了時刻も同じとなっています。時間ステップ幅を確認するために関数ハンドルを使って@ (x){独特(diff (x))}という処理を加えています。Process = wls1のデ,タを見ると
Gstats.fun1_timestamp {1}
と1分から3時間までばらきますね。このサンプルコドではこの点にいて特に処置は行わずこのまま進めます。デタの前処理にいてはデ,タの前処理:デ,タクリ,ニング,平滑化,グル,プ化で紹介している内容が役立かもしれません。
異常の発生状況プロット
学習デ,タ内の異常発生状況を確認します。
uniqueOri = unique(trainData.origin);
图(1)
tiledlayout (“流”);
为2 = 1:长度(uniqueOri)
idx = trainData。origin == uniqueOri(ii);
tmp = trainData(idx,:);
nexttile
yyaxis左
情节(tmp.timestamp tmp.Anomaly,线宽= 2)
ylabel (“异常”)
持有在
Difftimestep = [0;diff (tmp.timestamp)];
yyaxis正确的
情节(tmp。时间戳,分钟(difftimestep),线宽= 2)
ylabel (“间隔(分钟)”)
持有从
标题(uniqueOri (ii))
结束
Wls1では5回,wls2では2回異常が発生しています。時間ステップの揺らぎ合わせてプロットしていますが,異常発生と同時に起こっている場合もあれば関係なく発生している箇所もあります。
説明変数の絞り込み
説明変数が約170個と多いので,サクッと計算させるために使用する変数を絞り込みます。絞り込む方法は多数考えられますがこらのヘルプペジ(特徴選択の紹介)も参考になるかもしれません。ここでは异常と相関が高いもの,そして相互に相関が高いものは片方だけを残すことにします。时间戳,主机,进程以外の数値デ,タを対象とします。
S = vartype(“数字”);
features = trainData(:,S);%数値デタだけ取り出す
corrcoef関数で相互相関を計算して,异常との相関係数の絶対値(1行目)を昇順に並べます。
R = corrcoef(features.Variables);
[Rsort,idx] = sort(abs(R(1,:)),“下”,“MissingPlacement”,“最后一次”);
数字
酒吧(函数(2)):
标题(“异常との相関係数絶対値”)
次に异常との相関係数(絶対値)が上位30の変数に絞って,相互相関を見てみます。
Features30 = features(:,idx(1:30));
数字
R = corrcoef(features30.Variables);
热图(abs (R))
标题(“相互相関(絶対値)”)
説明変数間でも相関係数が高いものがあります。特に高い(0.9以上)ものは同じ情報を持っているとみなして片方だけ使用することで更に変数を絞り込みます。
absR = abs(R);
tmp = triu(absR>0.9,1);行列の上三角部分
[row,col] = ind2sub(size(absR),find(tmp));% 0.9以上の位置
idxDiag = row == col;
row = row(~idxDiag);
col = col(~idxDiag);% 0.9未満のものだけ残す
数字
Features2use = featres30;
Features2use (:,col) = [];
R = corrcoef(features2use.Variables);
数字
热图(abs (R))
异常情况含めて23個残りました。変数の名前(异常との相関(絶対値)が高い順)を確認しておきます。
varnames = features2use.Properties.VariableNames '
予測モデルの学習
次はこの変数で予測モデルを作ってみます。
学習に使用するデ,タ区間の切り出し
上で見た通り正常(异常= 0)のデータが多いため,正常データのアンダーサンプリングの為以下の操作を行います。
- 異常発生箇所を確認し異常区間の長さ(デ,タ点数)を確認
- 異常中(异常= 1)の前後に異常区間の長さ分のデ,タを加えた区間を抽出
dataSeg = [];%デタ確保用変数
dataOri = [];%デタ元
dataAll = [];%デ,タ確保用変数(単純に繋げたもの)
uniqueOri = unique(trainData.origin)
%注意:スタ,トとエンドは正常であることが前提(lphost7のデ,タはOK)
为2 = 1:长度(uniqueOri)
idx = trainData。origin == uniqueOri(ii);
tmp = trainData(idx,varnames);
以下を探します。
% 0から1に変化する箇所:异常启动
% 1から0に変化する箇所:异常结束
isAnomaly1 = tmp.Anomaly;
isAnomaly2 = [0;isAnomaly1 (1: end-1)];
isChange = xor(isAnomaly1, isAnomaly2);% 変化点検知
posFalls = find(isChange & isAnomaly2);% 1 -> 0 (end)
posRises = find(isChange & ~isAnomaly2);% 0 -> 1(开始)
为jj = 1:长度(posRises)
duration = 1*(posFalls(jj) - posRises(jj));
如果posRises(jj) - duration > 0
idxStart = posRises(jj) - duration;
其他的
idxStart = 1;
结束
如果posFalls(jj) + duration < height(tmp)
idxEnd = posFalls(jj) + duration;
其他的
idxEnd = height(tmp);
结束
dataSeg = [dataSeg;{tmp (idxStart: idxEnd:)}];
dataAll = [dataAll;tmp (idxStart: idxEnd:)];
dataOri = [dataOri;uniqueOri (ii)];
结束
结束
汇总(dataAll.Anomaly)
正常(0)と異常(1)のデタ比が2:1程度です。
切り出し部分のプロット
まず単純に繋げてプロット。
数字
区(dataAll.Anomaly)
标题(“异常”)
包含(“数据”)
異常箇所毎に分けてプロット。
数字
tiledlayout (“流”);
为2 = 1:长度(dataSeg)
nexttile
tmp = dataSeg{ii};
区(tmp。异常,“线宽”, 2)
标题(dataOri (ii));
结束
持有从
予測モデル学習LSTM
まずは時系列データとしてではなく,単純に各観測値を独立したものとみて予測モデルを作ってみるのも手です。このスクリプトでは省略しますがこらのペジ(モデルの作成と評価:特徴選択,特徴量エンジニアリング,モデル選択,ハ)が参考になるかと思います。
ここではLSTMを使って予測モデルを作ってみます。時系列デ,タの分類問題として深層学習を使用した序列对序列分類を参考します。時系列,シ,ケンス,およびテキストを使用した深層学習のペ,ジも時系列デ,タの取り扱いに関する情報元として参考になるかもしれません。
デ,タの分割
上で作った各異常区間のデ,タ(dataSeg)を使用しますが,まずは学習用とテスト用に分割します。ここではデータ元(lphost17wls1或lphost17wls2)で層化させて,学習データと検証データを分割します。
rng (0)%同じ結果が再現するように乱数シトを固定
cv = cvpartition(dataOri,“坚持”, 0.4);
学習デ,タ(6セット)
trainSeg = dataSeg(cv.training)
検証デタ(3セット)
testSeg = dataSeg(cv.test)
LSTMの学習データとして使用するために,各時系列セグメントとラベルデータをセル配列として成形します。generateDataset4LSTM関数はスクリプト下部にロ,カル関数として定義しています。
[xTrain,yTrain] = generateDataset4LSTM(trainSeg);%学習デタ
[xTest,yTest] = generateDataset4LSTM(testSeg);%テストデタ
こんな形です。セルの中身は22個の特徴量が22 × Nの形で並んでいることに注意。
xTrain
ネットワ,ク構築
試しに隠れユニット数100のLSTM層を2層としてみます。この辺は最適化する余地はたくさんありそうです。実験マネ,ジャ,アプリが役に立かもしれません。
numFeatures = 22;特徴量変数の数
numHiddenUnits = 100;隠れユニット数
numClasses = 2;%予測クラス数(異常·正常)
层= [...
sequenceInputLayer (numFeatures)
lstmLayer (numHiddenUnits“OutputMode”,“序列”)
lstmLayer (numHiddenUnits“OutputMode”,“序列”)
fullyConnectedLayer (numClasses)
softmaxLayer
classificationLayer (“类”, {' 0 ',' 1 '},“ClassWeights”[1,2]))
分類層の設定で重み付きクロスエントロピ,損失関数を使用しています。詳細はこらのclassificationLayerのヘルプペ,ジ(英語)を確認してください。
学習オプション設定
选项= trainingOptions(“亚当”,...
“MaxEpochs”10...
“MiniBatchSize”, 1...
“ValidationData”{xTest,欧美},...
“阴谋”,“训练进步”);
学習
rng (0)%同じ結果が再現するように乱数シトを固定
net = trainNetwork(xTrain,yTrain,图层,选项);
保存しておきます。
保存(“lstmnet_lphost17_LSTM.mat”,“净”,“varnames”);
検証デ,タへの予測精度を再確認
[yPred, scores] = category (net,xTest);
数字
混同行列を描きます(異常区間ごとにセル配列になっているのですべて結合しています)
confusionchart([欧美{:}]、[yPred {}):,...
“ColumnSummary”,“column-normalized”,...
“RowSummary”,“row-normalized”);
まあまぁです。
評価指標PRC(预测-回忆-曲线)
今回の評価指標であるPRC(预测-回忆-曲线)を描いてみます。
trueLabel = [yTest{:}];
labelScores = [scores{:}];
abnormyscores = labelScores(2,:);% labels(2) = 1(異常)の分数
N = 100;閾値の段階数
召回=零(N,1);
精度=零(N,1);
阈值= linspace(0,1,N);
标签= net.Layers(end).Classes;
%閾値を変えて召回率/精度を計算
为2 = 1: N
Th =阈值(ii);
[recall (ii), precsions (ii)] = getRecallPrecisionCurve(th,anomalyScores,trueLabel,labels);
结束
数字
情节(回忆说,精度)
提出用の予測作成
Datadirフォルダ内にtest.csvがある想定です。
负载(“lstmnet_lphost17_LSTM.mat”,“净”,“varnames”);モデル読み込み
テストデ,タ読み込み
Test.csvファソフトウェアの異常検知)から参加登録後に入手してdatadirに保存していることが前提です。
Matfilepath = fullfile(datadir,“test.mat”);
如果存在(matfilepath“文件”)
负载(matfilepath“testData”);
其他的
Filepath = fullfile(datadir,“test.csv”);
testData = readtable(文件路径);
% matファescルからの読み込みの方が速いので保存しておく
保存(matfilepath,“testData”);
结束
学習に使用した変数varnamesとid/主机/进程のみを取り出します。
testData = testData(:,[{“id”;“主机”;“过程”}; varnames(2:结束)]);% varname(1)は异常
头(testData)
ここは思い切って、主机/过程もまとまったうえで,時系列順にidが並んでいるという想定で進めます・・。主机/进程別に識別できるようデタ元(origin)変数を作っておきます。
testData。origin = categorical(string(testData.host) + string(testData.process));
予測
主机/进程毎に切り分けて予測処理を実行します。
teststori = unique(testData.origin);
testData。异常= zeros(height(testData),1);
为2 = 1:长度(testOri)
idx = testData。origin == testOri(ii);
tmpData = testData{idx,varnames(2:结束)};
tmpData = zscore(tmpData);%変数を正規化(方法は検討の余地あり)
[~,tmpScores] = category (net,tmpData ');
testdata . exception (idx,:) = tmpScores(2,:) ';%标签(2)の分数
结束
提出ファ@ @ル作成
submission.csvに出力する値は异常= 1であるスコアなので,上の分数の2列目です。
输出= testData(:,[“id”,“异常”]);
头(输出)
writetable(输出,“submission.csv”);
まとめ
無事に最後の提出用ファ@ @ル作成までたどり着きました。今回はサクサク進めるように一部のデータだけを使ってみましたが,ぜひ本番のtrain.csvでも試してみてください。
もう少しデータを詳しく調査してもっとよい変数を探してみたり,新たな特徴量を作ってみたり,モデルに凝ってみたり,といろいろ試したいことが出てきますが,ここから先はコンペに参加する方のお楽しみということで私からの紹介はここまでとします。
いずれにしても一部の変数(或一部のデータ)から始めてみて,まずデータの把握と課題の理解が第一歩かと思います。応募締め切りは4月26日。入賞目指して頑張ってください!
コンペへの参加登録はこらから:ソフトウェアの異常検知
Matlabラescセンス
冒頭でも触れましたがmatlabを使って参加される方にはラescセンスも提供しています。上でも触れた機械学習を行う统计和机器学习工具箱™,そしてディ,プラ,ニングをカバ,する深度学习工具箱™を含む18個の製品が利用可能です。是非ご活用ください。
関連リンク集
- Nishikaソフトウェアの異常検知
- Matlabラ转换器センス申し込みペ转换器ジと申し込みガ@ @ド
- ベンチマ,クスクリプト(MATLAB Drive)
- ヘルプペ,ジ:デ,タの前処理:デ,タクリ,ニング,平滑化,グル,プ化
- ヘルプペ,ジ:特徴選択の紹介
- ヘルプペ,ジ:モデルの作成と評価:特徴選択,特徴量エンジニアリング,モデル選択,ハ
- ヘルプペ,ジ:深層学習を使用した序列对序列分類
- ヘルプペ,ジ:時系列,シ,ケンス,およびテキストを使用した深層学習
ヘルパ,関数
閾値を変えて召回と精度を計算する関数
函数[recall,precision] = getRecallPrecisionCurve(threshold,anomalyScores,trueLabel,labels)
预测= repelem(labels(1), length(trueLabel),1);
预测(abnormyscores > threshold,:) = labels(2);
results = confusimat (trueLabel,预测);
TN = results(1,1);
TP = results(2,2);
FN = results(2,1);
FP = results(1,2);
精度= TP/(TP+FP);
召回率= TP/(TP+FN);
结束
LSTMを学習する為にデ,タを成形する関数
函数[x,y] = generateDataset4LSTM(dataSeg)
X = [];
Y = [];
为2 = 1:长度(dataSeg)
tmpT = dataSeg{ii};
%异常以外の変数を正規化(方法は検討の余地あり)
tmpT{:,2:end} = zscore(tmpT{:,2:end});
tmpX = tmpT{:,2:结束}';
tmpY = tmpt . exception (:,:) ';
X = [X;{tmpX}];
Y = [Y;{分类(tmpY)});
结束
结束
댓글
댓글을남기려면링크를클릭하여MathWorks계정에로그하거나계정을새로만드십시오。