I have a simple logistic regression model in Python, set up using sklearn. The code for training the model (and calculating some metrics across multiple runs) looks something like this:
for i in range(30):
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size = 0.75)
train_scaler, test_scaler = StandardScaler(), StandardScaler()
X_train, X_test = train_scaler.fit_transform(X_train), test_scaler.fit_transform(X_test)
logistic = LogisticRegression(solver='newton-cg', class_weight=weights)
logistic.fit(X_train, y_train)
y_test = np.array(y_test)
predicted = logistic.predict(X_test)
accuracies = np.concatenate((accuracies, np.array([[sum((predicted==y_test)*(y_test==i))/sum(y_test==i) for i in range(2)]])))
for i in range(2):
print(f"The accuracy for category {i} is {np.mean(accuracies[1:, :], axis = 0)[i]}.")
And the output looks a bit like this:
The accuracy for category 0 is 0.6437247830550223. The accuracy for category 1 is 0.5607368278690966.
This model is fit on 408 examples with 306 predictors. Admittedly, this not much data relative to the number of predictors, but it still achieves an average accuracy of around 61% on the test set, predicting about 64% of label 1 and 56% of label 2 correctly, so better than chance. By contrast, a model that simply selects each class with a probability equal to its representation, the null model, hovers around 50%, unsurprisingly.
However, I calculate the deviance using the labels and variables for the test set as:
2*sklearn.metrics.log_loss(y_test, model.predict_proba(X_test), normalize=False)
In the case of the second model, instead of model.predict_proba(X_test)
, we have an array that looks like [[1-p, p], ..., [1-p, p]], since the probability of each label is constant in the null model, looking something like this:
array([[0.52205882, 0.47794118],
[0.52205882, 0.47794118],
[0.52205882, 0.47794118],
[0.52205882, 0.47794118]
...
[0.52205882, 0.47794118]])
This value is higher (about twice as higher) for the first model than for the second! Even when I write out my own explicit formula for the deviance, nothing changes. To my understanding, in theory, the (absolute value of the) deviance of any model should be strictly lower than that of the null model, since higher deviance indicates greater difference from the saturated model.
How can the deviance of a fitted logistic model be higher than that of the null model, particularly when the logistic model shows better predictive accuracy?
Note: the data is private, so I cannot share it here.