# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session


import os

print("Kaggle input dizinindeki hedef dosyalar taranıyor...")
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        if filename.lower().endswith(('.csv', '.txt')):
            print(os.path.join(dirname, filename))


import pandas as pd
import numpy as np
from scipy import stats
import gc # Garbage Collector (Bellek temizleyici)

# ==========================================
# FAZ 0: BELLEK OPTİMİZASYONLU VERİ OKUMA VE TEKİLLEŞTİRME
# ==========================================
demo_path = '/kaggle/input/datasets/rangan25102/faers-parsed/DEMOGRAPHIC.csv'
drug_path = '/kaggle/input/datasets/rangan25102/faers-parsed/DRUG.csv'
reac_path = '/kaggle/input/datasets/rangan25102/faers-parsed/REACTION.csv'

onco_drugs_list = ['DOXORUBICIN', 'TRASTUZUMAB', 'PACLITAXEL', 'NIVOLUMAB', 'PEMBROLIZUMAB', 
                   'CYCLOPHOSPHAMIDE', 'FLUOROURACIL', 'RITUXIMAB', 'CISPLATIN', 'CARBOPLATIN']

print("1. DRUG tablosu optimize edilerek okunuyor ve filtreleniyor...")
drug_chunks = []
# ÇÖZÜM: usecols içine lambda fonksiyonu ekleyerek büyük/küçük harf duyarlılığını aşıyoruz.
for chunk in pd.read_csv(drug_path, sep='\t', on_bad_lines='skip', dtype=str, 
                         usecols=lambda x: x.strip().lower() in ['primaryid', 'role_cod', 'drugname'], 
                         chunksize=1000000):
    chunk.columns = chunk.columns.str.strip().str.lower()
    # Chunk içinde filtreleme (RAM tasarrufu)
    chunk = chunk[chunk['role_cod'].str.strip().str.upper() == 'PS']
    chunk['drugname'] = chunk['drugname'].astype(str).str.strip().str.upper()
    chunk = chunk[chunk['drugname'].isin(onco_drugs_list)]
    drug_chunks.append(chunk)

df_onco = pd.concat(drug_chunks, ignore_index=True)
del drug_chunks # İşlem biten listeyi sil
gc.collect() # Belleği manuel boşalt
print(f"-> Filtrelenmiş Onkoloji İlaç Kaydı Sayısı: {len(df_onco):,}")

# Anahtar ID'leri bir sete alıyoruz ki diğer tabloları okurken sadece bu hastaları alalım
valid_primaryids = set(df_onco['primaryid'])

print("\n2. REAC tablosu onkoloji kohortuna göre hedeflenerek okunuyor...")
reac_chunks = []
for chunk in pd.read_csv(reac_path, sep='\t', on_bad_lines='skip', dtype=str, 
                         usecols=lambda x: x.strip().lower() in ['primaryid', 'pt'], 
                         chunksize=1000000):
    chunk.columns = chunk.columns.str.strip().str.lower()
    chunk = chunk[chunk['primaryid'].isin(valid_primaryids)]
    reac_chunks.append(chunk)

df_reac = pd.concat(reac_chunks, ignore_index=True)
del reac_chunks
gc.collect()
print(f"-> Filtrelenmiş REAC Kaydı Sayısı: {len(df_reac):,}")

print("\n3. DEMO tablosu onkoloji kohortuna göre hedeflenerek okunuyor...")
demo_chunks = []
for chunk in pd.read_csv(demo_path, sep='\t', on_bad_lines='skip', dtype=str, 
                         usecols=lambda x: x.strip().lower() in ['primaryid', 'caseid', 'age', 'sex'], 
                         chunksize=1000000):
    chunk.columns = chunk.columns.str.strip().str.lower()
    chunk = chunk[chunk['primaryid'].isin(valid_primaryids)]
    demo_chunks.append(chunk)

df_demo = pd.concat(demo_chunks, ignore_index=True)
del demo_chunks
gc.collect()

print("\n4. De-dup (Tekilleştirme) ve Birleştirme uygulanıyor...")
df_demo['primaryid_num'] = pd.to_numeric(df_demo['primaryid'], errors='coerce')
df_demo = df_demo.dropna(subset=['primaryid_num', 'caseid']) 
df_demo_dedup = df_demo.sort_values(['caseid', 'primaryid_num']).drop_duplicates(subset=['caseid'], keep='last')
df_demo_dedup = df_demo_dedup.drop(columns=['primaryid_num'])

df_cohort = df_demo_dedup.merge(df_onco[['primaryid', 'drugname']], on='primaryid', how='inner')
df_cohort = df_cohort.merge(df_reac[['primaryid', 'pt']], on='primaryid', how='inner')

print(f"✅ Faz 0 Tamamlandı! Nihai Kohort Satır Sayısı: {len(df_cohort):,}\n")


# ==========================================
# FAZ 1: TANIMLAYICI ANALİZ VE TABLO 1 (H1)
# ==========================================
print("Faz 1: Demografik analiz (Tablo 1) hesaplanıyor...\n")

cardiac_pts = ['MYOCARDITIS', 'CARDIAC FAILURE', 'HEART FAILURE', 'ATRIAL FIBRILLATION', 
               'MYOCARDIAL INFARCTION', 'PERICARDITIS', 'CARDIAC ARREST', 'TACHYCARDIA', 'BRADYCARDIA']
df_cohort['pt'] = df_cohort['pt'].astype(str).str.strip().str.upper()
df_cohort['is_cardiac'] = df_cohort['pt'].isin(cardiac_pts).astype(int)

df_cohort['age'] = pd.to_numeric(df_cohort['age'], errors='coerce')
df_cohort.loc[(df_cohort['age'] < 18) | (df_cohort['age'] > 100), 'age'] = np.nan 

df_cohort['sex'] = df_cohort['sex'].astype(str).str.strip().str.upper()
df_cohort['sex'] = df_cohort['sex'].map({'F': 'Female', 'M': 'Male'})

cardiac_cohort = df_cohort[df_cohort['is_cardiac'] == 1]
non_cardiac_cohort = df_cohort[df_cohort['is_cardiac'] == 0]

print("-" * 60)
print("TABLO 1: DEMOGRAFİK ÖZELLİKLER (Kardiyak vs. Non-Kardiyak AE)")
print("-" * 60)
print(f"Toplam Vaka (N): Kardiyak={len(cardiac_cohort):,}, Non-Kardiyak={len(non_cardiac_cohort):,}")
print(f"Yaş (Ort ± SS): {cardiac_cohort['age'].mean():.1f} ± {cardiac_cohort['age'].std():.1f} vs {non_cardiac_cohort['age'].mean():.1f} ± {non_cardiac_cohort['age'].std():.1f}")
print(f"Kadın Cinsiyet (n, %): {len(cardiac_cohort[cardiac_cohort['sex']=='Female']):,} ({(len(cardiac_cohort[cardiac_cohort['sex']=='Female'])/max(len(cardiac_cohort), 1))*100:.1f}%) vs {len(non_cardiac_cohort[non_cardiac_cohort['sex']=='Female']):,} ({(len(non_cardiac_cohort[non_cardiac_cohort['sex']=='Female'])/max(len(non_cardiac_cohort), 1))*100:.1f}%)")

t_stat, p_val = stats.ttest_ind(cardiac_cohort['age'].dropna(), non_cardiac_cohort['age'].dropna(), equal_var=False)
print(f"Yaş Karşılaştırması (Welch's t-test) p-değeri: {p_val:.4f}")
print("-" * 60)


import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns

# ==========================================
# FAZ 2: DISPROPORTIONALITY ANALİZİ (ROR)
# ==========================================
print("Faz 2: İlaç-Advers Olay Çiftleri için ROR hesaplanıyor...\n")

# df_cohort, onco_drugs_list ve cardiac_pts değişkenleri bir önceki hücreden hafızada hazırdır.
results = []

for drug in onco_drugs_list:
    for event in cardiac_pts:
        # 2x2 Olumsallık Tablosu Hücreleri
        # a: Hedef İlaç + Hedef Olay
        a = len(df_cohort[(df_cohort['drugname'] == drug) & (df_cohort['pt'] == event)])
        # b: Hedef İlaç + Diğer Olay
        b = len(df_cohort[(df_cohort['drugname'] == drug) & (df_cohort['pt'] != event)])
        # c: Diğer İlaç + Hedef Olay
        c = len(df_cohort[(df_cohort['drugname'] != drug) & (df_cohort['pt'] == event)])
        # d: Diğer İlaç + Diğer Olay
        d = len(df_cohort[(df_cohort['drugname'] != drug) & (df_cohort['pt'] != event)])
        
        # Haldane-Anscombe Düzeltmesi (Sıfıra bölmeyi önlemek için hücrelere +0.5 eklenmesi)
        if a == 0 or b == 0 or c == 0 or d == 0:
            a_calc, b_calc, c_calc, d_calc = a + 0.5, b + 0.5, c + 0.5, d + 0.5
        else:
            a_calc, b_calc, c_calc, d_calc = a, b, c, d
            
        # ROR ve Güven Aralığı (CI) Hesaplamaları
        ror = (a_calc * d_calc) / (b_calc * c_calc)
        se_ln_ror = np.sqrt(1/a_calc + 1/b_calc + 1/c_calc + 1/d_calc)
        ci_lower = np.exp(np.log(ror) - 1.96 * se_ln_ror)
        ci_upper = np.exp(np.log(ror) + 1.96 * se_ln_ror)
        
        # P-değeri (Fisher's Exact Test)
        _, p_val = stats.fisher_exact([[a, b], [c, d]])
        
        results.append({
            'Drug': drug,
            'Event': event,
            'a_Case_Count': a,
            'ROR': round(ror, 2),
            'CI_95_Lower': round(ci_lower, 2),
            'CI_95_Upper': round(ci_upper, 2),
            'p_value': p_val
        })

dpa_df = pd.DataFrame(results)

# Sinyal Doğrulama Kriteri: Vaka Sayısı >= 3, CI Alt Sınırı > 1.0 ve p < 0.05
dpa_df['Signal'] = (dpa_df['a_Case_Count'] >= 3) & (dpa_df['CI_95_Lower'] > 1.0) & (dpa_df['p_value'] < 0.05)

print(f"-> İncelenen Toplam İlaç-Olay Kombinasyonu: {len(dpa_df)}")
print(f"-> Tespit Edilen İstatistiksel Anlamlı Sinyal Sayısı: {dpa_df['Signal'].sum()}\n")

# ==========================================
# ÇIKTI 1: TABLO 2 (ANLAMLI SİNYALLER)
# ==========================================
significant_signals = dpa_df[dpa_df['Signal']].sort_values(by='ROR', ascending=False).reset_index(drop=True)

# Tablo Görselleştirmesi
styled_table = significant_signals.style.set_caption("TABLO 2: Anlamlı Kardiyak Disproportionality Sinyalleri (ROR > 1, a ≥ 3, p < 0.05)") \
                                  .format({'p_value': '{:.4e}'}) \
                                  .set_properties(**{'background-color': '#f9f9f9', 'border': '1px solid black'})

display(styled_table)


# ==========================================
# ÇIKTI 2: FİGÜR 2 (VOLCANO PLOT)
# ==========================================
plt.figure(figsize=(10, 7))

# Logaritmik dönüşümler (Sıfır hatalarını önlemek için küçük değerler eklenir)
dpa_df['log2_ROR'] = np.log2(dpa_df['ROR'].replace(0, np.nan))
dpa_df['neg_log10_p'] = -np.log10(dpa_df['p_value'].replace(0, 1e-300))

# Scatter plot: Sinyalleri kırmızı, diğerlerini gri yapıyoruz
sns.scatterplot(data=dpa_df, x='log2_ROR', y='neg_log10_p', 
                hue='Signal', palette={True: '#e74c3c', False: '#95a5a6'}, 
                alpha=0.8, s=60, edgecolor='k')

# Kritik Eşik Çizgileri
plt.axvline(x=0, color='black', linestyle='--', linewidth=1.2, label='ROR = 1') 
plt.axhline(y=-np.log10(0.05), color='blue', linestyle=':', linewidth=1.5, label='p = 0.05')

# En yüksek ROR'a sahip ilk 5 klinik sinyalin ismini grafiğe yazdırma
top_signals = dpa_df[dpa_df['Signal']].nlargest(5, 'ROR')
for i, row in top_signals.iterrows():
    plt.annotate(f"{row['Drug']}\n({row['Event']})", 
                 (row['log2_ROR'], row['neg_log10_p']),
                 textcoords="offset points", xytext=(0, 8), ha='center', fontsize=8,
                 bbox=dict(boxstyle="round,pad=0.2", fc="white", ec="gray", alpha=0.7))

plt.title('Figür 2: Disproportionality Analysis - Volcano Plot', fontsize=14, fontweight='bold', pad=15)
plt.xlabel('Log2 (Reporting Odds Ratio)', fontsize=12, fontweight='bold')
plt.ylabel('-Log10 (p-value)', fontsize=12, fontweight='bold')
plt.legend(title='İstatistiksel Sinyal', loc='upper left')
plt.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()


import pandas as pd
from statsmodels.stats.multitest import multipletests

# ==========================================
# FAZ 3: ÇOKLU TEST DÜZELTMESİ (FDR - BENJAMINI-HOCHBERG)
# ==========================================
print("Faz 3: Çoklu Test Düzeltmesi (FDR) uygulanıyor...\n")

# Faz 2'den gelen dpa_df içindeki p-değerlerini alıyoruz
p_values = dpa_df['p_value'].values

# Benjamini-Hochberg FDR Düzeltmesi
reject, pvals_corrected, _, _ = multipletests(p_values, alpha=0.05, method='fdr_bh')

# Sonuçları DataFrame'e ekleme
dpa_df['FDR_p_value'] = pvals_corrected

# YENİ SİNYAL KRİTERİ (Düzeltilmiş): Vaka >= 3, ROR_Lower > 1 ve FDR_p_value < 0.05
dpa_df['Validated_Signal'] = (
    (dpa_df['a_Case_Count'] >= 3) & 
    (dpa_df['CI_95_Lower'] > 1.0) & 
    (dpa_df['FDR_p_value'] < 0.05)
)

print(f"-> FDR Öncesi Anlamlı Sinyal Sayısı: {dpa_df['Signal'].sum()}")
print(f"-> FDR Düzeltmesi Sonrası Doğrulanmış Sinyal Sayısı: {dpa_df['Validated_Signal'].sum()}\n")

# ==========================================
# ÇIKTI 3: TABLO 2'NİN REVİZE VE ONAYLI HALİ (Kaggle Dark Mode Uyumlu)
# ==========================================
# Sadece doğrulanmış sinyalleri filtrele ve ROR'a göre sırala
final_signals = dpa_df[dpa_df['Validated_Signal']].sort_values(by='ROR', ascending=False).reset_index(drop=True)

# Görsel karmaşayı önlemek için Styler kullanmadan doğrudan Kaggle'ın native formatında bastırıyoruz
columns_to_show = ['Drug', 'Event', 'a_Case_Count', 'ROR', 'CI_95_Lower', 'CI_95_Upper', 'p_value', 'FDR_p_value']

print("-" * 100)
print("TABLO 2: DOĞRULANMIŞ KARDİYAK GÜVENLİLİK SİNYALLERİ (FDR Düzeltilmiş)")
print("-" * 100)
display(final_signals[columns_to_show])


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest
import gc
import warnings
warnings.filterwarnings('ignore')

# ==========================================
# FAZ 4: AI TABANLI ANOMALİ TESPİTİ (H4)
# ==========================================
print("Faz 4: AI Tabanlı Zaman Serisi ve Anomali Tespiti Başlıyor...\n")

# 1. Tarih Verisinin (fda_dt) Çekilmesi (Sadece analiz kohortu için)
valid_ids = set(df_cohort['primaryid'])
demo_path = '/kaggle/input/datasets/rangan25102/faers-parsed/DEMOGRAPHIC.csv'

print("Tarih verileri (fda_dt) okunuyor...")
date_chunks = []
for chunk in pd.read_csv(demo_path, sep='\t', on_bad_lines='skip', dtype=str, 
                         usecols=lambda x: x.strip().lower() in ['primaryid', 'fda_dt'], 
                         chunksize=1000000):
    chunk.columns = chunk.columns.str.strip().str.lower()
    chunk = chunk[chunk['primaryid'].isin(valid_ids)]
    date_chunks.append(chunk)

df_dates = pd.concat(date_chunks, ignore_index=True)
del date_chunks
gc.collect()

# df_cohort ile tarihleri birleştirme
df_ts = df_cohort.merge(df_dates, on='primaryid', how='left')

# Tarih formatını temizleme ve Yıl-Ay formatına çevirme
df_ts['fda_dt'] = pd.to_datetime(df_ts['fda_dt'], format='%Y%m%d', errors='coerce')
df_ts = df_ts.dropna(subset=['fda_dt'])
df_ts['YearMonth'] = df_ts['fda_dt'].dt.to_period('M')

# 2. Örnek "Emerging Signal" Analizi: NIVOLUMAB - MYOCARDITIS
target_drug = 'NIVOLUMAB'
target_event = 'MYOCARDITIS'

print(f"{target_drug} ve {target_event} için zaman serisi oluşturuluyor...\n")
ts_data = df_ts[(df_ts['drugname'] == target_drug) & (df_ts['pt'] == target_event)]
monthly_counts = ts_data.groupby('YearMonth').size().reset_index(name='Report_Count')

# Model girdisi hazırlama
monthly_counts['YearMonth_Str'] = monthly_counts['YearMonth'].astype(str)
X = monthly_counts[['Report_Count']].values

# 3. Isolation Forest Algoritması
# Contamination parametresi: Verideki beklenen anomali/sıçrama oranı (%10 olarak ayarlandı)
model = IsolationForest(contamination=0.10, random_state=42)
monthly_counts['Anomaly'] = model.fit_predict(X)

# AI'ın anomali olarak etiketledikleri (-1 döner)
anomalies = monthly_counts[monthly_counts['Anomaly'] == -1]
print(f"-> Tespit edilen anomali (beklenmeyen artış) ay sayısı: {len(anomalies)}")

# ==========================================
# ÇIKTI 4: FİGÜR 3 (ZAMAN SERİSİ ANOMALİ GRAFİĞİ)
# ==========================================
plt.figure(figsize=(12, 6))

# Temel trend çizgisi
plt.plot(monthly_counts['YearMonth_Str'], monthly_counts['Report_Count'], 
         marker='o', markersize=5, color='#34495e', linestyle='-', linewidth=1.5, label='Aylık Vaka Bildirimi')

# Anomali noktaları (Kırmızı ve büyük)
plt.scatter(anomalies['YearMonth_Str'], anomalies['Report_Count'], 
            color='#e74c3c', s=120, zorder=5, edgecolor='black', label='Yapay Zeka Anomali Tespiti (Emerging Signal)')

plt.title(f'Figür 3: AI-Tabanlı Emerging Signal Tespiti ({target_drug} - {target_event})', fontsize=14, fontweight='bold', pad=15)
plt.xlabel('Tarih (Yıl-Ay)', fontsize=12, fontweight='bold')
plt.ylabel('Bildirim Sayısı (N)', fontsize=12, fontweight='bold')
plt.xticks(rotation=45, ha='right', fontsize=9)

# X eksenindeki etiket kalabalığını önlemek için her 3 ayda bir etiket gösterme
ax = plt.gca()
for i, label in enumerate(ax.xaxis.get_ticklabels()):
    if i % 3 != 0:
        label.set_visible(False)

plt.legend(loc='upper left')
plt.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()


import matplotlib.pyplot as plt
import matplotlib.patches as patches

# ==========================================
# FAZ 5: PRISMA HASTA AKIŞ ŞEMASI (FİGÜR 1)
# ==========================================
print("Faz 5: PRISMA-like Veri Akış Şeması (Figür 1) oluşturuluyor...\n")

# Önceki aşamalardan elde ettiğimiz log verileri (Görsellerinizden alınmıştır)
n_total_demo = 16404979
n_onco_drug_reports = 125130 
n_final_cohort = 377615
n_cardiac = 4731
n_non_cardiac = 372884

fig, ax = plt.subplots(figsize=(10, 8))
ax.axis('off')

# Kutu Çizim Fonksiyonu
def draw_box(ax, x, y, width, height, text, facecolor='#ecf0f1'):
    rect = patches.FancyBboxPatch((x, y), width, height, boxstyle="round,pad=0.05", 
                                  edgecolor='black', facecolor=facecolor, linewidth=1.5)
    ax.add_patch(rect)
    ax.text(x + width/2, y + height/2, text, ha='center', va='center', 
            fontsize=11, fontweight='bold', wrap=True)

# Ok Çizim Fonksiyonu
def draw_arrow(ax, x, y, dx, dy):
    ax.annotate('', xy=(x+dx, y+dy), xytext=(x, y),
                arrowprops=dict(facecolor='black', shrink=0.05, width=2, headwidth=8))

# 1. Başlangıç Kutusu
draw_box(ax, 0.25, 0.85, 0.5, 0.1, f"FAERS Başlangıç Veri Seti\nDEMO Tablosu (N = {n_total_demo:,})")

# Ok 1
draw_arrow(ax, 0.5, 0.85, 0, -0.1)

# Dışlananlar 1 (Sağ ok)
draw_arrow(ax, 0.5, 0.78, 0.2, 0)
draw_box(ax, 0.72, 0.73, 0.25, 0.1, "Dışlananlar:\n- Eksik/Bozuk ID'ler\n- Tekilleştirme (De-dup)\n- Mükerrer Raporlar", facecolor='#ffcccc')

# 2. Onkoloji Filtresi
draw_box(ax, 0.25, 0.65, 0.5, 0.1, f"Aktif Karşılaştırıcı İzolasyonu\nSadece Antineoplastik Ajanlar (PS)\nKayıtlar filtrelendi")

# Ok 2
draw_arrow(ax, 0.5, 0.65, 0, -0.1)

# Dışlananlar 2 (Sağ ok)
draw_arrow(ax, 0.5, 0.58, 0.2, 0)
draw_box(ax, 0.72, 0.53, 0.25, 0.1, "Dışlananlar:\n- Onkoloji dışı ilaçlar\n- 'Primary Suspect' (PS)\nolmayan kayıtlar", facecolor='#ffcccc')

# 3. Nihai Analiz Kohortu
draw_box(ax, 0.25, 0.45, 0.5, 0.1, f"Nihai Analiz Kohortu\n(N = {n_final_cohort:,})", facecolor='#d5f5e3')

# Ok 3 (Çatallanma)
draw_arrow(ax, 0.5, 0.45, -0.25, -0.1)
draw_arrow(ax, 0.5, 0.45, 0.25, -0.1)

# 4. Alt Gruplar (Kardiyak vs Non-Kardiyak)
draw_box(ax, 0.05, 0.25, 0.35, 0.1, f"Kardiyak Advers Olaylar\nHedef AE (a ve c hücreleri)\n(N = {n_cardiac:,})", facecolor='#fad7a1')
draw_box(ax, 0.60, 0.25, 0.35, 0.1, f"Non-Kardiyak Advers Olaylar\nKontrol AE (b ve d hücreleri)\n(N = {n_non_cardiac:,})", facecolor='#aed6f1')

plt.title("Figür 1: Çalışma Kohortu Akış Şeması (PRISMA-like Attrition Diagram)", fontsize=14, fontweight='bold', pad=20)
plt.show()


import os

print("Son Aşama: Tablolar ve veri setleri dışa aktarılıyor (Export)...\n")

# Kaggle çalışma dizini
output_dir = '/kaggle/working/'

# 1. TABLO 2: Doğrulanmış Sinyallerin Kaydedilmesi
table2_path = os.path.join(output_dir, 'Tablo_2_Anlamli_Sinyaller_FDR.csv')
final_signals[columns_to_show].to_csv(table2_path, index=False)
print(f"✅ Tablo 2 (Anlamlı Sinyaller) başarıyla kaydedildi: {table2_path}")

# 2. NİHAİ KOHORT: SPSS, R veya JASP gibi programlarda ek analiz yapmak isterseniz diye ana verinin yedeği
cohort_path = os.path.join(output_dir, 'Nihai_Analiz_Kohortu.csv')
# Dosya boyutunu küçük tutmak için sadece gerekli sütunları kaydediyoruz
df_cohort[['primaryid', 'caseid', 'age', 'sex', 'drugname', 'pt', 'is_cardiac']].to_csv(cohort_path, index=False)
print(f"✅ Nihai kohort (N={len(df_cohort):,}) başarıyla kaydedildi: {cohort_path}")

print("\n🎉 BÜTÜN SÜREÇ TAMAMLANDI!")
print("Kaggle ekranının sağ panelindeki 'Output' (veya /kaggle/working) sekmesine tıklayarak bu dosyaları bilgisayarınıza indirebilirsiniz.")
