天天看點

動手實操丨基于随機森林算法進行硬碟故障預測

摘要:業界期望使用機器學習技術來建構硬碟故障預測的模型,更準确地提前感覺硬碟故障,降低運維成本,提升業務體驗。本案例将使用随機森林算法來訓練一個硬碟故障預測模型。

本文分享自華為雲社群《基于随機森林算法進行硬碟故障預測》,原文作者:山海之光。

實驗目标

  1. 掌握使用機器學習方法訓練模型的基本流程;
  2. 掌握使用pandas做資料分析的基本方法;
  3. 掌握使用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.資料集和機器學習中的随機森林算法,來訓練一個硬碟故障預測模型,并測試效果。

關于随機森林算法的理論講解,可參考此視訊。

注意事項

  1. 如果你是第一次使用 JupyterLab,請檢視《ModelAtrs JupyterLab使用指導》了解使用方法;
  2. 如果你在使用 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      
動手實操丨基于随機森林算法進行硬碟故障預測

資料解釋:

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 可直接運作本案例代碼

點選關注,第一時間了解華為雲新鮮技術~

繼續閱讀