无纺布制造设备参数优化。
# 导入库
import pandas as pd # 数据分析
import numpy as np # 科学计算
# 加载线性回归需要的模块和库
import statsmodels.api as sm # 最小二乘
from statsmodels.formula.api import ols # 加载ols模型
# 划分训练集与测试集
from sklearn.model_selection import train_test_split
import random
random.seed(123) #设立随机数种子
# 导入.cvs文件
df = pd.read_csv(r'C:\Users\70765\Documents\lantian\data_pre.csv', encoding='GBK',sep=',')
# 列数过多的话,默认省略显示中间列。用以下方式显示所有列
pd.options.display.max_columns = None
# 查看完整数据表
df
# 查看找数据所在行
df.loc[df['厚度1' ]==2.85] # 厚度1这列中,数值为2.85的这行数据(查到的是哪行)
# 查找某一行数据
df_res.iloc[1] # 索引为1的这行数据(第一行这行的数据)(查到的是数据)
# 查看数据表基本信息
df.info()
# 查看数据统计信息
df.describe()
# 发现很多异常数据,开始数据清理!
# 先去掉数据类型为字符串的列,将所得的dataframe赋值到新的dataframe中,命名为df2
# (有些数据类型为字符串的列应该也具有有用信息,但考虑起来有点复杂,暂不考虑。)
df2 = df.select_dtypes(include = [float, int]) # 只包含是float或int数据类型的列
# 将df2复制到df_res(相当于使用备份的数据。保留df2的数据,只对df_res做更新)
df_res = df2.copy()
# 默认数据为正态分布(并不一定是,有的很不是,这里为了方便)
# 用3σ原则筛除出异常数据(outlier)(如果数据为正态分布则如此筛选可保留到99.7%的数据)
# 提取出所有列中无异常数据的数据行(大于(μ-3σ)并小于(μ+3σ)的数据)
for col in df2.columns: # df2中的每一列
df_res = df_res[df_res[col]<(df_res[col].mean()+3*df_res[col].std())].reset_index(drop=True)
df_res = df_res[(df_res[col].mean()-3*df_res[col].std()) < df_res[col]].reset_index(drop=True)
# col相当于列名
# .reset_index(drop=True) 索引重新赋值
# 查看清理过后的数据
df_res
# 数据行变少啦,有异常数据的行被筛除了。
开始数据分析
发现这个数据有很多项参数(自变量),有些应该对因变量影响很小,我们需要剔除它们。
通过逐步回归(向前)来选择统计显著的自变量
为了避免过拟合,我们需要通过交叉验证去验证模型
将原始数据划分为训练集与测试集(验证集)
a=random.sample(range(len(df_res)),round(len(df_res)*0.2)) # 验证集的索引的集合
a是一个随机选取的部分原始数据的索引的集合(验证集的索引的集合)
len(df_res) 数据集df_res的数据量(record数量,元素数量)
range(len(df_res)):0-len(df_res), (range(start,stop,step))
round(len(df_res)*0.2) 随机选取20%的record作为验证集,并将len(df_res)*0.2四舍五入到整数
random.sample(list,k)函数:返回一个长度为k新列表,新列表存放list中产生的k个随机的唯一的元素
# 验证集
df_res_test=[]
for i in a:
df_res_test.append(df_res.iloc[i])
# df_res.iloc[i] 索引
# a.append(b):添加。是将b原封不动的追加到a的末尾上,会改变a的值,其中,b可为列表、元组、字符串、一串数/字符/字符串
df_res_test=pd.DataFrame(df_res_test) # 将df_res_test转化成dataframe格式
# 训练集
df_res_train=df_res.drop(a) # df_res_train 训练集就是df_res去掉a(测试集)
根据AIC准则定义向前逐步回归进行变量筛选
AIC:
AIC即赤池值,是衡量模型拟合优良性和模型复杂性的一种标准,在建立多元线性回归模型时,变量过多,且有不显著的变量时,可以使用AIC准则结合逐步回归进行变量筛选。AICD数学表达式如下:
A
I
C
=
2
p
+
n
(
l
o
g
(
R
S
S
/
n
)
AIC = 2p +n(log(RSS/n)
AIC=2p+n(log(RSS/n)
其中,p 是进入模型当中的自变量个数,n 为样本量,RSS是残差(误差)平方和( Residual sum of squares (RSS) 亦被称为 the sum of squared errors of prediction (SSE)),在n 固定的情况下,p 越小,AIC越小,RSS越小,AIC越小。p 越小代表着模型越简洁,RSS越小代表着模型越精准,即拟合度越好,综上所诉,AIC越小,即模型就越简洁和精准。
逐步回归(Stepwise regression):
逐步回归分为三种,分别是向前逐步回归(Forward selection),向后逐步回归(backward selection),逐步回归。
在向前选择中,开始时没有预测因子(自变量),一个一个逐步添加对R2有最大贡献的预测值,当贡献不再显著时,停止添加。
在向后选择(或向后删除)中,一开始就给出了一个完整的模型(包含所有自变量),然后从中一次删除统计不显著的变量,直到模型中的所有自变量都是统计显著的。
R2(R方统计量,决定系数):
取值范围在0-1之间,它测量了数据中可被模型解释的变异性的比例, 可以用来评估模型对数据的拟合程度。
R
2
=
1
−
∑
i
=
1
n
(
y
i
−
y
^
i
)
∑
i
=
1
n
(
y
i
−
y
‾
i
)
=
1
−
R
S
S
S
S
t
o
t
a
l
R^2 = 1- \frac {\sum_{i=1}^n(y_i -\hat y_i)}{\sum_{i=1}^n(y_i - \overline y_i)} = 1 - \frac {RSS}{SS_{total}}
R2=1−∑i=1n(yi−yi)∑i=1n(yi−y^i)=1−SStotalRSS
变异性(散布,离散度):
变异性是对一个分布中的数据分散开或聚集在一起的程度的数量测量。可看作是对不同数值间的差异性的度量。
反映数据变异性的常用指标有极差、标准差和方差。
总体(population)方差: σ 2 = ∑ i = 1 n ( x i − x ‾ i ) 2 N \sigma^2 = \frac {\sum_{i=1}^n(x_i - \overline x_i)^2}{N} σ2=N∑i=1n(xi−xi)2
样本(sample)方差: s 2 = ∑ i = 1 n ( x i − x ‾ i ) 2 n − 1 s^2 = \frac {\sum_{i=1}^n(x_i - \overline x_i)^2}{n-1} s2=n−1∑i=1n(xi−xi)2数据组中所有数值与均值的平均距离。表示数据组中变异性的平均数量。
(方差开方)
总体(population)标准差: σ = ∑ i = 1 n ( x i − x ‾ i ) 2 N \sigma = \sqrt{\frac {\sum_{i=1}^n(x_i - \overline x_i)^2}{N}} σ=N∑i=1n(xi−xi)2
样本(sample)方差: s = ∑ i = 1 n ( x i − x ‾ i ) 2 n − 1 s = \sqrt{\frac {\sum_{i=1}^n(x_i - \overline x_i)^2}{n-1}} s=n−1∑i=1n(xi−xi)2
普通最小二乘 OLS (Ordinary Least Square):
找到让RSS最小化的回归线。
# 定义向前逐步回归函数
def forward_select(data,target): # target: 因变量
variate=set((data.columns)[:-35]) # 自变量
# 将字段名们转换成一个无序的集合(去掉后35个,因为后面的都不是自变量)
# set(): 确定性, 无序性, 唯一性(无重复性)
selected=[] # 新建一个名为‘selected’的list,存放被选择的自变量
# list: 有序集合,用户可以精确控制列表中每个元素插入位置 用户可以通过整数索引访问元素,并搜索列表中的元素 与Set集合不同,列表通常允许重复的元素
current_score,best_new_score=float('inf'),float('inf') #目前的分数和最好分数初始值都为无穷大(因为AIC越小越好)
#循环筛选变量
while variate:
aic_with_variate=[]
for candidate in variate: #逐个遍历自变量
formula="{}~{}".format(target,"+".join(selected+[candidate])) #将自变量名连接起来
# "{}~{}".format(a,b): a~b
# "+".join(selected+[candidate]): 用“+”将list ‘selected’里的元素与当前的‘candidate’组合起来
aic=ols(formula=formula,data=data).fit().aic #利用ols训练模型得出aic值
aic_with_variate.append((aic,candidate)) #将第每一次的aic值放进空列表
aic_with_variate.sort(reverse=True) #降序排序aic值
best_new_score,best_candidate=aic_with_variate.pop() #最好的aic值等于删除列表的最后一个值,以及最好的自变量等于列表最后一个自变量
# pop(): 用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
if current_score>best_new_score: #如果目前的aic值大于最好的aic值
variate.remove(best_candidate) #移除加进来的变量名,即第二次循环时,不考虑此自变量了
selected.append(best_candidate) #将此自变量作为加进模型中的自变量
current_score=best_new_score #最新的分数等于最好的分数
print("aic is {},continuing!".format(current_score)) #输出最小的aic值
else:
print("for selection over!")
break
formula="{}~{}".format(target,"+".join(selected)) #最终的模型式子
print("final formula is {}".format(formula))
model=ols(formula=formula,data=data).fit()
return(model.summary())