簡介
上一篇文章中介紹了ROOT的基本使用與函數繪製。在這邊文章中筆者會以著名的Iris dataset介紹如何使用ROOT進行資料分析。
資料可以在這裡下載:https://www.kaggle.com/uciml/iris/data
數據分析
把下載回來的資料解壓鎖後會有兩個檔案。Iris.csv
與database.sqlite
。因為csv比sqlite常見所以我們先使用csv看看。
root [0] rdf = ROOT::RDF::MakeCsvDataFrame("Iris.csv")
(ROOT::RDataFrame &) A data frame associated to the data source "CSV data source"
ROOT的RDataFrame具同Python裡Pandas提供的DataFrame一樣的功能。他是一個能夠儲存數據的二維表格。只是由於RDataFrame是在去年才正式推出的功能,他的使用上還是有點受限。
我們可以透過GetColumnNames()
得到所有欄位的名稱
root [1] rdf.GetColumnNames()
(ROOT::RDF::RInterface::ColumnNames_t) { "Id", "SepalLengthCm", "SepalWidthCm", "PetalLengthCm", "PetalWidthCm", "Species" }
SepalLengthCm
看起來是個有意思的欄位。我們可以使用RDataFrame::Histo1D
查看這個欄位的數值分佈。
root [2] h1 = rdf.Histo1D("SepalLengthCm");
root [3] h1->Draw()
SepalLengthCm的Histogram |
在這裡使用筆電的讀者如果有跟著操作的話有可能會注意到h1->Draw()
的執行速度比前面h1 = rdf.Histo1D("SepalLengthCm")
還要慢。這是正常的現象。RDataFrame下幾乎所有的運算都是Lazy Evaulated,也就是說只有當真正需要資料的時候才會去進行計算,前面的步驟都只是在準備而已。
這張圖看起來有些像是常態分佈。為了驗證我們用Fit
函數試著將常態分佈擬合到這個圖形上看看。
root [4] h1->Fit("gaus");
FCN=42.6871 FROM MIGRAD STATUS=CONVERGED 77 CALLS 78 TOTAL
EDM=1.83384e-08 STRATEGY= 1 ERROR MATRIX ACCURATE
EXT PARAMETER STEP FIRST
NO. NAME VALUE ERROR SIZE DERIVATIVE
1 Constant 4.94917e+00 6.56929e-01 1.54143e-03 -2.95222e-04
2 Mean 5.82870e+00 1.09569e-01 3.41844e-04 -9.68451e-04
3 Sigma 9.28614e-01 1.19380e-01 1.05036e-04 -1.58562e-03
將高斯分佈擬合的結果 |
不過一個常態分佈可能沒辦法提供太多有用的資訊。沒關係。我們可以用Filter()
過濾某些特定品種的資料。Filter
跟 Histo1D
一樣屬於 lazey evaulation,只有在必要的時候才會進行計算來降低需要的處理資源。
root [5] h1 = rdf.Filter("Species == \"Iris-setosa\"").Histo1D("SepalLengthCm");
root [6] h1->Draw()
Iris-setosa的SepalLengthCm的分佈 |
好吧,看起來沒有太多幫助。But you get the idea. Filter
能夠根據用來過濾資料。除了生成Histogram外我們也可以用Plot
生成Scatter plot. 在這裡就可以看出ROOT已經有些年紀了。不像現代的繪圖程式會用參數決定繪圖的模式,ROOT依靠各種Method與parser決定樣式。詳細的設定方法可以參考ROOT的說明文件。
root [7] g1 = rdf.Graph("SepalLengthCm", "PetalLengthCm");
root [8] g1->SetMarkerStyle(6);
root [9] c1->Clear();
root [10] g1->Draw("AP");
用ROOT畫出來的scatter plot |
這時如果我們想,也是可以對這張圖進行函數擬合。看起來頗線性的,我們試試看線性函數 pol1
。(代表Polynomial 1。同理二次函數則是pol2
,以此類推。)
root [11] g1->Fit("pol1")
****************************************
Minimizer is Linear
Chi2 = 111.365
NDf = 148
p0 = -7.09519 +/- 0.506447
p1 = 1.85748 +/- 0.0858193
使用線性函數擬合至scatter plot上 |
那這兩筆資料有多相關呢?我們可以透過相關係數得知。
root [12] g1->->GetCorrelationFactor()
(double) 0.87173546
小節
本文展示了ROOT下基本的資料分析方法。能夠載入資料與繪製不同種的圖表。RDataFrame是ROOT新的資料載入界面(相較於行之有年的TTree系統),能簡單的操作資料與繪製圖形。