先导入各种需要的包,导入数据
#导入包
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,3步,确定需求、y、x都是根据理论确定
#------------第4步--------------,
#描述数据——获取每个变量的分布形态、均值、中位数、最大值、最小值等常用指标。
#分布形态——记录分布异常的变量
data.iloc[:,1:].hist(figsize=(20,16))
#统计量
data.iloc[:,1:].describe()
对图片中一些分布在3:1以上的数据进行适当的调整,属于异常值处理
这里采用随机森林方法去填充缺失值
#----------第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)
当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)
#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
具体见注释
#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之间
#--------------函数及图形---------------------------
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()
#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()
# 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()
#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)