数据挖掘 – 数据预处理

1. 数据清洗

数据清洗包括数据样本采样和异常值(null)处理

  1. 直接丢弃(包括重复数据)
  2. 将是否有异常视为新属性,替换原来的值
  3. 集中引用
  4. 边界值指定
  5. 插值
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. 特征预处理

  1. 反映目的的属性称之为标注(也叫作标记、标签、label)
  2. 特征预处理分为四个部分:
  • 特征选择
  • 特征变换
  • 特征降维
  • 特征推导

2.1 特征选择

  • 特征选择:删除与注释无关或多余的特征
  • 其中一个思路是数据缩减:包括三个思路
  1. 过滤思路:特征与标注的相关性
  2. Wrapping思想:遍历特征子集,即构造一个简单的模型,根据系数去除弱特征
  3. 嵌入想法:构建简单的回归模型
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 特征变换

特征变换可以分为六种类型:

  1. 对指化:大于0部分的数据若差距较小,经过指数化可加大尺度
  2. 离散化
  3. 数据平滑
  4. 归一化(归一化)
  5. 数值化
  6. 正常化
# 对指化
"""
 大于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 特征降维的区别于联系:

  • 连接:
  1. 两者都可以降低数据的维数。
  2. 两者在降维中都使用了矩阵特征分解的思想。
  3. 两者都假设数据符合高斯分布
  • 区别:
  1. LDA是有监督的降维方法,而PCA是无监督的降维方法
  2. LDA降维最多降到类别数k-1的维数,而PCA没有这个限制。
  3. LDA除了可以用于降维,还可以用于分类。
  4. 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

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年4月7日 下午12:05
下一篇 2022年4月7日

相关推荐