python3 偏最小二乘法實現


python3的sklearn庫中有偏最小二乘法。

可以參見下面的庫說明:http://scikit-learn.org/stable/modules/generated/sklearn.cross_decomposition.PLSRegression.html

 

 對下面的程序進行改寫,可以在python3中運行了

程序來源:來源:https://blog.csdn.net/li_huifei/article/details/78467689 經過修改可以在python3上運行

我的數據A.csv

我的數據RON.csv

 

 

# -*- coding: utf-8 -*-

#看來這個程序適合的是python2版本的。來源:https://blog.csdn.net/li_huifei/article/details/78467689
#這個目前也可以用了,主要還是在第60行的數據轉換,,,不太清楚怎樣去做裝換。主要是因為數據類型不清楚,所以用了最笨的方法,不知道結果正不正確。????【這個是錯誤的】
#PLSR3經過摸索,第68行,還是因為數據結構類型不對,之后把array類型的數組轉換成了list,,,這樣方便在外面套一個[],,之后運行沒有問題,但是結果的正確與否,還有待驗證。



#導入庫的部分
import csv
from sklearn import preprocessing
from sklearn.cross_validation import train_test_split
from sklearn.decomposition import RandomizedPCA
from sklearn.cross_decomposition import PLSRegression   #偏最小二乘法的實現,  在這里是可以跳進 PLSRegression 里面的
import numpy as np
import math
import matplotlib.pyplot as plt
 


#導入數據的部分
A = np.loadtxt('A.csv',delimiter=',')                   #讀入數據   這里的A就是y的矩陣   #讀了這么多的數據???哪個是x,,哪個又是y呢???
print (A.shape)

RON = np.loadtxt('RON.csv',delimiter=',')               #這里的RON就是x的矩陣
print (RON.shape)

 

#暫且在這里設置全局變量吧。
x_train_st_i=[]




#定義全局函數的部分。
def error(y_predict,y_test):                            #定義計算誤差平方和函數,,,傳入的是估算出的值,和測試值,,這里僅僅是用來定義的,方便后面的調用。
    errs = []
    for i in range(len(y_predict)):
        e = (y_predict[i]-y_test[i])**2
        errs.append(e)
    return sum(errs)
 
    


#偏最小二乘法的實現部分。
x_train, x_test, y_train, y_test = train_test_split(RON,A,test_size=0.5)       #划分訓練集測試集,,,這個是一個庫函數?? ,,,,這里能夠看出是A和RON進行建模的。
x_train_st = preprocessing.scale(x_train)                                      #數據標准化,這個是內置函數
y_train_st = preprocessing.scale(y_train)                                      #數據標准化,,這一句是我仿照上面的一句改寫的。
n_components = 0                                                               #這個應該是保存主成分的個數。
 
while n_components<x_train_st.shape[1]:
    n_components=n_components+1                                                #在第一遍的時候n_components是1,第二遍循環的時候是2,,,第n遍循環是n,,最大是x的列數,也就是特征的個數,
    pls2 = PLSRegression(n_components=n_components)                            #計算SS (SS這個是全建模 , PRESS是減去一個進行建模,,,,在python里建模很簡單,設置好參數,調用一下函數就能建模了)
                                                                               #這個不是偏最小二乘法嗎???,,這里是循環計算主成分的個數,直到達到滿意的精度。
    pls2.fit(x_train_st, y_train)                                              #fit也是一個函數,,,兩個參數,第一個參數是訓練集,第二個參數是目標。
    y_predict0 = pls2.predict(x_train_st)                                      #predict也是一個內置的函數,,,,這個是不是用建好的模型去做預測,,,,把參數訓練集輸入進去,得到的是預測的值。
    SS = error(y_predict0,y_train)                                             #這里是預測的值和真正的值之間的誤差大小。
    y_predict1 = []                                                            #這是創建了一個新的變量。根據名字的意思,根據模型得到的y的預測值,實際上這個模型是留一法建立的模型。
    for i in range(x_train_st.shape[0]):                                       #計算PRESS,,,,這個是x_train_st的行數
        n_components1 = n_components                                           #但是我不明白,為什么這里還要加1,主成分不可能是0個吧,所以就從1開始了。
        x_train_st1 = np.delete(x_train_st,i,0)                                #這里的0是行,1是列,,這個應該是刪除第i行,,,這里是標准化的數組。留一法的實現
        y_train_st1 = np.delete(y_train,i,0)                                   #這個也是刪除第i行,這里都是經過標准化的(但這個x是經過標准化的,y卻沒有用標准化的數據)。,,這個沒有用到過,是不是這里寫錯了??
        pls2 = PLSRegression(n_components=n_components1)                       #偏最小二乘法參數的設置,,,這里面一般有5個參數,,但這里只傳入了主成分的個數。
        #參數1:n_components:int ,(default 2) ,,要保留的主成分數量,默認為2
        #參數2:scale:boolean,(default True),,是否歸一化數據,默認為是
        #參數3:max_iter: an integer,(default 500),,使用NIPALS時的最大迭代次數
        #參數4:tol: non-negative real(default 1e-06),,迭代截止條件
        #參數5:copy: Boolean,(default True),,
        pls2.fit(x_train_st1, y_train_st1)                                     #這里是根據前面設置好的參數建模過程,這里的建模過程是不是不太對(這里x是歸一化的,y並沒有用歸一化的),應該都是用歸一化的才行呀。???
        
        
        
        #這里主要是進行了數據格式的轉換,因為做預測要傳進的是矩陣【格式很重要】
        x_train_st_i=[]                                                        #用之前要進行清空,這個很重要。用一個參數之前要進行清空。
        x_train_st_list=x_train_st[i].tolist()
        x_train_st_i.append(x_train_st_list)


        print ('the x_train_st is ',x_train_st_i)                              #輸出一下變量,查看格式是否正確,因為下面的predict函數需要用[[1,1,1,1,1,1]] 這種格式的數據
        
        
        
        
        
        y_predict11 = pls2.predict(x_train_st_i)                               #預測函數,給定之前留一法沒有用到的樣本,進行建模,預測對應的y值。????可是已經刪除了不是嗎???           ZHE這句出了一點問題????就是數據格式有問題,需要在最外面在加一個[]
                                 
        
        
        
        y_predict1.append(y_predict11)                                         #把所有的y值組成一個數組,便於計算誤差。,這個也是y的預測值,用它來算出另一個誤差。
    PRESS = error(y_predict1,y_train)                                          #可能錯誤:https://blog.csdn.net/little_bobo/article/details/78861578
    Qh = 1-float(PRESS/SS)
    if Qh<0.0985:                                                              #判斷精度                           模型達到精度要求,可以停止主成分的提取了。
        plt.figure(1)
        plt.scatter(y_predict0,y_train)                                        #畫了一個圖,這個圖是預測值,與測量值的圖???
        plt.figure(2)
        plt.scatter(y_predict1,y_train)
        print ('the Qh is ',Qh)
        print ('the PRESS is',PRESS)
        print ('the SS is',SS)
        break                                                                  #達到了上面的精度,就可以停止while的迭代了
        
        
                                                                               #這下面就沒有看懂了。
 
print ('n_components is ',n_components+1)                                      #這里為什么要加1???,,,難道因為計數是從0開始的??
SECs = []
errors = []
e = 100
for i in range(10):                                                            #循環測試
    #print i 
    x_train, x_test, y_train, y_test = train_test_split( RON,A, test_size=0.5)  #划分訓練集與測試集,這個是一個內置的函數。
    x_test_st = preprocessing.scale(x_test)                                     #數據標准化
    y_predict = pls2.predict(x_test_st)                                         #進行預測
    SECs.append(np.sqrt(error(y_predict,y_test)/(y_test.shape[0]-1)))            
    errors.append(float(error(y_predict,y_test)))
    if SECs[-1]<e:
        y_predict_min = y_predict
        y_test_min = y_test
        
print ('the prediced value is ' ,y_predict.T)                                    #畫圖,打印結果
print ('the true value is',y_test)
print ('the mean error is',float(np.mean(errors)))
print ("the mean SEC is ",float(np.mean(SECs)))
 
plt.figure(3)
plt.scatter(y_predict_min,y_test_min)

 

摘自:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM