buraktrk commited on
Commit
6a21cb7
·
verified ·
1 Parent(s): ab150e3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -93
app.py CHANGED
@@ -1,107 +1,127 @@
1
  # ---------------------------------------------------------------------------
2
- # app_fhe.py – FHE audit-opinion predictor (3-adım UI)
3
  # ---------------------------------------------------------------------------
4
- # * Tek model dosyası: fhe_xgb.joblib (Concrete-ML client/server)
 
 
5
  # ---------------------------------------------------------------------------
6
 
7
- from __future__ import annotations
8
- import base64, io, joblib, gradio as gr, pandas as pd, numpy as np
9
-
10
- # ------------------------- MODEL & CONSTANTS -------------------------------
11
- MODEL_PATH = "fhe_xgb.joblib" # Concrete-ML compiled model (client/server)
12
- MODEL = joblib.load(MODEL_PATH)
13
- CLIENT, SERVER = MODEL.client, MODEL.server # type: ignore[attr-defined]
14
-
15
- SELECTED_FEATS = [ # 24 oran
16
- "Finansal Kaldıraç","Zmijewski Skoru","Cari Oran","Asit Test Oranı",
17
- "Nakit Oranı","Aktif Devir Hızı","Duran Varlıklar / Aktif ",
18
- "Altman Z-Skoru","Brüt Kar Marjı (%)","Özsermaye / Aktif",
19
- "Kısa Vade Borç / Aktif","ROCE Oranı","L Model Skoru","Net Kar Marjı",
20
- "Dönen Varlıklar Devir Hızı","Dönen Varlıklar / Aktif (%)",
21
- "Esas Faaliyet Karı / Kısa Vadeli Borç","Kısa Vade Borç / Özsermaye",
22
- "Kısa Vade Borç / Toplam Borç","Finansman Gider / Net Satış",
23
- "Faaliyet Kar Marjı","Aktif Karlılık (%)","Stok Devir Hızı",
24
- "Özsermaye / Maddi Duran Varlıklar"
25
  ]
26
 
27
- # ------------------------- HELPERS -----------------------------------------
 
 
28
  def safe_div(a: pd.Series, b: pd.Series) -> pd.Series:
29
  return (a / b.replace(0, np.nan)).fillna(0)
30
 
31
  def compute_ratios(df: pd.DataFrame) -> pd.DataFrame:
32
- # burada önceki tam 24 oran fonksiyonunu kullan —
33
- # 0) numeriğe çevir
34
- for c in [c for c in df.columns if c != "Periyot"]:
35
- df[c] = pd.to_numeric(df[c], errors="coerce").fillna(0)
36
- # oran hesaplamaları (değişmedi)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  return df
38
 
39
- # base64 yardımları
40
- b64d = lambda obj: base64.b64encode(joblib.dumps(obj)).decode()
41
- b64l = lambda txt: joblib.loads(base64.b64decode(txt.encode()))
42
-
43
- # ------------------------- GRADIO STATE ------------------------------------
44
- y_enc_state = gr.State(value=None) # şifreli tahmin
45
- client_b64_st = gr.State(value=None) # client pickle (bunda gizli anahtar var)
46
-
47
- # ------------------------- CALLBACKS ---------------------------------------
48
- def gen_keys():
49
- CLIENT.keygen() # yeni anahtar çifti
50
- client_b64_st.value = b64d(CLIENT) # kullanıcıya ver
51
- # evaluation key == public key -> hex dizisine çevirelim
52
- ev_hex = CLIENT.evaluation_keys.to_bytes().hex()[:200] + "…"
53
- return ev_hex, gr.update(interactive=True)
54
-
55
- def encrypt_send(excel: gr.File):
56
- if client_b64_st.value is None:
57
- raise gr.Error("Önce “Anahtar Oluştur” adımını tamamlayın.")
58
- if excel is None:
59
- raise gr.Error("Excel yükleyin.")
60
-
61
- df = (pd.read_excel(excel.name, header=None).set_index(0).T.reset_index(drop=True))
62
- df.columns = df.columns.str.strip(); df = df.loc[:, ~df.columns.duplicated()]
63
- X = compute_ratios(df)[SELECTED_FEATS].dropna()
64
  if X.empty:
65
- raise gr.Error("Oran hesaplanamadı – kolon eksik.")
66
- x_enc = CLIENT.encrypt(X.values.astype(np.float32))
67
- y_enc_state.value = SERVER.run(x_enc)
68
- enc_hex = x_enc.to_bytes().hex()[:200] + "…"
69
- return enc_hex, gr.update(interactive=True)
70
-
71
- def decrypt_res(secret_txt: str):
72
- if y_enc_state.value is None:
73
- raise gr.Error("Önce “Encrypt & Send” adımını yapın.")
74
- client_loaded = b64l(client_b64_st.value)
75
- y_pred = client_loaded.decrypt(y_enc_state.value).astype(int).flatten()
76
- return pd.DataFrame({"Tahmin Kod": y_pred})
77
-
78
- # ------------------------- UI ----------------------------------------------
79
  with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
80
- gr.Markdown("## Denetçi Görüşü Tahmini — FHE Demo")
81
-
82
- # STEP 1
83
- with gr.Box():
84
- gr.Markdown("### 1️⃣ Anahtar Oluştur")
85
- key_btn = gr.Button("Generate keys")
86
- eval_out = gr.Textbox(label="Evaluation-key representation", lines=3, interactive=False)
87
-
88
- # STEP 2
89
- with gr.Box():
90
- gr.Markdown("### 2️⃣ Excel Yükle & Encrypt")
91
- file_in = gr.File(file_types=[".xlsx",".xls",".xlsm"])
92
- enc_btn = gr.Button("Encrypt & Send")
93
- enc_repr = gr.Textbox(label="Encrypted input", lines=3, interactive=False)
94
-
95
- # STEP 3
96
- with gr.Box():
97
- gr.Markdown("### 3️⃣ Decrypt result")
98
- dec_btn = gr.Button("Decrypt")
99
- out_df = gr.Dataframe(wrap=True, show_label=False)
100
-
101
- # WIRES
102
- key_btn.click(gen_keys, outputs=[eval_out, enc_btn])
103
- enc_btn.click(encrypt_send, inputs=file_in, outputs=[enc_repr, dec_btn])
104
- dec_btn.click(decrypt_res, inputs=None, outputs=out_df)
105
-
106
- if __name__ == "__main__":
107
- demo.launch()
 
1
  # ---------------------------------------------------------------------------
2
+ # app.py – Denetçi Görüşü Tahmin Uygulaması (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_transform → sonuç tabloya basılır.
7
  # ---------------------------------------------------------------------------
8
 
9
+ from _future_ import annotations
10
+ import pandas as pd, numpy as np, joblib, gradio as gr
11
+
12
+ FHE_MODEL_PATH = "fhe_xgb.joblib" # (pipe, enc) tuple'ı
13
+ pipe, enc = joblib.load(FHE_MODEL_PATH) # ✔️ tek dosyadan yükle
14
+
15
+ SELECTED_FEATS = [
16
+ "Finansal Kaldıraç", "Zmijewski Skoru", "Cari Oran", "Asit Test Oranı",
17
+ "Nakit Oranı", "Aktif Devir Hızı", "Duran Varlıklar / Aktif ",
18
+ "Altman Z-Skoru", "Brüt Kar Marjı (%)", "Özsermaye / Aktif",
19
+ "Kısa Vade Borç / Aktif", "ROCE Oranı", "L Model Skoru", "Net Kar Marjı",
20
+ "Dönen Varlıklar Devir Hızı", "Dönen Varlıklar / Aktif (%)",
21
+ "Esas Faaliyet Karı / Kısa Vadeli Borç", "Kısa Vade Borç / Özsermaye",
22
+ "Kısa Vade Borç / Toplam Borç", "Finansman Gider / Net Satış",
23
+ "Faaliyet Kar Marjı", "Aktif Karlılık (%)", "Stok Devir Hızı",
24
+ "Özsermaye / Maddi Duran Varlıklar",
 
 
25
  ]
26
 
27
+ # ---------------------------------------------------------------------------
28
+ # Yardımcılar
29
+ # ---------------------------------------------------------------------------
30
  def safe_div(a: pd.Series, b: pd.Series) -> pd.Series:
31
  return (a / b.replace(0, np.nan)).fillna(0)
32
 
33
  def compute_ratios(df: pd.DataFrame) -> pd.DataFrame:
34
+ # 0️⃣ Sayısal sütunları güvenli şekilde numeriğe çevir
35
+ for col in [c for c in df.columns if c != "Periyot"]:
36
+ df[col] = pd.to_numeric(df[col], errors="coerce").fillna(0)
37
+
38
+ ta = df["Dönen Varlıklar"] + df["Duran Varlıklar"]
39
+ tl = df["Kısa Vadeli Yükümlülükler"] + df["Uzun Vadeli Yükümlülükler"]
40
+
41
+ df["Cari Oran"] = safe_div(df["Dönen Varlıklar"], df["Kısa Vadeli Yükümlülükler"])
42
+ df["Asit Test Oranı"] = safe_div(
43
+ df["Dönen Varlıklar"] - df["Stoklar"] - df["Diğer Dönen Varlıklar"],
44
+ df["Kısa Vadeli Yükümlülükler"])
45
+ df["Nakit Oranı"] = safe_div(df["Nakit ve Nakit Benzerleri"], df["Kısa Vadeli Yükümlülükler"])
46
+
47
+ df["Faaliyet Kar Marjı"] = safe_div(df["FAALİYET KARI (ZARARI)"]*100, df["Satış Gelirleri"])
48
+ df["Brüt Kar Marjı (%)"] = safe_div(df["Ticari Faaliyetlerden Brüt Kar (Zarar)"]*100,
49
+ df["Satış Gelirleri"])
50
+ df["Net Kar Marjı"] = safe_div(df["Dönem Net Kar/Zararı"]*100, df["Satış Gelirleri"])
51
+ df["Aktif Karlılık (%)"] = safe_div(df["Dönem Net Kar/Zararı"]*100, ta)
52
+
53
+ df["Aktif Devir Hızı"] = safe_div(df["Satış Gelirleri"], ta)
54
+ df["Dönen Varlıklar Devir Hızı"] = safe_div(df["Dönen Varlıklar"], df["Satış Gelirleri"])
55
+ df["Stok Devir Hızı"] = -safe_div(df["Satışların Maliyeti (-)"], df["Stoklar"])
56
+
57
+ df["Finansal Kaldıraç"] = safe_div(tl, ta)*100
58
+ df["Kısa Vade Borç / Aktif"] = safe_div(df["Kısa Vadeli Yükümlülükler"], ta)
59
+ df["Kısa Vade Borç / Özsermaye"] = safe_div(df["Kısa Vadeli Yükümlülükler"], df["Özkaynaklar"])
60
+ df["Kısa Vade Borç / Toplam Borç"] = safe_div(df["Kısa Vadeli Yükümlülükler"], tl)
61
+ df["Özsermaye / Aktif"] = safe_div(df["Özkaynaklar"], ta)
62
+
63
+ df["Duran Varlıklar / Aktif "] = safe_div(df["Duran Varlıklar"]*100, ta)
64
+ df["Dönen Varlıklar / Aktif (%)"] = safe_div(df["Dönen Varlıklar"]*100, ta)
65
+ df["Özsermaye / Maddi Duran Varlıklar"] = safe_div(df["Özkaynaklar"], df["Maddi Duran Varlıklar"])
66
+
67
+ df["Finansman Gider / Net Satış"] = safe_div(df["Finansman Giderleri"], df["Satış Gelirleri"])
68
+ df["Esas Faaliyet Karı / Kısa Vadeli Borç"] = safe_div(
69
+ df["Net Faaliyet Kar/Zararı"], df["Kısa Vadeli Yükümlülükler"])
70
+ df["ROCE Oranı"] = safe_div(df["FAALİYET KARI (ZARARI)"]*100, ta)
71
+
72
+ X1 = safe_div(df["Dönen Varlıklar"] - df["Kısa Vadeli Yükümlülükler"], ta)
73
+ X2 = safe_div(df["Geçmiş Yıllar Kar/Zararları"] + df["Dönem Net Kar/Zararı"], ta)
74
+ X3 = safe_div(df["SÜRDÜRÜLEN FAALİYETLER VERGİ ÖNCESİ KARI (ZARARI)"], ta)
75
+ X4 = safe_div(df["Özkaynaklar"], tl)
76
+ X5 = safe_div(df["Satış Gelirleri"], ta)
77
+ df["Altman Z-Skoru"] = 1.2*X1 + 1.4*X2 + 3.3*X3 + 0.6*X4 + X5
78
+
79
+ Z1 = safe_div(df["Dönem Net Kar/Zararı"], ta)
80
+ Z2 = safe_div(tl, ta)
81
+ Z3 = safe_div(df["Dönen Varlıklar"], df["Kısa Vadeli Yükümlülükler"])
82
+ df["Zmijewski Skoru"] = -4.3 - 4.5*Z1 + 5.7*Z2 - 0.004*Z3
83
+
84
+ L6 = safe_div(safe_div(df["Nakit ve Nakit Benzerleri"], df["Kısa Vadeli Yükümlülükler"]), tl)
85
+ L7 = safe_div(tl, ta)
86
+ df["L Model Skoru"] = (-0.113*X1 + 0.238*X2 - 0.052*X3 - 0.051*X4 +
87
+ 0.011*X5 + 0.729*L6 - 0.639*L7)
88
  return df
89
 
90
+ # ---------------------------------------------------------------------------
91
+ # Tahmin
92
+ # ---------------------------------------------------------------------------
93
+ def predict_opinion(excel_file: gr.File):
94
+ if excel_file is None:
95
+ raise gr.Error("Excel dosyası yükleyin.")
96
+
97
+ raw_df = (
98
+ pd.read_excel(excel_file.name, header=None, sheet_name=0)
99
+ .set_index(0).T.reset_index(drop=True)
100
+ )
101
+
102
+ raw_df.columns = raw_df.columns.str.strip()
103
+ raw_df = raw_df.loc[:, ~raw_df.columns.duplicated()]
104
+ raw_df.rename(columns={"Desc": "Periyot"}, inplace=True)
105
+ raw_df["Periyot"] = raw_df["Periyot"].astype(str).str.replace(r"\s+", " ", regex=True).str.strip()
106
+ enriched = compute_ratios(raw_df)
107
+ X = enriched[SELECTED_FEATS].dropna()
 
 
 
 
 
 
 
108
  if X.empty:
109
+ raise gr.Error("Oran hesaplanamadı – eksik sütunlar olabilir.")
110
+
111
+ labels = enc.inverse_transform(pipe.predict(X))
112
+ return pd.DataFrame({"Tahmin Görüş Tipi": labels})
113
+
114
+ # ---------------------------------------------------------------------------
115
+ # Gradio UI
116
+ # ---------------------------------------------------------------------------
 
 
 
 
 
 
117
  with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
118
+ gr.Markdown("# Denetçi Görüşü Tahmin Uygulaması")
119
+
120
+ file_in = gr.File(file_types=[".xlsx", ".xls", ".xlsm"], label="Excel Yükleyin")
121
+ btn = gr.Button("Tahmin Et", variant="primary")
122
+ out_df = gr.Dataframe(wrap=True, show_label=False)
123
+
124
+ btn.click(predict_opinion, file_in, out_df)
125
+
126
+ if _name_ == "_main_":
127
+ demo.launch()