В моей схеме классификации есть несколько шагов, в том числе:Помещенные индивидуальные функции в трубопроводе Sklearn
- поражал (Synthetic меньшинства над дискретизация Техника)
- критериев Фишера для выбора функции
- стандартизации (Z- счет нормализации)
- SVC (Support Vector Классификатор)
Основные параметры должны быть настроены в СХ eme выше - процентиль (2.) и гиперпараметры для SVC (4.), и я хочу пройти поиск сетки для настройки.
Текущее решение создает «частичный» трубопровода, включая стадии 3 и 4 в схеме clf = Pipeline([('normal',preprocessing.StandardScaler()),('svc',svm.SVC(class_weight='auto'))])
и разбивает схему на две части:
1) Настройте процентиль функций, чтобы через поиск первой сетки
skf = StratifiedKFold(y)
for train_ind, test_ind in skf:
X_train, X_test, y_train, y_test = X[train_ind], X[test_ind], y[train_ind], y[test_ind]
# SMOTE synthesizes the training data (we want to keep test data intact)
X_train, y_train = SMOTE(X_train, y_train)
for percentile in percentiles:
# Fisher returns the indices of the selected features specified by the parameter 'percentile'
selected_ind = Fisher(X_train, y_train, percentile)
X_train_selected, X_test_selected = X_train[selected_ind,:], X_test[selected_ind, :]
model = clf.fit(X_train_selected, y_train)
y_predict = model.predict(X_test_selected)
f1 = f1_score(y_predict, y_test)
Оценки f1 будут сохранены, а затем будут усреднены по всем складкам разметки для всех процентилей, и возвращается процентиль с лучшим результатом CV. Цель ставить «процентиль для цикла» в качестве внутреннего цикла - это обеспечить справедливую конкуренцию, поскольку у нас есть одни и те же данные тренировки (включая синтезированные данные) во всех складчатых разделах для всех процентилей.
2) После определения процентиль, настройтесь на гиперпараметры по второй категории сетки
skf = StratifiedKFold(y)
for train_ind, test_ind in skf:
X_train, X_test, y_train, y_test = X[train_ind], X[test_ind], y[train_ind], y[test_ind]
# SMOTE synthesizes the training data (we want to keep test data intact)
X_train, y_train = SMOTE(X_train, y_train)
for parameters in parameter_comb:
# Select the features based on the tuned percentile
selected_ind = Fisher(X_train, y_train, best_percentile)
X_train_selected, X_test_selected = X_train[selected_ind,:], X_test[selected_ind, :]
clf.set_params(svc__C=parameters['C'], svc__gamma=parameters['gamma'])
model = clf.fit(X_train_selected, y_train)
y_predict = model.predict(X_test_selected)
f1 = f1_score(y_predict, y_test)
Это делается в очень похожим образом, за исключением того, мы настроить hyperparamter для SVC, а не процентиль возможностей для выбора.
Мои вопросы:
I) В данном решении, я вовлекают только 3. и 4. в clf
и сделать 1. и 2. своего рода «вручную» в двух вложенных циклов, как описано выше. Есть ли способ включить все четыре этапа в конвейер и выполнить весь процесс сразу?
II) Если это нормально, чтобы держать первый вложенный цикл, то это возможно (и как) для упрощения следующего вложенного цикла с использованием одного трубопровода
clf_all = Pipeline([('smote', SMOTE()),
('fisher', Fisher(percentile=best_percentile))
('normal',preprocessing.StandardScaler()),
('svc',svm.SVC(class_weight='auto'))])
и просто использовать GridSearchCV(clf_all, parameter_comb)
для настройки?
Обратите внимание, что как SMOTE
, так и Fisher
(критерии ранжирования) должны выполняться только для учебных данных в каждой складчатой перегородке.
Это было бы так оценено за любые комментарии.
РЕДАКТИРОВАТЬSMOTE
и Fisher
показаны ниже:
def Fscore(X, y, percentile=None):
X_pos, X_neg = X[y==1], X[y==0]
X_mean = X.mean(axis=0)
X_pos_mean, X_neg_mean = X_pos.mean(axis=0), X_neg.mean(axis=0)
deno = (1.0/(shape(X_pos)[0]-1))*X_pos.var(axis=0) +(1.0/(shape(X_neg[0]-1))*X_neg.var(axis=0)
num = (X_pos_mean - X_mean)**2 + (X_neg_mean - X_mean)**2
F = num/deno
sort_F = argsort(F)[::-1]
n_feature = (float(percentile)/100)*shape(X)[1]
ind_feature = sort_F[:ceil(n_feature)]
return(ind_feature)
SMOTE
от https://github.com/blacklab/nyan/blob/master/shared_modules/smote.py, он возвращает данные, синтезированные. Я изменил его, чтобы вернуть исходные исходные данные, собранные вместе с синтезированными данными, вместе с его метками и синтезированными.
def smote(X, y):
n_pos = sum(y==1), sum(y==0)
n_syn = (n_neg-n_pos)/float(n_pos)
X_pos = X[y==1]
X_syn = SMOTE(X_pos, int(round(n_syn))*100, 5)
y_syn = np.ones(shape(X_syn)[0])
X, y = np.vstack([X, X_syn]), np.concatenate([y, y_syn])
return(X, y)
Спасибо, я включил обе функции в ОП. – Francis
См. Редактирование, извините за прыжок с пистолета, но я не думаю, что это возможно, так как ваши функции должны применяться к вашей цели. – David
Извините за поздний ответ. Мне интересно, что вы имели в виду под «процессом Фишера, который работал бы, если бы сама функция не влияла на вашу целевую переменную». Счет Фишера здесь принимает цели (т. Е. Y) в качестве входных данных и преобразует x в качестве вывода, что мне кажется, что оно не преобразует y. – Francis