LASSO推导及其在恒星光谱上的应用
LASSO推导及其在恒星光谱上的应用
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
import numpy as np
import scipy.io as sio
import pandas as pd
import matplotlib.pyplot as plt
def Lasso_first_derivatives(X,Y,W):
    '''
    Return the value of the first derivatives of f when the argument is X, Y, W.
    Parameters
    ----------
    X : numpy.array
        The amount of rows is the amount of the features.
        The amount of columns is the amount of the samples.
    Y : numpy.array
        The labels of samples.
        Y.shape = [ 1, samples ]
    W : numpy.array
        The weights in the linear fiting.
        W.shape = [ features, 1 ]
    Returns
    -------
    The value of the first derivatives of f when the argument is X, Y, W. 
    In the shape of [ 1, samples ].
    '''
    Y_minus_WTX = Y - W.T * X
    return 2 * np.sum(Y_minus_WTX * X , axis=1)
def Lasso_second_derivative( X ):
    '''
    Return the value of the second derivatives of f when the argument is X.
    Parameters
    ----------
    X : numpy.array
        The amount of rows is the amount of the samples.
        The amount of columns is the amount of the features.
    Returns
    -------
    The value of the second derivatives of f when the argument is X. 
    The value is a floating number. 
    '''
    v = []
    for i in range( X.shape[ 0 ] ):
        v.append( np.dot( X[ i ], X[ i ] ) )
    return np.sum( np.array( v ) )
def get_L( X ):
    '''
    Return L in the theory.
    Parameters
    ----------
    X : numpy.array
        The amount of rows is the amount of the samples.
        The amount of columns is the amount of the features.
    Returns
    -------
    L = 0.5 * Lasso_second_derivative( X )
    The value is a floating number.
    '''
    return 0.5 * Lasso_second_derivative( X )
def get_z( W, L, X, Y ):
    '''
    Return z in the theory.
    Parameters
    ----------
    X : numpy.array
        The amount of rows is the amount of the samples.
        The amount of columns is the amount of the features.
    Returns
    -------
    z = W - Lasso_first_derivatives( X.T, Y, W ) / L
    The result is a vector in the shape of [ 1, features ].
    '''
    return W - Lasso_first_derivatives( X.T, Y, W ) / L
def load_data():
    sc_train = sio.loadmat('SpectralClassificationTrain.mat')
    sc_test = sio.loadmat('SpectralClassificationTest.mat')
    X = np.array( pd.DataFrame( sc_train['train_x'] ) )
    Y = sc_train['train_y'][:,0]
    X_test = np.array( pd.DataFrame( sc_test['test_x'] ) )
    Y_test = sc_test['test_y'][:,0]
    return X,Y,X_test,Y_test
def get_W(W,L,lambd,z,flag):
    j = 0
    f0 = 0
    while True:
        for i in range( d ):
            if abs( z[ 0, i ] ) > flag:
                W[ 0, i ] = z[ 0, i ] - flag
            else:
                W[ 0, i ] = 0
        f = np.sum( W == 0 )
        if f0 == f:
            j += 1
        # If the amount of 0 in W is unchanged in 20 iterations,then stop the looping.
        if j == 20: 
            break
        else:
            f0 = f
            z = get_z( W, L, X, Y )
    print 'W.dimension:', np.sum( W == 0 )
    return W
X,Y,X_test,Y_test = load_data()
num, d = X.shape
W = np.random.random( [ 1, d ] )
L = get_L( X )
lambd = 2
z = get_z( W, L, X, Y )
flag = lambd / L
W = get_W(W,L,lambd,z,flag) 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号