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)