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

Статьи

Vibe-кодинг приватного ИИ-аналитика на Python

Проект vibe-кодинга на Python создал приватного ИИ-аналитика финансов с локальными LLM. Приложение автоматически разбирает CSV разных банков, классифицирует транзакции по правилам, находит аномалии Isolation Forest и генерирует insights через Ollama. Всё работает локально с интерактивными Plotly-графиками в Streamlit.

25 марта 2026 г.
8 мин
25
Создание приватного ИИ-финансового аналитика на Python и локальных LLM
Изображение к статье

Введение

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

Что начиналось как хобби на выходные, превратилось в исследование обработки данных из реальной жизни, применения машинного обучения и возможностей локальных больших языковых моделей. Здесь разберут создание приложения для финансового анализа на Python с использованием vibe-кодинга. Получится освоить навыки, полезные для любых задач по данным — от логов продаж до отзывов клиентов.

В итоге станет ясно:

  • Как собрать надежную цепочку подготовки данных для хаотичных CSV-файлов из практики.
  • Как подбирать модели машинного обучения при дефиците обучающих примеров.
  • Как строить интерактивные графики, которые решают задачи пользователей.
  • Как подключить локальную языковую модель для текстовых выводов без ущерба приватности.
Панель приложения с разбивкой расходов и выводами ИИ
Панель приложения отображает разбивку расходов и insights от ИИ

Задача: зачем появился этот инструмент

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

  1. Позволять загружать и разбирать данные сразу.
  2. Работать полностью локально — без облака и утечек.
  3. Давать insights от ИИ, а не только статичные диаграммы.

Проект помог освоить ключевые умения для специалистов по данным: борьбу с разными форматами, выбор алгоритмов для малых наборов и создание ИИ-функций с защитой приватности.

Архитектура проекта

Перед кодом — обзор структуры, чтобы понять связи компонентов:

project/├── app.py # Основное приложение Streamlit├── config.py # Настройки (категории, конфиг Ollama)├── preprocessing.py # Автоопределение форматов CSV, нормализация├── ml_models.py # Классификатор транзакций + детектор аномалий Isolation Forest├── visualizations.py # Графики Plotly (круговая, столбцы, временная шкала, тепловая карта)├── llm_integration.py # Интеграция Ollama со стримингом├── requirements.txt # Зависимости├── README.md # Документация с глубокими разбором уроков└── sample_data/├── sample_bank_statement.csv└── sample_bank_format_2.csv

Каждый слой разберут по порядку.

Шаг 1: Надежная цепочка подготовки данных

Первое открытие — данные из жизни всегда беспорядочны. Банки экспортируют CSV по-разному: Chase использует "Transaction Date" и "Amount", Bank of America — "Date", "Payee" плюс отдельные столбцы "Debit" и "Credit". Moniepoint и OPay имеют свои варианты.

Цепочка подготовки обязана справляться с этим автоматически.

Автоопределение соответствий столбцов

Система на основе шаблонов распознает столбцы независимо от названий. Регулярные выражения сопоставляют их со стандартными полями.

import re
COLUMN_PATTERNS = {
    "date": [r"date", r"trans.*date", r"posting.*date"],
    "description": [r"description", r"memo", r"payee", r"merchant"],
    "amount": [r"^amount$", r"transaction.*amount"],
    "debit": [r"debit", r"withdrawal", r"expense"],
    "credit": [r"credit", r"deposit", r"income"],
}

def detect_column_mapping(df):
    mapping = {}
    for field, patterns in COLUMN_PATTERNS.items():
        for col in df.columns:
            for pattern in patterns:
                if re.search(pattern, col.lower()):
                    mapping[field] = col
                    break
    return mapping

Суть в адаптации к вариациям, а не к фиксированным форматам. Подходит для любых CSV с типичными финансовыми терминами.

Нормализация к единой схеме

После распознавания все приводят к общему виду. Банки с раздельными debit/credit объединяют в один столбец amount (отрицательный для трат, положительный для доходов):

if "debit" in mapping and "credit" in mapping:
    debit = df[mapping["debit"]].apply(parse_amount).abs() * -1
    credit = df[mapping["credit"]].apply(parse_amount).abs()
    normalized["amount"] = credit + debit

Главный вывод: нормализуйте данные на старте. Это упрощает дальнейшую работу — от создания признаков до моделей и графиков.

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

Шаг 2: Выбор моделей машинного обучения при малом объеме данных

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

Классификация транзакций: гибридный метод

Вместо чистого ML применили комбинацию:

  1. Сопоставление по правилам для ясных случаев (например, "WALMART" → продукты).
  2. Шаблоны для неоднозначных операций.
SPENDING_CATEGORIES = {
    "groceries": ["walmart", "costco", "whole foods", "kroger"],
    "dining": ["restaurant", "starbucks", "mcdonald", "doordash"],
    "transportation": ["uber", "lyft", "shell", "chevron", "gas"],
    # ... другие категории
}

def classify_transaction(description, amount):
    for category, keywords in SPENDING_CATEGORIES.items():
        if any(kw in description.lower() for kw in keywords):
            return category
    return "income" if amount > 0 else "other"

Система запускается без обучения и легко настраивается.

Обнаружение аномалий: преимущества Isolation Forest

Для подозрительных трат требовался алгоритм, который:

  1. Работает на малых наборах (не глубокое обучение).
  2. Не зависит от распределения данных (не просто Z-score).
  3. Дает быстрые предсказания для интерфейса.

Isolation Forest из scikit-learn подошел идеально. Он изолирует аномалии случайными разбиениями: редкие и отличные точки требуют меньше разделов.

from sklearn.ensemble import IsolationForest
detector = IsolationForest(
    contamination=0.05, # Ожидаем ~5% аномалий
    random_state=42
)
detector.fit(features)
predictions = detector.predict(features) # -1 = аномалия

Добавили Z-score для явных выбросов. Z-score показывает расстояние от среднего в стандартных отклонениях:
z = (x - μ) / σ
Комбинация ловит больше, чем каждый метод по отдельности.

Главный вывод: простые подходящие алгоритмы часто лучше сложных при дефиците данных.

Детектор аномалий помечает необычные транзакции на временной шкале
Детектор аномалий выделяет подозрительные операции на timeline

Шаг 3: Графики, которые решают вопросы

Визуализации обязаны давать ответы, а не просто отображать цифры. Plotly выбрали за интерактивность, позволяющую пользователям самим копать глубже. Принципы:

  1. Единая цветовая схема: красный для трат, зеленый для доходов.
  2. Сравнения для контекста: доходы рядом с расходами.
  3. Постепенное раскрытие: обзор сначала, детали по клику.

Разбивка трат — в виде пончика для чистоты:

import plotly.express as px
fig = px.pie(
    category_totals,
    values="Amount",
    names="Category",
    hole=0.4,
    color_discrete_map=CATEGORY_COLORS
)

Streamlit упрощает вставку через st.plotly_chart() для отзывчивой панели.

Разные типы графиков дают новые взгляды на данные
Несколько видов чартов предлагают разные ракурсы на одни данные

Шаг 4: Локальная большая языковая модель для текстовых выводов

Последний элемент — человекочитаемые insights. Подключили Ollama для локального запуска LLM. Почему не OpenAI или Claude?

  1. Приватность: банковские данные не уходят с машины.
  2. Экономия: безлимитные запросы, ноль затрат на API.
  3. Скорость: без сетевых задержек (генерация занимает секунды).

Стриминг для удобства

LLM генерирует медленно, но Streamlit показывает токены по мере поступления, сокращая ощущение ожидания. Пример с requests:

import requests
import json

def generate(self, prompt):
    response = requests.post(
        f"{self.base_url}/api/generate",
        json={"model": "llama3.2", "prompt": prompt, "stream": True},
        stream=True
    )
    for line in response.iter_lines():
        if line:
            data = json.loads(line)
            yield data.get("response", "")

В Streamlit — st.write_stream().

st.write_stream(llm.get_overall_insights(df))

Промты для финансовых данных

Качество вывода зависит от структурированного промта с реальными цифрами:

prompt = f"""
Analyze this financial summary:
- Total Income: ${income:,.2f}
- Total Expenses: ${expenses:,.2f}
- Top Category: {top_category}
- Largest Anomaly: {anomaly_desc}
Provide 2-3 actionable recommendations based on this data."""

Конкретные значения делают insights точными.

Интерфейс загрузки прост: выберите CSV, и ИИ возьмет на себя остальное
Интерфейс загрузки минималистичен: файл CSV — и анализ готов

Запуск приложения

Установка проста. Нужен Python, затем:

pip install -r requirements.txt
# Опционально, для insights ИИ
ollama pull llama3.2
streamlit run app.py

Загрузите CSV банка (формат определяется сам), и панель покажет категории, аномалии и insights от ИИ.

Итоги

Проект показал: рабочий прототип — только старт. Настоящее понимание приходит при разборе причин успеха каждого блока:

  • Автоопределение столбцов нужно, потому что данные не следуют схеме. Гибкая цепочка экономит часы на ручной чистке.
  • Isolation Forest подходит для малых наборов. Глубокое обучение не всегда обязательно.
  • Локальные LLM важны для приватности и затрат. Их запуск стал реальностью.

Эти принципы работают за пределами финансов: для продаж, логов серверов или измерений. Надежная подготовка, практичные модели и ИИ с защитой данных пригодятся везде.

Горячее

Загружаем популярные статьи...