python统计分析--2.预分析:异常值、缺失值处理

本文介绍了数据预处理的重要步骤,包括缺失值处理、异常值处理和特征筛选。在缺失值处理中,使用了随机森林模型进行填充。针对异常值,通过设定阈值进行修正,并通过Filter过滤法进行特征筛选。同时,探讨了共线性问题,通过曲线绘制展示了不同函数变换的效果。最终,进行了编码和多变量异常值的进一步处理,以提升模型的预测性能。
摘要由CSDN通过智能技术生成

1.缺失值处理

1.1 导入数据

先导入各种需要的包,导入数据

#导入包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.formula.api as smf
from sklearn import linear_model
import seaborn as sns
%matplotlib inline
plt.rcParams["font.sans-serif"]=["SimHei"]
plt.rcParams["axes.unicode_minus"]=False
#使用pandas读取数据支持xls和xlsx
data=pd.read_excel(r"残耗.xlsx")
data.head(2)
data.info()

1.2 观察数据

观察并记录分布异常的变量

# 第1,2,3步,确定需求、y、x都是根据理论确定

#------------第4步--------------,
#描述数据——获取每个变量的分布形态、均值、中位数、最大值、最小值等常用指标。
#分布形态——记录分布异常的变量
data.iloc[:,1:].hist(figsize=(20,16))
#统计量
data.iloc[:,1:].describe()

在这里插入图片描述
对图片中一些分布在3:1以上的数据进行适当的调整,属于异常值处理
在这里插入图片描述

1.3 缺失值处理方法

  • 大数据分析缺失值处理方法
    缺失值在3%以内一般用中位数来填写
    缺失值在3%~20%以内一般用模型添补来填写(KNN 或者 随机森林)
    缺失值在20%~80%以内一般用缺失值分类法来填写
    缺失值在80%以上一般用业务人员分析(一般删除这组数据)

这里采用随机森林方法去填充缺失值

#----------第5步--------------
#5.1 缺失值---60%以上的缺失,分类法处理或删除,其他中位数填补;
data.isnull().sum()/data.shape[0]  #缺失值比例
#data51=data.fillna(value=data.median())#中位数填补(中位数模型77.5%,随机森林79.2%)

# import sklearn.neighbors._base
# import sys
# sys.modules['sklearn.neighbors.base'] = sklearn.neighbors._base

#-----------或使用模型填补----------
# 随机森林添补异常值
#MissForest和RandForestregressor两个都是随机森林
#MissForest是集成的包不需要设置参数
#RandForestregressor需要自己手动设置参数,所以一般采用MissForest
from missingpy import KNNImputer,MissForest

imput=MissForest(n_estimators=2,min_samples_leaf=9000,n_jobs=-1,copy=False)
data5=imput.fit_transform(data.iloc[:,1:])

data51=pd.DataFrame(data5,columns=data.iloc[:,1:].columns)
# data51.info()
x,y=data51.iloc[:,1:],data51['v残耗']
reg=linear_model.LinearRegression()
reg.fit(x,y)
reg.score(x,y)   
  • 用随机森林得到的正确率为:0.7907806712612082

2. 异常值处理

2.1 异常值—强异常值的处理

当data51中的第i列大于j时,data51[i]=j
当data51中的第i列小于t时,data51[i]=t
具体解释看注释

# 5.2异常值---强异常值的处理(模型83%)
var=[(-0.01,'lHH',140000),(-0.01,'偏离位',10000),(0,'助燃',100),(-0.01,'助燃反应',2000),
     (-0.01,'助燃柠檬',10000),(20,'助燃添加',29.7),(0,'助燃点',1000),(-0.01,'吸阻',1000),
     (10,'吸阻过滤',129),(0,'噪声',100),(-10000,'圆周点位',29.7),(-0.01,'撤回点位',1000),
     (0,'收紧度',1000),(0,'标注',129),(0,'检查点位',100),(-0.01,'气体综合',10000),
     (0,'消耗烟脂',500),(-200,'温控',200),(-0.01,'烟碱HW',2000),(-0.01,'烟碱量',10000),
     (0,'焦油量',200),(-0.01,'起点位',1000),(-0.01,'过滤时效',1500),(30,'通路',40),
     (-10000,'钠元素',500),(20,'钾元素',100)
    ]
# 当data51中的第i列大于j时,data51[i]=j
# 当data51中的第i列小于t时,data51[i]=t
for (t,i,j) in var:
    data51[i+str("01")]=np.where(data51[i]>=j,j,
                                               np.where(data51[i]<=t,t,data51[i].copy()))
#     print(data51[i+str("01")].describe())
data52=data51.iloc[:,[*range(0,6),*range(32,58)]]
# data52.info()
x,y=data52.iloc[:,2:],data52['v残耗']
reg=linear_model.LinearRegression().fit(x,y)
reg.score(x,y)  

2.2 特征筛选(Filter过滤法)

#5.3 特征筛选(Filter过滤法)--业务上不重要的
# SelectKBest表示选择的数量
# SelectPercentile表示选择的百分比
#f_regression表示回归算法
from sklearn.feature_selection import SelectKBest,SelectPercentile,f_regression
# 选取数据中所有行和第二列开始到最后一列作为x
# 选取残差作为y(因变量)
x,y=data52.iloc[:,2:],data52['v残耗']
#选取f_regression算法,选择百分比为60%
fit=SelectPercentile(score_func=f_regression,percentile=60)

fitt=fit.fit_transform(x,y)
# fit.get_support(indices=True)是选择出指定的列,指定的列array([ 0,  1,  2,  5,  6,  8, 10, 11, 12, 13, 15, 17, 19, 22, 23, 25, 26,28], dtype=int64)
# pd.concat表示合并数据集
data53=pd.concat([data52['v残耗'],x.iloc[:,fit.get_support(indices=True)]],axis=1)
data53

2.3 共线性

具体见注释

#5.4 共线性--严重共线性0.9以上,合并或删除,共线性指的是x与x之间,不是指x与y之间
#corr()表示相关分析,不把小于0.9的替换成0.01的话会分不清楚那些是高相关还是低相关
# d=data53.corr();d[d<=0.9]=0.01#赋值显示高相关的变量,提取出高相关的变量
# # 绘制热力图
# sns.heatmap(d)
# print([data53['气体综合01'].corr(data53['烟碱量01']),data53['过滤时效01'].corr(data53['v3燃料类型'])])
# plt.scatter(data53['v3燃料类型'],data53['过滤时效01'])#删除过滤时效01,在业务上不重要
# plt.scatter(data53['气体综合01'],data53['烟碱量01'])

# #拟合线性形式的模型
from scipy.optimize import curve_fit

def f(x,b0,b1):
    return b0+b1*x  #调整x和y的任意函数关系,如b0*np.exp(b1*dt['x'])
popt,pcov=curve_fit(f,data53["烟碱量01"],data53["气体综合01"])
b0=popt[0]
b1=popt[1]

# data53["成分烟碱"]=b0+b1*data53["烟碱量01"]#整合新字段并计算r方
print("r**2:",(data53["成分烟碱"].corr(data53['v残耗'])))#如果与y的相关高于单个x与y的相关则保留;

# #drop弹出指标。"气体综合01",'过滤时效01',"成分烟碱"这些都是弱相关或者强相关合并后需要删除的变量
data54=data53.drop(["气体综合01",'过滤时效01',"成分烟碱"],axis=1)#最终决定删除"气体综合01"和'过滤时效01'
data54.shape

#--------------函数及图形---------------------------
plt.subplots(2,3,figsize=(16,8));b0=1;b1=2;
plt.subplot(231);x=np.random.randint(-5,5,100);y=1/(1+np.exp((-b0-b1*x)))
plt.scatter(x,y,label='logistic');plt.legend()
plt.subplot(232);b0=5;b1=2;x=np.random.randint(0,100,100);y=b0 + (b1 * np.log(x))
plt.scatter(x,y,label='对数');plt.legend()
plt.subplot(233);b0=5;b1=2;x=np.random.randint(0,10,100);y=b0 * (np.exp((b1 * x))) 
plt.scatter(x,y,label='指数');plt.legend()
plt.subplot(234);b0=5;b1=2;x=np.random.randint(0,10,100);y=b0 + (b1 / x) 
plt.scatter(x,y,label='逆');plt.legend()
plt.subplot(235);b0=5;b1=2;x=np.random.randint(0,10,100);y=b0 * (x**b1)
plt.scatter(x,y,label='幂');plt.legend()
plt.subplot(236);b0=5;b1=2;x=np.random.randint(-100,100,100);y=np.exp(b0 + (b1/x))
plt.scatter(x,y,label='S 曲线');plt.legend()

共线性–严重共线性0.9以上,合并或删除,共线性指的是x与x之间,不是指x与y之间

  • 绘制热力图观察自变量之间的相关性
    从图中可以看出自变量之间那些是强相关性的,不用与残耗相关
    在这里插入图片描述
    V3燃料类型与过滤时效01之间的相关性,一般不采用散点图,效果不是很明显
    在这里插入图片描述
    气体综合01和烟碱量01之间的相关性
    在这里插入图片描述

2.4 logistics、对数、指数、逆、幂、曲线的绘制

#--------------函数及图形---------------------------
plt.subplots(2,3,figsize=(16,8));b0=1;b1=2;
plt.subplot(231);x=np.random.randint(-5,5,100);y=1/(1+np.exp((-b0-b1*x)))
plt.scatter(x,y,label='logistic');plt.legend()
plt.subplot(232);b0=5;b1=2;x=np.random.randint(0,100,100);y=b0 + (b1 * np.log(x))
plt.scatter(x,y,label='对数');plt.legend()
plt.subplot(233);b0=5;b1=2;x=np.random.randint(0,10,100);y=b0 * (np.exp((b1 * x))) 
plt.scatter(x,y,label='指数');plt.legend()
plt.subplot(234);b0=5;b1=2;x=np.random.randint(0,10,100);y=b0 + (b1 / x) 
plt.scatter(x,y,label='逆');plt.legend()
plt.subplot(235);b0=5;b1=2;x=np.random.randint(0,10,100);y=b0 * (x**b1)
plt.scatter(x,y,label='幂');plt.legend()
plt.subplot(236);b0=5;b1=2;x=np.random.randint(-100,100,100);y=np.exp(b0 + (b1/x))
plt.scatter(x,y,label='S 曲线');plt.legend()

图形如下
在这里插入图片描述

3.编码

#5.5 变量变换-----关注y是否需要变换
# data54['v残耗log']=np.log(data54['v残耗'])#本案例中无需变换
#5.6 编码-----消除异常值、分组(标签化)
# data53['烟碱量02']=pd.qcut(data53['烟碱量01'],q=4)#本案例中无需变换
data54.shape
  • 总的结果
x,y=data54.iloc[:,1:],data54['v残耗']
reg=linear_model.LinearRegression()# 用于大数据回归
reg.fit(x,y)
reg.score(x,y)

plt.subplots(1,2,figsize=(12,8))
plt.subplot(121)
r2=reg.score(x,y);plt.plot(y,reg.predict(x),'o',label=r2)#r方评分和图示
plt.legend()
plt.subplot(122)
resid=y-reg.predict(x)
std_resid=(resid-np.mean(resid))/np.std(resid)
plt.plot(reg.predict(x),std_resid,'o',label="残差图")#r方评分和图示
plt.legend()

在这里插入图片描述

3.1 异常值—多变量异常值处理

# 5.2+ 异常值---多变量异常值处理
data54["标准化残差"]=std_resid#复制保存
data54_99=data54[np.abs(data54["标准化残差"])<=6]#设置异常条件
data54_2=data54_99.drop(["标准化残差"],axis=1)
print(data54_2.shape)

x,y=data54_2.iloc[:,1:],data54_2['v残耗']
reg=linear_model.LinearRegression()
reg.fit(x,y)
print(reg.score(x,y))
resid=y-reg.predict(x)
plt.plot(reg.predict(x),(resid-np.mean(resid))/np.std(resid),'o',label="残差图")#r方评分和图示
plt.legend()

3.2 特征筛选

#5.3+ 特征筛选(Wrapper包装法RFE;Embedded嵌入法SelectFromModel)
from sklearn.feature_selection import RFE,SelectFromModel
from sklearn.ensemble import RandomForestRegressor
from sklearn.svm import LinearSVR

x54_1,y54_1=data54_2.iloc[:,1:],data54_2['v残耗']
# rfr=RandomForestRegressor(n_estimators=10,min_samples_leaf=10000)
# selector=RFE(rfr,n_features_to_select=5).fit(x54_1,y54_1)
data54_3=pd.concat([data54_2['v残耗'],data54_2[data54_2.columns[selector.get_support(indices=True)]]],axis=1)

x,y=data54_3.iloc[:,2:],data54_3['v残耗']
reg=linear_model.LinearRegression().fit(x,y)
print(reg.score(x,y))
data54_3.head(6)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值