├── calculate_L.m ├── Proof of Eq.(7).png ├── Go.m ├── IPU.m ├── README.md └── SDFS.m /calculate_L.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StevenWangNPU/L20_FS_IJCAI2020/HEAD/calculate_L.m -------------------------------------------------------------------------------- /Proof of Eq.(7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StevenWangNPU/L20_FS_IJCAI2020/HEAD/Proof of Eq.(7).png -------------------------------------------------------------------------------- /Go.m: -------------------------------------------------------------------------------- 1 | % max tr(W'AW), subject to W'W=I, ||W||_2,0 <= k 2 | % W is d-by-m, A is d-by-d 3 | % Require: m<=k<=d, rank(A)<=m 4 | 5 | function W = Go(A, m, k) 6 | 7 | [d, ~] = size(A); 8 | Aopt=A; 9 | 10 | if rank(A) > m 11 | [vec, val] = eigs(A, m); 12 | A = vec * val * vec'; 13 | end 14 | 15 | [~, ind] = sort(diag(A), 'descend'); 16 | opt_index = sort(ind(1:k)); 17 | 18 | W = zeros(d, m); 19 | Aopt = Aopt(opt_index, opt_index); 20 | [V, ~] = eigs(Aopt, m); 21 | 22 | W(opt_index, :) = V; 23 | 24 | end -------------------------------------------------------------------------------- /IPU.m: -------------------------------------------------------------------------------- 1 | % max tr(W'AW), subject to W'W=I, ||W||_2,0 <= k 2 | % W is d-by-m, A is d-by-d 3 | % Require: m<=k<=d 4 | function W = IPU(A, m, k,d,W0) 5 | 6 | NITER = 20; 7 | 8 | if nargin < 4 9 | W0 = Go(A, m, k); 10 | end 11 | W = W0; 12 | 13 | if rank(A) <= m 14 | W = W0; 15 | return; 16 | end 17 | 18 | for iter = 1:NITER 19 | P = A*W*pinv(W'*A*W)*W'*A; 20 | [~, ind] = sort(diag(P), 'descend'); 21 | opt_index = sort(ind(1:k)); 22 | Aopt = A(opt_index, opt_index); 23 | [V, ~] = eigs(Aopt, m); 24 | W(opt_index, :) = V; 25 | W(setdiff(1:d,opt_index),:) = 0; 26 | end 27 | 28 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # L20-FS 2 | 3 | The matlab function named SDFS is the main funciton of the following paper. If you hava any question and problem, please contact me via 4 | email: zhengwangml@gmail.com 5 | 6 | Discriminative Feature Selection via A Structured Sparse Subspace Learning Module IJCAI 2020 7 | 8 | please cite our paper by 9 | 10 | @inproceedings{wang2020discriminative, 11 | title={Discriminative Feature Selection via A Structured Sparse Subspace Learning Module.}, 12 | author={Wang, Zheng and Nie, Feiping and Tian, Lai and Wang, Rong and Li, Xuelong}, 13 | booktitle={IJCAI}, 14 | pages={3009--3015}, 15 | year={2020} 16 | } 17 | -------------------------------------------------------------------------------- /SDFS.m: -------------------------------------------------------------------------------- 1 | function [W, obj] = SDFS(X, Y, m, k) 2 | % X: d by n 3 | % Y: n by 1 4 | % Written by Steven Wang, email: zhengwangml@gmail.com 5 | d = size(X,1); 6 | W0 = orth(rand(d,m)); 7 | [Sb, Sw, ~, ~] = calculate_L(X',Y); 8 | lambda = trace(W0'*Sb*W0)/trace(W0'*Sw*W0); 9 | obj = []; 10 | for iter = 1:50 11 | obj = [obj;lambda]; 12 | % The abs of smallest value ensures step 18 13 | eigvalue = eigs(Sb - lambda*Sw,1,'SA'); 14 | if eigvalue>=0 15 | A = Sb - lambda*Sw; 16 | else 17 | eta = - eigvalue; 18 | A = Sb - lambda*Sw + eta*eye(d); 19 | end 20 | W = IPU(A,m,k,d,W0); 21 | lambda = trace(W'*Sb*W)/trace(W'*Sw*W); 22 | W0 = W; 23 | end --------------------------------------------------------------------------------