無(wú)信息變量選擇(UVE)波長(zhǎng)篩選算法--基于OpenSA開(kāi)源庫(kù)實(shí)現(xiàn)

系列文章目錄

“光晰本質(zhì),譜見(jiàn)不同”,光譜作為物質(zhì)的指紋,被廣泛應(yīng)用于成分分析中。伴隨微型光譜儀/光譜成像儀的發(fā)展與普及,基于光譜的分析技術(shù)將不只停留于工業(yè)和實(shí)驗(yàn)室,即將走入生活,實(shí)現(xiàn)萬(wàn)物感知,見(jiàn)微知著。本系列文章致力于光譜分析技術(shù)的科普和應(yīng)用

前言

典型的光譜分析模型(以近紅外光譜作為示意,可見(jiàn)光、中遠(yuǎn)紅外、熒光、拉曼、高光譜等分析流程亦相似)建立流程如下所示,在建立過(guò)程中,需要使用算法對(duì)訓(xùn)練樣本進(jìn)行選擇,然后使用預(yù)處理算法對(duì)光譜進(jìn)行預(yù)處理,或?qū)庾V的特征進(jìn)行提取,再構(gòu)建校正模型實(shí)現(xiàn)定量分析,最后針對(duì)不同測(cè)量?jī)x器或環(huán)境,進(jìn)行模型轉(zhuǎn)移或傳遞。因此訓(xùn)練樣本的選擇、光譜的預(yù)處理、波長(zhǎng)篩選、校正模型、模型傳遞以及上述算法的參數(shù)都影響著模型的應(yīng)用效果。


建模流程.jpg

針對(duì)光譜分析流程所涉及的常見(jiàn)的訓(xùn)練樣本的劃分、光譜的預(yù)處理、波長(zhǎng)篩選、校正模型算法建立了完整的算法庫(kù),名為OpenSA(OpenSpectrumAnalysis)。整套算法庫(kù)的架構(gòu)如下所示。


OpenSA.jpg

樣本劃分模塊提供隨機(jī)劃分、SPXY劃分、KS劃分三種數(shù)據(jù)集劃分方法,光譜預(yù)處理模塊提供常見(jiàn)光譜預(yù)處理,波長(zhǎng)篩選模塊提供Spa、Cars、Lars、Uve、Pca等特征降維方法,分析模塊由光譜相似度計(jì)算、聚類、分類(定性分析)、回歸(定量分析)構(gòu)建,光譜相似度子模塊計(jì)算提供SAM、SID、MSSIM、MPSNR等相似計(jì)算方法,聚類子模塊提供KMeans、FCM等聚類方法,分類子模塊提供ANN、SVM、PLS_DA、RF等經(jīng)典化學(xué)計(jì)量學(xué)方法,亦提供CNN、AE、Transformer等前沿深度學(xué)習(xí)方法,回歸子模塊提供ANN、SVR、PLS等經(jīng)典化學(xué)計(jì)量學(xué)定量分析方法,亦提供CNN、AE、Transformer等前沿深度學(xué)習(xí)定量分析方法。模型評(píng)估模塊提供常見(jiàn)的評(píng)價(jià)指標(biāo),用于模型評(píng)估。自動(dòng)參數(shù)優(yōu)化模塊用于自動(dòng)進(jìn)行最佳的模型設(shè)置參數(shù)尋找,提供網(wǎng)格搜索、遺傳算法、貝葉斯概率三種最優(yōu)參數(shù)尋找方法。可視化模塊提供全程的分析可視化,可為科研繪圖,模型選擇提供視覺(jué)信息??赏ㄟ^(guò)幾行代碼快速實(shí)現(xiàn)完整的光譜分析及應(yīng)用(注: 自動(dòng)參數(shù)優(yōu)化模塊和可視化模塊暫不開(kāi)源,等畢業(yè)后再說(shuō))
本篇針對(duì)OpenSA的光譜波長(zhǎng)篩選模塊進(jìn)行代碼開(kāi)源和使用示意。

一、光譜數(shù)據(jù)讀入

提供兩個(gè)開(kāi)源數(shù)據(jù)作為實(shí)列,一個(gè)為公開(kāi)定量分析數(shù)據(jù)集,一個(gè)為公開(kāi)定性分析數(shù)據(jù)集,本章僅以公開(kāi)定量分析數(shù)據(jù)集作為演示。

1.1 光譜數(shù)據(jù)讀入

# 分別使用一個(gè)回歸、一個(gè)分類的公開(kāi)數(shù)據(jù)集做為example
def LoadNirtest(type):

    if type == "Rgs":
        CDataPath1 = './/Data//Rgs//Cdata1.csv'
        VDataPath1 = './/Data//Rgs//Vdata1.csv'
        TDataPath1 = './/Data//Rgs//Tdata1.csv'

        Cdata1 = np.loadtxt(open(CDataPath1, 'rb'), dtype=np.float64, delimiter=',', skiprows=0)
        Vdata1 = np.loadtxt(open(VDataPath1, 'rb'), dtype=np.float64, delimiter=',', skiprows=0)
        Tdata1 = np.loadtxt(open(TDataPath1, 'rb'), dtype=np.float64, delimiter=',', skiprows=0)

        Nirdata1 = np.concatenate((Cdata1, Vdata1))
        Nirdata = np.concatenate((Nirdata1, Tdata1))
        data = Nirdata[:, :-4]
        label = Nirdata[:, -1]

    elif type == "Cls":
        path = './/Data//Cls//table.csv'
        Nirdata = np.loadtxt(open(path, 'rb'), dtype=np.float64, delimiter=',', skiprows=0)
        data = Nirdata[:, :-1]
        label = Nirdata[:, -1]

    return data, label

1.2 光譜可視化

    #載入原始數(shù)據(jù)并可視化
    data, label = LoadNirtest('Rgs')
    plotspc(data, "raw specturm")

采用的開(kāi)源光譜如圖所示:


image.png

二、光譜波長(zhǎng)篩選

2.1 光譜預(yù)處理模塊

提供常見(jiàn)的UVE、Cars、SPA、LARS、PCA等波長(zhǎng)篩選算法,并進(jìn)行了相應(yīng)的封裝,使用者僅需要改變名字,即可選擇對(duì)應(yīng)的光譜波長(zhǎng)篩選算法,滿足論文快速?gòu)?fù)現(xiàn)、算法快速建模,下面是光譜篩選模塊的核心代碼
第一種波長(zhǎng)篩選算法,無(wú)信息變量選擇算法(UVE)

class UVE:
    def __init__(self, x, y, ncomp=1, nrep=500, testSize=0.2):

        '''
        X : 預(yù)測(cè)變量矩陣
        y :標(biāo)簽
        ncomp : 結(jié)果包含的變量個(gè)數(shù)
        testSize: PLS中劃分的數(shù)據(jù)集
        return :波長(zhǎng)篩選后的光譜數(shù)據(jù)
        '''

        self.x = x
        self.y = y
        # The number of latent components should not be larger than any dimension size of independent matrix
        self.ncomp = min([ncomp, rank(x)])
        self.nrep = nrep
        self.testSize = testSize
        self.criteria = None

        self.featureIndex = None
        self.featureR2 = np.full(self.x.shape[1], np.nan)
        self.selFeature = None

    def calcCriteria(self):
        PLSCoef = np.zeros((self.nrep, self.x.shape[1]))
        ss = ShuffleSplit(n_splits=self.nrep, test_size=self.testSize)
        step = 0
        for train, test in ss.split(self.x, self.y):
            xtrain = self.x[train, :]
            ytrain = self.y[train]
            plsModel = PLSRegression(min([self.ncomp, rank(xtrain)]))
            plsModel.fit(xtrain, ytrain)
            PLSCoef[step, :] = plsModel.coef_.T
            step += 1
        meanCoef = np.mean(PLSCoef, axis=0)
        stdCoef = np.std(PLSCoef, axis=0)
        self.criteria = meanCoef / stdCoef

    def evalCriteria(self, cv=3):
        self.featureIndex = np.argsort(-np.abs(self.criteria))
        for i in range(self.x.shape[1]):
            xi = self.x[:, self.featureIndex[:i + 1]]
            if i<self.ncomp:
                regModel = LinearRegression()
            else:
                regModel = PLSRegression(min([self.ncomp, rank(xi)]))

            cvScore = cross_val_score(regModel, xi, self.y, cv=cv)
            self.featureR2[i] = np.mean(cvScore)

    def cutFeature(self, *args):
        cuti = np.argmax(self.featureR2)
        self.selFeature = self.featureIndex[:cuti+1]
        if len(args) != 0:
            returnx = list(args)
            i = 0
            for argi in args:
                if argi.shape[1] == self.x.shape[1]:
                    returnx[i] = argi[:, self.selFeature]
                i += 1
        return returnx

def SpctrumFeatureSelcet(method, X, y):
    """
       :param method: 波長(zhǎng)篩選/降維的方法,包括:Cars, Lars, Uve, Spa, Pca
       :param X: 光譜數(shù)據(jù), shape (n_samples, n_features)
       :param y: 光譜數(shù)據(jù)對(duì)應(yīng)標(biāo)簽:格式:(n_samples,)
       :return: X_Feature: 波長(zhǎng)篩選/降維后的數(shù)據(jù), shape (n_samples, n_features)
                y:光譜數(shù)據(jù)對(duì)應(yīng)的標(biāo)簽, (n_samples,)
    """
    if method == "None":
        X_Feature = X
    if method== "Cars":
        Featuresecletidx = CARS_Cloud(X, y)
        X_Feature = X[:, Featuresecletidx]
    elif method == "Lars":
        Featuresecletidx = Lar(X, y)
        X_Feature = X[:, Featuresecletidx]
    elif method == "Uve":
        Uve = UVE(X, y, 7)
        Uve.calcCriteria()
        Uve.evalCriteria(cv=5)
        Featuresecletidx = Uve.cutFeature(X)
        X_Feature = Featuresecletidx[0]
    elif method == "Spa":
        Xcal, Xval, ycal, yval = train_test_split(X, y, test_size=0.2)
        Featuresecletidx = SPA().spa(
            Xcal= Xcal, ycal=ycal, m_min=8, m_max=50, Xval=Xval, yval=yval, autoscaling=1)
        X_Feature = X[:, Featuresecletidx]
    elif method == "Pca":
        X_Feature = Pca(X)
    else:
        print("no this method of SpctrumFeatureSelcet!")

    return X_Feature, y

2 .2 光譜波長(zhǎng)篩選的使用

在example.py文件中,提供了光譜波長(zhǎng)篩選模塊的使用方法,具體如下,僅需要兩行代碼即可實(shí)現(xiàn)所有常見(jiàn)的光譜預(yù)處理。
示意:利用OpenSA實(shí)現(xiàn)UVE無(wú)信息變量選擇進(jìn)行波長(zhǎng)篩選

 #載入原始數(shù)據(jù)并可視化
   #載入原始數(shù)據(jù)并可視化
    data, label = LoadNirtest('Rgs')
    plotspc(data, "raw specturm")
    # #波長(zhǎng)特征篩選并可視化
    SpectruSelected, y = SpctrumFeatureSelcet('Uve', data, label)

可以看到通過(guò)OpenSA一行代碼,原始波長(zhǎng)655個(gè)維度,經(jīng)過(guò)Uve波長(zhǎng)篩選后后,得到了70個(gè)關(guān)鍵數(shù)據(jù)點(diǎn)(相關(guān)篩選波長(zhǎng)維度可以通過(guò)改變Uve對(duì)應(yīng)參數(shù)修改)


1649905849(1).png

總結(jié)

利用OpenSA可以非常簡(jiǎn)單的實(shí)現(xiàn)對(duì)光譜的預(yù)處理,完整代碼可從獲得GitHub倉(cāng)庫(kù) 如果對(duì)您有用,請(qǐng)點(diǎn)贊!
代碼現(xiàn)僅供學(xué)術(shù)使用,若對(duì)您的學(xué)術(shù)研究有幫助,請(qǐng)引用本人的論文,同時(shí),未經(jīng)許可不得用于商業(yè)化應(yīng)用,歡迎大家繼續(xù)補(bǔ)充OpenSA中所涉及到的算法,如有問(wèn)題,微信:Fu_siry

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容