1. 数据清洗
数据清洗包括数据样本抽样和异常值(空值)处理
- 直接丢弃(包括重复数据)
- 把是否有异常当做一个新的属性,替代原值
- 集中指代
- 边界值指代
- 插值
import pandas as pd
import numpy as np
df = pd.DataFrame({
"A":['a0','a1','a1','a2','a3','a4'],
"B":['b0','b1','b2','b2','b3',None],
"C":[1,2,None,3,4,5],
"D":[0.1,10.2,11.4,8.9,9.1,12],
"E":[10,19,32,25,8,None],
"F":["f0","f1","g2","f3","f4","f5"]
})
# 识别异常值和空值
df.isnull()
df.dropna()
df.dropna(how = "any",subset = ["B"]) # subset为根据某个字段进行去除空值
# 直接丢弃
df.duplicated(["A"]) # 当.duplicated给定多个字段时,只有当每个字段都相同时才会返回True
df.drop_duplicates(["B"])
df.drop_duplicates(["A"],keep = False) # keep有三个可传参数 first last False 也有inplace方法
# 集中指代
df.fillna(method = "ffill",axis = 0) # 用上方数据填充
df["E"].fillna(df["E"].mean())
# 插值指代
df["C"].interpolate() # 调用interpolate时必须为Series
df["C"].interpolate(method = "spline",order = 3) # interpolate方法还可以指定插值方法,如三次样条插值
# 取上下四分位数的k倍为边界值 k一般取1.5-3
k = 1.5
upper_q = df["D"].quantile(q = 0.75)
lower_q = df["D"].quantile(q = 0.25)
q_int = upper_q - lower_q
df[df["D"] > lower_q - k*q_int][df["D"] < upper_q+k*q_int]
# 去除"F"字段不是以f开头的数据
df.drop([2])
df[[True if value.startswith("f") else False for value in list(df["F"].values)]]
2. 特征预处理
- 反映目的的属性称之为标注(也叫作标记、标签、label)
- 特征预处理分为四个部分:
- 特征选择
- 特征变换
- 特征降维
- 特征衍生
2.1 特征选择
- 特征选择:剔除与标注不相关或者冗余的特征
- 其中一种思路为数据归约:包括三种思想
- 过滤思想:特征与标注的相关性
- 包裹思想:遍历特征子集,即构造简单模型,根据系数去掉弱特征
- 嵌入思想:建立简单回归模型
import numpy as np
import pandas as pd
import scipy.stats as ss
df = pd.DataFrame({ "A":ss.norm.rvs(size = 100),
"B":ss.norm.rvs(size = 100),
"C":ss.norm.rvs(size = 100),
"D":ss.norm.rvs(size = 100),
"E":np.random.randint(low = 0,high = 2,size = 100)
})
X = df.loc[:,["A","B","C","D"]]
Y = df.loc[:,["E"]]
# 过滤思想
from sklearn.feature_selection import SelectKBest
skb = SelectKBest(k = 2)
"""
klearn.feature_selection.SelectKBest(score_func=<function f_classif>, k=10)
其中score_func为指定特征选择函数:默认为:f_classif(方差分析),其他还有chi2(卡方检验),mutual_info_classif(互信息),根据特征的属性选择合适的函数
k为最大特征选择数目
"""
skb.fit(X,Y)
result = skb.transform(X)
# 包裹思想
"""
采用RFE算法(即递归特征消除recursive feature elimination)
"""
from sklearn.svm import SVR
"""
svm为支持向量机
SVR为支持向量回归
"""
from sklearn.feature_selection import RFE
rfe = RFE(estimator = SVR(kernel = "linear"),n_features_to_select = 2,step = 1)
"""
estimator:对特征含有权重的预测模型(例如,线性模型对应参数coefficients)
n_features_to_list:最终特征选择数目
step:每次消除特征的数目
"""
rfe.fit_transform(X,Y)
# 嵌入思想
"""
建立简单回归模型现在的模型与最终的模型要有一定的关联。
"""
from sklearn.tree import DecisionTreeRegressor
from sklearn.feature_selection import SelectFromModel
sfm = SelectFromModel(estimator = DecisionTreeRegressor(),threshold = 0.3) # threshold为权重的阈值
sfm.fit_transform(X,Y)
2.2 特征变换
特征变换可分为六种:
- 对指化:大于0部分的数据若差距较小,经过指数化可加大尺度
- 离散化
- 数据平滑
- 归一化(标准化)
- 数值化
- 正规化
# 对指化
"""
大于0部分的数据若差距较小,经过指数化可加大尺度
"""
# 指数化
"""
将较大数据缩放到我们容易计算的范围
如声音强度和地震强度
"""
# 离散化
"""
将连续变量分成几段
原因:1、克服数据缺陷
2、某些算法需要:朴素贝叶斯算法
3、非线数据映射
方法:1、等频(等深)放大
2、等距(等宽)放大
3、自因变量优化
"""
lst = [56,8,10,15,16,24,25,30,40,67]
pd.qcut(lst,q = 3,labels = ["low","medium","high"])# 等深分箱
pd.cut(lst,bins = 3,labels = ["low","medium","high"])# 等宽分箱
# 归一化
"""
[0,1]
"""
from sklearn.preprocessing import MinMaxScaler
data = np.array([1,5,9,89,26,56,38]).reshape(-1,1)
to_one = MinMaxScaler()
to_one.fit_transform(data)
# 标准化(狭义)
"""
均值为0,标准差为1
"""
from sklearn.preprocessing import StandardScaler
normal = StandardScaler()
normal.fit_transform(data)
# 数值化
"""
四种数据类型:
1、定类:需要数值化(如:低 中 高)--独热编码
2、定序:需要数值化(如:红 绿 蓝)--标签编码
3、定距:需要归一化
4、定比
数值化的方式:
1、标签化(label):如0、1、2
2、独热(one-hot encode):用稀疏矩阵表示
"""
from sklearn.preprocessing import LabelEncoder
data1 = np.array(["up","down","down","down","up"]).reshape(-1,1)
le = LabelEncoder()
le.fit_transform(data1) # 标签编码
from sklearn.preprocessing import OneHotEncoder,LabelEncoder
data2 = np.array(["green","red","yellow","red","green","green"])
ohe = OneHotEncoder()
"""
独热编码前需要标签编码
"""
data_tran = LabelEncoder().fit_transform(data2)
ohe_result = ohe.fit_transform(data_tran.reshape(-1,1)) # 返回结果为压缩稀疏矩阵
ohe_result.toarray() # 使用toarray方法转化为数组
"""
对于独热编码 pandas提供了更为简易的方法
df = pd.get_dummies(df,columns = [])
"""
# 正规化(规范化)
"""
正规化一般针对一条记录数据进行
根据距离度量的次数不同 一般使用L1或L2
"""
data = np.array([5,6,8,9,3,4,7,8,15,69]).reshape(1,-1)# 默认对每一行进行正规化(且为二维数组)
from sklearn.preprocessing import Normalizer
norm1 = Normalizer(norm = "l1")
norm1.fit_transform(data)
norm2 = Normalizer(norm = "l2")
norm2.fit_transform(data)
3 特征降维
PCA 和 LDA 特征降维的区别于联系:
- 联系:
- 两者均可以对数据进行降维。
- 两者在降维时均使用了矩阵特征分解的思想。
- 两者都假设数据符合高斯分布
- 区别:
- LDA是有监督的降维方法,而PCA是无监督的降维方法
- LDA降维最多降到类别数k-1的维数,而PCA没有这个限制。
- LDA除了可以用于降维,还可以用于分类。
- LDA选择分类性能最好的投影方向,而PCA选择样本点投影具有最大方差的方向。这点可以从下图形象的看出,在某些数据分布下LDA比PCA降维较优。
import numpy as np
import pandas as pd
X = np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
Y = np.array ([1,1,1,2,2,2])
# PCA 降维
from sklearn.decomposition import PCA
pca = PCA(n_components = 1)
pca.fit(X)
pca.transform(X)
pca.explained_variance_ratio_ # 它代表降维后的各主成分的方差值占总方差值的比例,这个比例越大,则越是重要的主成分。
# LDA降维
"""sklearn.decomposition么会产生不相关特征引入、过度拟合等问题。我们可以使用PCA来降维,但PCA没有将类别标签考虑进去,属于无监督的。
"""
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis(n_components = 1)
lda.fit(X,Y)
lda.transform(X)
lda.explained_variance_ratio_ # 每一个维度解释的方差占比
# LDA还可以用作分类器 即Fisher分类器
lda.predict([[-1,-3]])
by CyrusMay 2022 04 05