[Python, Data Mining, Big Data, R, Визуализация данных] Оценка кредитного портфеля на R
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В ходе обсуждений возникла «маленькая» задачка — построить динамику структуры кредитного портфеля (динамика кредитной карты, например). В качестве важной специфики — необходимо применять метод FIFO для погашения займов. Т.е. при погашении первыми должны гаситься самые ранние займы. Это накладывает определенные требования на расчет статуса каждого отдельного займа и определения его даты погашения.
Ниже приведен код на R с прототипом подхода. Не более одного экрана кода на прототип и никаких циклов (закладные для производительности и читаемости).
Декомпозиция
Поскольку мы делаем все с чистого листа, то задачу разбиваем на три шага:
- Формирование тестовых данных.
- Расчет даты погашения каждого займа.
- Расчет и визуализация динамики для заданного временнОго окна.
Допущения и положения для прототипа:
- Гранулярность до даты. В одну дату — только одна транзакция. Если в один день будет несколько транзакций, то надо будет их порядок устанавливать (для соблюдения принципа FIFO). Можно использовать доп. индексы, можно использовать unixtimestamp, можно еще что-либо придумывать. Для прототипа это несущественно.
- Явных циклов for быть не должно. Лишних копирований быть не должно. Фокус на минимальное потребление памяти и максимальную производительность.
- Будем рассматривать следующие группы задержек: "< 0", "0-30", "31-60", "61-90", "90+".
Шаг 1.
Генерируем датасет. Просто тестовый датасет. Для каждого пользователя сформируем ~ по 10 записей. Для расчетов полагаем, что займ — положительное значение, погашение — отрицательное. И весь жизненный цикл для каждого пользователя должен начинаться с займа.
Генерация датасета
SPL
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"))
Шаг 2. Расчитываем даты погашения каждого займа
data.table позволяет изменять объекты по ссылке даже внутри функций, будем этим активно пользоваться.
Расчет даты погашения
SPL
# инициализируем аккумулятор
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)]
Шаг 3. Считаем динамику задолженности за период
Расчет динамики
SPL
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()
Можем получить примерно такую картинку.
Один экран кода, как и требовалось.
Предыдущая публикация — «Storytelling R отчет против BI, прагматичный подход».
===========
Источник:
habr.com
===========
Похожие новости:
- [Usability, Разработка под e-commerce, Growth Hacking, Искусственный интеллект] Как чат-боты помогают цирку, вузу и эко-проекту — 5 неординарных кейсов на визуальном конструкторе c NLU
- [Big Data, Data Engineering] Курсы валют и аналитика – использование обменных курсов в Хранилище Данных
- В менеджере паролей 1Password реализована полноценная поддержка Linux
- [Анализ и проектирование систем, Облачные вычисления, API, Облачные сервисы, Serverless] Облачные Gateway API: зачем нужны подобные сервисы и чем они отличаются у разных платформ
- [Облачные сервисы] Google объединила Документы с другими офисными продуктами
- [Java, Apache] Как на самом деле работает auto-commit в Kafka и можем ли мы на него расчитывать?
- [Программирование, Анализ и проектирование систем, Аналитика мобильных приложений] Какие ошибки совершает аналитик в первые полгода работы и как их избежать
- [Разработка под Windows, Софт] Microsoft «убила» проект Windows 10X
- [Разработка мобильных приложений, Искусственный интеллект, Здоровье, IT-компании] «Сбер» запустил мобильное приложение AI Resp, диагностирующее признаки COVID-19 по дыханию и кашлю
- [Python, HTML] Форма № 16
Теги для поиска: #_python, #_data_mining, #_big_data, #_r, #_vizualizatsija_dannyh (Визуализация данных), #_data_science, #_biznesanaliz (бизнес-анализ), #_python, #_data_mining, #_big_data, #_r, #_vizualizatsija_dannyh (
Визуализация данных
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:15
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В ходе обсуждений возникла «маленькая» задачка — построить динамику структуры кредитного портфеля (динамика кредитной карты, например). В качестве важной специфики — необходимо применять метод FIFO для погашения займов. Т.е. при погашении первыми должны гаситься самые ранние займы. Это накладывает определенные требования на расчет статуса каждого отдельного займа и определения его даты погашения. Ниже приведен код на R с прототипом подхода. Не более одного экрана кода на прототип и никаких циклов (закладные для производительности и читаемости). Декомпозиция Поскольку мы делаем все с чистого листа, то задачу разбиваем на три шага:
Допущения и положения для прототипа:
Шаг 1. Генерируем датасет. Просто тестовый датасет. Для каждого пользователя сформируем ~ по 10 записей. Для расчетов полагаем, что займ — положительное значение, погашение — отрицательное. И весь жизненный цикл для каждого пользователя должен начинаться с займа. Генерация датасетаSPLlibrary(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")) Шаг 2. Расчитываем даты погашения каждого займа data.table позволяет изменять объекты по ссылке даже внутри функций, будем этим активно пользоваться. Расчет даты погашенияSPL# инициализируем аккумулятор
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)] Шаг 3. Считаем динамику задолженности за период Расчет динамикиSPLcalcDebt <- 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() Можем получить примерно такую картинку. Один экран кода, как и требовалось. Предыдущая публикация — «Storytelling R отчет против BI, прагматичный подход». =========== Источник: habr.com =========== Похожие новости:
Визуализация данных ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:15
Часовой пояс: UTC + 5