Bewertung der Struktur des Kreditportfolios auf R.

Während der Diskussionen entstand eine "kleine" Aufgabe - die Dynamik der Struktur des Kreditportfolios aufzubauen (zum Beispiel die Dynamik einer Kreditkarte). Es gibt eine wichtige Besonderheit - es ist notwendig, die FIFO-Methode anzuwenden, um Kredite zurückzuzahlen. Jene. Bei der Rückzahlung sollten die frühesten Kredite zuerst zurückgezahlt werden. Dies stellt bestimmte Anforderungen an die Berechnung des Status jedes einzelnen Kredits und die Bestimmung seines Fälligkeitsdatums.







Betrachten Sie es als ein Olympiadenproblem. Keine „ blutigen Energiepreise “ und kein Code-Pedalieren, der Ansatz ist ausschließlich „ zuerst denken “. Nicht mehr als ein Codebildschirm pro Prototyp und keine Schleifen (eingebettet in Leistung und Lesbarkeit). Unten ist der R-Code mit einem Prototyp-Ansatz.







Es ist eine Fortsetzung einer Reihe früherer Veröffentlichungen .







Zersetzung



Da wir alles von Grund auf neu machen, teilen wir die Aufgabe in drei Schritte:







  1. Bildung von Testdaten.
  2. Berechnung des Fälligkeitstermins jedes Darlehens.
  3. Berechnung und Visualisierung der Dynamik für ein bestimmtes Zeitfenster.


Annahmen und Bestimmungen für den Prototyp:







  1. Granularität auf dem neuesten Stand. Nur eine Transaktion an einem Datum. Wenn an einem Tag mehrere Transaktionen stattfinden, muss deren Reihenfolge festgelegt werden (um dem FIFO-Prinzip zu entsprechen). Sie können add verwenden. Indizes, Sie können unixtimestamp verwenden, Sie können sich etwas anderes einfallen lassen. Dies ist für den Prototyp irrelevant.
  2. Es for



    sollte keine expliziten Schleifen geben . Es sollten keine unnötigen Kopien vorhanden sein. Konzentrieren Sie sich auf minimalen Speicherverbrauch und maximale Leistung.
  3. Wir werden die folgenden Gruppen von Verzögerungen betrachten: "<0", "0-30", "31-60", "61-90", "90+".


Schritt 1. Generieren des Datensatzes



Nur ein Testdatensatz, alle Übereinstimmungen sind zufällig. Für jeden Benutzer werden ~ 10 Datensätze generiert. Für Berechnungen gehen wir davon aus, dass das Darlehen einen positiven Wert hat, die Rückzahlung negativ ist. Und der gesamte Lebenszyklus für jeden Benutzer sollte mit einem Darlehen beginnen.







Datensatzgenerierung
library(tidyverse)
library(lubridate)
library(magrittr)
library(tictoc)
library(data.table)

total_users <- 100

events_dt <- tibble(
  date = sample(
    seq.Date(as.Date("2021-01-01"), as.Date("2021-04-30"), by = "1 day"),
    total_users * 10,
    replace = TRUE)
  ) %>%
  #    50 .
  mutate(amount = (runif(n(), -2000, 1000)) %/% 50 * 50) %>%
  #   
  mutate(user_id = sample(!!total_users, n(), replace = TRUE)) %>%
  setDT(key = "date") %>%
  #     
  .[.[, .I[1L], by = user_id]$V1, amount := abs(amount)] %>%
  #        , 
  #          
  #       
  unique(by = c("user_id", "date"))
      
      





Schritt 2. Berechnen Sie das Fälligkeitsdatum jedes Darlehens



data.table



ermöglicht es Ihnen, Objekte auch innerhalb von Funktionen durch Referenz zu ändern, wir werden dies aktiv nutzen.







Berechnung des Fälligkeitsdatums
#  
accu_dt <- events_dt[amount < 0, .(accu = cumsum(amount), date), by = user_id]

ff <- function(dt){
  #           
  #   
  accu_dt[dt, amount := i.amount, on = "user_id"]
  accu_dt[is.na(amount) == FALSE, accu := accu + amount][accu > 0, accu := NA, by = user_id]
  calc_dt <- accu_dt[!is.na(accu), head(date, 1), by = user_id]

  #     data.frame,   
  calc_dt[dt, on = "user_id"]$V1
}

repay_dt <- events_dt[amount > 0] %>%
  .[, repayment_date := ff(.SD), by = date] %>%
  .[order(user_id, date)]
      
      





Schritt 3. Berechnung der Dynamik der Struktur für den Zeitraum



Dynamikberechnung
calcDebt <- function(report_date){
  as_tibble(repay_dt) %>%
    #  ,      
    filter(is.na(repayment_date) | repayment_date > !! report_date) %>%
    mutate(delay = as.numeric(!!report_date - date)) %>%
    #  
    mutate(tag = santoku::chop(delay, breaks = c(0, 31, 61, 90),
                               labels = c("< 0", "0-30", "31-60", "61-90", "90+"),
                               extend = TRUE, drop = FALSE)) %>%
    #  
    group_by(tag) %>%
    summarise(amount = sum(amount)) %>%
    mutate_at("tag", as.character)
}

#   
df <- seq.Date(as.Date("2021-04-01"), as.Date("2021-04-30"), by = "1 day") %>%
  tibble(date = ., tbl = purrr::map(., calcDebt)) %>%
  unnest(tbl)

#  
ggplot(df, aes(date, amount, colour = tag)) +
  geom_point(alpha = 0.5, size = 3) +
  geom_line() +
  ggthemes::scale_colour_tableau("Tableau 10") +
  theme_minimal()
      
      





Wir können so etwas bekommen.







Ein Codebildschirm nach Bedarf.







Vorheriger Beitrag - "Storytelling R Report vs. BI, ein pragmatischer Ansatz . "








All Articles