Machine Learning

Kolmogorov-Smirnov figure, explains: Model modeling model in the credit risk model

Days, people take a loan greater than ever. Anyone who wants to build their own house, home loan is available and if you own the property, you can receive a loan. There is agricultural loan, education loan, business loans, gold loans, and many others.

In addition, purchase items such as television, refrigerators, furniture and mobile phones, we have EMI options.

But everyone gets their loan allowed request?

Banks do not give credit to everyone using the application; There is a procedure they follow to allow loan.

We know that the machine study and data science is now included in all industries, and banks also use them.

When the customer works with loans, banks need to know the opportunities for the Customer back at the time.

In this case, banks use speculative models, especially based on a reasonable return or other machine learning methods,

We already know that through these methods, each applicant was assigned to possibly.

This is the model of separation, and we need to distinguish fakers and non-corrupt ones.

They do not: Customers fail to pay their loan (payment costs or stop paying completely).

Non-apects: Customers return their loan on time.

We have discussed accuracy and ROC-AUC to check the separation models.

In this article, we will discuss Kolmogorov-Smirnov Station (KS Statistic) which is used to assess the planning models mainly in the banking sector.

Understanding KS figure, we will use the German credit data.

This data contains information about 1000 applicants, explaining 20 features such as account condition, loan period, credit period, employment, housing, and condition.

The intended variations indicate that the applicant is not responsible for (represented at 1) or defaulter (represented by 2).

You can find information about the Data and the data here.

We now need to create a separation model to separate applicants. Since the binary problem is binary separation, we will use Locisistic money in this data.

Code:

import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

# Load dataset
file_path = "C:/german.data"
data = pd.read_csv(file_path, sep=" ", header=None)

# Rename columns
columns = [f"col_{i}" for i in range(1, 21)] + ["target"]
data.columns = columns

# Features and target
X = pd.get_dummies(data.drop(columns=["target"]), drop_first=True)
y = data["target"]   # keep as 1 and 2

# Train-test split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

# Train logistic regression
model = LogisticRegression(max_iter=10000)
model.fit(X_train, y_train)

# Predicted probabilities
y_pred_proba = model.predict_proba(X_test)

# Results DataFrame
results = pd.DataFrame({
    "Actual": y_test.values,
    "Pred_Prob_Class2": y_pred_proba[:, 1]
})

print(results.head())

We already know that when we use logical arts, we get opportunities to give up.

Photo by the writer

Now to understand how KS Sticistic is calculated, let's look at 10 points sample in the outgoing.

Photo by the writer

Here the highest predictable is 0.92, meaning 92% of the Appeal will make a mistake.

Now let's go on the number of KS figure.

First, we will filter the applicants about orderly, so that the top applicants are high.

Photo by the writer

We already know that '1' is symbolizing non-falferters and '2' symbolizes the odds.

In the following step, we calculate the accumulated count of Fallersors and Fakeraders in each step.

Photo by the writer

In the following step, we convert custodial and non-false regulations at a balanced price.

We separate defilitative systemulatives by the total number of alias, and non-true relatives at the total number of non-degraded number.

Photo by the writer

Next, lists the difference between the default degree of defaulter and the definition of defaul.

Photo by the writer

The main difference between the accumulated cleaning rate and the defaulter is 0.83, the Statistic KS sample.

Here the KS statistic is 0.83, occurring at 0.29.

This means that the model captures 83 fakers more efficiently than non-refundable.


Here, we can see that:

The rate of a joint cleaning = a good measure of true (how many real fakerler wins so far).

A non-Defaulter level = a good false rate (how many non-falker is improperly captured as fake).

But since we didn't fix any limit here, how can we get good prices and false rates?

Let's see how to collect the TPR and FPR.

First of all, we look at all possible as a rainborn and count TPR and FPR.

[
begin{aligned}
mathbf{At threshold 0.92:} & \[4pt]
TP & = 1, QA AAD FN = 3, QUAD FP = 0, quaad TN = 6 \[6pt]
TPR & = tffac {1} {4} = 0.25 \[6pt]
FPR & = tfrac {0} {6} = 0 \[6pt]
Rightarrow ( mathrow {FPR}, , mathrm {TPR}) & = (0.25)
Finally {aligned}
]

[
begin{aligned}
mathbf{At threshold 0.63:} & \[4pt]

TP & = 2, QA AAD FN = 2, QUAD FP = 0, QUAD TN = 6 \[6pt]

TPR & = tffac {2} {4} = 0.50 \[6pt]

FPR & = tfrac {0} {6} = 0 \[6pt]

Marerow ( Mathrm {FPR}, , mathm {TPR}) & = (0, , 0.50)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.51:} & \[4pt]

TP & = 3, QA AAD FN = 1, QUAD FP = 0, qua AD = 6 [6pt]

TPR & = tffac {3} {4} = 0.75 \[6pt]

FPR & = tfrac {0} {6} = 0 \[6pt]

Rightarrow ( mathrow {FPR}, , mathrm {TPR}) & = (0, , 0.75)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.39:} & \[4pt]

TP & = 3, QA AAD FN = 1, QA AAD FP = 1, quaad TN = 5 \[6pt]

TPR & = tffac {3} {4} = 0.75 \[6pt]

FPR & = tfrac {1} {6} approx 0.17 \[6pt]

Marerow ( Mathrm {FPR}, , mathrm {TPR}) & = (0.17, , 0.75)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.29:} & \[4pt]

TP & = 4, QA AAD FN = 0, QUAD FP = 1, quaad TN = 5 \[6pt]

TPR & = tffac {4} {4} = 1.00 \[6pt]

FPR & = tfrac {1} {6} approx 0.17 \[6pt]

Marerow ( Mathrm {FPR}, , mathrm {TPR}) & = (0.17, , 1.00)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.20:} & \[4pt]

TP & = 4, QA AAD FN = 0, QUAD FP = 2, QUAD TN = 4 \[6pt]

TPR & = tffac {4} {4} = 1.00 \[6pt]

FPR & = tfrac {2} {6} approx 0.33 \[6pt]

Marerow ( Mathm {FPR}, , mathrm {TPR}) & = (0.33, , 1.00)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.13:} & \[4pt]

TP & = 4, QA AAD FN = 0, QUAD FP = 3, QUAD TN = 3 \[6pt]

TPR & = tffac {4} {4} = 1.00 \[6pt]

FPR & = tffac {3} {6} = 0.50 \[6pt]

Marerow ( Mathrm {FPR}, , mathm {TPR}) & = (0.50, , 1.00)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.10:} & \[4pt]

TP & = 4, QA AAD FN = 0, QUAD FP = 4, quaad TN = 2 \[6pt]

TPR & = tffac {4} {4} = 1.00 \[6pt]

FPR & = tffac {4} {6} approx 0.67 \[6pt]

Marerow ( Mathrm {FPR}, , mathrm {TPR}) & = (0.67, , 1.00)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.05:} & \[4pt]

TP & = 4, QA AAD FN = 0, QUAD FP = 5, qua AD = 1 \[6pt]

TPR & = tffac {4} {4} = 1.00 \[6pt]

FPR & = tfrac {5} {6} approx 0.83 \[6pt]

Marerow ( Mathrm {FPR}, , mathm {TPR}) & = (0.83, , 1.00)
Finally {aligned}
][
begin{aligned}
mathbf{At threshold 0.01:} & \[4pt]

TP & = 4, QA AAD FN = 0, QAAD FP = 6, quaad TN = 0 \[6pt]

TPR & = tffac {4} {4} = 1.00 \[6pt]

FPR & = tfrac {6} {6} = 1.00 \[6pt]

Marerow ( Mathrm {FPR}, , mathrm {TPR}) & = (1.00, , 1.00)
Finally {aligned}
]

From the statements above, we see that the end of the endless dirt is similar to the relevant level (TPR), and a non defaul level corresponds to the false level (FPR).

When calculating an automated default rate and non-default level, each line represents a limit, and the quality is calculated until it comes to it.

Here we can see that KS statistic = max (| TPR – FPR |


Now let's count the full dataset figure.

Code:

# Create DataFrame with actual and predicted probs
results = pd.DataFrame({
    "Actual": y.values,
    "Pred_Prob_Class2": y_pred_proba
})

# Mark defaulters (2) and non-defaulters (1)
results["is_defaulter"] = (results["Actual"] == 2).astype(int)
results["is_nondefaulter"] = 1 - results["is_defaulter"]

# Sort by predicted probability
results = results.sort_values("Pred_Prob_Class2", ascending=False).reset_index(drop=True)

# Totals
total_defaulters = results["is_defaulter"].sum()
total_nondefaulters = results["is_nondefaulter"].sum()

# Cumulative counts and rates
results["cum_defaulters"] = results["is_defaulter"].cumsum()
results["cum_nondefaulters"] = results["is_nondefaulter"].cumsum()
results["cum_def_rate"] = results["cum_defaulters"] / total_defaulters
results["cum_nondef_rate"] = results["cum_nondefaulters"] / total_nondefaulters

# KS statistic
results["KS"] = (results["cum_def_rate"] - results["cum_nondef_rate"]).abs()
ks_value = results["KS"].max()
ks_index = results["KS"].idxmax()

print(f"KS Statistic = {ks_value:.3f} at probability {results.loc[ks_index, 'Pred_Prob_Class2']:.4f}")

# Plot KS curve
plt.figure(figsize=(8,6))
plt.plot(results.index, results["cum_def_rate"], label="Cumulative Defaulter Rate (TPR)", color="red")
plt.plot(results.index, results["cum_nondef_rate"], label="Cumulative Non-Defaulter Rate (FPR)", color="blue")

# Highlight KS point
plt.vlines(x=ks_index,
           ymin=results.loc[ks_index, "cum_nondef_rate"],
           ymax=results.loc[ks_index, "cum_def_rate"],
           colors="green", linestyles="--", label=f"KS = {ks_value:.3f}")

plt.xlabel("Applicants (sorted by predicted probability)")
plt.ylabel("Cumulative Rate")
plt.title("Kolmogorov–Smirnov (KS) Curve")
plt.legend(loc="lower right")
plt.grid(True)
plt.show()

Conspiracy:

Photo by the writer

The big gap is 0.530 at 0.2928 opportunities.


When we understand how to calculate the number of KS, let us consider the importance of this figure.

Here we build a separation model and test it to use statistic KS, but also contain other mathemakers such as accuracy, ROC-AUC, etc.

We already know that accuracy is specified in one threshold, and changes according to the organization.

ROC-AUC gives us a number that shows the full potential skill.

But why are KS statistics used in banks?

The KS figure offers one number, representing a higher gap between the integrated and non-clothing distribution.

Let's go back to our sample data.

We have KS 0.83 figures on 0.29.

We have already discussed that each line works as a rump.

So, what happens at 0.29?

Threshold = 0.29 means that high or equal to 0.29 is fagged as strangers.

On 0.29, 5 high lines Read as laughs. Among the five, four are the real and one reality is not wrongly corrupt.

Here real positives = 4 and false = 1.

The 5 lines will be predicted as good.

During this time, the model has held all the four of the four ones and the wrong non-defaulter as a default.

Here TPR is walled in 1 and FPR is 0.17.

Therefore, KS statistic = 1-0.17 = 0.83.

If we continue to count other chance.

This reduces the gap between two groups.

Here we can say that by 0.29, the model has been rejected by all funny and 17% of the fact (according to sample data) and are authorized by 83% of the missing 83%.


Are banks deciding limit based on KS statistics?

While KS figures show a higher gap between two groups, banks do not limit the basis from this calculation.

The KS figure is used to ensure the power of models, while the actual limit is determined by monitoring the risk, the benefit and administrative guidelines.

If less than 20 KS, it is considered a weak model.
If between 20-20, it is considered acceptable.
If KS is in grade 50-70, it is considered a good model.


Dataset average

The data used in this blog is German credit data, which is popped in public to the UCI machine study. Provided under Creative Commons Recisions License 4.0 (CC is 4.0). This means that it can be used freely and allocated with proper adtification.


I hope this blog post has given you the basic understanding of the Kolmogorov-smirnov figure. If you enjoy reading, think to share your network, and feel comfortable to discuss your thoughts.

If you didn't read my blog on ROC-AUC at the moment, you can check it here.

Thanks for reading!

Source link

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button