數據預處理_標準化和分類數據轉換

一、數據說明

本次演練的數據集為某企業(yè)業(yè)務部門的客戶數據,將對該數據集進行數據預處理等操作。

二、缺失值判斷及處理

# 設置cell多行輸出
from IPython.core.interactiveshell import InteractiveShell 
InteractiveShell.ast_node_interactivity = 'all' #默認為'last'

# 導入相關庫
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
os.chdir(r'E:\python_learn\data\python_book_v2\chapter4')
file_name = 'cluster.txt'
data = pd.read_table(file_name,sep=',')
print(data.head())
   USER_ID  AVG_ORDERS  AVG_MONEY IS_ACTIVE  SEX
0        1        3.58      40.43        活躍    1
1        2        4.71      41.16       不活躍    1
2        3        3.80      39.49       不活躍    2
3        4        2.85      38.36       不活躍    1
4        5        3.71      38.34        活躍    1
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 5 columns):
USER_ID       1000 non-null int64
AVG_ORDERS    1000 non-null float64
AVG_MONEY     1000 non-null float64
IS_ACTIVE     1000 non-null object
SEX           1000 non-null int64
dtypes: float64(2), int64(2), object(1)
memory usage: 39.1+ KB

從返回信息可知,數據結構為(1000,5),1000條數據,5個字段,分別是:
- 用戶ID(USER_ID)
- 平均用戶訂單數量(AVG_ORDERS)
- 平均訂單價值(AVG_MONEY)
- 是否活躍(IS_ACTIVE)
- 性別(SEX),0(未知),1(男),2(女)

通過以上數據說明,可以發(fā)現有幾個字段需要做相關預處理
- USER_ID字段,不參與計算分析,分割出來
- AVG_ORDERS,AVG_MONEY這兩個字段,單位不一樣,也就是存在量綱差異,不能直接參與分析,需要標準化處理
- IS_ACTIVE字段,是字符串類型,為方便后面分析計算,需對其進行轉換為分類類型數據
- SEX字段,其實際應屬于分類類型數據

# 缺失值判斷(其實就data.info()返回信息看出不存在缺失值)
data.isna().sum() # 不存在缺失值,不需要處理缺失值
data.isna().sum().sum()
USER_ID       0
AVG_ORDERS    0
AVG_MONEY     0
IS_ACTIVE     0
SEX           0
dtype: int64






0

三、分割數據,提取需要處理的字段

# 分割數據
data_id = data['USER_ID']  
data_numeric = data.iloc[:,1:3]

四、數據標準化處理

1、z-score標準化

z-socre標準化,又稱為零均值標準化。

公式:(x-x.mean)/x.std

z-score標準化后的數據集是以0為均值,1為標準差的正態(tài)分布。

但是z-score標準化是一種去中心化的方法會改變原數據的分布結構,不適用于稀疏數據使用。

print(data_numeric.head())
   AVG_ORDERS  AVG_MONEY
0        3.58      40.43
1        4.71      41.16
2        3.80      39.49
3        2.85      38.36
4        3.71      38.34

方法1 → 創(chuàng)建匿名函數直接使用公式,并用apply()函數將公式映射到DataFrame的每一列

f1 = lambda x :(x-x.mean())/x.std()
data_1 = data_numeric.apply(f1)
print(data_1.head())
   AVG_ORDERS  AVG_MONEY
0    0.255318   0.754353
1    1.388814   1.473263
2    0.475998  -0.171366
3   -0.476941  -1.284200
4    0.385720  -1.303896

方法2 → 使用sklearn.preprocessing的StandarScaler方法做z-score標準化處理

from sklearn import preprocessing  

zscore = preprocessing.StandardScaler() # 創(chuàng)建StandarScaler對象
data_scaler_1 = zscore.fit_transform(data_numeric)  # 用fit_transform方法轉換

data_scaler_1 = pd.DataFrame(data_scaler_1,columns=['AVG_ORDERS','AVG_MONEY'])
print(data_scaler_1.head())
   AVG_ORDERS  AVG_MONEY
0    0.255445   0.754731
1    1.389509   1.474000
2    0.476236  -0.171452
3   -0.477180  -1.284842
4    0.385913  -1.304548

2、Max-Min歸一標準化

Max-Min歸一標準化又稱為最大-最小標準化。

公式:(x-x.min)/(x.max-x.min)

Max-Min標準化后的數據會落入[0,1]區(qū)間內,并且Max-Min標準化最大優(yōu)點是保持原數據的結構,適合用于稀疏數據

print(data_numeric.head())
   AVG_ORDERS  AVG_MONEY
0        3.58      40.43
1        4.71      41.16
2        3.80      39.49
3        2.85      38.36
4        3.71      38.34

1.方法1 → 創(chuàng)建匿名函數直接使用公式,并用apply()函數將公式映射到DataFrame的每一列

f2 = lambda x : (x-x.min())/(x.max()-x.min())
data_2 = data_numeric.apply(f2)
print(data_2.head())
   AVG_ORDERS  AVG_MONEY
0    0.642005   0.625917
1    0.911695   0.804401
2    0.694511   0.396088
3    0.467780   0.119804
4    0.673031   0.114914

方法2 → 使用sklearn.preprocessing的MinMaxScaler方法做Max-Min標準化處理

minmaxscaler = preprocessing.MinMaxScaler()  # 創(chuàng)建MinMaxScaler對象
data_scaler_2 = minmaxscaler.fit_transform(data_numeric) # 標準化處理

data_scaler_2 = pd.DataFrame(data_scaler_2,columns=['AVG_ORDERS','AVG_MONEY'])
print(data_scaler_2.head())
   AVG_ORDERS  AVG_MONEY
0    0.642005   0.625917
1    0.911695   0.804401
2    0.694511   0.396088
3    0.467780   0.119804
4    0.673031   0.114914

3、MaxAbs最大值絕對值標準化

MaxAbs標準化與Max-Min標準化類似。

公式:x/|x.max()|

MaxAbs標準化后的數據也是落入一個區(qū)間,但區(qū)間為[-1,1],并且MaxAbs標準化也能保持數據原有分布結構,因而能用于稀疏數據

方法1 → 創(chuàng)建匿名函數直接使用公式,并用apply()函數將公式映射到DataFrame的每一列

f3 = lambda x : x/abs(x.max())
data_3 = data_numeric.apply(f3)
print(data_3.head())
   AVG_ORDERS  AVG_MONEY
0    0.704724   0.963537
1    0.927165   0.980934
2    0.748031   0.941134
3    0.561024   0.914204
4    0.730315   0.913727

2.方法2 → 使用sklearn.preprocessing的MaxAbsScaler方法做MaxAbs標準化處理

maxabsscaler = preprocessing.MaxAbsScaler()  # 創(chuàng)建MaxAbsScaler對象
data_scaler_3 = maxabsscaler.fit_transform(data_numeric)  # 標準化處理

data_scaler_3 = pd.DataFrame(data_scaler_3,columns=['AVG_ORDERS','AVG_MONEY'])
print(data_scaler_3.head())
   AVG_ORDERS  AVG_MONEY
0    0.704724   0.963537
1    0.927165   0.980934
2    0.748031   0.941134
3    0.561024   0.914204
4    0.730315   0.913727

4、RobustScaler標準化

RobustScaler是針對離群點的標準化方法。

當需要最大限度保留數據中的異常值時,可以使用該方法進行標準化

# 僅使用data_numeric數據作為演示RobustScaler的使用,不代表data_numeric的數據屬于離群點
robustscaler = preprocessing.RobustScaler()
data_scaler_4 = robustscaler.fit_transform(data_numeric)
data_scaler_4
array([[-0.07212205,  0.63355705],
       [ 0.55478502,  1.02550336],
       [ 0.04993065,  0.12885906],
       ...,
       [-0.81553398, -0.35973154],
       [-0.58807212, -0.05369128],
       [-0.0554785 ,  0.1557047 ]])

5、數據標準化處理-總結

  • 實際運用種應選擇何種方法進行標準化處理?
    • 要做中心化處理,并且對數據分布有正態(tài)分布的需求時 ---->>> z-score標準化
    • 要指定標準化后的數據范圍時 ---->>> Max-Min和MaxAbs標準化都適用,但前者更好
    • 要對稀疏數據進行處理時 ---->>> Max-Min和MaxAbs標準化都是理想的選擇
    • 要最大限度保留數據中的異常值時 ---->>> RobustScaler標準化

五、分類數據轉換為標志變量

  • 1、分類數據:沒有內在數學意義的數據,僅用于區(qū)分事物類別
  • 2、分類數據轉換為標志變量的方法:用pandas的pd.get_dummies()方法轉換
    • pd.get_dummies(data,prefix=None,prefix_sep='_',dummy_na=False,columns=None,sparse=False,drop_first=False,dtype=None)
    • data,需要轉換的對象,Series或DataFrame
    • prefix_sep,轉換后列名前綴的分隔符,默認下劃線_
    • dummy_na,是否增加一列表示NaN值,默認False,忽略NaN
    • columns,可以指定需要轉換的列名,默認所有數據類型為category,object的類型列都會被轉換
    • sparse,是否為稀疏矩陣,默認False
# 提取分類數據

data_category = data.iloc[:,3:]
print(data_category.head())
  IS_ACTIVE  SEX
0        活躍    1
1       不活躍    1
2       不活躍    2
3       不活躍    1
4        活躍    1
# sex列應為category類型數據,先查看其一共有多是個唯一值
data_category['SEX'].unique()
array([1, 2, 0], dtype=int64)
# 將sex字段轉換為分類類型

data_category['SEX'] = data_category['SEX'].astype('category')
data_category.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 2 columns):
IS_ACTIVE    1000 non-null object
SEX          1000 non-null category
dtypes: category(1), object(1)
memory usage: 9.0+ KB
# 用pd.get_dummies()將兩個分類數據轉換為標志數據

data_category = pd.get_dummies(data_category)
print(data_category.head())
   IS_ACTIVE_不活躍  IS_ACTIVE_活躍  SEX_0  SEX_1  SEX_2
0              0             1      0      1      0
1              1             0      0      1      0
2              1             0      0      0      1
3              1             0      0      1      0
4              0             1      0      1      0
# 為了方便辨認,給其列標簽修改名字
data_category = data_category.rename(columns={'SEX_0':'SEX_未知','SEX_1':'SEX_男','SEX_2':'SEX_女'})
print(data_category.head())
   IS_ACTIVE_不活躍  IS_ACTIVE_活躍  SEX_未知  SEX_男  SEX_女
0              0             1       0      1      0
1              1             0       0      1      0
2              1             0       0      0      1
3              1             0       0      1      0
4              0             1       0      1      0

六、數據接拼重塑

data_clean = pd.concat([data_id,data_1,data_category],axis=1)
print(data_clean.head())

# data_1是上面已經使用z-score進行標準化后的數據
   USER_ID  AVG_ORDERS  AVG_MONEY  IS_ACTIVE_不活躍  IS_ACTIVE_活躍  SEX_未知  SEX_男  \
0        1    0.255318   0.754353              0             1       0      1   
1        2    1.388814   1.473263              1             0       0      1   
2        3    0.475998  -0.171366              1             0       0      0   
3        4   -0.476941  -1.284200              1             0       0      1   
4        5    0.385720  -1.303896              0             1       0      1   

   SEX_女  
0      0  
1      0  
2      1  
3      0  
4      0  

知識補充 --->>> 什么是稀疏數據?
稀疏數據是指絕大多數數值缺失或為0的數據。但稀疏數據絕不是無用數據,通過適當的手段能夠挖掘出大量有用的信息。在一些情況下,稀疏數據達到95%以上

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容