iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 6
0
AI & Data

Python機器學習介紹與實戰系列 第 6

DAY[6]-數據前處理(1) 資料類型與資料操作

在機器學習的過程中,對於資料的解釋以及處理是最前期也最重要的環節,在這個章節中,將使用資料本身較乾淨並且相當容易獲取的玩具資料集進行基礎講解,在基礎講解結束後將帶領各位讀者進行實際資料的實戰演練。

讀取資料

from sklearn.datasets import load_diabetes # 匯入Sklearn內建資料集
data = load_diabetes() # 將數據匯入

觀察資料

import pandas as pd # 匯入pandas套件並更名成pd

df = pd.DataFrame(data.data,columns = data.feature_names) 
# 透過data.data來呼叫數據 回傳numpy.ndarray型態
# 透過data.feature_names來呼叫特徵名稱
# 將原先的data由numpy.ndarray變更為pandas.DataFrame型態
# 將特徵名稱與資料放入對應的行(columns)

data.head() # 顯示頭五筆資料
# 可使用data.head(10)顯示前10筆或是使用data.tail()顯示最後五筆資料

預處理

重要觀念-量尺

常見的量尺分為四種,對於不同的量尺所表達的數據有不同的處理原則。

  1. 順序量尺
    用數值1、2、3來表示順序差異,例如一年級、二年級或是滿意度1~5顆星等等,並沒有實際的數值關係,有次序性(大小差別),不能做加減乘除的運算,沒有自然零點。
  2. 等距量尺
    1與2的距離等同2與3的距離,常見如溫度等等的指標,可以做加減運算但不能乘除(2度不是1度的兩倍),沒有自然零點。
  3. 類別量尺
    數值僅代表不同的類別,也可能不用數值表示,常見如性別、城市、職業等等,不能做運算也沒有自然零點。
  4. 等比量尺
    數值有完整的意義,不需要相對比較就可以代表具體的量,常見如重量、長度等等,可以做所有的運算,有自然零點(0公斤是真正意義的0)。

從資料的名稱中我們可以發現,sex類別應該是1與0的數值,但他在這筆數裡面是0.050680與-0.044642兩個數字,顯示這整筆資料應該做過標準化處理,而sex類別表示的是男女,以1、0來表示會有遞增的關係,男女類別應該屬於「類別量尺」,因此在處理的過程中我們要先將數值還原成1、0並且將男、女兩個屬性獨立成一個特徵,這個動作叫做one-hot enconding。

基礎選取與修改資料

# 對pandas.DataFrame或是pandas.Series可以執行兩種函式進行元素的選取
# .loc使用「key值」,也可以說使用「名稱」
# 例如.loc[列名稱,行名稱]

df.loc[0,"sex"] # ->回傳0.050680
df.loc[0,"age"] # ->回傳-0.001882

# .iloc使用「索引」
# 例如.iloc[列索引,行索引]

df.loc[0,1] # ->回傳0.050680
df.loc[0,0] # ->回傳-0.001882

預處理
有些讀者在選取與修改資料的時候,習慣與陣列相同使用切片(slice)操作,有時候會造成資料無法正確的修改,建議養成使用loc與iloc的操作進行改值會較為精準。

# 有機會造成值沒有正確修改
df["sex"][0] = 1

# 建議使用loc與iloc
df.loc[0,"sex"] = 1
df.loc[0,1] = 1

# 另外補充
df.loc[:,["sex"]]將回傳DataFrame型態
df.loc[:,"sex"]將回傳Series型態

# 冒號 : ->與slice相同 表示列/行全選

重要撰寫技巧-apply與lambda

在進行資料的預處理時,由於每列(row)的資料都是一筆獨特的人、事、交易等等,因此時常需要針對單個列進行處理,相信部分讀者曾經遇過上百萬筆數據需要一筆一筆取出並調整,但這時候使用迴圈會因為python原生的限制導致速度極度的緩慢,這時候應該使用apply進行處理。

df.loc[:,"age"].apply(function)
# 這個操作將把df的資料依照列一筆一筆的傳遞給function
# 依序為 0.038076,-0.001882,0.085299......

這時候如果你想針對大於零或小於零的值做區隔,將兩個不同的條件分別套用到不同的值,可以使用匿名函式lambda。

condition = lambda x: 1 if x > 0 else 0
df.loc[:,"sex"].apply(condition)
# 或 df.loc[:,"sex"].apply(lambda x: 1 if x > 0 else 0)
# 兩個操作是等價的 個人偏好後者

這樣就可以高速的達到更新資料並且不需要使用到迴圈,但你可能想問,如果條件沒有這麼複雜,不需要使用到函數的話該怎麼辦呢?
這時候可以使用mask(掩碼數組)的操作來達到快速的選取資料與修改

df.loc[:,"sex"] > 0 # 將以Series回傳整個行的布林值
# 此處不修改值 使用df["sex"] > 0 亦可

預處理2

# 將這個布林陣列放入前方的列索引
df.loc[df["sex"] > 0,"sex"] # 回傳符合條件(值>0)的資料
df.loc[df["sex"] > 0,"sex"] = 1 # 直接針對這些資料進行修改

預處理3

學會上述這些方法之後,在資料的操作上比較不會手忙腳亂,也能夠較高效率的處理資料,更進一步的補值邏輯與其他預處理將在下篇文章介紹~


上一篇
DAY[5]-雲端基礎教學(2) colab基本操作與建議
下一篇
DAY[7]-數據前處理(2) 補值與EDA(1)
系列文
Python機器學習介紹與實戰30

尚未有邦友留言

立即登入留言