2015-03-10 5 views
0

По libsvm часто задаваемые вопросы, по следующей шкале кода одной строки каждая функция в интервале [0,1] в Matlabspdiags и функции масштабирования

(data - repmat(min(data,[],1),size(data,1),1))*spdiags(1./(max(data,[],1)-min(data,[],1))',0,size(data,2),size(data,2)) 

поэтому я использую этот код:

v_feature_trainN=(v_feature_train - repmat(mini,size(v_feature_train,1),1))*spdiags(1./(maxi-mini)',0,size(v_feature_train,2),size(v_feature_train,2)); 
v_feature_testN=(v_feature_test - repmat(mini,size(v_feature_test,1),1))*spdiags(1./(maxi-mini)',0,size(v_feature_test,2),size(v_feature_test,2)); 

где я использую первый обучить классификатор, а второй для классификации ...

в моем масштабировании скромного мнения, должен быть выполнен:

enter image description here

т.е .:

v_feature_trainN2=(v_feature_train -min(v_feature_train(:)))./(max(v_feature_train(:))-min((v_feature_train(:)))); 
v_feature_test_N2=(v_feature_test -min(v_feature_train(:)))./(max(v_feature_train(:))-min((v_feature_train(:)))); 

Теперь сравнили результаты классификации с использованием этих двух методов масштабирования и первый превосходит второй. Вопрос: 1) Что именно делает первый метод? Я этого не понимал. 2) Почему код, предложенный libsvm, превосходит второй (например, 80% против 60%)? Большое спасибо заранее

+0

Не могли бы вы согласиться с именами переменных? Может быть, использовать «данные» и для второй версии. – knedlsepp

+1

Protip: вместо того, чтобы писать один и тот же код дважды с немного разными именами переменных, вы должны определить функцию. Вы даже можете использовать анонимную функцию. 'normalize = @ (D) (D-min (D (:))) ./ (max (D (:)) - min (D (:)));' и затем использовать: 'v_feature_trainN = normalize (v_feature_train) ' – knedlsepp

ответ

1

Прежде всего: код, описанный в libsvm делает что-то другое, чем ваш код:

Он отображает каждый столбец независимо на интервале [0,1]. Однако ваш код использует глобальные min и max для сопоставления всех столбцов с использованием одного и того же аффинного преобразования вместо отдельного преобразования для каждого столбца.


Первый код работает следующим образом:

  • (data - repmat(min(data,[],1),size(data,1),1))
    Это вычитает минимум каждого столбца из всей колонны. Он делает это, вычисляя вектор строки минимумов min(data,[],1), который затем реплицируется, чтобы построить матрицу того же размера, что и data. Затем он вычитается из data.

  • spdiags(1./(max(data,[],1)-min(data,[],1))',0,size(data,2),size(data,2))
    Это создает диагональную матрицу. Запись (i,i) этой матрицы равна 1, деленной на разность максимума и минимума i-го столбца: max(data(:,i))-min(data(:,i)).

  • Правильное умножение этой диагональной матрицы означает: умножить каждый столбец левой матрицы на соответствующий диагональный элемент. Это эффективно делит столбец i на max(data(:,i))-min(data(:,i)).


Вместо того, чтобы использовать разреженный диагональную матрицу, вы могли бы сделать это еще более эффективно с bsxfun:

bsxfun(@rdivide, ... 
     bsxfun(@minus, ... 
       data, min(data,[],1)), ... 
     max(data,[],1)-min(data,[],1)) 

Какой MATLAB способ написания:

  • Divide :
    • Разница:
      • каждый столбец и его соответствующий минимальный
    • по разнице каждого столбца max и min.
+0

@Kevin: Я понятия не имею, на каком алгоритме вы работаете, поскольку вы никоим образом не упомянули об этом. Таким образом, масштабирование всей матрицы может иметь такое же значение, как масштабирование отдельных столбцов. – knedlsepp

+0

масштабирование каждого столбца по их минимальному и максимальному значению является правильным способом, поскольку каждая функция (столбец) будет охватывать другой диапазон значений. Допустим, у вас две колонки: возраст и кровяное давление. Возраст будет охватывать диапазон 18-80, но артериальное давление может составлять от 70 до 180. Также вы должны учитывать, что такие значения будут использоваться для измерения несходства в SVM (т.е. функции ядра) и некоторых показателей (таких как евклидова) будут различать разные функции в разных диапазонах. Вот почему каждый столбец должен находиться в диапазоне [0; 1] (т. Е. Нормализован с помощью min-max) – Alessiox

0

Я знаю, что это уже правильно ответил, но я хотел бы представить еще одно решение, которое, я думаю, тоже правильно, и я нашел более интуитивным/shorther затем один представленный knedlsepp. Я новичок в MatLab и, как я изучал knedlsepp решение, я нашел его более интуитивным, чтобы решить эту проблему с помощью следующей формулы:

function [ output ] = feature_scaling(y) 

output = (y - repmat(min(y),size(y,1),1)) * diag(1./(max(y) - min(y))); 

end 

Я нахожу это немного проще в использовании DIAG этот путь вместо spdiags, но Я считаю, что он дает тот же результат с целью этого упражнения.

Умножая первый член на второй, эффективно делит каждый элемент матрицы (Y-min (Y)) на скалярное значение 1/(max (y) -min (y)), достигая желаемого результата.

Если кто-то предпочитает более короткую версию, возможно, это может быть полезно.

Смежные вопросы