Принцип
Алгоритм последовательных проекций (successive projections algorithm, SPA) — это метод прямого отбора переменных. SPA использует анализ векторных проекций, сравнивая размеры проекционных векторов путём проецирования одной волны на другую. Выбирается волна с наибольшей длиной проекционного вектора. Затем на основе скорректированной модели выбирается окончательная длина волны признака. SPA выбирает комбинацию переменных с наименьшим количеством избыточной информации и минимальной коллинеарностью. Алгоритм состоит из следующих шагов:
Задаётся начальный итерационный вектор $x_{k(0)}$, количество выбираемых переменных $N$, а также спектральная матрица $J$.
Выбирается одна колонка из спектральной матрицы $J$ (столбец $j$), и значения столбца присваиваются переменной $x_j$. Полученное значение записывается как $x_{k(0)}$.
Определяется множество векторов-столбцов, которые не были выбраны ранее. Это множество обозначается как $s$. $$ s=\lbrace j,1\leq{j}\leq{J}, j\notin \lbrace k(0), \cdots, k(n-1) \rbrace \rbrace $$
Для каждого вектора $x_j$ в множестве $s$ вычисляется его проекция на остальные векторы: $$ P_{x_j} = x_j-(x^T_j x_{k(n-1)})x_{k(n-1)}(x^T_{k(n-1)}x_{k(n-1)})^{-1},j\in s $$
Из множества $s$ выбирается столбец с максимальной длиной проекции. Обозначим его номер как $k(n)$. $$ k(n) = arg(max(| P_(x_j) |), j \in s) $$
Присваиваем $x_j = p_x, j \in s$.
Увеличиваем значение $n$ на 1. Если $n < N$, то повторяем вычисления по формулам (1).
В итоге выбираются переменные $\lbrace x_{k(n)} = 0, \cdots, N-1 \rbrace$. Для каждой итерации с $k(0)$ и $N$ строится модель множественной линейной регрессии (MLR). Получаем среднеквадратичное отклонение (RMSECV) для взаимодействия между моделями. Наименьшее значение RMSECV соответствует оптимальным значениям $k(0)$ и $N$. Обычно SPA выбирает небольшое количество признаков $N$.
Быстрое использование
0. Предупреждение
На момент разработки проекта использовались следующие версии Python и Scikit-learn: Python == 3.7 и Scikit-learn == 0.24.0. В последующих версиях могут возникнуть ошибки. Рекомендуется использовать виртуальную среду для запуска этого скрипта.
Скрипт был написан по аналогии с версией MATLAB и может служить только примером. Он не был тщательно протестирован и не гарантирует универсальности. Если вы внесли структурные изменения в проект, обязательно сообщите об этом автору для синхронизации изменений.
1. Чтение данных
# Импорт библиотек pandas и numpy
import pandas as pd
import numpy as np
# Чтение данных
data = pd.read_csv("./data/peach_spectra_brix.csv")
data[:5]
2. Разделение данных
# m * n
print("Форма матрицы data.shape:",data.shape)
# 50 образцов, 600 диапазонов, первый столбец - значение степени спелости персика, которое нужно отделить
X = data.values[:,1:]
# Эквивалентная операция
# X = data.drop(['Brix'], axis=1)
y = data.values[:,0]
# Эквивалентная операция
# y = data.loc[:,'Brix'].values
print(f"Форма X.shape:{X.shape}, форма y.shape:{y.shape}")
X,y
3. Импорт SPA
# Импортируем пакет SPA
import SPA
# Создаём объект SPA
spa = SPA.SPA()
# Нормализуем данные
from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler(feature_range=(-1, 1)) # Здесь feature_range можно настроить самостоятельно, по умолчанию (0,1)
X_ = min_max_scalers.fit_transform(X)
print(X[1,:5])
print(X_[1,:5])
# Разделяем данные на обучающий и тестовый наборы
from sklearn.model_selection import train_test_split
# Обратите внимание на разделение X_
# Если после разделения получается, что выбран диапазон с минимальным значением, можно соответствующим образом настроить соотношение обучающего и тестового наборов test_size от 0,3 до 0,5
Xcal, Xval, ycal, yval = train_test_split(X_, y, test_size=0.4, random_state=0)
Форма Xcal.shape,Xval.shape
4. Построение модели и отбор признаков
# Построение модели и отбор признаков
# m_max по умолчанию равен 50 (если Xcal(m*n) m < 50, m_max=m-2)
var_sel, var_sel_phase2 = spa.spa(
Xcal, ycal, m_min=2, m_max=28,Xval=Xval, yval=yval, autoscaling=1)
5. Экспорт выбранных диапазонов
# Экспорт отобранных диапазонов спектра
# spa возвращает номера столбцов, а не данные спектра
# Получение списка диапазонов
absorbances = data.columns.values[1:]
print("Первые 5 диапазонов:",absorbances[:5])
# Диапазоны, выбранные spa (например, при test_size = 0.3)
print("Диапазоны, отобранные spa:",absorbances[var_sel])
# Экспорт данных выбранных диапазонов спектра
X_select = X[:,var_sel]
print("X_select.shape:",X_select.shape)
Примечание
Спектральная матрица (m * n) представляет собой матрицу, где m строк соответствуют образцам, а n столбцов — диапазонам спектра. Перед построением модели необходимо разделить данные на обучающую и тестовую выборки и нормализовать спектр. Можно сначала разделить данные, а затем нормализовать их, или наоборот. Ниже приведён пример разделения данных перед нормализацией:
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
Xcal, Xval, ycal, yval = train_test_split(x, y, test_size=0.4, random_state=0)
min_max_scaler = MinMaxScaler(feature_range=(-1, 1))
Xcal = min_max_scaler.fit_transform(Xcal)
Xval = min_max_scaler.transform(Xval)
Пример данных взят с сайта nirpyresearch.com.
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.