From 16c7e05812d756fa474dc3cd76b8aa04a4649a65 Mon Sep 17 00:00:00 2001 From: lokeshramchand-ctrl Date: Fri, 22 Aug 2025 11:18:01 +0530 Subject: [PATCH] OHO-17(Perfect Prediction) --- .vscode/settings.json | 6 +- .../transaction_rules.cpython-313.pyc | Bin 0 -> 8482 bytes AI/Rules/transaction_rules.py | 289 ++++++++++++++++++ AI/predict_api.py | 47 ++- .../training.ipynb} | 0 5 files changed, 335 insertions(+), 7 deletions(-) create mode 100644 AI/Rules/__pycache__/transaction_rules.cpython-313.pyc create mode 100644 AI/Rules/transaction_rules.py rename AI/{model/ml_transcation.ipynb => train/training.ipynb} (100%) diff --git a/.vscode/settings.json b/.vscode/settings.json index d3cb2ac..bc8cda7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,7 @@ { - "postman.settings.dotenv-detection-notification-visibility": false + "postman.settings.dotenv-detection-notification-visibility": false, + "python.analysis.extraPaths": [ + "./AI/Rules/transaction_", + "./AI/Rules/transaction_" + ] } diff --git a/AI/Rules/__pycache__/transaction_rules.cpython-313.pyc b/AI/Rules/__pycache__/transaction_rules.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..103ddc532cf8fd2d8c1356a1371282b1c8aa1ca4 GIT binary patch literal 8482 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 Xh|>cD194_OGcfkb_-9k}$`AbyC(>-w literal 0 HcmV?d00001 diff --git a/AI/Rules/transaction_rules.py b/AI/Rules/transaction_rules.py new file mode 100644 index 0000000..194436b --- /dev/null +++ b/AI/Rules/transaction_rules.py @@ -0,0 +1,289 @@ +# vendor_rules.py +def get_category_from_rules(vendor_name: str): + if not vendor_name: + return None + + vendor = vendor_name.lower() + + # Food , Shopping , Bills , Travel , Entertainment , Other + mapping = { + # ---------- FOOD ---------- + "mcdonalds": "Food", + "kfc": "Food", + "hotel": "Food", + "restaurant": "Food", + "canteen": "Food", + "dhaba": "Food", + "mess": "Food", + "biryani": "Food", + "tiffins": "Food", + "cafe": "Food", + "coffee": "Food", + "tea stall": "Food", + "bakery": "Food", + "sweets": "Food", + "ice cream": "Food", + "juice": "Food", + "snacks": "Food", + "lunch": "Food", + "dinner": "Food", + "food court": "Food", + "catering": "Food", + "canteen store": "Food", + "dominos": "Food", + "pizza hut": "Food", + "subway": "Food", + "starbucks": "Food", + "cafe coffee day": "Food", + "ccd": "Food", + "swiggy": "Food", + "zomato": "Food", + "ubereats": "Food", + "barbeque nation": "Food", + "wow momo": "Food", + "cream stone": "Food", + "bikanervala": "Food", + "haldiram": "Food", + "paradise biryani": "Food", + "behrouz biryani": "Food", + "freshmenu": "Food", + "burger king": "Food", + "taco bell": "Food", + "sagar ratna": "Food", + "shs canteen": "Food", + "babai hotel": "Food", + "taj hotel": "Food", + "itc hotel": "Food", + "novotel": "Food", + "radisson": "Food", + "trident": "Food", + + # ---------- SHOPPING ---------- + "mall": "Shopping", + "store": "Shopping", + "supermarket": "Shopping", + "bazaar": "Shopping", + "market": "Shopping", + "mart": "Shopping", + "fashion": "Shopping", + "clothing": "Shopping", + "footwear": "Shopping", + "electronics": "Shopping", + "mobile store": "Shopping", + "accessories": "Shopping", + "furniture": "Shopping", + "home decor": "Shopping", + "appliances": "Shopping", + "cosmetics": "Shopping", + "salon": "Shopping", + "boutique": "Shopping", + "jewellery": "Shopping", + "stationery": "Shopping", + "amazon": "Shopping", + "flipkart": "Shopping", + "myntra": "Shopping", + "ajio": "Shopping", + "tatacliq": "Shopping", + "meesho": "Shopping", + "snapdeal": "Shopping", + "shopclues": "Shopping", + "bigbasket": "Shopping", + "grofers": "Shopping", + "dmart": "Shopping", + "reliance fresh": "Shopping", + "more supermarket": "Shopping", + "spencers": "Shopping", + "vishal mega mart": "Shopping", + "zudio": "Shopping", + "pantaloons": "Shopping", + "lifestyle": "Shopping", + "shoppers stop": "Shopping", + "westside": "Shopping", + "max fashion": "Shopping", + "nike": "Shopping", + "adidas": "Shopping", + "puma": "Shopping", + "reebok": "Shopping", + "levi": "Shopping", + "h&m": "Shopping", + "zara": "Shopping", + "decathlon": "Shopping", + "ikea": "Shopping", + + # ---------- BILLS ---------- + "electricity": "Bills", + "power": "Bills", + "water bill": "Bills", + "internet": "Bills", + "wifi": "Bills", + "broadband": "Bills", + "dth": "Bills", + "recharge": "Bills", + "gas": "Bills", + "cylinder": "Bills", + "mobile bill": "Bills", + "postpaid": "Bills", + "prepaid": "Bills", + "telecom": "Bills", + "landline": "Bills", + "sewage": "Bills", + "municipal": "Bills", + "property tax": "Bills", + "credit card": "Bills", + "loan emi": "Bills", + "bescom": "Bills", # electricity + "tsspdcl": "Bills", + "apspdcl": "Bills", + "torrent power": "Bills", + "bese": "Bills", + "bmtc pass": "Bills", + "airtel": "Bills", + "jio": "Bills", + "vi": "Bills", + "bsnl": "Bills", + "act fibernet": "Bills", + "hathway": "Bills", + "den broadband": "Bills", + "tatasky": "Bills", + "airtel dth": "Bills", + "sun direct": "Bills", + "dishtv": "Bills", + "dth recharge": "Bills", + "gas bill": "Bills", + "bharat gas": "Bills", + "hp gas": "Bills", + "indane gas": "Bills", + + # ---------- TRAVEL ---------- + "cab": "Travel", + "taxi": "Travel", + "auto": "Travel", + "bus": "Travel", + "train": "Travel", + "railway": "Travel", + "metro": "Travel", + "flight": "Travel", + "airlines": "Travel", + "airport": "Travel", + "air ticket": "Travel", + "ticket": "Travel", + "boarding": "Travel", + "lodge": "Travel", + "resort": "Travel", + "tour": "Travel", + "travel agency": "Travel", + "holiday": "Travel", + "trip": "Travel", + "taxi service": "Travel", + "ola": "Travel", + "uber": "Travel", + "redbus": "Travel", + "abhibus": "Travel", + "irctc": "Travel", + "indigo": "Travel", + "air india": "Travel", + "vistara": "Travel", + "spicejet": "Travel", + "goair": "Travel", + "akasa air": "Travel", + "makemytrip": "Travel", + "yatra": "Travel", + "cleartrip": "Travel", + "booking.com": "Travel", + "oyo": "Travel", + "treebo": "Travel", + "fabhotel": "Travel", + "trivago": "Travel", + "zoomcar": "Travel", + "drivezy": "Travel", + + # ---------- ENTERTAINMENT ---------- + "cinema": "Entertainment", + "movie": "Entertainment", + "theatre": "Entertainment", + "concert": "Entertainment", + "event": "Entertainment", + "show": "Entertainment", + "festival": "Entertainment", + "ticketnew": "Entertainment", + "games": "Entertainment", + "gaming": "Entertainment", + "amusement": "Entertainment", + "theme park": "Entertainment", + "club": "Entertainment", + "pub": "Entertainment", + "bar": "Entertainment", + "karaoke": "Entertainment", + "music": "Entertainment", + "streaming": "Entertainment", + "subscription": "Entertainment", + "video": "Entertainment", + "netflix": "Entertainment", + "amazon prime": "Entertainment", + "hotstar": "Entertainment", + "disney+": "Entertainment", + "sonyliv": "Entertainment", + "zee5": "Entertainment", + "aha": "Entertainment", + "spotify": "Entertainment", + "gaana": "Entertainment", + "wynk": "Entertainment", + "saregama": "Entertainment", + "bookmyshow": "Entertainment", + "pvr": "Entertainment", + "inox": "Entertainment", + "cinepolis": "Entertainment", + "jio cinema": "Entertainment", + "altbalaji": "Entertainment", + "voot": "Entertainment", + "apple music": "Entertainment", + "youtube premium": "Entertainment", + + # ---------- OTHER ---------- + "apollo pharmacy": "Other", + "pharmacy": "Other", + "medical": "Other", + "chemist": "Other", + "clinic": "Other", + "hospital": "Other", + "doctor": "Other", + "diagnostic": "Other", + "lab": "Other", + "insurance": "Other", + "policy": "Other", + "atm": "Other", + "bank": "Other", + "branch": "Other", + "transaction": "Other", + "school": "Other", + "college": "Other", + "university": "Other", + "coaching": "Other", + "training": "Other", + "service": "Other", + "repair": "Other", + "medplus": "Other", + "1mg": "Other", + "pharmeasy": "Other", + "netmeds": "Other", + "urbanclap": "Other", + "urban company": "Other", + "justdial": "Other", + "olx": "Other", + "quikr": "Other", + "paytm": "Other", + "phonepe": "Other", + "google pay": "Other", + "freecharge": "Other", + "mobikwik": "Other", + "upi": "Other", + "insurance": "Other", + "policybazaar": "Other", + "bank": "Other" + } + + for keyword, category in mapping.items(): + if keyword in vendor: + return category + + return None diff --git a/AI/predict_api.py b/AI/predict_api.py index 7d85772..e609be1 100644 --- a/AI/predict_api.py +++ b/AI/predict_api.py @@ -1,10 +1,39 @@ +# from flask import Flask, request, jsonify +# import joblib +# import sklearn +# import numpy as np +# from Rules.transaction_rules import get_category_from_rules + +# model = joblib.load("model/category_model.pkl") +# vectorizer = joblib.load("model/vectorizer.pkl") + +# app = Flask(__name__) + +# @app.route("/api/predict", methods=["POST"]) +# def predict(): +# data = request.json +# description = data.get("description", "") + +# if not description: +# return jsonify({"error": "Description is required"}), 400 + +# category = get_category_from_rules(description) +# if not category: +# X = vectorizer.transform([description]) +# prediction = model.predict(X)[0] + +# return jsonify({"category": prediction}) + +# if __name__ == "__main__": +# app.run(host="0.0.0.0", port=5000) from flask import Flask, request, jsonify -import joblib -import sklearn +import joblib +import sklearn import numpy as np +from Rules.transaction_rules import get_category_from_rules model = joblib.load("model/category_model.pkl") -vectorizer = joblib.load("model/vectorizer.pkl") +vectorizer = joblib.load("model/vectorizer.pkl") app = Flask(__name__) @@ -16,9 +45,15 @@ def predict(): if not description: return jsonify({"error": "Description is required"}), 400 - # Preprocess and predict - X = vectorizer.transform([description]) - prediction = model.predict(X)[0] + # First try rules + category = get_category_from_rules(description) + + if category: + prediction = category # ✅ assign directly + else: + # fallback to ML + X = vectorizer.transform([description]) + prediction = model.predict(X)[0] return jsonify({"category": prediction}) diff --git a/AI/model/ml_transcation.ipynb b/AI/train/training.ipynb similarity index 100% rename from AI/model/ml_transcation.ipynb rename to AI/train/training.ipynb