Python 資料科學入門

XiaoxiaoLi發表於2016-06-21

Python 在資料科學領域越來越流行了。它的流行不無道理。 Python 容易學,有超強資料科學庫,並且和 Hadoop 以及 Spark 等資料庫和工具整合得非常好。Python 可以從頭至尾完成一個資料科學專案,無論是讀取資料、分析資料、資料視覺化還是用機器學習來做預測都可以。

本文介紹如何用 Python 上手資料科學。如果想要了解更多內容請訪問 Dataquest, 那裡有使用 Python 完成資料科學任務的深入講解。

本文使用的是關於 2016 美國總統大選政治資助的資料集(連結 在此)。檔案是 csv 格式,每行代表對一個候選人的一次捐贈。這個資料集有幾列比較值得一提,比如:

  • cand_nm – 接受捐贈的候選人姓名
  • contbr_nm – 捐贈人姓名
  • contbr_state – 捐贈人所在州
  • contbr_employer – 捐贈人所在公司
  • contbr_occupation – 捐贈人職業
  • contb_receipt_amount – 捐贈數額(美元)
  • contb_receipt_dt – 收到捐款的日期

安裝 Python

要分析這些資料,首先要安裝 Python。利用 Anaconda 這個工具來安裝 Python 是非常簡單的。Anaconda 在安裝 Python 的同時還會安裝一些流行的資料分析庫。點選 這裡 下載 Anaconda。建議安裝最新的 Python 3.5 版本。這個連結 裡介紹了一些 Python 2 與 Python 3 的對比。

Anaconda 會自動安裝一些這篇文章會用到的庫,包括 JupyterPandasscikit-learn 和 matplotlib

Jupyter 入門

都安裝好之後可以啟動 Jupyter notebook (原名 IPython notebook)。Jupyter notebook 是個強有力的資料分析工具。它能夠幫助快速檢視資料、將結果視覺化以及把結果分享給他人。谷歌、IBM、微軟的資料科學家都用它來分析資料以及組內協作。

在命令列裡輸入 ipython notebook 來執行 Jupyter。如果遇到問題可以去它的 官方文件 裡查詢答案。

Python 資料科學入門

啟動後會出現一個可以檢視檔案的瀏覽器介面,在這個頁面上可以建立新的 notebook。請建立一個叫 Python 3 的 notebook,一會兒的資料分析中會用到它。如果剛才的安裝還沒成功,這篇文章 也許有幫助。

Notebook 工作區塊

每個 Jupyter notebook 都包含多個區塊(cell),區塊可以執行程式碼也可以只包含文件。每個 notebook 開始時都自帶一個區塊,如有需要可以自行增加多個區塊,比如:

In [ ]:
In [ ]:

如果想要了解更多關於 Jupyter 的知識請閱讀作者提供的更深入的 教程

Pandas 入門

Pandas 是 Python 上的一個資料分析庫。它能讀取包括 csv 在內的不同格式的資料,分析資料也很有效。可以通過下面的程式碼來讀取資料:

In [2]:
In [3]:
Out[3]:
In [4]:
Out[4]:
cmte_id cand_id cand_nm contbr_nm contbr_city contbr_st contbr_zip contbr_employer contbr_occupation contb_receipt_amt contb_receipt_dt receipt_desc memo_cd memo_text form_tp file_num tran_id election_tp
C00458844 P60006723 Rubio, Marco KIBBLE, KUMAR DPO AE 092131903 U.S. DEPARTMENT OF HOMELAND SECURITY LAW ENFORCEMENT 500 27-AUG-15 NaN NaN NaN SA17A 1029457 SA17.813360 P2016 NaN
C00458844 P60006723 Rubio, Marco HEFFERNAN, MICHAEL APO AE 090960009 INFORMATION REQUESTED PER BEST EFFORTS INFORMATION REQUESTED PER BEST EFFORTS 210 27-JUN-15 NaN NaN NaN SA17A 1029436 SA17.796904 P2016 NaN

上面的區塊用 import pandas as pd 這個語句匯入了 Pandas 庫,然後用 read_csv() 這個函式把 political_donations.csv 這個檔案讀入了變數 donations 中。變數 donations 現在就是一個 Pandas DataFrame。Pandas DataFrame 可以被看做是加強版的矩陣,它自帶資料分析函式,並且允許不同的列包含不同的資料型別。

可以通過變數 donations 的 shape 屬性來列印它多少行多少列。每個區塊的最後一行語句或變數都會自動顯示,這個功能超讚!下一個區塊用了 DataFrames 的 head() 函式列印出了變數 donations 的頭兩行,這樣就能看裡面的資料了。

如想更深入地瞭解 Pandas 請參閱作者提供的 課程

每個候選人收到的捐款總額

使用Pandas 中的 groupby() 函式能計算出每個候選人的整體統計資料。根據變數 cand_nm(候選人姓名)來把變數 donations 分成不同的子集就可以針對每個候選人分別統計資料。首先要算的是捐款總額。把候選人的 contb_receipt_amount 這一列加起來就可以得到收到的捐款總額了。

In [14]:
Out[14]:
contb_receipt_amt file_num
cand_nm
Pataki, George E. 365090.98 234695430
Webb, James Henry Jr. 398717.25 709419893
Lessig, Lawrence 621494.50 1378488449
Santorum, Richard J. 781401.03 822086638
Trump, Donald J. 1009730.97 2357347570
Jindal, Bobby 1013918.12 584896776
Perry, James R. (Rick) 1120362.59 925732125
Huckabee, Mike 1895549.15 2700810255
O’Malley, Martin Joseph 2921991.65 2664148850
Graham, Lindsey O. 2932402.63 3131180533
Kasich, John R. 3734242.12 2669944682
Christie, Christopher J. 3976329.13 2421473376
Paul, Rand 4376828.14 16056604577
Fiorina, Carly 4505707.06 12599637777
Walker, Scott 4654810.30 5636746962
Sanders, Bernard 9018526.00 71139864714
Rubio, Marco 10746283.24 22730139555
Carson, Benjamin S. 11746359.74 75613624360
Cruz, Rafael Edward ‘Ted’ 17008622.17 69375616591
Bush, Jeb 23243472.85 14946097673
Clinton, Hillary Rodham 61726374.09 86560202290

上面的程式碼首先用donations.groupby("cand_nm") 根據cand_nmdonations 分成了不同的組。這個語句返回的是 GroupBy 物件,GroupBy 型別自帶一些專門用來整合資料的函式。其中就包含sum() 函式,在這個問題中可以用來計算每組中每一列中資料的和。

Pandas 在讀取資料的時候就會自動識別每一列的資料型別,在進行求和時只會針對數字型別的列來操作。這樣就得到了一個包含每個候選人contb_receipt_amt列中所有數字之和及file_num 列中所有數字之和的 DataFrame。最後使用 DataFrames 中的 sort() 函式將contb_receipt_amt 的和從小到大排序。這樣就得到了每個候選人收到的捐款總額。

將捐款總額視覺化

Python 中最主要的視覺化包就是 matplotlib,可以用它來畫圖。Jupyter notebook 能夠在瀏覽器中直接渲染 matplotlib 的圖表。這個功能需要通過啟用 matplotlib 的 inline 模式來開啟。可以利用 Jupyter magics 中的命令來啟用它就能直接在 notebook 中看圖表了。

Magics 就是以 % 或者 %% 開頭的、能改變 Jupyter notebook 本身的命令。它們是為了讓能夠通過命令列改變 Jupyter 的設定,同時儘量不與 Python 程式碼混淆而存在的。要想在瀏覽器裡直接看 matplotlib 的圖表,需要在程式碼區塊裡執行 %matplotlib inline。更多關於用 Jupyter 畫圖的內容可以 在此 閱讀。

用下面的程式碼來匯入 matplotlib 庫並且開啟 inline 模式:

In [15]:

Pandas 中的 DataFrames 自帶對視覺化的支援,呼叫 plot() 函式就可以生成 matplotlib 圖表。這麼用一般會比呼叫 matplotlib 更方便快捷。先給之前的 DataFrame 賦值給一個變數 total_donations,再利用 indexing 來選擇 DataFrame 中的一列: contb_receipt_amt。這樣就生成了一個 Pandas 中的 Series 型別的變數。

Pandas 中的 Series 和 DataFrames 包含的函式都差不多,但是 Series 只能存一維資料,比如單一行或者單一列。呼叫 Series 的 plot() 函式就生成了一個顯示每個候選人收到的捐款總額的柱狀圖。

In [16]:
In [20]:
Out[20]:
Python 資料科學入門
如果想深入學習 matplotlib, 可以學習作者提供的 課程

計算捐款平均值

已經學會算捐款總額啦,再想算捐款平均值超級容易。直接用求平均值的 mean() 函式來替換求和用的 sum() 函式就得了。

In [22]:
Out[22]:

Python 資料科學入門

預測捐款數目

下面來寫個簡單的根據一個人所在的州(contbr_st)、職業(contbr_occupation)及支援的候選人(cand_nm)來預測捐款數額的簡單演算法吧。首先用這幾列及要預測的 contb_receipt_amt 列來另外建立一個 Dataframe。

In [41]:

下面來看看變數 pdonations 裡每一列的資料型別。Pandas 讀取 csv 檔案時會自動給每列賦予資料型別。只有數值型(numeric)的列才能用來做預測。

In [42]:
Out[42]:

倒黴的是想要用的列都是 object 型的(都是字串)。這是因為它們都是分類資料(categorical data)。每列中有幾個可能的值,但這些選項是用文字來表示的而不是用數值型程式碼來表示的。可以先把每列都轉換成分型別(categorical),然後再轉換成數值型。這裡 有關於分型別資料的更多介紹。本質上就是分型別資料在後臺給一列中每個不同的值賦予了一個不同的數值型代號。可以將一列種的值都換成這些代號,這樣一列就完全被轉換成數值型的了。

In [43]:
In [44]:
Out[44]:

可以看到 contbr_st 列已經被轉換成數值型的了。下面對 contbr_occupation 及 cand_nm 兩列也進行同樣的操作。

In [ ]:

訓練集和測試集的拆分

接下來的預測步驟中可以利用到 Python 中最主要的機器學習包 scikit-learn。首先要把資料拆分成兩個部分。一部分用於訓練演算法,稱為訓練集;另一部分用於評估模型的效果,稱為測試集。這樣做是為了避免過擬合(overfitting)產生的有誤導性的結果。

train_test_split() 這個函式可以將 pdonations 拆分成一個訓練集和一個測試集。

In [48]:

上面的程式碼將訓練演算法需要用的列及結果列(contb_receipt_amt)中的值分成了訓練集和測試集。測試集中包含33%的資料。每行資料被隨機分配到訓練集中或者測試集中。

擬合模型

下面會使用隨機森林(random forest)演算法來做預測。隨機森林是一個效果比較好並且適用於很多問題的演算法,在 scikit-learn 包中是通過 RandomForestRegressor 類來實現的。使用這個類訓練模型及用模型做預測都很簡單。

首先用 trainy_train 來訓練模型:

In [52]:
Out[52]:

scikit-learn 包一個優點是裡面所有演算法都有一致的 API。訓練一個線性規劃(linear regression)模型和訓練一個隨機森林模型用的方法是一模一樣的。有了合適的模型就可以用它來做預測了。

預測及誤差計算

用 scikit-learn 包做預測也非常簡單。直接把測試集傳給訓練好的模型就行了。

In [54]:

有了預測結果之後來算算誤差值。誤差能體現模型的效果,在調整模型時也能作為一個衡量標準。下面會用一個常見的誤差標準,均方誤差(mean squared error)。

In [57]:
Out[57]:

如果想了解更多關於 scikit-learn 的知識可以閱讀作者撰寫的 教程

接下來做點什麼

對誤差求平方根得到的值和捐款額之間的關係更直觀。如果不求平方根而只用平均方差 (average squared error),那它就和上面用的資料沒什麼直接關係。無論怎麼算目前的誤差值都很大,有很多減小誤差的方法,比如:

  • 利用上其他列中的資料
  • 看看是否對每個候選人訓練一個模型效果會更好
  • 嘗試用其他演算法

還有一些有意思的對資料的探索可以做,比如:

  • 找出每個州哪個候選人得到的捐款最多
  • 畫出對每個候選人來說,來自哪種職業的人捐的錢最多的圖
  • 根據候選人是民主黨還是共和黨劃分,看看是否會有有意思的模式出現
  • 通過名字給資料新增性別,看看如果根據性別劃分資料是否會顯現出有意思的模式
  • 根據美國不同地區的捐款總額畫一個熱圖(heatmap)

想要深入瞭解本文講解到的概念,請參閱作者提供的 Python 資料科學 課程。

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

Python 資料科學入門

相關文章