数据挖掘:降低汽油精制过程中的辛烷值损失模型(一)
目錄
一、背景
二、目標(biāo)
三、問題
四、數(shù)據(jù)預(yù)處理
4.1 先開始285數(shù)據(jù)的處理:?
4.2 附件313數(shù)據(jù)的處理:
?4.3附件一的處理:
?4.4 拉以達(dá)準(zhǔn)則
?4.5 缺失值的處理
題目文件:
鏈接: https://pan.baidu.com/s/1nuLPVPcZ7Ess8HCpbtC75Q 提取碼: t9s7?
一、背景
汽油是小型車輛的主要燃料,汽油燃燒產(chǎn)生的尾氣排放對(duì)大氣環(huán)境有重要影響。為此,世界各國都制定了日益嚴(yán)格的汽油質(zhì)量標(biāo)準(zhǔn)(見下表)。汽油清潔化重點(diǎn)是降低汽油中的硫、烯烴含量,同時(shí)盡量保持其辛烷值。
歐盟和我國車用汽油主要規(guī)格
| 車用汽油標(biāo)準(zhǔn) | 辛烷值 | 硫含量/(μg/g) ≯ | 苯含量/% ≯ | 芳烴含量/% ≯ | 烯烴含量/% ≯ | |
| 國Ⅲ(2010年) | 90-97 | 150 | 1 | 40 | 30 | |
| 國Ⅳ(2014年) | 90-97 | 50 | 1 | 40 | 28 | |
| 國Ⅴ(2017年) | 89-95 | 10 | 1 | 40 | 24 | |
| 國Ⅵ-A(2019年) | 89-95 | 10 | 0.8 | 35 | 18 | |
| 國Ⅵ-B(2023年) | 89-95 | 10 | 0.8 | 35 | 15 | |
| 歐Ⅴ(2009年) | 95 | 10 | 1 | 35 | 18 | |
| 歐VI(2013年) | 95 | 10 | 1 | 35 | 18 | |
| 世界燃油規(guī)范(Ⅴ類汽油) | 95 | 10 | 1 | 35 | 10 |
注: μg/g是一個(gè)濃度單位,也有用mg/kg或ppm表示的(以下同)
我國原油對(duì)外依存度超過70%,且大部分是中東地區(qū)的含硫和高硫原油。原油中的重油通常占比40-60%,這部分重油(以硫?yàn)榇淼碾s質(zhì)含量也高)難以直接利用。為了有效利用重油資源,我國大力發(fā)展了以催化裂化為核心的重油輕質(zhì)化工藝技術(shù),將重油轉(zhuǎn)化為汽油、柴油和低碳烯烴,超過70%的汽油是由催化裂化生產(chǎn)得到,因此成品汽油中95%以上的硫和烯烴來自催化裂化汽油。故必須對(duì)催化裂化汽油進(jìn)行精制處理,以滿足對(duì)汽油質(zhì)量要求。
辛烷值(以RON表示)是反映汽油燃燒性能的最重要指標(biāo),并作為汽油的商品牌號(hào)(例如89#、92#、95#)。現(xiàn)有技術(shù)在對(duì)催化裂化汽油進(jìn)行脫硫和降烯烴過程中,普遍降低了汽油辛烷值。辛烷值每降低1個(gè)單位,相當(dāng)于損失約150元/噸。以一個(gè)100萬噸/年催化裂化汽油精制裝置為例,若能降低RON損失0.3個(gè)單位,其經(jīng)濟(jì)效益將達(dá)到四千五百萬元。
化工過程的建模一般是通過數(shù)據(jù)關(guān)聯(lián)或機(jī)理建模的方法來實(shí)現(xiàn)的,取得了一定的成果。但是由于煉油工藝過程的復(fù)雜性以及設(shè)備的多樣性,它們的操作變量(控制變量)之間具有高度非線性和相互強(qiáng)耦聯(lián)的關(guān)系,而且傳統(tǒng)的數(shù)據(jù)關(guān)聯(lián)模型中變量相對(duì)較少、機(jī)理建模對(duì)原料的分析要求較高,對(duì)過程優(yōu)化的響應(yīng)不及時(shí),所以效果并不理想。
某石化企業(yè)的催化裂化汽油精制脫硫裝置運(yùn)行4年,積累了大量歷史數(shù)據(jù),其汽油產(chǎn)品辛烷值損失平均為1.37個(gè)單位,而同類裝置的最小損失值只有0.6個(gè)單位。故有較大的優(yōu)化空間。請(qǐng)參賽研究生探索利用數(shù)據(jù)挖掘技術(shù)來解決化工過程建模問題。
二、目標(biāo)
依據(jù)從催化裂化汽油精制裝置采集的325個(gè)數(shù)據(jù)樣本(每個(gè)數(shù)據(jù)樣本都有354個(gè)操作變量),通過數(shù)據(jù)挖掘技術(shù)來建立汽油辛烷值(RON)損失的預(yù)測模型,并給出每個(gè)樣本的優(yōu)化操作條件,在保證汽油產(chǎn)品脫硫效果(歐六和國六標(biāo)準(zhǔn)均為不大于10μg/g,但為了給企業(yè)裝置操作留有空間,本次建模要求產(chǎn)品硫含量不大于5μg/g)的前提下,盡量降低汽油辛烷值損失在30%以上。
三、問題
1. 數(shù)據(jù)處理:請(qǐng)參考近4年的工業(yè)數(shù)據(jù)(見附件一“325個(gè)數(shù)據(jù)樣本數(shù)據(jù).xlsx”)的預(yù)處理結(jié)果,依“樣本確定方法”(附件二)對(duì)285號(hào)和313號(hào)數(shù)據(jù)樣本進(jìn)行預(yù)處理(原始數(shù)據(jù)見附件三“285號(hào)和313號(hào)樣本原始數(shù)據(jù).xlsx”)并將處理后的數(shù)據(jù)分別加入到附件一中相應(yīng)的樣本號(hào)中,供下面研究使用。
2. 尋找建模主要變量:
由于催化裂化汽油精制過程是連續(xù)的,雖然操作變量每3 分鐘就采樣一次,但辛烷值(因變量)的測量比較麻煩,一周僅2次無法對(duì)應(yīng)。但根據(jù)實(shí)際情況可以認(rèn)為辛烷值的測量值是測量時(shí)刻前兩小時(shí)內(nèi)操作變量的綜合效果,因此預(yù)處理中取操作變量兩小時(shí)內(nèi)的平均值與辛烷值的測量值對(duì)應(yīng)。這樣產(chǎn)生了325個(gè)樣本(見附件一)。
建立降低辛烷值損失模型涉及包括7個(gè)原料性質(zhì)、2個(gè)待生吸附劑性質(zhì)、2個(gè)再生吸附劑性質(zhì)、2個(gè)產(chǎn)品性質(zhì)等變量以及另外354個(gè)操作變量(共計(jì)367個(gè)變量),工程技術(shù)應(yīng)用中經(jīng)常使用先降維后建模的方法,這有利于忽略次要因素,發(fā)現(xiàn)并分析影響模型的主要變量與因素。因此,請(qǐng)你們根據(jù)提供的325個(gè)樣本數(shù)據(jù)(見附件一),通過降維的方法從367個(gè)操作變量中篩選出建模主要變量,使之盡可能具有代表性、獨(dú)立性(為了工程應(yīng)用方便,建議降維后的主要變量在30個(gè)以下),并請(qǐng)?jiān)敿?xì)說明建模主要變量的篩選過程及其合理性。(提示:請(qǐng)考慮將原料的辛烷值作為建模變量之一)。
3. 建立辛烷值(RON)損失預(yù)測模型:采用上述樣本和建模主要變量,通過數(shù)據(jù)挖掘技術(shù)建立辛烷值(RON)損失預(yù)測模型,并進(jìn)行模型驗(yàn)證。
4. 主要變量操作方案的優(yōu)化:要求在保證產(chǎn)品硫含量不大于5μg/g的前提下,利用你們的模型獲得325個(gè)數(shù)據(jù)樣本(見附件四“325個(gè)數(shù)據(jù)樣本數(shù)據(jù).xlsx”)中,辛烷值(RON)損失降幅大于30%的樣本對(duì)應(yīng)的主要變量優(yōu)化后的操作條件(優(yōu)化過程中原料、待生吸附劑、再生吸附劑的性質(zhì)保持不變,以它們?cè)跇颖局械臄?shù)據(jù)為準(zhǔn))。
5. 模型的可視化展示:工業(yè)裝置為了平穩(wěn)生產(chǎn),優(yōu)化后的主要操作變量(即:問題2中的主要變量)往往只能逐步調(diào)整到位,請(qǐng)你們對(duì)133號(hào)樣本(原料性質(zhì)、待生吸附劑和再生吸附劑的性質(zhì)數(shù)據(jù)保持不變,以樣本中的數(shù)據(jù)為準(zhǔn)),以圖形展示其主要操作變量優(yōu)化調(diào)整過程中對(duì)應(yīng)的汽油辛烷值和硫含量的變化軌跡。(各主要操作變量每次允許調(diào)整幅度值Δ見附件四“354個(gè)操作變量信息.xlsx”)。
四、數(shù)據(jù)預(yù)處理
數(shù)據(jù)處理方法如下:
(1)對(duì)于只含有部分時(shí)間點(diǎn)的位點(diǎn),如果其殘缺數(shù)據(jù)較多,無法補(bǔ)充,將此類位點(diǎn)刪除;
(2)刪除325個(gè)樣本中數(shù)據(jù)全部為空值的位點(diǎn);
(3)對(duì)于部分?jǐn)?shù)據(jù)為空值的位點(diǎn),空值處用其前后兩個(gè)小時(shí)數(shù)據(jù)的平均值代替;
(4)根據(jù)工藝要求與操作經(jīng)驗(yàn),總結(jié)出原始數(shù)據(jù)變量的操作范圍,然后采用最大最小的限幅方法剔除一部分不在此范圍的樣本;
(5)根據(jù)拉依達(dá)準(zhǔn)則(3σ準(zhǔn)則)去除異常值。
圖源于:?http://t.csdn.cn/Ok3d1
4.1 先開始285數(shù)據(jù)的處理:?
import numpy as np import pandas as pd data=pd.read_excel('附件三:285號(hào)和313號(hào)樣本原始數(shù)據(jù).xlsx',sheet_name='操作變量285') data?
查看第一列的時(shí)間:?
times=data.iloc[:,0] times這里發(fā)現(xiàn)時(shí)間步的間隔都是3min,查看是否存在時(shí)間步不為3的行。
from datetime import datetime, date Seconds=[] for i in range(1,40):time_i=data.iloc[i-1,0]time_i_1=data.iloc[i,0]time_i_struct = datetime.strptime(time_i.strip(), "%Y-%m-%d %H:%M:%S")time_i_1_struct = datetime.strptime(time_i_1.strip(), "%Y-%m-%d %H:%M:%S")seconds = (time_2_struct - time_1_struct).secondsSeconds.append(seconds/60) Seconds得到結(jié)果全為3,所以不用處理了。
去除空值:經(jīng)過查找,不存在空值。?
?因?yàn)閿?shù)據(jù),必須滿足附件四中操作變量的范圍:
data_range=pd.read_excel('附件四:354個(gè)操作變量信息.xlsx') data_range.head() # 得到最大最小范圍的函數(shù)import re # 通過符號(hào)‘-’進(jìn)行分割。 def get_min_range_value(data):try:# 如果字符串的第一個(gè)字符為‘-’,說明是負(fù)數(shù)。if data[0]=='-':return -float(data.split('-')[1])else:return float(data.split('-')[0])except:print(data.split('-'))def get_max_range_value(data):if ('(' in data) or (')' in data):try:temp=re.search('\((.*?)\)',data).group(1)except:temp=re.search("((.*?))",data).group(1)return float(temp)try:return float(data.split('-')[-1])except:print(data)?添加兩列,保存最大最小值:
data_range['min_region']=data_range.apply(lambda x:get_min_range_value(x['取值范圍']),axis=1) data_range['max_region']=data_range.apply(lambda x:get_max_range_value(x['取值范圍']),axis=1) data_range data=pd.read_excel('附件三:285號(hào)和313號(hào)樣本原始數(shù)據(jù).xlsx',sheet_name='操作變量285') data data=data.iloc[:,1:] data?檢查285號(hào)樣本數(shù)據(jù)不在范圍內(nèi)的數(shù)據(jù)點(diǎn):
def check_data(data,min_values,max_values):if (data > max_values) or (data < min_values):return np.nanelse:return data查看第一列是什么 :?
names=data_range.iloc[i,1] names 'S-ZORB.CAL_H2.PV' for i in range(data_range.shape[0]):names=data_range.iloc[i,1]data_min=data_range.iloc[i,6]data_max=data_range.iloc[i,7]data[names]=data[names].apply(lambda x:check_data(x,data_min,data_max))data現(xiàn)在已經(jīng)把不在范圍內(nèi)的點(diǎn)替換成空值了。
data.isnull().sum()?
因?yàn)閿?shù)據(jù)很長,我們無法準(zhǔn)確看到究竟那一列數(shù)據(jù)空值點(diǎn),我們做一步查找:?
data.isnull().sum()[data.isnull().sum()!=0]發(fā)現(xiàn)這三列的數(shù)據(jù)有問題。
4.2 附件313數(shù)據(jù)的處理:
接下來分析313的數(shù)據(jù)。
data_1=pd.read_excel('附件三:285號(hào)和313號(hào)樣本原始數(shù)據(jù).xlsx',sheet_name='操作變量313') data_1=data_1.iloc[:,1:] data_1?同理檢查不在范圍內(nèi)的數(shù)據(jù):
def check_data(data_1,min_values,max_values):if (data_1 > max_values) or (data_1 < min_values):return np.nanelse:return data_1for j in range(data_range.shape[0]):names=data_range.iloc[j,1]data_min=data_range.iloc[j,6]data_max=data_range.iloc[j,7]data_1[names]=data_1[names].apply(lambda x:check_data(x,data_min,data_max)) data_1 data_1.isnull().sum()[data_1.isnull().sum()>0]?4.3附件一的處理:
data_325_all=pd.read_excel('附件一:325個(gè)樣本數(shù)據(jù).xlsx') data_325_all_cao_zuo=data_325_all.iloc[:,0:] data_325_all_cao_zuo先對(duì)數(shù)據(jù)進(jìn)行了簡單的處理一下。中間的是不變的。?
def check_data(data_325_all_cao_zuo,min_values,max_values):if (data_325_all_cao_zuo > max_values) or (data_325_all_cao_zuo < min_values):return np.nanelse:return data_325_all_cao_zuofor j in range(data_range.shape[0]):names=data_range.iloc[j,1]data_min=data_range.iloc[j,6]data_max=data_range.iloc[j,7]data_325_all_cao_zuo[names]=data_325_all_cao_zuo[names].apply(lambda x:check_data(x,data_min,data_max)) data_325_all_cao_zuo data_325_all_cao_zuo.isnull().sum()[data_325_all_cao_zuo.isnull().sum()>0]?
?4.4 拉以達(dá)準(zhǔn)則
def three_sigma(df_col):"""df_col:DataFrame數(shù)據(jù)的某一列"""rule = (df_col.mean() - 3 * df_col.std() > df_col) | (df_col.mean() + 3 * df_col.std() < df_col)index = np.arange(df_col.shape[0])[rule]out_range_index=[pd.DataFrame(df_col.iloc[index]).columns,pd.DataFrame(df_col.iloc[index]).shape[0]]return out_range_index # 285 out_range_285_idx=[] for i in range(data.shape[1]):df_col=data.iloc[:,i]out_range_285=three_sigma(df_col)out_range_285_idx.append(out_range_285) out_range_285_idx # 計(jì)算符合數(shù)據(jù)的個(gè)數(shù) counts=0 for m in range(len(out_range_285_idx)):if out_range_285_idx[m][1]==0:counts+=1else:counts+=0 counts354
out_range_313_idx=[] for i in range(data_1.shape[1]):df_col_1=data_1.iloc[:,i]out_range_313=three_sigma(df_col_1)out_range_313_idx.append(out_range_313) out_range_313_idx counts=0 for n in range(len(out_range_313_idx)):if out_range_313_idx[n][1]==0:counts+=1else:counts+=0 counts313
找出異常數(shù)據(jù)。
# 找出異常數(shù)據(jù)index_313=[] for k in range(354):if out_range_313_idx[k][1]!=0:index_313.append((out_range_313_idx[k][0],out_range_313_idx[k][1])) index_313處理完的數(shù)據(jù):
鏈接: https://pan.baidu.com/s/11OL6B3d3FV8oJ2aQlBK3Kg 提取碼: 8u4u
?4.5 缺失值的處理
首先計(jì)算各位點(diǎn)數(shù)據(jù)的缺失值比率。將計(jì)算值與缺失值比率的閾值(20%)相比,按照其是否超過閾值將缺失數(shù)據(jù)分為兩類:
(1)缺失值比率低的數(shù)據(jù);
(2)數(shù)據(jù)缺失值比率高的數(shù)據(jù)。
import numpy as np import pandas as pd import matplotlib.pyplot as pltdata_285=pd.read_excel('附件三:285號(hào)和313號(hào)樣本原始數(shù)據(jù).xlsx',sheet_name='操作變量285') data_285=data_285.iloc[:,1:] data_285 data_313=pd.read_excel('附件三:285號(hào)和313號(hào)樣本原始數(shù)據(jù).xlsx',sheet_name='操作變量313') data_313=data_313.iloc[:,1:] data_313?檢查不符合3σ原則的數(shù)據(jù),并標(biāo)記為空值
def three_sigma(data_input):for i in range(data_input.shape[0]):for j in range(data_input.shape[1]):mean=data_input.iloc[:,j].mean()std=data_input.iloc[:,j].std()if abs(data_input.iloc[i,j]-mean)>3*std:data_input.iloc[i,j]=np.nanelse:continuereturn data_input我們看一下313的數(shù)據(jù)集:?
data_313_2=three_sigma(data_313) data_313_2 data_313_2.isnull().sum()[data_313_2.isnull().sum()>0]?
第一列為索引位置,我們檢查一下空值的位置:?
isnull=[] for i in data_313_2.columns:for j in data_313_2.index:if data_313_2.isnull().loc[j,i]:isnull.append((j,i)) isnull,len(isnull) # 檢查一下空值的位置 第一列為索引位置?嘗試查看一個(gè):
data_313_2.loc[37,'S-ZORB.FC_2801.PV'] # 嘗試一個(gè) nan from scipy.interpolate import lagrange #傳入存在缺失值的列,缺失值所在0軸坐標(biāo)index,按前后k個(gè)數(shù)來計(jì)算拉格朗日插值,返回index的拉格朗日插值 def lag_fill(df,i,k):r=0 if (i-k)<0 else (i-k) # python的三目運(yùn)算符較為特殊l=len(df.index) if (i+1+k)>len(df.index) else (i+1+k)y=df.loc[list(range(r,i))+list(range(i+1,l))] #取index前后k個(gè)數(shù)據(jù)作為y代入拉格朗日函數(shù)進(jìn)行擬合for j in y.index:if y.isnull().loc[j]:y.drop(index=j,inplace=True)x=y.indexlag=lagrange(x.values,y.values)return lag(i) for i in isnull:fnum=lag_fill(data_313_2.loc[:,i[1]],i[0],1)data_313_2.loc[i[0],i[1]]=fnum我們檢驗(yàn)一下新數(shù)據(jù)據(jù)是否合適:?
# 用3sigma 函數(shù)在檢驗(yàn)一下 data_313_2_new=three_sigma(data_313_2) data_313_2_new data_313_2_new.isnull().sum()[data_313_2_new.isnull().sum()>0] isnull_2=[] for i in data_313_2_new.columns:for j in data_313_2_new.index:if data_313_2_new.isnull().loc[j,i]:isnull_2.append((j,i)) isnull_2,len(isnull_2) for j in isnull_2:fnum_1=lag_fill(data_313_2_new.loc[:,j[1]],j[0],1)data_313_2_new.loc[j[0],j[1]]=fnum_1再次檢查:?
data_313_2_new_2=three_sigma(data_313_2_new) data_313_2_new_2.isnull().sum()[data_313_2_new_2.isnull().sum()>0] isnull_3=[] for i in data_313_2_new_2.columns:for j in data_313_2_new_2.index:if data_313_2_new_2.isnull().loc[j,i]:isnull_3.append((j,i)) isnull_3,len(isnull_3) for m in isnull_3:fnum_2=lag_fill(data_313_2_new_2.loc[:,m[1]],m[0],1)data_313_2_new_2.loc[m[0],m[1]]=fnum_2 isnull_4=[] for i in data_313_2_new_3.columns:for j in data_313_2_new_3.index:if data_313_2_new_3.isnull().loc[j,i]:isnull_4.append((j,i)) isnull_4,len(isnull_4)?
for n in isnull_4:fnum_3=lag_fill(data_313_2_new_3.loc[:,n[1]],n[0],1)data_313_2_new_3.loc[n[0],n[1]]=fnum_3data_313_2_new_4=three_sigma(data_313_2_new_3) data_313_2_new_4.isnull().sum()[data_313_2_new_4.isnull().sum()>0]?
?至此,數(shù)據(jù)處理結(jié)束。
總結(jié)
以上是生活随笔為你收集整理的数据挖掘:降低汽油精制过程中的辛烷值损失模型(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【经典阅读】CSAPP-3.2-程序的机
- 下一篇: 【Android】灵云手写离线识别使用说