Machine learning Interview
24.4K subscribers
1.04K photos
69 videos
12 files
701 links
Разбираем вопросы с собеседований по Machine Learning, Data Science, Deep Learning и Нейронным сетям, Python.

Вопросы - @notxxx1


@itchannels_telegram -🔥лучшие it каналы

РКН: clck.ru/3FmwRz
Download Telegram
Как узнать больше об LLM?

Large Language Models в последнее время стали слишком популярны, и многие строят свои ML-решения поверх таких LLM. Но не все знают, что злоумышленники могут делать инъекции через промты и нарушить работу модели или вообще сломать систему.

Поэтому VK устраивает онлайн-семинар, где расскажет, какие могут быть опасности и как защитить решения, основанные на LLM. Регистрация по ссылке.
📌Отличие рекуррентных нейронные сети от других методов машинного обучения? Назовите способы улучшения стандартных рекуррентных сетей?

Рекуррентные нейронные сети (RNN) отличаются от других методов машинного обучения тем, что они способны обрабатывать серии событий во времени или последовательные логические цепочки. Рекуррентные нейронные сети могут использовать свою внутреннюю память для обработки последовательностей разной длины.

RNN применимы в таких задачах как, например: распознавание рукописного текста, анализ текстов, распознавание речи и др.

Кроме того, известно, что RNN являются полными по Тьюрингу, и поэтому имеют возможность имитировать произвольные программные процедуры. Но на практике это не всегда просто сделать.

Рекуррентные нейронные сети хорошо справляются с задачами обучения на последовательностных данных и с задачами обучения с подкреплением, но очень ограничены в возможностях для решения задач, связанных с работой со структурами данных и переменными, а также хранением данных в течение длинных временных промежутков из-за отсутствия долгосрочной памяти.

Одним из способов улучшения стандартных рекуррентных сетей для успешного решения алгоритмических задач является введение адресной памяти большого размера. В отличие от машины Тьюринга, нейронная машина Тьюринга (NTM) является полностью дифференцируемой моделью, которая может быть обучена модификациями метода градиентного спуска (например, RMSProp), что дает практический механизм для обучения программ на примерах.

Модель NTM была предложена в 2014-ом году в работе. В этой работе не описаны подробно детали функционирования данной нейросетевой модели. Одной из задач выпускной квалификационной работы является предоставление детального описания работы нейронной машины Тьюринга.

Основным фактором появления нейронных сетей с внешней памятью является изобретение дифференцируемых механизмов внимания.

В 2016-ом году в работе была предложена усовершенствованная модель нейронной сети с внешней памятью под названием дифференцируемый нейронный компьютер. В ней также было лишь краткое описание принципов работы этой модели.

В 2018-ом году в работе были предложены четыре модификации для дифференцируемого нейронного компьютера, которые позволяли улучшить качество решения задач, связанных с вопросно-ответными системами (QA tasks). Эти модификации были основаны на работах.

На сегодняшний день очень высока актуальность создания новых рекуррентных нейросетевых моделей, способных хранить большие объёмы данных, а также успешно решать задачи, предъявляемые к вопросно-ответным системам (QA-задачи).

К таким нейросетевым моделям предъявляются следующие требования:

наличие «долгосрочной» обучаемой памяти;

высокая скорость обучения;

устойчивость процесса обучения (процесс обучения не должен существенно зависеть от начальной инициализации);

прозрачность принятия решений моделью и интерпретируемость работы нейронной сети (попытка уйти от концепции «черного ящика»);

способность решать QA-задачи;

модель должна содержать относительно небольшое количество обучаемых параметров;

способность работать с переменными, а также со структурами данных (например, с графами), решать алгоритмические задачи.

@machinelearning_interview
🖥 Как бы вы реализовали функцию потерь в PyTorch?

В PyTorch функции потерь могут быть реализованы путем создания подкласса класса nn.Module и переопределения метода forward. Метод forward принимает на вход прогнозируемый выход и фактический выход и возвращает значение потерь.

Приведем пример кода:

import torch
import torch.nn as nn

class CustomLoss(nn.Module):
def __init__(self):
super(MyLoss, self).__init__()

def forward(self, output, target):

loss = ... # compute the loss

return loss


Теперь, чтобы использовать функцию потерь, необходимо инициализировать ее и передать в качестве аргумента параметру criterion оптимизатора в цикле обучения.

model = ...
optimizer = ...
criterion = CustomLoss()

# цикл обучения
for epoch in range(num_epochs):

optimizer.zero_grad()
outputs = model(data)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

...


#pytorch #junior

@machinelearning_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет код?
import numpy as np
Polynomial = np.polynomial.Polynomial
p = Polynomial([1, -1, 1])
q = Polynomial([2, -3])
print(int((p + q)(1)))
Выберите правильный вариант
Anonymous Quiz
2%
-2
4%
-1
27%
0
7%
1
3%
2
8%
3
4%
4
3%
17
42%
Посмотреть результаты
🔍 Выявление неявных связей при анализе графов или как увидеть незримое

Неявные связи в графах. Что это и как с ними работать, разберу на примерах.

Граф — множество узлов, объединенных множеством ребер.

С узлами все понятно, взяли города России, клиентов банка или компьютеры в сети, и получили множество объектов, которые и будут узлами для графа.

Что же с ребрами? На первый взгляд все просто: города соединены дорогами, клиенты совершают переводы денежных средств, а компьютеры постоянно обмениваются информацией. Все, что было перечислено, относится к явным типам связей.

Существует факт взаимосвязи между объектами: если дороги нет, то ребро между узлами отсутствует.
Что же относится к неявным связям? Неявные связи сложнее, они могут зависеть от явных связей или же быть самостоятельными.

Например, возьмем двух людей, которые работают на абсолютно разных работах, живут в разных концах города. На первый взгляд, они не имеют ничего общего, но при этом они оба по выходным приходят на матч любимой команды – это и есть неявная связь.

Теперь перейдем к практическому примеру.
Есть 2 файла:

◾️Данные о мошенниках, их номерах телефонов, а также периоды их активности;
◾️Данные о клиентах и номерах телефонов с периодами активности.
◾️Данные с номерами телефонов сложно найти в открытом доступе, придется сгенерировать их самостоятельно. Код для генерации необходимых данных расположен по ссылке.

Следующим этапом будет создание графа. Для этой задачи понадобятся следующие python-библиотеки:

▪️Pandas – для работы с файлами;
▪️NetworkX – для создания графа связей, его визуализации;
▪️Matplotlib и Numpy – нужны для настройки визуализации графа;
▪️Datetime – для операций над временными данными.

Перед созданием графа взглянем на данные, с которыми нам предстоит работать.

Описание данных:

📍index – id клиента / мошенника;
📍numbers – номер телефона;
📍Date_start – начало периода активности;
📍Date_end – окончание периода активности.

➡️ Продолжение
Please open Telegram to view this post
VIEW IN TELEGRAM
🎯Подробный разбор механизма Self-attention больших языковых моделей

В этой статье пошагово с прмиерами кода разобрана работа Self-attention механизма.

Self-attention это механизм предназначенный для обработки последовательных данных с учётом контекста каждой метки времени.

📌Статья

@machinelearning_interview
🖥 Аналитика небольших данных: как совместить Excel, Python и SQL с помощью инструментов с открытым исходным кодом

Однажды Джоэл Спольски в своей знаменитой презентации «You Suck at Excel» сказал, что существуют сотни коммерческих продуктов, вместо которых можно было бы использовать табличку Excel.

В этой шутке очень высокая доля правды. Excel благородя интуитивному UI, формулам и VBA дает возможность пользователям самим решать широкий спектр задач, избавляя от необходимости каждый раз обращаться за помощью к разработчикам или внедрять в компании новый продукт. Excel используется везде от мелкой розницы до Fortune 500 и CERN.

Пользовательский интерфейс Excel оказался, настолько удачным – ни один из конкурентов так и отошел от привычных таблиц. Для пользователя Excel интерфейс Google Spreadsheet будет привычным и интуитивно понятным. А вот по своим функциональным возможностям Excel до сих пор превосходит большинство конкурентов.

Как с помощью двух мощных инструментов с открытым исходным кодом можно совместить привычный для пользователей интерфейс, надежность и мощь SQL, гибкость Python и командную работу как в Google Spreadsheet? Давайте рассмотрим это на простом примере.

📌Читать дальше

@machinelearning_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👆 Принципы SOLID в инженерии данных. Часть 1.

SOLID — это набор основных принципов процесса разработки ПО, направленных на упрощение чтения, тестирования и сопровождения кода.

Как расшифровывается SOLID

Акроним SOLID расшифровывается так:

Single responsibility principle («Принцип единственной ответственности»).
Open/close principle («Принцип открытости/закрытости»).
Liskov substitution principle («Принцип подстановки Лисков»).
Interface segregation principle («Принцип разделения интерфейса»).
Dependency inversion principle («Принцип инверсии зависимостей).

1. Принцип единственной ответственности
Согласно этому принципу, класс должен меняться только по одной причине. То есть у каждого модуля должно быть только одно назначение, отчего код становится удобнее для восприятия и тестирования.

Примеры
Продемонстрируем нарушение и соблюдение принципа единственной ответственности, создав простой класс для банковского счета:

а) нарушение принципа:
class BankAccount:
def __init__(self, account_number: int, balance: float):
self.account_number = account_number
self.balance = balance

def deposit_money(self, amount: float):
self.balance += amount

def withdraw_money(self, amount: float):
if amount > self.balance:
raise ValueError("Unfortunately your balance is insufficient for any withdrawals right now ... ")
self.balance -= amount

def print_balance(self):
print(f'Account no: {self.account_number}, Balance: {self.balance} ')

def change_account_number(self, new_account_number: int):
self.account_number = new_account_number
print(f'Your account number has changed to "{self.account_number}" ')

Принцип нарушается, поскольку классом BankAccount контролируется больше одной задачи, связанной с банковскими счетами: управление профилями счетов и управление денежными средствами.

б) соблюдение принципа:

А вот пример соблюдения принципа:
class DepositManager:
def deposit_money(self, account, amount):
account.balance += amount


class WithdrawalManager:
def withdraw_money(self, account, amount):
if amount > account.balance:
raise ValueError("Unfortunately your balance is insufficient for any withdrawals right now ... ")
account.balance -= amount


class BalancePrinter:
def print_balance(self, account):
print(f'Account no: {account.account_number}, Balance: {account.balance} ')


class AccountNumberManager:
def change_account_number(self, account, new_account_number):
account.account_number = new_account_number
print(f'Your account number has changed to "{account.account_number}" ')


class BankAccount:
def __init__(self, account_number: int, balance: float):
self.account_number = account_number
self.balance = balance
self.deposit_manager = DepositManager()
self.withdrawal_manager = WithdrawalManager()
self.balance_printer = BalancePrinter()
self.account_number_manager = AccountNumberManager()

def deposit_money(self, amount: float):
self.deposit_manager.deposit_money(self, amount)

def withdraw_money(self, amount: float):
self.withdrawal_manager.withdraw_money(self, amount)

def print_balance(self):
self.balance_printer.print_balance(self)

def change_account_number(self, new_account_number: int):
self.account_number_manager.change_account_number(self, new_account_number)

Задачи, связанные с управлением банковским счетом, мы разделили на отдельные классы, упростив в случае необходимости изменение классов одинакового назначения.

в) пример расширения кодовой базы:

🔘 Продолжение части 1
🔘 Часть 2
🔘 Часть 3

@machinelearning_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
🔝Лучшие GitHub репозитории для изучения MLOps.

#️⃣ MLOps-Basics

#️⃣ MLOps-Guide

#️⃣ Awesome MLOps

#️⃣ Awesome MLOps - Tools

#️⃣ DTU MLOps

#️⃣ MLOps Course

@machinelearning_interview
🐼Как устроен Pandas: взгляд изнутри

Структура данных Pandas
Как правило, датафрейм поддерживается каким-нибудь массивом, например NumPy или Pandas ExtensionArray. Эти массивы хранят данные датафрейма. pandas добавляет промежуточный слой Block и BlockManager. Он управляет этими массивами, обеспечивая максимальную эффективность операций. Это одна из причин, почему в Pandas методы, работающие с несколькими столбцами, могут быть очень быстрыми. Далее более подробно рассмотрим упомянутые слои.

Массивы
Фактические данные датафрейма могут храниться в наборе массивов NumPy или Pandas ExtensionArray. Этот слой обычно направляет к базовой реализации, например использует NumPy API при условии хранения данных в массивах NumPy. Pandas хранит в них данные и вызывает свои методы без расширения интерфейса.

Массивы NumPy обычно являются двумерными и дают ряд преимуществ в производительности, о которых речь пойдет далее. На данный момент Pandas ExtensionArray в основном представляют собой одномерные структуры данных, благодаря чему операции становятся предсказуемыми.
Однако не обошлось и без недостатков: в ряде случаев страдает производительность.

ExtensionArray допускает применение датафреймов, которые поддерживаются массивами PyArrow и другими типами данных Pandas.

Block

Датафрейм обычно состоит из столбцов, представленных по крайней мере одним массивом. Как правило, имеется коллекция массивов, так как один массив может хранить только один определенный тип данных. Эти массивы хранят данные, но не владеют информацией о том, какие столбцы они представляют. Каждый массив из датафрейма обернут соответствующим блоком Block.
Block добавляет дополнительную информацию в массивы, например расположение представленных им столбцов.
Block служит слоем вокруг фактических массивов с возможностью расширения вспомогательными методами, необходимыми для операций Pandas.
При выполнении фактической операции с датафреймом Block гарантирует, что метод направляется в базовый массив. Например, при вызове astype он убедится, что эта операция вызывается в массиве.

Данный слой не располагает информацией о других столбцах в датафрейме, являясь автономным объектом.

BlockManager
Как следует из названия, BlockManager управляет всеми Block, связанными с одним датафреймом. Он содержит сами Block и информацию об осях датафрейма, например имена столбцов и метки Index.
И самое главное в том, что он направляет большинство операций к фактическим Block:

df.replace(...)

BlockManager гарантирует, что replace выполняется для каждого Block.

Понятие консолидированного датафрейма
Мы исходим из того, что датафреймы поддерживаются типами данных NumPy, например их данные могут храниться в двумерных массивах.

При создании датафрейма Pandas гарантирует, что на каждый тип данных приходится только один Block:

df = pd.DataFrame(
{
"a": [1, 2, 3],
"b": [1.5, 2.5, 3.5],
"c": [10, 11, 12],
"d": [10.5, 11.5, 12.5],
}
)

У этого датафрейма есть 4 столбца, представленные двумя массивами: один из них хранит целочисленный тип данных, а другой — числа с плавающей точкой. Это и есть консолидированный датафрейм.

Добавим новый столбец к этому датафрейму:
df["new"] = 100

У него такой же тип данных, как и у существующих столбцов "a" и "c". Рассмотрим 2 возможных варианта дальнейших действий:

1. Добавление нового столбца в существующий массив, содержащий целочисленные столбцы.
2. Создание нового массива только для хранения нового столбца.

◾️ Первый вариант предусматривает добавление нового столбца в существующий массив. Для этого требуется скопировать данные, поскольку NumPy не поддерживает эту операцию без копирования. В итоге добавление одного столбца оборачивается слишком большими затратами.

◾️ Второй вариант

📌 Читать

@machinelearning_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔍 Анализ данных для задач НЛП

Для успешного NLP-проекта одним из важнейших этапов является предварительная обработка данных. В этой статье мы рассмотрим все шаги, связанные с анализом данных для любой задачи НЛП.

Для анализа данных мы можем использовать статистические методы, вычислительные алгоритмы, чтобы обработать данные и повысить производительность модели. Шаги, описанные в этом посте, могут быть использованы для анализа данных для любой задачи НЛП.

Настройка среды
Первым шагом любого проекта является настройка среды, т.е. установка важных пакетов и импорт важных библиотек.
!pip install nltk
!pip install pandas


import pandas as pd
import nltk
from nltk.tokenize import sent_tokenize,word_tokenize
from nltk.stem import PorterStemmer
from nltk.corpus import stopwords
import re

Обзор данных
Следующим этапом проекта будет загрузка датасета. В данном случае мы будем использовать набор данных твитов о катастрофах из Kaggle.
Мы можем загрузить наш датасет с помощью библиотеки pandas.

df = pd.read_csv("/train.csv")

Для того чтобы получить общее представление о данных, мы можем просмотреть верхние строки набора данных с помощью функции head в pandas:

df.head(10)

Для анализа столбца ключевых слов мы используем библиотеку seaborn, которая позволяет визуализировать распределение ключевых слов и их корреляцию с целью.

plt.figure(figsize=(10,70))
sns.countplot(data=df,y="keyword",hue="target",saturation=0.50)
plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0)
plt.show()


📌 Продолжение

@machinelearning_interview
🚀 TorchServe – это фреймворк, который является частью экосистемы PyTorch для обслуживания моделей, который является гибким и простым в использовании.

Инструмент позволяет развертывать обученные модели PyTorch без необходимости писать собственный код.

Он обеспечивает очень легкую настройку и низкую задержку даже для масштабных проектов.

Возможности:

Поддержка нескольких форматов моделей (torchscript, onnx, ipex, tensorrt);
TorchServe можно использовать для многих типов вывода в производственных условиях.
Объединение нескольких моделей в один граф/workflow;
Инференс API (REST и GRPC);
API для управления моделями;
Метрики из коробки.

pip install torch==1.7.0 torchvision==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
pip install torchserve==0.2.0 torch-model-archiver==0.2.0


Примеры, демонстрирующие возможности и интеграции TorchServe

@machinelearning_interview
🚗 Тест-драйв PyTorch 2.0 и заглядываем под капот «двушки»

⚜️ Новейший метод для ускорения кода в PyTorch 2.0 — torch.compile(), который позволяет JIT‑компилировать код PyTorch в оптимизированные ядра, требуя минимальных изменений кода.

JIT‑компиляция (Just‑In‑Time compilation) — это процесс, при котором код на высокоуровневом языке преобразуется в код на низкоуровневом языке, который может быть быстрее и эффективнее исполнен процессором или графическим ускорителем. torch.compile() использует TorchDynamo и заданный бэкенд для JIT‑компиляции кода PyTorch.

Рассмотрим, насколько эффективен torch.compile() на практике, заглянем под капот «двушки» PyTorch 2.0, чтобы узнать, как работает этот метод и какие преимущества он дает.

Разработчики PyTorch заявляют, что torch.compile() может дать прирост производительности до 50% по сравнению с обычным кодом PyTorch. Для проверки этого заявления мы проведем ряд экспериментов на разных моделях и данных, выясним, есть ли реальная выгода от использования torch.compile().

📌 Для того чтобы понять, как работает torch.compile() рассмотрим основные его компоненты, которые отвечают за различные аспекты JIT‑компиляции кода PyTorch:

▪️TorchDynamo — это динамический компилятор, который анализирует код PyTorch и определяет, какие части кода могут быть скомпилированы в оптимизированные ядра. Отслеживает изменения в коде и перекомпилирует его при необходимости.

▪️AOT AutoGrad — это система автоматического дифференцирования, которая позволяет вычислять градиенты для скомпилированных ядер. Генерирует код для обратного распространения ошибки во время компиляции, а не во время исполнения, что ускоряет процесс обучения нейронных сетей.

▪️PrimTorch — это набор примитивных операций, которые используются для построения скомпилированных ядер. Включает в себя базовые математические и логические операции, а также операции над тензорами, такие как сложение, умножение, свертка и т. д.

▪️TorchInductor — это бэкенд для JIT‑компиляции кода PyTorch в оптимизированные ядра для разных устройств. Поддерживает разные бэкенды и адаптирует код PyTorch к специфике каждого устройства.

Далее подробнее рассмотрим, как работают компоненты TorchDynamo и TorchInductor и как они взаимодействуют друг с другом, чтобы обеспечить JIT‑компиляцию кода PyTorch.

📌Читать

@machinelearning_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
🚀 Опишите алгоритм для нахождения миллиона наименьших чисел в наборе из миллиарда чисел. Память компьютера позволяет хранить весь миллиард чисел. Если придумали какое-либо решение, то оцените его эффективность по времени. Есть ли более эффективное решение?

Решение 1. Сортировка
Можно отсортировать элементы в порядке возрастания, а затем взять первый миллион чисел. Это потребует O(n log(n)) времени.

Решение 2. Минимум кучи
Чтобы решить эту задачу, можно использовать минимум кучи. Мы сначала создаем кучу для первого миллиона чисел с наибольшим элементом сверху.

Затем мы проходимся по списку. Вставляя элемент в список, удаляем наибольший элемент.

В итоге мы получим кучу, содержащую миллион наименьших чисел. Эффективность алгоритма O(n log(m)), где m — количество значений, которые нужно найти.

Решение 3. Ранжирование (если изменять исходный массив)
Данный алгоритм очень популярен и позволяет найти i-й наименьший (или наибольший) элемент в массиве.

Если элементы уникальны, поиск i-гo наименьшего элемента потребует О(n) времени. Основной алгоритм будет таким:

Выберите случайный элемент в массиве и используйте его в качестве «центра». Разбейте элементы вокруг центра, отслеживая число элементов слева.

Если слева находится ровно i элементов, вам нужно вернуть наибольший элемент.

Если слева находится больше элементов, чем i, то повторите алгоритм, но только для левой части массива.

Если элементов слева меньше, чем i, то повторите алгоритм справа, но ищите алгоритм с рангом i - leftSize.

Приведенный далее код реализует этот алгоритм.

public int partition(int[] array, int left, int right, int pivot) {
while (true) {
while (left <= right && array[left] <= pivot) {
left++;
}

while (left <= right && array[right] > pivot) {
right--;
}

if (left > right) {
return left - 1;
}

swap(array, left, right);
}
}

public int rank(int[] array, int left, int right, int rank) {
int pivot = array[randomIntInRange(left, right)];

/* Раздел и возврат конца левого раздела */
int leftEnd = partition(array, left, right, pivot);

int leftSize = leftEnd - left + 1;
if (leftSize == rank + 1) {
return max(array, left, leftEnd);
} else if (rank < leftSize) {
return rank(array, left, leftEnd, rank);
} else {
return rank(array, leftEnd + 1, right, rank - leftSize);
}
}

Как только найден наименьший i-й элемент, можно пройтись по массиву и найти все значения, которые меньше или равны этому элементу.

Если элементы повторяются (вряд ли они будут «уникальными»), можно слегка модифицировать алгоритм, чтобы он соответствовал этому условию. Но в этом случае невозможно будет предсказать время его выполнения.

Существует алгоритм, гарантирующий, что мы найдем наименьший i-й элемент за линейное время, независимо от «уникальности» элементов. Однако эта задача несколько сложнее. Если вас заинтересовала эта тема, этот алгоритм приведен в книге Т. Кормен, Ч. Лейзер-сон, Р. Ривестп, К. Штайн «CLRS’ Introduction to Algorithms» (есть в переводе).

Пишите свое решение в комментариях👇

@machinelearning_interview
📃 Генерация отчетов графовой аналитики в формате PDF с помощью Python

Создание отчетов графовой аналитики является важной частью работы многих проектов и бизнес-процессов.
Однако, процесс создания и настройки таких отчетов может быть сложным и требовать больших усилий.

Рассмотрим, как использование языка программирования Python и его библиотек может значительно упростить генерацию отчетов графовой аналитики в формате PDF.

Для работы с PDF в Python есть множество библиотек, самые популярные из них: PyPDF2, ReportLab, FPDF.

Сравнение основных библиотек: в изображении.

По совокупным критериям для дальнейшего разбора мной была выбрана библиотека ReportLab.

Одной из самых популярных библиотек для работы с графами в Python является NetworkX. Она предоставляет широкий набор инструментов для создания и анализа графов. Ее и буду использовать для создания графа и анализа данных.

В посте приведен код, необходимый для воспроизведения. Полный код доступен по ссылке.

Данные сгенерирую с помощью Python.
Пусть будет 500 операций, где будет информация об отправителе, получателе, сумме операции и флаг подозрительности операции.

df_dict = {}
count_operation = 500
for i in range(count_operation):
df_dict[i] = {'reciver' : random.randint(1, count_operation/2),
'sender': random.randint(1, count_operation/2),
'sum_oper': random.randint(1000, 1000000),
'suspisios_transaction': random.randint(0, 1)}


Добавлю 100 переводов, где получателем будет клиент 1, а отправителем- любой другой клиент из основного датасета:

for i in range(100):
df_dict[i] = {'reciver' : 1,
'sender': random.randint(1, count_operation/2),
'sum_oper': random.randint(1000, 1000000),
'suspisios_transaction': random.randint(0, 1)}
df = pd.DataFrame().from_dict(df_dict).T


Получится вот такой датасет:

Смотреть
Please open Telegram to view this post
VIEW IN TELEGRAM