buraktrk commited on
Commit
24fe75e
·
verified ·
1 Parent(s): 7ef2edf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -154
app.py CHANGED
@@ -1,39 +1,16 @@
1
- # -----------------------------------------------------------------------------
2
- # app_fhe.py – FHE audit‑opinion predictor (minimal UI, encoder mapping added)
3
- # -----------------------------------------------------------------------------
4
- # Akış
5
- # -----
6
- # 1. Kullanıcı Excel yükler24 oran hesaplanır.
7
- # 2. Özellik vektörü FHE ile şifrelenir; sunucuda tahmin (sınıf kodu) yapılır.
8
- # 3. Kullanıcıya gizli anahtar verilir; anahtar yapıştırılıp **Çöz** denildiğinde
9
- # tahmin sınıf kodu **encoder** yardımıyla metin etiketine çevrilir.
10
- # -----------------------------------------------------------------------------
11
 
12
  from __future__ import annotations
 
 
13
 
14
- import base64
15
- import io
16
- from typing import Any, Tuple
17
-
18
- import gradio as gr
19
- import joblib
20
- import numpy as np
21
- import pandas as pd
22
- # concrete-ml import kaldırıldı; model joblib ile doğrudan yükleniyor.
23
- # -----------------------------------------------------------------------------
24
- # PATHS & CONSTANTS
25
- # -----------------------------------------------------------------------------
26
- SAMPLE_DIR = "Sample Inputs (Excel)"
27
- EXAMPLE_XLSX = [
28
- f"{SAMPLE_DIR}/ADESE_2021.xlsx",
29
- f"{SAMPLE_DIR}/YYAPI_2017.xlsx",
30
- f"{SAMPLE_DIR}/SRVGY_2022.xlsx",
31
- f"{SAMPLE_DIR}/THYAO_2023.xlsx",
32
- f"{SAMPLE_DIR}/TTRAK_2024.xlsx",
33
- ]
34
-
35
- FHE_MODEL_PATH = "fhe_xgb.joblib" # Concrete‑ML compiled model (class codes)
36
- PIPE_ENCODER_PATH = "pipe_encoder.joblib" # joblib dump: (sklearn Pipeline, LabelEncoder)
37
 
38
  SELECTED_FEATS = [
39
  "Finansal Kaldıraç", "Zmijewski Skoru", "Cari Oran", "Asit Test Oranı",
@@ -47,140 +24,99 @@ SELECTED_FEATS = [
47
  "Özsermaye / Maddi Duran Varlıklar",
48
  ]
49
 
50
- # -----------------------------------------------------------------------------
51
- # LOAD MODELS / ENCODER
52
- # -----------------------------------------------------------------------------
53
- # Compiled FHE model doğrudan yüklenir.
54
- FHE_MODEL = joblib.load(FHE_MODEL_PATH) # type: ignore), dtype=np.float32))
55
-
56
- PIPE: Any
57
- ENC: Any
58
- try:
59
- PIPE, ENC = joblib.load(PIPE_ENCODER_PATH)
60
- except FileNotFoundError:
61
- ENC = None # fallback – will show numeric code
62
-
63
- # -----------------------------------------------------------------------------
64
- # HELPER FUNCTIONS
65
- # -----------------------------------------------------------------------------
66
-
67
- def safe_div(num: pd.Series, denom: pd.Series) -> pd.Series:
68
- denom_replaced = denom.replace(0, np.nan)
69
- return (num / denom_replaced).fillna(0)
70
 
 
 
 
 
 
71
 
72
  def compute_ratios(df: pd.DataFrame) -> pd.DataFrame:
73
- # -- same full ratio calculations as previous version (omitted for brevity) --
74
- # ensure SELECTED_FEATS are produced
75
- total_assets = df["Dönen Varlıklar"] + df["Duran Varlıklar"]
76
- total_liab = df["Kısa Vadeli Yükümlülükler"] + df["Uzun Vadeli Yükümlülükler"]
77
- # [likidite, kârlılık, verimlilik, kaldıraç, distress hesaplamaları...]
78
- # ...
79
- return df # placeholder – replace with full implementation
80
-
81
- _b64_dump = lambda obj: base64.b64encode(joblib.dumps(obj)).decode()
82
- _b64_load = lambda txt: joblib.loads(base64.b64decode(txt.encode()))
83
-
84
- # -----------------------------------------------------------------------------
85
- # STATE & CALLBACKS
86
- # -----------------------------------------------------------------------------
87
-
88
- encrypted_pred_state = gr.State(value=None)
89
-
90
- # helper: gerekli FHE metodlarının varlığını hızlıca kontrol et
91
- for fn in ("keygen", "encrypt", "run", "decrypt"):
92
- if not hasattr(FHE_MODEL, fn):
93
- raise AttributeError(f"FHE model eksik metod: {fn}")
94
-
95
-
96
- def encrypt_and_predict(excel_file: gr.File):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  if excel_file is None:
98
- raise gr.Error("Lütfen analiz edilecek Excel dosyasını yükleyin.")
99
-
100
- p = gr.Progress(track_tqdm=False)
101
- p(0.05, "Excel okunuyor…")
102
 
103
- raw_vert = pd.read_excel(excel_file.name, header=None, sheet_name=0)
104
- raw_df = raw_vert.set_index(0).T.reset_index(drop=True)
105
- raw_df.columns = raw_df.columns.str.strip()
106
 
107
- p(0.30, "Oranlar hesaplanıyor…")
108
- enriched = compute_ratios(raw_df.copy())
109
  model_input = enriched[SELECTED_FEATS].dropna()
110
  if model_input.empty:
111
- raise gr.Error("Hiç analiz edilebilir satır kalmadı – oran hesaplanamadı.")
112
-
113
- p(0.55, "Anahtarlar oluşturuluyor…")
114
- public_key, secret_key = FHE_MODEL.keygen()
115
-
116
- p(0.75, "Şifreli tahmin yapılıyor…")
117
- y_enc = FHE_MODEL.run(FHE_MODEL.encrypt(model_input.values.astype(np.float32), public_key))
118
- encrypted_pred_state.value = y_enc
119
-
120
- return (
121
- gr.update(value="### Tahmin (Şifreli)", visible=True),
122
- gr.update(value="Gizli anahtarı kopyalayın, yapıştırın ve 'Çöz' deyin.", visible=True),
123
- gr.update(value=_b64_dump(secret_key), visible=True),
124
- )
125
-
126
-
127
- def decrypt_prediction(secret_key_b64: str):
128
- if encrypted_pred_state.value is None:
129
- raise gr.Error("Önce şifreli tahmini üretin.")
130
- if not secret_key_b64:
131
- raise gr.Error("Gizli anahtarı girin.")
132
-
133
- secret_key = _b64_load(secret_key_b64)
134
- class_codes = FHE_MODEL.decrypt(encrypted_pred_state.value, secret_key).astype(int).flatten()
135
-
136
- # Map to human‑readable labels if encoder exists
137
- if ENC is not None:
138
- try:
139
- labels = ENC.inverse_transform(class_codes)
140
- except Exception:
141
- labels = class_codes # fallback to numeric
142
- else:
143
- labels = class_codes
144
-
145
- return (
146
- gr.update(value="### Tahmin Sonuçları", visible=True),
147
- gr.update(value=pd.DataFrame({"Tahmin": labels}), visible=True),
148
- )
149
-
150
- # -----------------------------------------------------------------------------
151
- # GRADIO UI
152
- # -----------------------------------------------------------------------------
153
- with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
154
- gr.Markdown("# Denetçi Görüşü Tahmini – FHE (Encoder Destekli)")
155
 
156
- with gr.Row():
157
- file_input = gr.File(file_types=[".xlsx", ".xls", ".xlsm"], label="Excel Yükleyin")
158
- predict_btn = gr.Button("Şifrele & Tahmin Et", variant="primary")
159
 
160
- gr.Examples(EXAMPLE_XLSX, inputs=file_input, label="Örnek Dosyalar", cache_examples=False)
161
 
162
- enc_title = gr.Markdown(visible=False)
163
- enc_msg = gr.Markdown(visible=False)
164
- secret_key_output = gr.Textbox(label="Gizli Anahtar (kopyalayın)", visible=False, interactive=False)
165
-
166
- decrypt_key_input = gr.Textbox(label="Gizli Anahtarı Yapıştırın", visible=False)
167
- decrypt_btn = gr.Button("Çöz", variant="secondary", visible=False)
168
-
169
- pred_title = gr.Markdown(visible=False)
170
- pred_table = gr.Dataframe(visible=False, wrap=True, show_label=False)
171
 
172
- predict_btn.click(
173
- encrypt_and_predict,
174
- inputs=[file_input],
175
- outputs=[enc_title, enc_msg, secret_key_output]
176
- ).then(lambda: gr.update(visible=True), None, decrypt_key_input
177
- ).then(lambda: gr.update(visible=True), None, decrypt_btn)
178
 
179
- decrypt_btn.click(
180
- decrypt_prediction,
181
- inputs=[decrypt_key_input],
182
- outputs=[pred_title, pred_table]
183
- )
184
 
185
  if __name__ == "__main__":
186
  demo.launch()
 
1
+ # ---------------------------------------------------------------------------
2
+ # app.py – Denetçi Görüşü Tahmini (pipe + LabelEncoder)
3
+ # ---------------------------------------------------------------------------
4
+ # 1. Excel yüklenir → 24 finansal oran hesaplanır.
5
+ # 2. (pipeline, LabelEncoder) ikilisi joblib'den yüklenir.
6
+ # 3. pipe.predict enc.inverse_transformsonuç tabloya basılır.
7
+ # ---------------------------------------------------------------------------
 
 
 
8
 
9
  from __future__ import annotations
10
+ import pandas as pd, numpy as np, joblib, gradio as gr
11
+ from pathlib import Path
12
 
13
+ FHE_MODEL_PATH = "fhe_xgb.joblib" # içinde (pipe, enc) tuple'ı var
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  SELECTED_FEATS = [
16
  "Finansal Kaldıraç", "Zmijewski Skoru", "Cari Oran", "Asit Test Oranı",
 
24
  "Özsermaye / Maddi Duran Varlıklar",
25
  ]
26
 
27
+ pipe, enc = joblib.load(FHE_MODEL_PATH) # pipeline + LabelEncoder
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # ---------------------------------------------------------------------------
30
+ # Oran hesaplama yardımcıları
31
+ # ---------------------------------------------------------------------------
32
+ def safe_div(a: pd.Series, b: pd.Series) -> pd.Series:
33
+ return (a / b.replace(0, np.nan)).fillna(0)
34
 
35
  def compute_ratios(df: pd.DataFrame) -> pd.DataFrame:
36
+ ta = df["Dönen Varlıklar"] + df["Duran Varlıklar"]
37
+ tl = df["Kısa Vadeli Yükümlülükler"] + df["Uzun Vadeli Yükümlülükler"]
38
+
39
+ df["Cari Oran"] = safe_div(df["Dönen Varlıklar"], df["Kısa Vadeli Yükümlülükler"])
40
+ df["Asit Test Oranı"] = safe_div(
41
+ df["Dönen Varlıklar"] - df["Stoklar"] - df["Diğer Dönen Varlıklar"],
42
+ df["Kısa Vadeli Yükümlülükler"])
43
+ df["Nakit Oranı"] = safe_div(df["Nakit ve Nakit Benzerleri"], df["Kısa Vadeli Yükümlülükler"])
44
+
45
+ df["Faaliyet Kar Marjı"] = safe_div(df["FAALİYET KARI (ZARARI)"]*100, df["Satış Gelirleri"])
46
+ df["Brüt Kar Marjı (%)"] = safe_div(df["Ticari Faaliyetlerden Brüt Kar (Zarar)"]*100,
47
+ df["Satış Gelirleri"])
48
+ df["Net Kar Marjı"] = safe_div(df["Dönem Net Kar/Zararı"]*100, df["Satış Gelirleri"])
49
+ df["Aktif Karlılık (%)"] = safe_div(df["Dönem Net Kar/Zararı"]*100, ta)
50
+
51
+ df["Aktif Devir Hızı"] = safe_div(df["Satış Gelirleri"], ta)
52
+ df["Dönen Varlıklar Devir Hızı"] = safe_div(df["Dönen Varlıklar"], df["Satış Gelirleri"])
53
+ df["Stok Devir Hızı"] = -safe_div(df["Satışların Maliyeti (-)"], df["Stoklar"])
54
+
55
+ df["Finansal Kaldıraç"] = safe_div(tl, ta)*100
56
+ df["Kısa Vade Borç / Aktif"] = safe_div(df["Kısa Vadeli Yükümlülükler"], ta)
57
+ df["Kısa Vade Borç / Özsermaye"] = safe_div(df["Kısa Vadeli Yükümlülükler"], df["Özkaynaklar"])
58
+ df["Kısa Vade Borç / Toplam Borç"] = safe_div(df["Kısa Vadeli Yükümlülükler"], tl)
59
+ df["Özsermaye / Aktif"] = safe_div(df["Özkaynaklar"], ta)
60
+
61
+ df["Duran Varlıklar / Aktif "] = safe_div(df["Duran Varlıklar"]*100, ta)
62
+ df["Dönen Varlıklar / Aktif (%)"] = safe_div(df["Dönen Varlıklar"]*100, ta)
63
+ df["Özsermaye / Maddi Duran Varlıklar"] = safe_div(df["Özkaynaklar"], df["Maddi Duran Varlıklar"])
64
+
65
+ df["Finansman Gider / Net Satış"] = safe_div(df["Finansman Giderleri"], df["Satış Gelirleri"])
66
+ df["Esas Faaliyet Karı / Kısa Vadeli Borç"] = safe_div(
67
+ df["Net Faaliyet Kar/Zararı"], df["Kısa Vadeli Yükümlülükler"])
68
+ df["ROCE Oranı"] = safe_div(df["FAALİYET KARI (ZARARI)"]*100, ta)
69
+
70
+ X1 = safe_div(df["Dönen Varlıklar"] - df["Kısa Vadeli Yükümlülükler"], ta)
71
+ X2 = safe_div(df["Geçmiş Yıllar Kar/Zararları"] + df["Dönem Net Kar/Zararı"], ta)
72
+ X3 = safe_div(df["SÜRDÜRÜLEN FAALİYETLER VERGİ ÖNCESİ KARI (ZARARI)"], ta)
73
+ X4 = safe_div(df["Özkaynaklar"], tl)
74
+ X5 = safe_div(df["Satış Gelirleri"], ta)
75
+ df["Altman Z-Skoru"] = 1.2*X1 + 1.4*X2 + 3.3*X3 + 0.6*X4 + X5
76
+
77
+ Z1 = safe_div(df["Dönem Net Kar/Zararı"], ta)
78
+ Z2 = safe_div(tl, ta)
79
+ Z3 = safe_div(df["Dönen Varlıklar"], df["Kısa Vadeli Yükümlülükler"])
80
+ df["Zmijewski Skoru"] = -4.3 - 4.5*Z1 + 5.7*Z2 - 0.004*Z3
81
+
82
+ L6 = safe_div(safe_div(df["Nakit ve Nakit Benzerleri"], df["Kısa Vadeli Yükümlülükler"]), tl)
83
+ L7 = safe_div(tl, ta)
84
+ df["L Model Skoru"] = (-0.113*X1 + 0.238*X2 - 0.052*X3 - 0.051*X4 +
85
+ 0.011*X5 + 0.729*L6 - 0.639*L7)
86
+ return df
87
+
88
+ # ---------------------------------------------------------------------------
89
+ # PREDICT CALLBACK
90
+ # ---------------------------------------------------------------------------
91
+ def predict_opinion(excel_file: gr.File):
92
  if excel_file is None:
93
+ raise gr.Error("Excel dosyası yükleyin.")
 
 
 
94
 
95
+ raw = pd.read_excel(excel_file.name, header=None, sheet_name=0).set_index(0)
96
+ df = raw.T.reset_index(drop=True)
97
+ df.columns = df.columns.str.strip()
98
 
99
+ enriched = compute_ratios(df.copy())
 
100
  model_input = enriched[SELECTED_FEATS].dropna()
101
  if model_input.empty:
102
+ raise gr.Error("Oran hesaplanamadı; eksik sütunlar olabilir.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
+ pred_label = enc.inverse_transform(pipe.predict(model_input))
105
+ result_df = pd.DataFrame({"Tahmin Görüş Tipi": pred_label})
 
106
 
107
+ return result_df
108
 
109
+ # ---------------------------------------------------------------------------
110
+ # GRADIO UI
111
+ # ---------------------------------------------------------------------------
112
+ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
113
+ gr.Markdown("# Denetçi Görüşü Tahmin Uygulaması (Pipe + Encoder)")
 
 
 
 
114
 
115
+ file_in = gr.File(file_types=[".xlsx", ".xls", ".xlsm"], label="Excel Yükleyin")
116
+ btn = gr.Button("Tahmin Et", variant="primary")
117
+ out_tbl = gr.Dataframe(wrap=True, show_label=False)
 
 
 
118
 
119
+ btn.click(predict_opinion, inputs=file_in, outputs=out_tbl)
 
 
 
 
120
 
121
  if __name__ == "__main__":
122
  demo.launch()