I am trying to understand Logistic Regression in relation to credit scoring model. I wish to understand the significance of "20/ln(2)" in logistic regression. Why and how is it used?
-
6$\begingroup$ Could you please give a www link how 20/ln(2) is applied? Thanks! $\endgroup$– GaBorgulyaCommented Apr 28, 2011 at 12:04
-
$\begingroup$ Looks like a simple transformation (on a linear scale) bit.ly/klhGCr $\endgroup$– chlCommented Apr 28, 2011 at 12:49
3 Answers
This is a common scaling factor used for credit scoring models built with logistic regression.
The interpretation of the dependent variable in logistic regression is as log odds, but in credit scoring, we like to deal in points, thus a scaling factor is applied to the log odds to convert to the point system.
A widely used convention in credit scoring is the concept of "Points to Double the Odds" (often abbreviated PDO), and this is the source of the $\ln (2)$ in the question. For example, how many points does the score change if the odds increase from 100:1 to 200:1.
A common default value for PDO is 20, because it produces credit score ranges that people tend to like.
So, the interpretation of the $20/\ln(2)$ is that for a 20-point increase in score, the odds double.
Typically in credit scoring one would choose a baseline score e.g. 600. We assign a certain meaning to 600 for example, 600 means the good bad odd is 30:1 (where bad typically means a default, the default definition is typically 90 days past payment due on the loan, however the bad definition can vary). Typically they also define that a 20 point jump means doubling of odds, for example 620 means the good bad odd if 60:1 and 640 is 120:1 etc. This definition comes from logistic regression.
If we fit a logistic regression model the model being fitted is this
$$\log(p/(1-p)) = a + b_1d_1 + \cdots + b_n d_n$$
where $a$ and $b_i$ are parameter estimates and $p$ is the probability of good $d_i$ are your raw data (explanatory variables). The LHS is the log good bad odds. To conform to the above mentioned standard (i.e. 600 is 30:1 and 620 is 60:1) we scale the RHS using $c$ and $d$ found by solving these simultaneous equations
$$600 = c\log(30/1) + d = c + d(a + b_1d_1 + \cdots + b_n d_n)$$ $$620 = c\log(60/1) + d = c + d(a + b_1d_1 + \cdots + b_n d_n)$$
you will get $c = 20/\log(2)$. Hence scaling the RHS by $c$ and $d$ will give you the scores you want. Hence we see that $20/\log(2)$ is just to achieve the 20 points to double odds mantra.
As for me all this theory wasn't that obvious I provide code with formulas to explain how all the "definitions" are translated into the resulting score.
import pandas as pd
import numpy as np
df=pd.DataFrame()
df['fc']=[206, 205, 200, 220, 230, 235, 236, 240,250]
df['cat']=[0, 1, 0, 0, 0, 1, 1, 1,0]
df['good']=[0, 1, 0, 0, 1, 0, 1, 1,1]
train=df[['fc','cat']]
y=df['good']
from sklearn.linear_model import LogisticRegression
clf=LogisticRegression(fit_intercept=True, solver='lbfgs')
clf=clf.fit(train, y)
coefficients = np.append (clf.intercept_, clf.coef_)
print('Coefficients', coefficients)
#Option 1: Predict proba
test=pd.DataFrame (np.array([200,1]).reshape(1,2))
y_pred=clf.predict_proba(test)[:,1]
print('Predict proba: ' ,y_pred)
#Option 2: Calculate Probability
ln_odds=sum(np.multiply(coefficients,np.array([1,200,1]))) # sum(coefficients*values)=ln(odds)
odds=np.exp(ln_odds)
prob_good=odds/(1+odds)
print('Resulting probablity: ', prob_good)
#score from Siddiqi
pdo=20
factor=pdo/np.log(2)
offset=200
score1=offset+factor*np.log(1) #p_bad=0.5, bad=good > odds=1
score2=offset+factor*np.log(2) #p_bad=0,3(3) good=2 bad=1
score3=offset+factor*np.log(4) #p_bad=0,2 good=4 bad=1
print(f'Difference 2 and 1: {score2-score1} \nDifference 3 and 2: {score3-score2}' )
'''To calculate score from logregression '''
#NB! in regression target 1 should be set to good as in Siddiqi odds are 100:1 meaning 100 good and 1 bad
score=offset-factor*sum(np.multiply(coefficients,np.array([1,200,1])))
print(f'Score from regression: {round(score,0)}')
#score from probability
score=offset+factor*np.log(prob_good/(1-prob_good))
print(f'Score from probability: {round(score,0)}')