Implementing AI Expense Analysis and Transaction Categorization in a Mobile App
Manual transaction categorization — users do it the first week, then abandon it. Rule-based automation ("if memo contains 'LENTA' → 'Groceries'") works for major retailers but fails on "OOO PERSPEKTIVA" or "IP Ivanov A.V.". An ML categorizer with an LLM on top delivers a different quality level. We implement turnkey solutions — from data collection to deployment in App Store and Google Play. Our 5+ years of mobile development experience (40+ projects) lets us embed AI modules without sacrificing device performance.
How the Hybrid Approach Works
ML classifier (TF-IDF + LightGBM or distilBERT). Trained on historical transactions with labels. Inference < 10 ms, works offline, cost — zero after training. Accuracy on top-100 merchants: 95%+, on long-tail (small businesses): 60–70%.
LLM for unrecognized transactions. Transactions with low classifier confidence (< 0.7) are sent to an LLM. GPT-4o-mini, temperature=0, single prompt with categories and examples — response in 300–500 ms, accuracy on unusual names: 80–90%.
# Server-side categorization pipeline async def categorize_transaction(transaction: Transaction) -> CategoryResult: # 1. Fast classifier ml_result = classifier.predict(transaction.description) if ml_result.confidence >= 0.75: return CategoryResult( category=ml_result.category, confidence=ml_result.confidence, method="ml_classifier" ) # 2. LLM for uncertain predictions llm_category = await llm_categorize( description=transaction.description, amount=transaction.amount, merchant=transaction.merchant_name ) return CategoryResult( category=llm_category, confidence=0.85, # LLM more confident in complex cases method="llm_fallback" ) Hybrid approach: 85–90% of transactions handled by fast classifier (free), 10–15% by LLM. At 1,000 transactions per day per user, LLM query cost is negligible.
Comparison of Categorization Approaches
| Approach | Accuracy on known merchants | Accuracy on rare merchants | Response time |
|---|---|---|---|
| Rules (regex) | 70-80% | 30-50% | <1 ms |
| ML classifier (LightGBM) | 95%+ | 60-70% | <10 ms |
| LLM (GPT-4o-mini) | 85-90% | 80-90% | 300-500 ms |
| Hybrid (ML+LLM) | 95%+ | 85-90% | <50 ms |
Hybrid wins overall: high accuracy across the spectrum at minimal cost.
Merchant Data Enrichment
Bank statement names are dirty data. "MAGNIT COSMETIC 0001" and "МАГНИТ КОСМЕТИК" are the same merchant. Normalization via merchant databases (Clearbit, Plaid Enrich, or custom mapping) significantly boosts classifier accuracy.
An additional signal is the MCC code (Merchant Category Code) that banks transmit with each transaction. MCC 5411 — grocery stores, MCC 5812 — restaurants. Using MCC as a classifier feature yields +5–10% accuracy.
AI Analysis of Spending Patterns
Categorization is step one. AI analysis on top of categorized data — that turns an app from a tracker into an advisor.
// iOS — Swift: LLM request for monthly expense analysis func generateExpenseInsights(transactions: [CategorizedTransaction]) async -> [Insight] { let summary = transactions.groupBy(\.category) .mapValues { txs in (count: txs.count, total: txs.map(\.amount).reduce(0, +)) } .map { "\($0.key): \($0.value.total) RUB (\($0.value.count) transactions)" } .joined(separator: "\n") let prompt = """ Analyze the user's monthly expenses and give 2-3 specific observations. Not generic advice — concrete patterns from the data. Expenses by category:\n\(summary) """ let response = await llmClient.complete(prompt, maxTokens: 300, temperature: 0.4) return parseInsights(response) } The LLM sees: "Delivery food spending increased significantly compared to last month" and generates a concrete observation, not a generic "watch your food expenses".
Why Choose AI Categorization?
Rules become stale, and users don't want to spend time on manual entry. AI categorization with personalization boosts app retention by 20–30%. We guarantee classification accuracy of at least 90% on complete data after two weeks of training. Contact us for a consultation — we'll assess your project and propose the optimal architecture.
Training on User Corrections
Users correct misclassified categories — that's gold for retraining. Each correction is a new labeled example. After accumulating enough corrections (50–100 per user), we can fine-tune a personalized model or add user-specific rules:
// Android — saving user correction fun saveUserCorrection(transactionId: String, correctedCategory: Category) { val correction = UserCorrection( transactionDescription = getTransaction(transactionId).description, merchantId = getTransaction(transactionId).merchantId, correctedCategory = correctedCategory, timestamp = System.currentTimeMillis() ) localDatabase.saveCorrection(correction) // Sync to server for retraining syncService.scheduleCorrectionUpload(correction) } What's Included
- AI module architecture and integration with existing app
- ML classifier development (LightGBM or BERT) with training pipeline
- LLM wrapper for handling complex transactions
- User correction collection and retraining mechanism
- Integration with App Store and Google Play (via Firebase App Distribution)
- Code documentation, maintenance and retraining instructions
- One month of technical support post-release
Timeline Estimates
Rule + MCC classifier: 3–5 days. ML classifier with LLM fallback: 1–2 weeks. Full system with pattern analysis, insights, and correction learning: 2–4 weeks.
Order AI categorization development for your mobile app. Contact us — we'll prepare a commercial proposal tailored to your data and requirements.







