首頁 > 後端開發 > Python教學 > 使用Python進行資料清洗的完整指南

使用Python進行資料清洗的完整指南

WBOY
發布: 2023-04-11 20:16:21
轉載
2378 人瀏覽過

你一​​定聽過這句著名的資料科學名言:

在資料科學專案中, 80% 的時間是在做資料處理。

如果你沒有聽過,那麼請記住:資料清洗是資料科學工作流程的基礎。機器學習模型會根據你提供的資料執行,混亂的資料會導致效能下降甚至錯誤的結果,而乾淨的資料是良好模型效能的先決條件。當然乾淨的數據並不意味著一直都有好的性能,模型的正確選擇(剩餘 20%)也很重要,但是沒有乾淨的數據,即使是再強大的模型也無法達到預期的水平。

在本文中將列出資料清洗中需要解決的問題並展示可能的解決方案,透過本文可以了解如何逐步進行資料清洗。

缺失值

當資料集中包含缺失資料時,在填充之前可以先進行一些資料的分析。因為空單元格本身的位置可以告訴我們一些有用的信息。例如:

  • NA值僅在資料集的尾部或中間出現。這意味著在資料收集過程中可能存在技術問題。可能需要分析該特定樣本序列的資料收集過程,並嘗試找出問題的根源。
  • 如果列NA數量超過 70–80%,可以刪除該列。
  • 如果 NA 值在表單中作為可選問題的欄位中,則該欄位可以被額外的編碼為使用者回答(1)或未回答(0)。

missingno這個python函式庫就可以用來檢查上述情況,並且使用起來非常的簡單,例如下圖中的白線是NA:

import missingno as msno
msno.matrix(df)
登入後複製

使用Python進行資料清洗的完整指南

對於缺失值的填補計算有很多方法,例如:

  • 平均,中位數,眾數
  • kNN
  • 零或常數等

不同的方法相互之間有優勢和不足,並且沒有適用於所有情況的「最佳」技術。具體可以參考我們先前發布的文章

異常值

異常值是相對於資料集的其他點而言非常大或非常小的值。它們的存在極大地影響了數學模型的表現。讓我們來看看這個簡單的範例:

使用Python進行資料清洗的完整指南

在左圖中沒有異常值,我們的線性模型非常適合資料點。在右圖中有一個異常值,當模型試圖覆蓋資料集的所有點時,這個異常值的存在會改變模型的擬合方式,並且使我們的模型不適合至少一半的點。

對於異常值來說我們有必要介紹如何確定異常,這就要從數學角度明確什麼是極大或極小。

大於Q3 1.5 x IQR或小於Q1-1.5 x IQR都可以當例外值。 IQR(四分位數間距) 是 Q3 和 Q1 之間的差 (IQR = Q3-Q1)。

可以使用下面函數來檢查資料集中異常值的數量:

def number_of_outliers(df):

df = df.select_dtypes(exclude = 'object')

Q1 = df.quantile(0.25)
Q3 = df.quantile(0.75)
IQR = Q3 - Q1

return ((df < (Q1 - 1.5 * IQR)) | (df > (Q3 + 1.5 * IQR))).sum()
登入後複製

處理異常值的一種方法是可以讓它們等於 Q3 或 Q1。下面的lower_upper_range 函數使用 pandas 和 numpy 函式庫來尋找其外部為異常值的範圍, 然後使用clip 函式將值裁切到指定的範圍。

def lower_upper_range(datacolumn):
sorted(datacolumn)
Q1,Q3 = np.percentile(datacolumn , [25,75])
IQR = Q3 - Q1
lower_range = Q1 - (1.5 * IQR)
upper_range = Q3 + (1.5 * IQR)
return lower_range,upper_range

for col in columns: 
lowerbound,upperbound = lower_upper_range(df[col])
df[col]=np.clip(df[col],a_min=lowerbound,a_max=upperbound)
登入後複製

資料不一致

異常值問題是關於數字特徵的,現在讓我們看看字元類型(分類)特徵。資料不一致意味著列的唯一類別具有不同的表示形式。例如在性別欄中,既有m/f,又有male/female。在這種情況下,就會有4個類,但實際上有兩類。

這種問題目前沒有自動處理的辦法,所以需要手動進行分析。 pandas 的unique函數就是為了這個分析準備的,下面看一個汽車品牌的例子:

df['CarName'] = df['CarName'].str.split().str[0]
print(df['CarName'].unique())
登入後複製

使用Python進行資料清洗的完整指南

maxda-mazda, Nissan-nissan, porcshce-porsche, toyouta-toyota等都可以進行合併。

df.loc[df['CarName'] == 'maxda', 'CarName'] = 'mazda'
df.loc[df['CarName'] == 'Nissan', 'CarName'] = 'nissan'
df.loc[df['CarName'] == 'porcshce', 'CarName'] = 'porsche'
df.loc[df['CarName'] == 'toyouta', 'CarName'] = 'toyota'
df.loc[df['CarName'] == 'vokswagen', 'CarName'] = 'volkswagen'
df.loc[df['CarName'] == 'vw', 'CarName'] = 'volkswagen'
登入後複製

無效資料

無效的資料表示在邏輯上根本不正確的值。例如,

  • 某人的年齡是560;
  • 某個操作花了-8 小時;
  • 一個人的身高是1200 cm等;

對於數值列,pandas的describe 函數可用於識別此類錯誤:

df.describe()
登入後複製

使用Python進行資料清洗的完整指南

無效資料的產生原因可能有兩種:

1、資料收集錯誤:例如在輸入時沒有進行範圍的判斷,在輸入身高時錯誤的輸入了1799cm 而不是179cm,但是程式沒有對資料的範圍進行判斷。

2、資料操作錯誤

数据集的某些列可能通过了一些函数的处理。 例如,一个函数根据生日计算年龄,但是这个函数出现了BUG导致输出不正确。

以上两种随机错误都可以被视为空值并与其他 NA 一起估算。

重复数据

当数据集中有相同的行时就会产生重复数据问题。 这可能是由于数据组合错误(来自多个来源的同一行),或者重复的操作(用户可能会提交他或她的答案两次)等引起的。 处理该问题的理想方法是删除复制行。

可以使用 pandas duplicated 函数查看重复的数据:

df.loc[df.duplicated()]
登入後複製

在识别出重复的数据后可以使用pandas 的 drop_duplicate 函数将其删除:

df.drop_duplicates()
登入後複製

数据泄漏问题

在构建模型之前,数据集被分成训练集和测试集。 测试集是看不见的数据用于评估模型性能。 如果在数据清洗或数据预处理步骤中模型以某种方式“看到”了测试集,这个就被称做数据泄漏(data leakage)。 所以应该在清洗和预处理步骤之前拆分数据:

使用Python進行資料清洗的完整指南

以选择缺失值插补为例。数值列中有 NA,采用均值法估算。在 split 前完成时,使用整个数据集的均值,但如果在 split 后完成,则使用分别训练和测试的均值。

第一种情况的问题是,测试集中的推算值将与训练集相关,因为平均值是整个数据集的。所以当模型用训练集构建时,它也会“看到”测试集。但是我们拆分的目标是保持测试集完全独立,并像使用新数据一样使用它来进行性能评估。所以在操作之前必须拆分数据集。

虽然训练集和测试集分别处理效率不高(因为相同的操作需要进行2次),但它可能是正确的。因为数据泄露问题非常重要,为了解决代码重复编写的问题,可以使用sklearn 库的pipeline。简单地说,pipeline就是将数据作为输入发送到的所有操作步骤的组合,这样我们只要设定好操作,无论是训练集还是测试集,都可以使用相同的步骤进行处理,减少的代码开发的同时还可以减少出错的概率。


以上是使用Python進行資料清洗的完整指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:51cto.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板