传统企业如何数字化,以及如何从中获得收益,一直是最近聊得比较多的话题。我与许多同事都聊过这个问题,大家一直以来都以项目成败论英雄,美名其曰“以结果为导向”。我们在这里并不讨论“以结果为导向”是多么的落后,而是想说,其实每个项目的过程数据也很美丽,它应该获得同等的重视。拿过项目管理证的人都知道,项目管理也有文档管理,文档的归档,但我觉得项目管理应该与时俱进,项目也要数字化。
好了,话不多说,咱们技术人不讲那么多套话。今天的话题是电流,电压和温升之间的关系,这也是公司RD研究中为数不多的数字化项目。
说到这里,有人眉头一皱,这玩意用得上多元回归吗?要知道有很多人一直还活在很久很久以前的开发环境中,就是做各种原型机,拉上一帮人然后做各种温升测试,得出结果。不可否认这种方法我自己就用了7~8年,这是我们上大学,课本以及公司老法师的的做法。这种方法可以说是费时费力,最辛苦的方法。后来公司引进了有限元分析,用仿真的方法去预测结果,这种方法加快了研发的速度,但是找个专业或者培养个有限元分析工程师,是多么不容易的事。还有个不争的事实是有限元软件都是国外公司垄断着,国内成熟的软件基本没有,买个正版的软件就一个字“贵”。那么有没有简单实用又不贵的着呢?答案是肯定的。
现在各行各业都讲究大数据,讲究数据挖掘,以前大家花时间,花精力测得的数据都还睡保险箱吧,是时候让他们活过来了。
这里我们研究的是塑壳开关的电流,电压与温升之间的关系,我们想以后只测电流和电压即能预测各个温升点的数值,数值可能无法做到100%准确,只要达到90%准确性就可以了。
首先把数据整理出来(这里我们研究4记开关,两极并联,再串联):
2P in parallel connection | |||||||||||||||
current (A) | Voltage-drop(mV) | Temperature rise (K) | |||||||||||||
L1 | T1 | ||||||||||||||
203 | 15.04 | 3.4 | 2.8 | ||||||||||||
403 | 29.81 | 10.5 | 9.9 | ||||||||||||
504 | 37.02 | 15.7 | 15.1 | ||||||||||||
603 | 44.2 | 21.4 | 20.6 | ||||||||||||
802 | 59.56 | 35.7 | 34.8 | ||||||||||||
1005 | 76.9 | 51.7 | 50.3 |
我们先把数据读取打开excel文档,这个是测试工程师通常保存数据的格式,如果公司数字化工作比较好的,可以直接读出,拷贝数据库,建议不要直接操作数据库,查找你想要的,拷贝出来。
##################################################################################################################################################
2020.12.04更新到此
##################################################################################################################################################
本来想多写点的,但是软件好久没更新了,整个环境老半天。
今天天气不是太好,好在老婆和小朋友都有地方去。
使用的话,还是喜欢用pandas来读excel文件,我就不客气了,开始堆代码:
#coding: utf-8
import csv #数据库文件格式
import numpy as ny #数据处理模块
import pandas as pd #数据处理模块
import xlrd #EXCEL文件格式
import xlwt #EXCEL文件库
RDDATA=pd.read_excel('2P.xlsx')
height,width = RDDATA.shape
print(height,width,type(RDDATA))
print(RDDATA)
话不多说先上个图:
我们来对比一下,源文件,可以看到Unnamed:1~Unnamed:15都是合并的单元格,NaN都是空格
############################################################################################################################################
2020.12.05更新到此
############################################################################################################################################
2020.12.06休息
############################################################################################################################################
2020.12.07心情非常不好,有些事情一念之差,觉得好累~
############################################################################################################################################
2020.12.08不知道该怎么办,俗话说男儿有泪不轻弹,路上忍不住,流下泪水,好烦~
############################################################################################################################################
2020.12.09事情总是要面对的,我也只能硬抗了,抗不住再说吧~
好不容易有些思路,上代码,每句基本都有注释
这当中我用了两种方法,遍历数据,好在数据量不大,个人觉得两种方法都可以。
好长时间不写代码,手有点生疏,倒是真的。
# coding: utf-8
# import csv # 数据库文件格式
# import numpy as ny # 数据处理模块
import pandas as pd # 数据处理模块
# import xlrd # EXCEL文件格式
# import xlwt # EXCEL文件库
pre_DATA = pd.read_excel('2P.xlsx', sheet_name=0) # 读取项目根目录下的excel文件
DATA = pre_DATA.fillna(0) # 把NaN都填上0
height, width = DATA.shape # 获取表单的行列数
print(height, width, type(DATA)) # 打印表单的行列数,以及数据结构
DATA_1 = DATA.iloc[:,[0]] # 截取第一列数据
CU = [] # 建立空列表
for DATA_2 in DATA_1.itertuples(): # 遍历电流数据
if type(DATA_2[1]) == int and DATA_2[1]>0: # 筛选数据
CU.append(DATA_2[1]) # 选出的数据保存到列表
print(CU) # 输出数据
pre_current = pd.read_excel('2P.xlsx', sheet_name=0, usecols=[0, 0]) # 读取表单的第一工作单,第一列
current = [] # 建立空列表
for current_row in pre_current.itertuples(): # 遍历第一列的数据
if type(current_row[1]) == int: # 判断数据类型为整数
current.append(current_row[1]) # 把数据存入空列表
print(current) # 输出串联电流数据
pre_L1_V = pd.read_excel('2P.xlsx', sheet_name=0, usecols=[1, 1]) # 读取表单的第一工作单,第二列
L1_V = [] # 建立空列表
for L1_V_row in pre_L1_V.itertuples(): # 遍历第二列的数据
if type(L1_V_row[1]) == float: # 判断数据类型为浮点型
L1_V.append(L1_V_row[1]) # 把数据存入空列表
print(L1_V) # 输出第一相的电压数据
pre_L2_V = (pd.read_excel('2P.xlsx', sheet_name=0, usecols=[2, 2]).fillna(0))
L2_V = []
for L2_V_row in pre_L2_V.itertuples():
if type(L2_V_row[1]) == float:
L2_V.append(L2_V_row[1])
print(L2_V) # 输出第二相的电压数据
pre_L3_V = (pd.read_excel('2P.xlsx', sheet_name=0, usecols=[3, 3]).fillna(0))
L3_V = []
for L3_V_row in pre_L3_V.itertuples():
if type(L3_V_row[1]) == float:
L3_V.append(L3_V_row[1])
print(L3_V) # 输出第三相的电压数据
pre_L4_V = (pd.read_excel('2P.xlsx', sheet_name=0, usecols=[4, 4]).fillna(0))
L4_V = []
for L4_V_row in pre_L4_V.itertuples():
if type(L4_V_row[1]) == float:
L4_V.append(L4_V_row[1])
print(L4_V) # 输出第四相的电压数据
pre_L1_T = pd.read_excel('2P.xlsx', sheet_name=0, usecols=[5, 5])
L1_T = []
for L1_T_row in pre_L1_T.itertuples():
if type(L1_T_row[1]) == float:
L1_T.append(L1_T_row[1])
print(L1_T) # 输出第一相端子的温升数据
pre_L2_T = (pd.read_excel('2P.xlsx', sheet_name=0, usecols=[6, 6]).fillna(0))
L2_T = []
for L2_T_row in pre_L2_T.itertuples():
if type(L2_T_row[1]) == float:
L2_T.append(L2_T_row[1])
print(L2_T) # 输出第二相端子的温升数据
pre_L3_T = (pd.read_excel('2P.xlsx', sheet_name=0, usecols=[7, 7]).fillna(0))
L3_T = []
for L3_T_row in pre_L3_T.itertuples():
if type(L3_T_row[1]) == float:
L3_T.append(L3_T_row[1])
print(L3_T) # 输出第三相端子的温升数据
pre_L4_T = (pd.read_excel('2P.xlsx', sheet_name=0, usecols=[8, 8]).fillna(0))
L4_T = []
for L4_T_row in pre_L4_T.itertuples():
if type(L4_T_row[1]) == float:
L4_T.append(L4_T_row[1])
print(L4_T) # 输出第四相端子的温升数据
数据处理的结果上图,大家可以参考:
#####################################################################################################################################################################2020.12.10 继续更新
#####################################################################################################################################################################数据清洗完了,怎么样判断,电流,电压,温升数据之间的关系,如果是线性相关的,如果与线性相关不紧密?来段代码
from statsmodels.formula.api import ols #导入数据统计的模块
groupL1 = pd.DataFrame({'x': current, 'y': L1_V, 'z': L1_T}) #把相关的数据按我们通常的X,Y,Z合成DataFrame结构的数据,这一步是指定方程方法必须先行处理的,如果不使用指定方程,可以省略。
x = current #把电流数据对应于X
y = L1_V #把电压数据对应于Y
z = L1_T #把温升数据对应于Z
formula = 'z~x+np.square(x)+y+np.square(y)' #指定方程格式
est = ols(formula, data=groupL1).fit() #对数据进行拟合
print(est.summary()) #输出拟合总结
有一段这个警告,大体意思就是数据只有6组,少于8组,有两组关于Omnibus的数据缺失。
有些参数的理解:
Dep.Variable: 就是因变量,dependent variable
Model:就是最小二乘模型,这里就是OLS。
Method:系统给出的结果是Least Squares,和上面的Model差不多一个意思。
Date:模型生成的日期。
Time:模型生成的具体时间。
No. Observations:样本量,就是输入的数据量
Df Residuals:残差自由度,即degree of freedom of residuals,其值= No.Observations - Df Model - 1。
Df Model:模型自由度,degree of freedom of model,其值=X的维度
Covariance Type:协方差阵的稳健性,在本例中是nonrobust,这个参数的原理过于复杂,想详细了解的朋友可以自行查询相关资料。不过在大多数回归模型中,我们完全可以不考虑这个参数。
R-squared:决定系数,其值=SSR/SST,SSR是Sum of Squares for Regression,SST是Sum of Squares for Total,这个值范围在[0, 1],其值越接近1,说明回归效果越好。
Adj. R-squared:利用奥卡姆剃刀原理,对R-squared进行修正,内容有些复杂,具体方法可自行查询。
F-statistic:这就是我们经常用到的F检验,这个值越大越能推翻原假设,本例中其值为156.9,这个值过大,说明我们的模型是线性模型,原假设是“我们的模型不是线性模型”。
Prob (F-statistic):这就是上面F-statistic的概率,这个值越小越能拒绝原假设,本例中为1.25e-08,该值非常小了,足以证明我们的模型是线性显著的。
Log likelihood:对数似然。对数函数和似然函数具有同一个最大值点。取对数是为了方便计算极大似然估计,通常先取对数再求导,找到极值点。这个参数很少使用,可以不考虑。
AIC:其用来衡量拟合的好坏程度,一般选择AIC较小的模型,其原理比较复杂,可以咨询查找资料。该参数一般不使用。
BIC:贝叶斯信息准则,其比AIC在大数据量时,对模型参数惩罚得更多,所以BIC更倾向于选择参数少的简单模型。该参数一般不使用。
coef:指自变量和常数项的系数,我们的方程系数。
std err:系数估计的标准误差。
t:就是我们常用的t统计量,这个值越大越能拒绝原假设。
P>|t|:统计检验中的P值,这个值越小越能拒绝原假设。
[0.025, 0.975]:这个是置信度为95%的置信区间的下限和上限。
Omnibus:基于峰度和偏度进行数据正态性的检验,其常和Jarque-Bera检验一起使用。
Prob(Omnibus):上述检验的概率。
Durbin-Watson:检验残差中是否存在自相关,其主要通过确定两个相邻误差项的相关性是否为零来检验回归残差是否存在自相关。
Skewness:偏度
Kurtosis:峰度
Jarque-Bera(JB):同样是基于峰度和偏度进行数据正态性的检验。
Prob(JB):JB检验的概率。
Cond. No.:多重共线性的检验,即检验变量之间是否存在精确相关关系或高度相关关系。
在进行回归分析时,重点考虑的参数有R-squared、Prob(F-statistic)以及P>|t|的两个值,这4个参数是判断我们的模型是否是线性显著的,同时知道显著的程度如何。
#####################################################################################################################################################################
2020.12.15继续更新
#####################################################################################################################################################################
最后我们考虑数据的可视化
干货满满,翠花上酸菜~
N = 20 # 等差数列的个数,个人感觉太多,速度慢,效果和20~30差不多。
xmar = np.linspace(min(groupL1.x), max(groupL1.x), N) # 建立等差数列(最大,最小值之间)
ymar = np.linspace(min(groupL1.y), max(groupL1.y), N) # 建立等差数列(最大,最小值之间)
X, Y = np.meshgrid(xmar, ymar) # 建立网格
df_grid = pd.DataFrame({'x': X.flatten(), 'y': Y.flatten()}) #X,Y降维,按x和y进行重组
Z = est.predict(df_grid) #预测Z
fig = plt.figure(figsize=(10, 8), dpi=90)
ax = fig.gca(projection='3d')
ax.view_init(azim=60, elev=20)
ax.grid(False)
ax.xaxis._axinfo['tick']['outward_factor'] = 0
ax.xaxis._axinfo['tick']['inward_factor'] = 0.4
ax.yaxis._axinfo['tick']['outward_factor'] = 0
ax.yaxis._axinfo['tick']['inward_factor'] = 0.4
ax.zaxis._axinfo['tick']['outward_factor'] = 0
ax.zaxis._axinfo['tick']['inward_factor'] = 0.4
ax.xaxis.pane.fill = False
ax.yaxis.pane.fill = False
ax.zaxis.pane.fill = False
ax.xaxis.pane.set_edgecolor('k')
ax.yaxis.pane.set_edgecolor('k')
ax.zaxis.pane.set_edgecolor('k')
p = ax.plot_surface(X, Y, Z.values.reshape(N, N), rstride=1, cstride=1, cmap='Spectral_r', alpha=1, edgecolor='k', linewidth=0.25)
ax.set_xlabel("current(A)")
ax.set_ylabel("voltage(mV)")
ax.set_zlabel("temperature(K)")
cbar = fig.colorbar(p, shrink=0.5, aspect=10)
cbar.set_label("temperature(K)")
plt.show()
来张美图~
#####################################################################################################################################################################