{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":121150,"databundleVersionId":15061024,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":136824685,"sourceType":"kernelVersion"},{"sourceId":288715334,"sourceType":"kernelVersion"},{"sourceId":290006699,"sourceType":"kernelVersion"},{"sourceId":291977319,"sourceType":"kernelVersion"}],"dockerImageVersionId":31259,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os, re, pandas as pd, numpy as np\nimport torch\nimport torch.nn as nn\nfrom sklearn.cluster import MiniBatchKMeans\nfrom sklearn.preprocessing import RobustScaler\nfrom sklearn.feature_extraction.text import TfidfVectorizer\nfrom sklearn.metrics.pairwise import cosine_similarity\n\n# --- 1. МОДЕЛИ БУСТИНГА ---\ntry:\n    from xgboost import XGBRegressor\n    from lightgbm import LGBMRegressor\n    from catboost import CatBoostRegressor\nexcept ImportError:\n    from sklearn.ensemble import RandomForestRegressor as XGBRegressor, ExtraTreesRegressor as LGBMRegressor, GradientBoostingRegressor as CatBoostRegressor\n\n# --- 2. ADAPTIVE RECSYS ---\nclass AkkadianRecSys:\n    def __init__(self, n_clusters=10):\n        self.n_clusters = n_clusters\n        self.model = None\n\n    def fit_predict(self, X):\n        n_samples = X.shape[0]\n        actual_clusters = min(self.n_clusters, n_samples)\n        self.model = MiniBatchKMeans(n_clusters=actual_clusters, n_init=3, random_state=42)\n        self.model.fit(X)\n        return cosine_similarity(X, self.model.cluster_centers_).max(axis=1)\n\n# --- 3. HEURISTIC ENGINE (10 ЭВРИСТИК) ---\nclass HeuristicEngine:\n    @staticmethod\n    def apply(text, score, rec_val):\n        t = text.lower()\n        \n        # 1. Определение типа документа (Письмо vs Контракт)\n        doc_type = \"Letter: \" if \"qibi-ma\" in t or \"ana\" in t[:5] else \"Document: \"\n        \n        # 2. Эвристика дат (Месяцы/Года)\n        if \"iti\" in t or \"mu\" in t: t += \" [dated]\"\n        \n        # 3. Эвристика валюты (Серебро/Золото)\n        t = t.replace(\"kug.babbar\", \"silver\").replace(\"kug.sig17\", \"gold\")\n        \n        # 4. Социальная иерархия\n        t = t.replace(\"lugal\", \"king\").replace(\"dumu\", \"son of\")\n        \n        # 5. Эвристика действий\n        if \"ba-zi\" in t: t = t.replace(\"ba-zi\", \"expended\")\n        if \"i3-dab5\" in t: t = t.replace(\"i3-dab5\", \"taken over\")\n        \n        # 6. Геолокация (Ниппур/Ур/Вавилон)\n        if \"nibru\" in t: t += \" (Origin: Nippur)\"\n        \n        # 7. Эвристика количества (Числительные)\n        t = re.sub(r'(\\d+)\\(disz\\)', r'\\1 unit(s)', t)\n        \n        # 8. Религиозная эвристика (Боги)\n        if \"dingir\" in t or \"d\" in t: t = t.replace(\"{d}\", \"deity \")\n        \n        # 9. Эвристика важности (на основе RecSys)\n        importance = \" [High Priority]\" if rec_val > 0.8 else \"\"\n        \n        # 10. Эвристика архивации (на основе Бустинга)\n        status = \" (Verified)\" if score > 0.5 else \" (Fragmentary)\"\n        \n        return f\"{doc_type}{t}{importance}{status}\".capitalize()\n\n# --- 4. CV & FEATURES ---\nclass TabletCNN(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.net = nn.Sequential(nn.Conv2d(1, 8, 3), nn.ReLU(), nn.AdaptiveAvgPool2d((2, 2)))\n        self.fc = nn.Linear(8 * 2 * 2, 4)\n    def forward(self, x): return self.fc(self.net(x).view(x.size(0), -1))\n\ndef get_features(df):\n    model = TabletCNN().eval()\n    cv_feats = []\n    for t in df['transliteration']:\n        b = str(t).encode('utf-8')[:256]\n        img = np.zeros(256, dtype=np.float32)\n        img[:len(b)] = np.frombuffer(b, dtype=np.uint8)\n        with torch.no_grad():\n            cv_feats.append(model(torch.from_numpy(img).view(1,1,16,16)).numpy().flatten())\n    \n    tfidf = TfidfVectorizer(max_features=30, analyzer='char', ngram_range=(2,3))\n    X_tfidf = tfidf.fit_transform(df['transliteration'].fillna('')).toarray()\n    X_struct = np.array([[len(str(s)), str(s).count('-')] for s in df['transliteration']])\n    \n    return RobustScaler().fit_transform(np.hstack([cv_feats, X_tfidf, X_struct]))\n\n# --- 5. MAIN ---\ndef main():\n    path = '/kaggle/input/deep-past-initiative-machine-translation/test.csv'\n    df = pd.read_csv(path) if os.path.exists(path) else pd.DataFrame({'id':[1,2], 'transliteration':['ana lugal qibi-ma', '1(disz) kug.babbar iti nibru']})\n    \n    X = get_features(df)\n    \n    # RecSys\n    recsys = AkkadianRecSys(n_clusters=5)\n    rec_vals = recsys.fit_predict(X)\n    \n    # Ensemble (Pseudo-target)\n    y_target = rec_vals * 0.7 + (X[:, -1] * 0.3)\n    m = XGBRegressor(n_estimators=100, max_depth=3, learning_rate=0.1)\n    m.fit(X, y_target)\n    scores = m.predict(X)\n    \n    # Final Translation with 10 Heuristics\n    engine = HeuristicEngine()\n    final_translations = [engine.apply(df['transliteration'].iloc[i], scores[i], rec_vals[i]) for i in range(len(df))]\n    \n    pd.DataFrame({'id': df['id'], 'translation': final_translations}).to_csv('submission.csv', index=False)\n    print(\"Done! 10 heuristics applied.\")\n\nif __name__ == \"__main__\":\n    main()\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-31T12:26:17.240878Z","iopub.execute_input":"2026-01-31T12:26:17.241133Z","iopub.status.idle":"2026-01-31T12:26:17.290661Z","shell.execute_reply.started":"2026-01-31T12:26:17.241115Z","shell.execute_reply":"2026-01-31T12:26:17.289733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}