数据预处理

数据预处理

定义:从数据中检测,纠正或者损坏不准确,不适用模型的记录的过程
目的:让数据适应模型,匹配模型的需求
面对的问题:

数据类型不同:有的是文字,有的是数字,有的连续,有的间断
数据质量不行:有噪声,有异常,有缺失,有重复,量纲不一,数据量过大或者过小

1、数据的无量纲化
功能:

  • 将不同规格的数据转换为同一规格,将不同分布的数据转换为特定分布的需求
  • 以梯度和矩阵为核心的算法(LR,SVM、神经网络):可加快速度
  • 距离模型(k-近邻,k-means):提升模型精度,避免某一个取值范围特别大的特征对距 离计算造成影响

无量纲化处理包括线性和非线性的,线性的有中心化和缩放处理
中心化:多有记录减去一个固定值,即样本数据平移到某一个位置
缩放:将所有记录除以(或者取对数)一个固定值,将数据固定在某个范围中

处理手段:
归一化–Normalization
先中心化(数据x-减去最小值)后缩放(除以最大值-最小值),处理后的数据服从正态分布,将不同规格的数据转换为同一规格
在这里插入图片描述
通过sklearn中的preprocessing.MinMaxScaler实现

from sklearn.preprocessing  import MinMaxScaler
import pandas as pd
from pandas import DataFrame
data=[[-1,-2],[-0.5,6],[0,10],[1,18]]
scaler=MinMaxScaler()
result=scaler.fit_transform(data)
result
array([[0.  , 0.  ],
       [0.25, 0.4 ],
       [0.5 , 0.6 ],
       [1.  , 1.  ]])
  注意:1、scaler.inverse_transform(result) --->可将归一化结果逆转
       2、当数据量过大时使用scaler.partial_fit(data)
scaler=MinMaxScaler(feature_range=[5,10])--->使用feature_range将数据结果归到[5:10]的范围
result=scaler.fit_transform(data1)
result
array([[ 5.  ,  5.  ],
       [ 6.25,  7.  ],
       [ 7.5 ,  8.  ],
       [10.  , 10.  ]])

标准化–Standardization
数据x按均值(u)中心化,再按标准差塞个马缩放,将不同分布的数据转换为特定分布的需求,数据服从标准正太分布(均值为零,方差为一)
在这里插入图片描述
代码处理:

from sklearn.preprocessing import StandardScaler
scaler=StandardScaler()
scaler.fit_transform(data2)
array([[-1.18321596, -1.38675049],
       [-0.50709255, -0.2773501 ],
       [ 0.16903085,  0.2773501 ],
       [ 1.52127766,  1.38675049]])

注意:
在标准化和归一化过程中:

  • 空值NAN当作是缺失值,fit时候忽略,transform保持NAN状态
  • fit接口只容许导入至少二维的数组,一维会报错,通常我们输入的x是特征矩阵,现实案例中的特征矩阵不太可能是一维,所以不太可能存在这个问题

在这里插入图片描述
2、缺失值 sklearn.preprocessing中的Imputer模块
在这里插入图片描述
具体处理详情
代码如下

import pandas as pd
from pandas import Series,DataFrame
data=pd.read_csv(r'C:\Users\kyrie\Desktop\data\Narrativedata.csv',index_col=0)
data.head()
data.info()
age=data['Age'].values.reshape(-1,1)##取出值并转换为二维数组
age
from sklearn.preprocessing import Imputer
imp_mean=Imputer()
imp_median=Imputer(strategy="median")
imp_0=Imputer(strategy="most_frequent")
imp_mean=imp_mean.fit_transform(age)
imp_median=imp_median.fit_transform(age)
imp_0=imp_0.fit_transform(age)
data['Age']=imp_mean

使用pandas和numpy进行填充

data1['Age']=data1['Age'].fillna(data1['Age'].median())#.fillna在DataFrame里直接进行填补
data1.dropna(axis=0,inplace=True)#.drop(axis=0)删除有缺失值的行.drop(axis=1)删除有缺失值的列
#inplace为True,表示在原数据集修改,默认为Flase,表示复制一个对象,不在原数据集修改

3、处理分类特征:编码与哑变量
原因:
在机器学习中大多数算法,比如LR、SVM、Knn只能处理数值型数据,不能处理文字,在sklearn当中,有专用处理文字的算法,但是其他算法在fit的时候要求输入数组或矩阵,不能够导入文字型数据,而且现实中的许多标签和数据在收集完毕的时候,都不是以数字来表现的,为了让数据适应算法和库,我们必须将数据进行编码,将文字型数据转换为数值型
preprocessing.LabelEncoding:标签专用,将分类转化为分类数值
在这里插入图片描述

from sklearn.preprocessing import LabelEncoder
from pandas import DataFrame,Series
import pandas as pd

data=DataFrame(data=[[-1,2],[-0.5,6],[0,10],[1,18]])
print(data)
y=data.iloc[:,-1]#要输入的是标签,所以容许一维数组
print(y)


le=LabelEncoder()
le.fit(y)#导入数据,调取结果
label=le.transform(y)
# print(le.fit_transform(y))
print("调取结果是:",label)
print(le.classes_)#查看标签中有多少类型


data.iloc[:,-1]=label
print(data)

/Users/dushuo/PycharmProjects/untitled5/venv/bin/python /Users/dushuo/PycharmProjects/sklearn/sklearn_test2.py
     0   1
0 -1.0   2
1 -0.5   6
2  0.0  10
3  1.0  18
0     2
1     6
2    10
3    18
Name: 1, dtype: int64
调取结果是: [0 1 2 3]
[ 2  6 10 18]
     0  1
0 -1.0  0
1 -0.5  1
2  0.0  2
3  1.0  3

Process finished with exit code 0
如果不需要数学展示
from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1]=LabelEncoder().fit_tranform(data.iloc[:,-1])

preprocessing.OrdinalEncoder:特征专用,能够将分类特征转换为分类数值–数据必须是多维

from sklearn.preprocessing import OrdinalEncoder #接口categories_对应LabelEncoder的接口classes_,一模一样的功能
data_ = data.copy()
data_.head()
OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_
data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
data_.head()```
**独热编码创建哑变量preprocessing.OneHotEncoder**

特征做哑变量
df=pd.read_csv('20181121222789n2hi02wz/Narrativedata.csv')
print(df.head())
from sklearn.preprocessing import OneHotEncoder

print(df.info())
print(df.columns)
#填充缺失值
from sklearn.impute import SimpleImputer
Age=df.loc[:,'Age'].values.reshape(-1,1)
df.loc[:,'Age']=SimpleImputer(strategy="median").fit_transform(Age)
Embarked=df.loc[:,'Embarked'].values.reshape(-1,1)
df.loc[:,'Embarked']=SimpleImputer(strategy="most_frequent").fit_transform(Embarked)
#独热编码
X=df.iloc[:,1:-1]
# OneHotEncoder(categories='auto').fit_transform(X).toarray()
enc=OneHotEncoder(categories="auto").fit(X)
result=enc.transform(X).toarray()
# print(result)
#编码还原pd.DataFrame(enc.inverse_transform(result))
result1=pd.DataFrame(enc.inverse_transform(result))
enc.get_feature_names()
print(pd.DataFrame(result).head())
print(df.head())
newdata=pd.concat([df,pd.DataFrame(result)],axis=1)
print(newdata.head())



/Users/dushuo/PycharmProjects/untitled5/venv/bin/python /Users/dushuo/PycharmProjects/sklearn/sklearn_test2.py
   Unnamed: 0   Age     Sex Embarked Survived
0           0  22.0    male        S       No
1           1  38.0  female        C      Yes
2           2  26.0  female        S      Yes
3           3  35.0  female        S      Yes
4           4  35.0    male        S       No
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 5 columns):
Unnamed: 0    891 non-null int64
Age           714 non-null float64
Sex           891 non-null object
Embarked      889 non-null object
Survived      891 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 34.9+ KB
None
Index(['Unnamed: 0', 'Age', 'Sex', 'Embarked', 'Survived'], dtype='object')
    0    1    2    3    4    5    6   ...   86   87   88   89   90   91   92
0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ...  0.0  0.0  0.0  1.0  0.0  0.0  1.0
1  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ...  0.0  0.0  1.0  0.0  1.0  0.0  0.0
2  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ...  0.0  0.0  1.0  0.0  0.0  0.0  1.0
3  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ...  0.0  0.0  1.0  0.0  0.0  0.0  1.0
4  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ...  0.0  0.0  0.0  1.0  0.0  0.0  1.0

[5 rows x 93 columns]
   Unnamed: 0   Age     Sex Embarked Survived
0           0  22.0    male        S       No
1           1  38.0  female        C      Yes
2           2  26.0  female        S      Yes
3           3  35.0  female        S      Yes
4           4  35.0    male        S       No
   Unnamed: 0   Age     Sex Embarked Survived  ...   88   89   90   91   92
0           0  22.0    male        S       No  ...  0.0  1.0  0.0  0.0  1.0
1           1  38.0  female        C      Yes  ...  1.0  0.0  1.0  0.0  0.0
2           2  26.0  female        S      Yes  ...  1.0  0.0  0.0  0.0  1.0
3           3  35.0  female        S      Yes  ...  1.0  0.0  0.0  0.0  1.0
4           4  35.0    male        S       No  ...  0.0  1.0  0.0  0.0  1.0

[5 rows x 98 columns]

Process finished with exit code 0

4、 处理连续特征:二值化与分段sklearn.preprocessing.Binarizer
原因:根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈 值的值映射为0。默认阈值为0时,特征中所有的正值都映射到1。二值化是对文本计数数据的常见操作,分析人员 可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯 设置中的伯努利分布建模)。

data_2=df.copy()
from sklearn.preprocessing import Binarizer
Age=data_2.iloc[:,0].values.reshape(-1,1)
Bin=Binarizer(threshold=40).fit_transform(Age)
print(Bin.shape)

preprocessing.KBinsDiscretizer分段
这是将连续型变量划分为分类变量的类,能够将连续型变量排序后按顺序分箱后编码。总共包含三个重要参数:
n_bins:每个特征中分箱的个数,默认5,一次会被运用到所有导入的特征

encode
编码的方式,默认“onehot” “onehot”: 做哑变量,之后返回一个稀疏矩阵,每一列是一个特征中的一个类别,含有该
类别的样本表示为1,不含的表示为0 “ordinal”:每个特征的每个箱都被编码为一个整数,返回每一列是一个特征,每个特征下含
有不同整数编码的箱的矩阵
“onehot-dense”: 做哑变量,之后返回一个密集数组。

strategy
用来定义箱宽的方式,默认
“quantile” “uniform”: 表示等宽分箱,即每个特征中的每个箱的最大值之间的差为
(特征.max() - 特征.min()) / (n_bins)
“quantile”: 表示等位分箱,即每个特征中的每个箱内的样本数量都相同
“kmeans”: 表示按聚类分箱,每个箱中的值到最近的一维k均值聚类的簇心得距离都相同

from sklearn.preprocessing import KBinsDiscretizer
X = df.iloc[:,0].values.reshape(-1,1)
est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
est.fit_transform(X)
#查看转换后分的箱:变成了一列中的三箱 set(est.fit_transform(X).ravel())    ravel降维
est = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='uniform') #查看转换后分的箱:变成了哑变量
result=est.fit_transform(X).toarray()
print(result)```


   Unnamed: 0   Age     Sex Embarked Survived
0           0  22.0    male        S       No
1           1  38.0  female        C      Yes
2           2  26.0  female        S      Yes
3           3  35.0  female        S      Yes
4           4  35.0    male        S       No
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 5 columns):
Unnamed: 0    891 non-null int64
Age           714 non-null float64
Sex           891 non-null object
Embarked      889 non-null object
Survived      891 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 34.9+ KB
None
Index(['Unnamed: 0', 'Age', 'Sex', 'Embarked', 'Survived'], dtype='object')
(891, 1)
[[1. 0. 0.]
 [1. 0. 0.]
 [1. 0. 0.]
 ...
 [0. 0. 1.]
 [0. 0. 1.]
 [0. 0. 1.]]

Process finished with exit code 0

5、类不平衡问题与SMOTE过采样算法
各个类别的样本量分布不均的问题——某些类别的样本数量极多,而有些类别的样本数量极少,也就是所谓的类不平衡(class-imbalance)问题。
解决方案

  • 过采样(SMOTE:算法的思想是合成新的少数类样本,合成的策略是对每个少数类样本a,从它的最近邻中随机选一个样本b,然后在a、b之间的连线上随机选一点作为新合成的少数类样本)
    对训练集里面样本数量较少的类别(少数类)进行过采样,合成新的样本来缓解类不平衡。

    from imblearn.over_sampling import SMOTE
    
  • 欠采样
    对训练集里面样本数量较多的类别(多数类)进行欠采样,抛弃一些样本来缓解类不平衡。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值