摘要:業界期望使用機器學習技術來建構硬碟故障預測的模型,更準确地提前感覺硬碟故障,降低運維成本,提升業務體驗。本案例将使用随機森林算法來訓練一個硬碟故障預測模型。
本文分享自華為雲社群《基于随機森林算法進行硬碟故障預測》,原文作者:山海之光。
實驗目标
- 掌握使用機器學習方法訓練模型的基本流程;
- 掌握使用pandas做資料分析的基本方法;
- 掌握使用scikit-learn進行随機森林模型的建構、訓練、儲存、加載、預測、統計準确率名額和檢視混淆矩陣的方法;
案例内容介紹
随着網際網路、雲計算的發展,資料的存儲需求與日倍增,大規模海量資料存儲中心是必不可少的基礎性設施。雖然新的存儲媒體例如SSD,已經很多方面擁有了比磁盤更好的性能,但就目前來講,其高昂的花費仍然使大部分資料中心難以負擔,是以,大型資料中心依然會采用傳統的機械硬碟作為存儲媒體。
機械硬碟生命周期通常為3到5年,在2到3年後故障率明顯升高,導緻換盤量陡增。據統計,在伺服器硬體故障中,硬碟故障占比達到48%+,是影響伺服器運作可靠性的重要因素。早在上個世紀九十年代,人們就意識到資料的寶貴性遠勝于硬碟自身價值,渴望有種技術能對硬碟故障進行預測并實作相對安全的資料保護,是以S.M.A.R.T.技術應運而生。
S.M.A.R.T.,全稱為“Self-Monitoring Analysis and Reporting Technology”,即“自我監測、分析及報告技術”,是一種自動的硬碟狀态檢測與預警系統和規範。通過在硬碟硬體内的檢測指令對硬碟的硬體如磁頭、盤片、馬達、電路的運作情況進行監控、記錄并與廠商所設定的預設安全值進行比較,若監控情況将或已超出預設安全值的安全範圍,就可以通過主機的監控硬體或軟體自動向使用者作出警告并進行輕微的自動修複,以提前保障硬碟資料的安全。除一些出廠時間極早的硬碟外,現在大部分硬碟均配備該項技術。關于該技術的更多介紹,請檢視S.M.A.R.T.-百度百科。
雖然硬碟廠商采用了S.M.A.R.T.技術來監測硬碟的健康狀态,但是大多數廠商都是基于設計規則制定的故障預測手段,預測效果非常差,不能滿足日漸嚴格的提前預測硬碟故障的需求。是以,業界期望使用機器學習技術來建構硬碟故障預測的模型,更準确地提前感覺硬碟故障,降低運維成本,提升業務體驗。
本案例将帶大家使用一份開源的S.M.A.R.T.資料集和機器學習中的随機森林算法,來訓練一個硬碟故障預測模型,并測試效果。
關于随機森林算法的理論講解,可參考此視訊。
注意事項
- 如果你是第一次使用 JupyterLab,請檢視《ModelAtrs JupyterLab使用指導》了解使用方法;
- 如果你在使用 JupyterLab 過程中碰到報錯,請參考《ModelAtrs JupyterLab常見問題解決辦法》嘗試解決問題。
實驗步驟
1. 資料集介紹
本案例使用的資料集是來自于Backblaze公司的開源資料集,它是一家計算機備份和雲存儲服務提供商。自2013年以來,Backbreze每年都會公開釋出他們的資料中心所使用硬碟的S.M.A.R.T.日志資料,有效地推動了使用機器學習技術進行硬碟故障預測的發展。
由于Backblaze公司釋出的S.M.A.R.T.日志資料量較大,本案例為快速示範使用機器學習建構硬碟故障預測模型的過程,僅使用了該公司釋出的2020年的資料,相關資料已經準備好,放在OBS中,運作如下代碼即可下載下傳這部分資料。
注意:本步下載下傳資料的代碼需要在華為雲 ModelArts Codelab 上運作
import os
import moxing as mox
if not os.path.exists('./dataset_2020.zip'):
mox.file.copy('obs://modelarts-labs-bj4/course/ai_in_action/2021/machine_learning/hard_drive_disk_fail_prediction/dataset_2020.zip', './dataset_2020.zip')
os.system('unzip dataset_2020.zip')
if not os.path.exists('./dataset_2020'):
raise Exception('錯誤!資料不存在!')
!ls -lh ./dataset_2020
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicGcq5ydwIzNfFTMyEGOyETZwkTMhVDZ5MmYycDZhdTM0kjMwQWNzEmZtIjdvwFM48CXt92YucWbphmeuIzYpB3Lc9CX6MHc0RHaiojIsJye.jpg)
資料解釋:
2020-12-08.csv:從backblaze公司釋出的2020 Q4資料集中抽取出來的2020-12-08這天的S.M.A.R.T.日志資料
2020-12-09.csv:從backblaze公司釋出的2020 Q4資料集中抽取出來的2020-12-09這天的S.M.A.R.T.日志資料
dataset_2020.csv:已經處理過的2020年全年S.M.A.R.T.日志資料,下文中“第2.6節 類别均衡度分析”會解釋如何得到這部分資料
prepare_data.py: 運作該腳本,會下載下傳2020年全年S.M.A.R.T.日志資料,并進行處理,得到dataset_2020.csv。運作該腳本需要20G的本地存儲空間
2. 資料分析
使用機器學習建構任何模型之前,都需要先對資料集進行分析,了解資料集的規模、屬性名、屬性值、各類統計名額及空值情況。因為我們要先了解資料,才能用好資料。
2.1 讀取csv檔案
pandas是常用的python資料分析子產品,我們先用它來加載資料集中的csv檔案。以2020-12-08.csv為例,我們先加載該檔案來分析S.M.A.R.T.日志資料的情況
2.2 檢視單個csv檔案資料的規模
2.3 檢視頭5行資料
使用pandas加載csv後,得到的是一個DataFrame對象,可以了解為一個表格,調用該對象的head()函數,可以檢視表格的頭5行資料
df_data.head()
5 rows × 149 columns
如上所示是表格的頭5行資料,表頭是屬性名,屬性名下面是屬性值,backblaze網站解釋了屬性值的含義,翻譯為如下:
2.4 檢視資料的統計名額
檢視完表格的頭5行資料,我們再調用DataFrame對象的describe()函數,計算表格資料的統計名額
df_data.describe()
8 rows × 146 columns
如上所示是表格資料的統計名額,describe()函數預設對數值類型的列進行統計分析,由于表格的前三列’date’、‘serial_number’、'model’是字元串類型,是以這三列沒有統計名額。
各行統計名額的含義解釋如下:
count: 該列有多少個非空值
mean: 該列的均值
std: 該列數值的标準差
min: 該列數值的最小值
25%: 該列數值的25%中位值
50%: 該列數值的50%中位值
75%: 該列數值的75%中位值
max: 該列數值的最大值
2.5 檢視資料空值情況
從上面的輸出可以觀察到,某些屬性的count名額比較小,比如smart_2_raw的count數就比df_train的總行數要小很多,是以我們要再進一步看看各列屬性的空值情況,執行如下代碼可以檢視空值情況
df_data.isnull().sum()
date 0
serial_number 0
model 0
capacity_bytes 0
failure 0
smart_1_normalized 179
smart_1_raw 179
smart_2_normalized 103169
smart_2_raw 103169
smart_3_normalized 1261
smart_3_raw 1261
smart_4_normalized 1261
smart_4_raw 1261
smart_5_normalized 1221
smart_5_raw 1221
smart_7_normalized 1261
smart_7_raw 1261
smart_8_normalized 103169
smart_8_raw 103169
smart_9_normalized 179
smart_9_raw 179
smart_10_normalized 1261
smart_10_raw 1261
smart_11_normalized 161290
smart_11_raw 161290
smart_12_normalized 179
smart_12_raw 179
smart_13_normalized 161968
smart_13_raw 161968
smart_15_normalized 162008
...
smart_232_normalized 160966
smart_232_raw 160966
smart_233_normalized 160926
smart_233_raw 160926
smart_234_normalized 162008
smart_234_raw 162008
smart_235_normalized 160964
smart_235_raw 160964
smart_240_normalized 38968
smart_240_raw 38968
smart_241_normalized 56030
smart_241_raw 56030
smart_242_normalized 56032
smart_242_raw 56032
smart_245_normalized 161968
smart_245_raw 161968
smart_247_normalized 162006
smart_247_raw 162006
smart_248_normalized 162006
smart_248_raw 162006
smart_250_normalized 162008
smart_250_raw 162008
smart_251_normalized 162008
smart_251_raw 162008
smart_252_normalized 162008
smart_252_raw 162008
smart_254_normalized 161725
smart_254_raw 161725
smart_255_normalized 162008
smart_255_raw 162008
Length: 149, dtype: int64
這種顯示方式不太友善檢視,我們把可以空值的數量繪制成曲線圖,看起來更直覺
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
df_data_null_num = df_data.isnull().sum()
x = list(range(len(df_data_null_num)))
y = df_data_null_num.values
plt.plot(x, y)
plt.show()
從上面的結果可以看出,表格中的某些屬性有大量的空值。
在機器學習領域中,資料集中存在空值是很常見的現象,引起空值的原因有很多種,比如一份使用者畫像中有很多個屬性,但又不是所有使用者都有對應的屬性值,這時就産生了空值。或者某些資料因為傳輸逾時,導緻沒有采集上來,也可能會出現空值。
2.6 類别均衡度分析
我們要實作的任務是“硬碟故障預測”,即預測某個硬碟在某個時間是正常還是損壞,這就是一個故障預測問題或異常檢測問題,這類問題有個特點就是:正常樣本非常多,故障樣本非常少,兩類樣本的數量差異非常大。
比如,執行如下代碼,可以看到df_data中硬碟正常的樣本有16萬個以上,故障的樣本卻隻有8個,類别極度不均衡。
由于大多數機器學習方法的學習過程都是基于統計學的思路來進行學習的,如果直接使用上面這樣類别不均衡的資料進行訓練,那麼模型的能力可能會明顯偏向于類别多的樣本,類别少的樣本就會被“淹沒”掉了,在學習過程中發揮不了作用,是以我們需要平衡不同類别的資料。
為了獲得更多的故障樣本資料,我們可以從backblaze公司釋出的2020年全年S.M.A.R.T.日志資料中将所有的故障樣本都挑選出來,同時也随機挑出相同數量的正常樣本,可以通過下面的代碼來實作。
這段代碼已被注釋掉,如需運作,需要20G的本地存儲空間。您也可以不必運作這段代碼,因為本案例開頭已經下載下傳了dataset_2020.zip,這個壓縮包中已經提供了dataset_2020.csv,該csv就是運作下面這段代碼得到的檔案
import gc
del df_data # 删除 df_data 對象
gc.collect() # 由于接下來的代碼将加載日志資料到df_data對象中,為避免記憶體溢出的風險,可以在此處先手動回收記憶體,因為jupyterlab在運作過程中不會自動回收環境中的記憶體
2.7 加載類别均衡的資料集
dataset_2020.csv是已經經過類别均衡處理的硬碟S.M.A.R.T.日志資料,下面我們加載該檔案,再确認一下類别均衡情況
可以看到,正常樣本和故障樣本都是1497個
3. 特征工程
準備好可用的訓練集之後,接下來要做特征工程,通俗地講,特性工程就是要選擇表格中的哪些屬性來建構機器學習模型。人工設計特征的好壞,很大程度上決定了機器學習模型效果的好壞,是以機器學習領域的研究人員需耗費大量精力在人工設計特征上,是一項比較耗時、耗力,且需要專家經驗的工程。
3.1 SMART屬性與硬碟故障的相關研究
(1)BackBlaze分析了其HDD故障和SMART屬性之間的相關性,并發現了SMART 5、187、188、197、198與HDD故障的相關率最高,這些SMART屬性還與掃描錯誤,重新配置設定計數和試用計數有關[1];
(2)El-Shimi等發現在随機森林模型中除了以上5個特征外,還有SMART 9、193、194、241、242這5個屬性有最大權重[2];
(3)Pitakrat等人評估了21種用于預測硬碟故障的機器學習算法,發現在測試的21種機器學習算法中,随機森林算法在ROC曲線下有最大面積,而KNN分類器具有最高的F1值[3];
(4)Hughes等人也研究用于預測硬碟故障的機器學習方法,他們分析了SVM、樸素貝葉斯的表現,SVM實作了最高性能,檢測率為50.6%,誤報率為0%[4];
[1] Klein, Andy. “What SMART Hard Disk Errors Actually Tell Us.” Backblaze Blog Cloud Storage & Cloud Backup,6 Oct. 2016, http://www.backblaze.com/blog/what-smart-stats-indicate-hard-drive-failures/
[2] El-Shimi, Ahmed. “Predicting Storage Failures.” VAULT-Linux Storage and File Systems Conference.VAULT-Linux Storage and File Systems Conference, 22 Mar. 2017, Cambridge.
[3] Pitakrat, Teerat, André van Hoorn, and Lars Grunske. “A comparison of machine learning algorithms for proactive hard disk drive failure detection.” Proceedings of the 4th international ACM Sigsoft symposium on Architecting critical systems. ACM, 2013.
[4] Hughes, Gordon F., et al. “Improved disk-drive failure warnings.” IEEE Transactions on Reliability 51.3 (2002):350-357.
如上就是前人的一些研究成果,本案例計劃采用随機森林模型,是以可以根據上面第2條研究成果,選擇SMART 5, 9, 187, 188, 193, 194, 197, 198, 241, 242這些屬性來作為特征,它們的含義分别是:
SMART 5: 重映射扇區計數
SMART 9: 通電時間累計
SMART 187: 無法校正的錯誤
SMART 188: 指令逾時計數
SMART 193: 磁頭加載/解除安裝計數
SMART 194: 溫度
SMART 197: 等待被映射的扇區數
SMART 198: 報告給作業系統的無法通過硬體ECC校正的錯誤
SMART 241: 邏輯塊尋址模式寫入總數
SMART 242: 邏輯塊尋址模式讀取總數
另外,由于不同硬碟廠商的不同型号硬碟記錄SMART日志資料的标準可能不一樣,是以我們最好将同一型号的硬碟資料挑出來作為訓練資料,專門訓練一個預測該型号硬碟是否故障的模型。如果需要預測多個不同型号的硬碟是否故障,則可能需要分别訓練多個模型。
3.2 硬碟型号選擇
執行下面的代碼,看一下每種型号的硬碟資料量有多少
df_data.model.value_counts()
ST12000NM0007 664
ST4000DM000 491
ST8000NM0055 320
ST12000NM0008 293
TOSHIBA MG07ACA14TA 212
ST8000DM002 195
HGST HMS5C4040BLE640 193
HGST HUH721212ALN604 153
TOSHIBA MQ01ABF050 99
ST12000NM001G 53
HGST HMS5C4040ALE640 50
ST500LM012 HN 40
TOSHIBA MQ01ABF050M 35
HGST HUH721212ALE600 34
ST10000NM0086 29
ST14000NM001G 23
HGST HUH721212ALE604 21
ST500LM030 15
HGST HUH728080ALE600 14
Seagate BarraCuda SSD ZA250CM10002 12
WDC WD5000LPVX 11
WDC WUH721414ALE6L4 10
ST6000DX000 9
TOSHIBA MD04ABA400V 3
ST8000DM004 2
ST18000NM000J 2
Seagate SSD 2
ST4000DM005 2
ST8000DM005 1
ST16000NM001G 1
DELLBOSS VD 1
TOSHIBA HDWF180 1
HGST HDS5C4040ALE630 1
HGST HUS726040ALE610 1
WDC WD5000LPCX 1
Name: model, dtype: int64
可以看到 ST12000NM0007 型号的硬碟資料量最多,是以我們把該型号硬碟的資料過濾出來
df_data_model = df_data[df_data['model'] == 'ST12000NM0007']
3.3 特征選擇
選取上文提到的10個屬性作為特征
有空值存在,是以先要填充空值
3.4 劃分訓練集和測試集
使用sklearn的train_test_split即可劃分訓練集和測試集,test_size表示測試集的比例,一般取值為0.3、0.2或0.1
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X_data, Y_data, test_size=0.2, random_state=0)
4. 開始訓練
4.1 構模組化型
準備好訓練集和測試集之後,就可以開始構模組化型了,構模組化型的步驟非常簡單,直接調用機器學習架構sklearn中的RandomForestClassifier即可
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier()
随機森林算法的超參數有很多個,取不同的參數值構模組化型會得到不同的訓練效果,對于初學者,可以直接使用庫中提供的預設參數值,在對随機森林算法的原理有一定的了解之後,可以嘗試修改模型的參數來調整模型的訓練效果。
4.2 資料拟合
模型訓練的過程,也就是拟合訓練資料的過程,實作也非常簡單,調用fit函數即可開始訓練
/home/ma-user/anaconda3/envs/XGBoost-Sklearn/lib/python3.6/site-packages/sklearn/ensemble/forest.py:248: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.
"10 in version 0.20 to 100 in 0.22.", FutureWarning)
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
max_depth=None, max_features='auto', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=10, n_jobs=None,
oob_score=False, random_state=None, verbose=0,
warm_start=False)
5 開始預測
調用predict函數即可開始預測
Y_pred = rfc.predict(X_test)
5.1 統計預測準确率
在機器學習中,分類問題的性能名額,常用的有四種:accuracy(精度)、precision(查準率)、recall(查全率)、F1-Score,四種名額越接近1,表示效果越好。sklearn庫中有這四種名額的函數,直接調用即可。
關于四種名額的理論解釋,可參考此文章
每次進行随機森林模型的訓練,會得到該模型不同的測試準确率名額,這是由于随機森林算法的訓練過程具有一定的随機性導緻的,是正常現象。但是同一模型、同一樣本的預測結果是确定不變的。
5.2 模型儲存、加載、再預測
模型儲存
import pickle
with open('hdd_failure_pred.pkl', 'wb') as fw:
pickle.dump(rfc, fw)
模型加載
with open('hdd_failure_pred.pkl', 'rb') as fr:
new_rfc = pickle.load(fr)
模型再預測
5.3 檢視混淆矩陣
要分析分類模型的效果如何,還可以使用混淆矩陣來檢視,混淆矩陣的橫軸表示預測結果的各個類别,縱軸表示真實标簽的類别,矩陣方格中的值就代表對應橫縱坐标重疊的測試樣本數量。
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
LABELS = ['Healthy', 'Failed']
conf_matrix = confusion_matrix(Y_test, Y_pred)
plt.figure(figsize =(6, 6))
sns.heatmap(conf_matrix, xticklabels = LABELS,
yticklabels = LABELS, annot = True, fmt ="d");
plt.title("Confusion matrix")
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.show()
6. 改進模型的思路
如上内容是使用随機森林算法建構硬碟故障預測模型的過程示範,模型精度并不算高,有如下幾個思路可以提升模型的精度:
(1)本案例隻使用了Backblaze公司2020年的資料,您可以嘗試使用更多的訓練資料;
(2)本案例隻使用了10個SMART屬性作為特征,您可以嘗試使用其他方法來建構特征;
(3)本案例使用了随機森林算法來訓練模型,您可以嘗試使用其他的機器學習算法;
點選進入華為雲 ModelArts Codelab 可直接運作本案例代碼
點選關注,第一時間了解華為雲新鮮技術~