Python探索性數據分析,這樣才容易掌握
譯文出品:Python數據之道
Python探索性數據分析教程
介紹
每個數據科學家都必須掌握的最重要的技能之一是正確研究數據的能力。徹底的探索性數據分析 (EDA, Exploratory Data Analysis) 是必要的,這是為了確保收集數據和執行分析的完整性。
本教程使用的示例是對歷史上 SAT 和 ACT 數據的探索性分析,以比較不同州 SAT 和 ACT 考試的參與度和表現。在本教程的最後,我們將獲得關於美國標準化測試的潛在問題的數據驅動洞察力。本教程的重點是演示探索性數據分析過程,併為希望練習使用數據的 Python 程序員提供一個示例。
為了這個分析,我在 Jupyter 中檢查和操作了包含 2017 年和 2018 年 SAT 和 ACT 數據的 CSV 數據文件。通過構造良好的可視化和描述性統計來研究數據,是瞭解你正在處理的數據並根據你的觀察制定假設的絕佳方法。
探索性數據分析(EDA)目標
1)快速描述一份數據集:行/列數、數據丟失情況、數據的類型、數據預覽。
2)清除髒數據:處理丟失的數據、無效的數據類型和不正確的值。
3)可視化數據分佈:條形圖,直方圖,箱型圖等。
4)計算並可視化展示變量之間的相關性(關係):熱圖 (heatmap)。
數據驅動方法的好處
標準化測試程序多年來一直是一個有爭議的話題, 已經為眾人所知。通過初步研究,我很快發現了 SAT 和 ACT 考試中一些明顯的問題。
例如,有些州只要求學生參加 SAT,有些州只要求學生參加 ACT,有些州要求學生兩種考試都要參加,還有些州要求選擇性標準化考試,或者每個學生都必須參加他們選擇的一種標準化考試。
每個州制定的標準化考試預期之間的這種差異,應該被視為州與州之間考試記錄存在偏差的一個重要來源,比如參與率和平均成績。研究可能是重要的,但採取數據驅動的方法來支持基於定性研究的主張(假設)是必要的。採用數據驅動的方法可以驗證以前提出的斷言/假設,並基於對數據的徹底檢查和操作開發新的見解。
入門
請從 GitHub 鏈接:
https://github.com/cbratkovics/sat actanalysis
下載代碼或數據,以方便跟隨教程:
使用 Python 研究數據的第一步是確保導入了正確的庫。
在本文中,我們需要的庫是 NumPy,Pandass,Matplotlib 和 Seaborn。導入庫時,可以為其分配別名,以減少使用每個庫屬性所需的鍵入量。下面的代碼顯示了必要的 import 語句:
使用 Pandas 庫,你可以將數據文件加載到容器對象(稱為數據幀, dataframe)中。顧名思義,這種類型的容器是一個框架,它使用 Pandas 方法pd.read_csv()
讀入的數據,該方法是特定於 CSV 文件的。將每個 CSV 文件轉換為 Pandas 數據幀對象如下圖所示:
檢查數據 & 清理髒數據
在進行探索性分析時,瞭解您所研究的數據是很重要的。幸運的是,數據幀對象有許多有用的屬性,這使得這很容易。當基於多個數據集之間比較數據時,標準做法是使用( .shape)屬性檢查每個數據幀中的行數和列數。如圖所示:
注意:左邊是行數,右邊是列數;(行、列)。
我們這份數據的第一個問題是 ACT 2017 和 ACT 2018 數據集的維度不一致。讓我們使用(.head()
)來更好地查看數據,通過 Pandas 庫展示了每一列的前五行,前五個標籤值。我將以 2018 年 ACT 數據為例:
在預覽了其他數據的前五行之後,我們推斷可能存在一個問題,即各個州的數據集是如何存入的。由於美國有 51 個州,ACT 2017 和 ACT 2018 的“州”欄中很可能有錯誤或重複的值。然而,在處理數據時,我們不能確定這種推斷。我們需要檢查有關的數據來確定確切的問題。
首先,讓我們使用.value_counts()
方法檢查 ACT 2018 數據中 “State” 列的值,該方法按降序顯示數據幀中每個特定值出現的次數:
請注意:“Maine” 在 2018 年 ACT 數據中出現了兩次。下一步是確定這些值是重複的還是數據輸入不正確引起的。我們將使用一種脱敏技術來實現這一點,它允許我們檢查滿足指定條件的數據幀中的行。例如,讓我們脱敏來查看 2018 ACT 數據中所有 “State” 值為 “Maine” 的行:
現在,已將亂碼確認為重複條目。因此,我們可以使用.drop()
方法,簡單地刪除值,使用.reset_index()*
重置數據幀索引,來解決這個問題:
現在我們已經解決了 ACT 數據幀之間行數不一致的問題,然而 SAT 和 ACT 數據幀之間仍然存在行數不一致的問題( ACT 52 行,SAT 51 行)。為了比較州與州之間 SAT 和 ACT 數據,我們需要確保每個州在每個數據幀中都被平等地表示。這是一次創新的機會來考慮如何在數據幀之間檢索 “State” 列值、比較這些值並顯示結果。我的方法如下圖展示:
函數compare_values()
從兩個不同的數據幀中獲取一列,臨時存儲這些值,並顯示僅出現在其中一個數據集中的任何值。讓我們來看看在比較 2017 年和 2018 年 SAT/ACT “State” 列值時,它是如何工作的:
好吧!現在我們知道,需要刪除 ACT 數據集中 “State” 列中的 “National” 值。這可以使用與我們在 2018 年 ACT 數據集 定位和刪除重複的 ‘Maine’ 值相同的代碼來完成:
然而,在 2018 年 SAT 和 ACT 數據中仍存在關於 ‘Washington, D.C.’ 和 ‘District of Columbia’ 另一種爭議。我們需要從四個數據集中確定能代表華盛頓特區/哥倫比亞特區的一貫值。你所做的選擇在這兩個選項中都不重要,但是最好選擇在數據集中出現率最高的名稱。由於 2017 年 SAT 和 2017 年 ACT “州”數據的唯一區別在於“國家”值,我們可以假設'華盛頓特區'和'哥倫比亞特區'在兩個數據中的'州'列中是一致的。讓我們使用脱敏技術來檢查 ‘Washington, D.C.’ 和 ‘District of Columbia’ 哪些值出現在 ACT 2017 的‘State’ 一列中:
現在我們有理由詳細在 ACT 2018 數據集中使用 ‘District of Columbia’ 取代 ‘Washington, D.C.’ 是正確的,通過使用 Pandas 庫中的.replace()
函數,我們就可以做到這一點。然後,我們可以使用 compare_values 函數確認我們的更改是否成功:
成功了!各個州的值現在在每個數據集是一致的。現在,我們可以解決 ACT 數據集中各個列不一致的問題。讓我們使用.columns
屬性比較每個數據幀之間的列名:
請注意,在顯示 print()的輸出後,添加 “\ n” 表達式會打印一個新行。
由於這次分析的目的是比較 SAT 和 ACT 數據,我們越能相似地表示每個數據集的值,我們的分析就越有幫助。
因此,我將在每個數據幀中保留的唯一列是 “State”、“Participation”、“Total” (僅SAT) 和 “Composite” (僅ACT)。
請注意,如果你的分析目標是不同的,比如比較 2017 年和 2018 年 SAT 的績效,那麼根據每個表現類別 (e.g. Math) 保存特定的數據將是至關重要的。為了與當前的任務保持一致,我們可以使用.drop()
方法刪除多餘的列,如下所示:
現在所有的數據都具有相同的維度! 不幸的是,仍有許多工作要做。讓我們看看是否有數據丟失,並查看所有數據的數據類型:
使用.isnull().sum()
檢查丟失的數據
用.dtypes
檢查數據類型
好消息是數據中不存在不存在的值。壞消息是存在數據類型的錯誤,特別是每個數據幀中的“參與”列都是對象類型,這意味着它被認為是一個字符串。這是有問題的,因為在研究數據時要觀察許多有用的可視化,需要數字類型變量才能發揮作用,比如熱力圖、箱形圖和直方圖。
同樣的問題也出現在兩個 ACT 數據集的 ‘Composite’ 列中。讓我們來看看 2018 年 SAT 和 ACT 數據的前五行:
2018 年 SAT 數據的前 5 行。
2018 ACT 前 5 行數據。
你可以看到 “Composite” 和 “Participation” 應該是 float 類型。好的做法是保持要比較的數值數據類型的一致性,因此將 “Total” 轉換為 float 類型也是可以接受的,而不會損害數據的完整性(integer = 1166, float = 1166.0)。
這種類型轉換的第一步是從每個 ’Participation’ 列中刪除 “%” 字符,以便將它們轉換為浮點數。下一步將把除每個數據幀中的 “State” 列之外的所有數據轉換為浮點數。這可能是乏味的,這給了我們另一個創建函數來節省時間的好機會!我的解決方案如下函數所示:
是時候讓這些功能發揮作用了。首先讓我們使用fix_participation()
函數:
現在我們可以使用convert_to_float()
函數轉換所有列的數據類型:
但是等等!運行convert_to_float()
函數應該會拋出一個錯誤。錯誤消息是否有用取決於你使用的 IDE。在 Jupyter Notebook 中,錯誤將清楚地指引你到 ACT 2017 數據集中的 “Composite” 列。要更仔細地查看這些值,可以使用.value_counts()
函數:
看起來我們的罪魁禍首是數據中的一個 “x” 字符,很可能是在將數據輸入到原始文件時輸入錯誤造成的。要刪除它,可以在.apply()
方法中使用.strip()
方法,如下所示:
太棒了!現在再試着運行這段代碼,所有的數據都是正確的類型:
在開始可視化數據之前的最後一步是將數據合併到單個數據中。為了實現這一點,我們需要重命名每個數據中的列,以描述它們各自代表的內容。
例如,2018 年 SAT ‘Participation’ 一欄的一個好名字應該是 “sat participation17”。當數據合併時,這個名稱更具描述性。
另一個注意事項是下劃線表示法,以消除訪問值時繁瑣的間距錯誤,以及用於加速鍵入的小寫約定。數據的命名約定由開發人員決定,但是許多人認為這是一種很好的實踐。你可以這樣重命名列:
為了合併數據而沒有錯誤,我們需要對齊 “state” 列的索引,以便在數據幀之間保持一致。我們通過對每個數據集中的 “state” 列進行排序,然後從 0 開始重置索引值:
最後,我們可以合併數據。我沒有一次合併所有四個數據幀,而是按年一次合併兩個數據幀,並確認每次合併都沒有出現錯誤。下面是每次合併的代碼:
2017 SAT 與 ACT 合併的數據集
2018 年 SAT 和 ACT 合併數據框架。
最終合併數據集。
一旦你清理了你的數據,保存它是一個好主意,這樣你就不用再去整理它了。使用 Pandas 中的pd.to_csv()
方法:
設置 index = False 保存沒有索引值的數據。
是時候可視化呈現數據了!現在,我們可以使用 Matplotlib 和 Seaborn 更仔細地查看我們已經清洗和組合的數據。在研究直方圖和箱形圖時,我將着重於可視化參與率的分佈。在研究熱圖時,將考慮所有數據之間的關係。
可視化數據分佈- Seaborn 直方圖
直方圖表示數值數據值出現在數據集中指定範圍內的頻率(例如,數據中有多少值出現在 40%-50% 的範圍內)。從直方圖中我們可以看出,2017 年和 2018 年,ACT 的參與率在 90%-100% 之間的州更多。相反,2017 年和 2018 年 SAT 考試的參與率為 0 -10% 的州更多。我們可以推斷,90%-100% ACT 參與率的州出現頻率較高,可能是由於需要採取 ACT 的某些規定引起的。
可視化數據分佈- Matplotlib 框圖
箱形圖表示數據的擴展,包括最小、最大和四分位數範圍(IQR)。四分位數範圍由第一分位數、中位數和第三分位數組成。從上面的方框圖可以看出,2017 年到 2018 年 SAT 的整體參與率有所上升。
我們可以注意到的另一件事是 2017 年到 2018 年 ACT 參與率的一致性。這就提出了一個問題,為什麼 SAT 的參與率總體上有所上升,儘管 ACT 的參與率並沒有顯著變化。
計算並可視化相關性-Seaborn Heat Map
更強的關係由熱圖中的值表示,更接近於負值或正值。較弱的關係由接近於零的值表示。正相關變量,即零和正相關的值,表示一個變量隨着另一個變量的增加而增加。負相關變量,負1和0之間的相關性值表示一個變量隨着另一個變量的增加而減少。
需要進一步研究的關係較強的變量包括 2017 年 SAT 參與情況和 2018 年 SAT 參與情況、2017 年 ACT 綜合得分和 2017 年 ACT 參與情況、2018 年 ACT 參與情況和 2018 年 SAT 參與情況。還有很多關係需要進一步研究,但這些都是很好的起點,可以指導研究為什麼這些關係會存在。
總結
徹底的探索性數據分析可確保你的數據清晰,可用,一致且直觀可視化。請記住,沒有所謂的乾淨數據,因此在開始使用數據之前探索數據是在數據分析過程中添加完整性和價值的好方法。通過對數據的深入研究來指導外部研究,你將能夠有效地獲得可證明的見解。