数据预处理_标准化和分类数据转换
一、数据说明
本次演练的数据集为某企业业务部门的客户数据,将对该数据集进行数据预处理等操作。
二、缺失值判断及处理
# 设置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(女)
通过以上数据说明,可以发现有几个字段需要做相关预处理
- 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为标准差的正态分布。
但是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 → 创建匿名函数直接使用公式,并用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() # 创建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]区间内,并且Max-Min标准化最大优点是保持原数据的结构,适合用于稀疏数据
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 → 创建匿名函数直接使用公式,并用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() # 创建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标准化后的数据也是落入一个区间,但区间为[-1,1],并且MaxAbs标准化也能保持数据原有分布结构,因而能用于稀疏数据
方法1 → 创建匿名函数直接使用公式,并用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() # 创建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、数据标准化处理-总结
-
实际运用种应选择何种方法进行标准化处理?
- 要做中心化处理,并且对数据分布有正态分布的需求时 ---->>> z-score标准化
- 要指定标准化后的数据范围时 ---->>> Max-Min和MaxAbs标准化都适用,但前者更好
- 要对稀疏数据进行处理时 ---->>> Max-Min和MaxAbs标准化都是理想的选择
- 要最大限度保留数据中的异常值时 ---->>> RobustScaler标准化
五、分类数据转换为标志变量
- 1、分类数据:没有内在数学意义的数据,仅用于区分事物类别
- 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%以上