Должны ли результаты "Gradient Boosting" быть разными, если поменять местами признаки
Есть набор данных для классификации в "Gradient Boosting". Если я меняю их местами получается разный результат. Так должно быть? Если результаты должны быть действительно разными, значит есть смысл попробовать разные последовательности? Разместил файл с данными здесь данные. Последнее значение справа это метки классов(бинарная классификация)
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report
df1 = pd.read_csv('dataclass.csv',
header=None)
split = 5700
y = df1.iloc[:, 11].values# метки классов
y = y.astype('int')
len_ = len(y)
q = np.ones((len_, 11), dtype=float)
q[0:len_, 0] = df1.iloc[:, 7].values
q[0:len_, 1] = df1.iloc[:, 8].values
q[0:len_, 2] = df1.iloc[:, 9].values
q[0:len_, 3] = df1.iloc[:, 10].values
q[0:len_, 4] = df1.iloc[:, 0].values
q[0:len_, 5] = df1.iloc[:, 5].values
q[0:len_, 6] = df1.iloc[:, 4].values
q[0:len_, 7] = df1.iloc[:, 3].values
q[0:len_, 8] = df1.iloc[:, 2].values
q[0:len_, 9] = df1.iloc[:, 1].values
q[0:len_, 10] = df1.iloc[:, 6].values
q = np.round(q, 5)
X_train = q[:split]
clf = GradientBoostingClassifier(max_depth=3, max_features="sqrt", n_estimators=30,
learning_rate=0.01,random_state=0)
clf.fit(X_train, y[:split])
yALL = clf.predict(q)
peport = classification_report(y, yALL)
print(peport)
y_test = clf.predict(q[split:])
confmat = confusion_matrix(y[split:], y_test)
print(confmat)
Если запускаю на обучение, то получаются следующие метрики:
precision recall f1-score support
0 0.61 0.05 0.09 3867
1 0.51 0.97 0.67 3983
accuracy 0.52 7850
macro avg 0.56 0.51 0.38 7850
weighted avg 0.56 0.52 0.39 7850
[[187 875]
[172 916]]
Делаю следующую очередность признаков:
q[0:len_, 0] = df1.iloc[:, 0].values
q[0:len_, 1] = df1.iloc[:, 1].values
q[0:len_, 2] = df1.iloc[:, 2].values
q[0:len_, 3] = df1.iloc[:, 3].values
q[0:len_, 4] = df1.iloc[:, 4].values
q[0:len_, 5] = df1.iloc[:, 5].values
q[0:len_, 6] = df1.iloc[:, 6].values
q[0:len_, 7] = df1.iloc[:, 7].values
q[0:len_, 8] = df1.iloc[:, 8].values
q[0:len_, 9] = df1.iloc[:, 9].values
q[0:len_, 10] = df1.iloc[:, 10].values
результат получается несколько иной:
precision recall f1-score support
0 0.63 0.04 0.08 3867
1 0.51 0.98 0.67 3983
accuracy 0.52 7850
macro avg 0.57 0.51 0.38 7850
weighted avg 0.57 0.52 0.38 7850
[[250 812]
[222 866]]
Ответы (1 шт):
Автор решения: CrazyElf
→ Ссылка
Посмотрел немного ваши данные. Могу сделать следующие выводы и замечания.
- вы зря предсказываете на всех данных, надо только на тесте предсказывать по-хорошему, дальше я делаю наблюдения по предсказаниям только на тесте, хотя и предсказание на всех данных даёт в принципе те же результаты
- качество предсказаний вашей модели близко к случайному
0.5с некоторой погрешностью - с заданным вами параметром
max_depth=1модель в 99% случаев предсказывает результат1, хотя во входных данных примерно поровну зачений0и1 - если увеличить глубину деревьев до
max_depth=10, то модель начинает больше 0 предсказывать (где-то 1/30на 2/31), но в целом качество модели всё-равно получается близко к случайному0.5 - если поиграться параметром
random_state, то вы увидите даже бОльший разброс качества, чем при перемешивании колонок, таким образом, наблюдающаяся разница целиком объясняется тем, что модель берёт случайные наборы колонок, какие именно и в каком порядке - зависит как отrandom_state, так и от физического расположения колонок, в общем, можно считать, что перемешивая колонки, вы просто меняетеrandom_state, вот и всё объяснение разницы в метриках
Изменённый код для более понятного разбиения на трейн/тест и проверки на тесте:
X_train, X_test = q[:split],q[split:]
y_train, y_test = y[:split],y[split:]
clf = GradientBoostingClassifier(max_depth=1, max_features="sqrt", n_estimators=30,
learning_rate=0.01,random_state=4)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
peport = classification_report(y_test, y_pred)
print(peport)