Как модели могут получить одинаковую точность для рандомизированных данных? - PullRequest
2 голосов
/ 09 мая 2019

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

Я запускаю их, и все они получают точность около 65-80%, это с вложенной перекрестной проверкой, чтобы избежать переобучения для получения этих процентов. Но затем я даю этим моделям рандомизированный набор данных, и некоторым моделям удается получить одинаковую точность при многократных прогонах (без перекрестной проверки и просто точного наблюдения с данными раздельного теста), действительно ли это возможно или это модели достигают плато? С моей точки зрения начинающего, я бы предположил, что это маловероятно, любая помощь будет оценена.

Вот мой код для тестирования случайных данных:

inner_cv = KFold(n_splits=10, shuffle=True, random_state=seed)
outer_cv = KFold(n_splits=10, shuffle=True, random_state=seed)

models = []
models.append(('LR', dcv.GridSearchCV(logreg, LR_par, cv=inner_cv, iid=False, n_jobs=-1)))
models.append(('SVM', dcv.GridSearchCV(svm, tuned_parameters, cv=inner_cv, iid=False, n_jobs=-1)))
models.append(('RFC', dcv.GridSearchCV(rfc, param_grid, cv=inner_cv,iid=False, n_jobs=-1)))
models.append(('Keras', GridSearchCV(estimator=keras, param_grid=kerasparams, cv=inner_cv,iid=False, n_jobs=-1)))

arr = np.arange(5400).reshape((600, 9))
random = np.random.permutation(arr)
ran = np.random.randint(4, size=600)
rand = np.column_stack((random, ran))
print(rand.shape)
X1 = rand[0:600,0:8]
Y1 = rand[0:600,-1]
print("Random data counts of label '0': {}".format(sum(ran==0)))
print("Random data counts of label '1': {}".format(sum(ran==1)))
print("Random data counts of label '2': {}".format(sum(ran==2)))
print("Random data counts of label '3': {}".format(sum(ran==3)))
print(X1.shape)
print(Y1.shape)
X1 = MinMaxScaler().fit_transform(X1)

X_train1, X_test1, Y_train1, Y_test1 = train_test_split(X1, Y1, test_size=0.2, random_state=0)

for name, model in models:
    model.fit(X1, Y1)
    print(name, 'Random accuracy: {:.2f}'.format(model.score(X_test1, Y_test1)*100),  '%')

Вывод выглядит так:

(600, 10)
Random data counts of label '0': 136
Random data counts of label '1': 153
Random data counts of label '2': 155
Random data counts of label '3': 156
(600, 8)
(600,)


LR Random accuracy: 26.67 %
SVM Random accuracy: 26.67 %
RFC Random accuracy: 38.33 %
Keras Random accuracy: 23.33 %

Похоже, что если я запускаю этот код 4 раза, то в первый раз точность отличается, в следующие 3 раза они остаются неизменными, как правило, для SVM и LR (логистическая регрессия).

Я использую Python 3.7 в Anaconda и Jupyterlab 0.35.4

1 Ответ

0 голосов
/ 19 мая 2019

Насколько я могу судить, ваша проблема заключается в том, как вы используете KFold из sklearn.Что касается RFC (с предположением относительно классификатора случайных лесов), он также имеет случайный элемент.Логистическая регрессия также имеет случайный фактор, и о SVM я не знаю.Для чего это стоит, вот часть документации.Прежде чем задавать вопросы о стековом потоке, я бы порекомендовал поискать документацию по каждому алгоритму.

Из документации по KFold:

shuffle: логическое значение, необязательно

Независимо от того, нужно ли перетасовывать данные перед разбиением на пакеты.

random_state: int, экземпляр RandomState или None, необязательно, по умолчанию = None

Если int,random_state - начальное число, используемое генератором случайных чисел;Если экземпляр RandomState, random_state является генератором случайных чисел;Если None, генератор случайных чисел - это экземпляр RandomState, используемый np.random.Используется, когда shuffle == True.

И классификатор случайных лесов

bootstrap: логический, необязательный (по умолчанию = True)

Используются ли образцы начальной загрузки при построении деревьев.Если значение False, весь набор данных используется для построения каждого дерева.

Поэтому, если вы хотите, чтобы каждый раз были одни и те же данные, вы должны сделать shuffle false и удалить random_state (потому что по умолчанию None).

inner_cv = KFold(n_splits=10, shuffle=False)
outer_cv = KFold(n_splits=10, shuffle=False)

Хотя это не гарантирует, что вы получите те же результаты, поскольку это очень зависит от алгоритмов, которые вы используете.Случайный лес и логистическая регрессия от Scikit-Learn имеют случайный элемент, который нельзя отключить, согласно документации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...