#2 입력 feature 생성 #
#2025-06-17
1. Load package #
%load_ext autoreload
%autoreload 2
import sys
import os
import pickle
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import pandas as pd
sys.path.append('/data3/projects/2025_Antibiotics/YSH/bin')
from sc import *
os.chdir('/data3/projects/2025_Antibiotics/YSH')
2. Previous #
seqdir = 'data/res_dict'
seq_list = os.listdir(seqdir)
print(len(seq_list))
169
항생제 169종에 대해서 size 10 sequence를 생성했었는데
- 모델 입력 feature로 다음을 제외하는대신
- antibiotics 리스트
- strain 리스트
- 저 2개 feature를 반영하는 새로운 feature를 2개 생성하려고 한다:
- 현재 antibiotics가 현재 strain 환자의 NEWS를 감소시킨 이력이 있는지? (binary: 0/1)
- 현재 antibiotics가 NEWS를 감소시키는데 소요 기간은? (범주형: short/mid/long)
3. Create feature1 #
먼저 feature1을 생성하기 위해
- 투여 후 NEWS가 감소한 sequence를 남기고
- keep된 sequence의 균주-항생제 pair를 얻는데
- 이때 ‘투여 후 NEWS의 감소’는?
- 투여 전날(D-1) NEWS 수치와
- 투여 후 7일(D+0~D+6)를 봣을때
- 투여 후 최고치가 투여 전날보다 낮으면 NEWS가 감소한 것으로 보았다.
med_dir = 'res'
seqdir = 'data/res_dict'
outdir = 'res/feature1'
with open(f"{med_dir}/all_meds.txt", 'r') as f:
all_meds = [line.strip() for line in f if line.strip()]
all_meds = [s.replace("/", "_") for s in all_meds]
for med in all_meds:
print(med)
cur_path = f'{seqdir}/{med}.pkl'
with open(cur_path, 'rb') as f:
res_dict = pickle.load(f)
feature1_list = []
for pid, df in res_dict.items():
news_bf = df.iloc[2]['NEWS'] # 3번째 행 (0-indexed)
news_af = df.iloc[3:]['NEWS'].max() # 4번째 행부터 마지막까지 중 최댓값
if news_af < news_bf: # "작은" 경우만 (같은 건 포함하지 않음)
feature1_list.append(pid)
print(len(feature1_list))
filtered_res_dict = {pid: res_dict[pid] for pid in feature1_list if pid in res_dict}
with open(f"{outdir}/{med}.pkl", 'wb') as f:
pickle.dump(filtered_res_dict, f)
Dexamethasone에 대해 selected sequence를 시각화한것을 보면
- 투여일(점선) 이후의 NEWS 수치들이 투여전날보다 낮은 것만 잘 선택된것을 확인 가능하다!
strain_dic = {}
for med in all_meds:
cur_path = f'{outdir}/{med}.pkl'
with open(cur_path, 'rb') as f:
filtered_res_dict = pickle.load(f)
for pid, df in filtered_res_dict.items():
if len(df) < 3:
continue # 3번째 행이 없는 경우 skip
try:
cur_strain = df.iloc[2]['strain']
if isinstance(cur_strain, list):
strains = cur_strain
else:
strains = [cur_strain]
except Exception as e:
continue
for strain in strains:
if strain in strain_dic:
strain_dic[strain].append(med)
else:
strain_dic[strain] = [med]
for strain in strain_dic:
strain_dic[strain] = list(set(strain_dic[strain]))
keep된 sequence의 균주-항생제 pair를 얻을 때는
- 각 항생제에 대해
- selected sequence의 투여 전날(D-1) 균주(들)에 해당 항생제 매핑
- 하는 방식으로 수행했다.
strains = list(strain_dic.keys())
print(len(strains))
print(strains[0], '\n', strain_dic[strains[0]])
98
Pseudomonas aeruginosa
['Imicil Kit', 'Prepenem', 'Sevatrim', 'Meropen', 'Finibax', 'Ciprobay', 'Hanomycin', 'Citopcin', 'Tazocin', 'Dexamethasone', 'Pospenem', 'Tygacil', 'Pentamidine Isethionate', 'Lagevrio', 'Plunazol', 'Vancomycin HCl']
균주별 효과 항생제 딕셔너리 strain_dic를 확인해보면
- 98개 균주에 대해
- 효능을 보인(것으로 추정되는) 항생제 목록이 제대로 생성돼있다!
ourdir = 'res'
with open(f"{outdir}/Feature1.pkl", 'wb') as f:
pickle.dump(strain_dic, f)
만든건 저장하기.
4. Create feature2 #
feature2는 솔직히 좀 애매한데 로직을 짜보면
- 일단 투여 후 NEWS가 감소한 sequence를 모두 모으고
- ‘일정 수준’이하로 감소하는데 소요된 시간을 봐서 (ex. 3이하는 moderate니까 3까지 도달하는데 소요된 날짜)
- 상위 30%/하위30%/나머지 « 이런 식으로 가려고 했으나?
- sequence의 선택 기준이 ‘투여 전날 news’로써
- sequence마다 기준이 달랐기때문에
- y축 즉 news 범위가 다 달라서 절대적인 값으로 설정하기 어려울거같다. (ex. 투여 전날 최고치가 3보다 낮을 수도 있음. 또는 투여후 3 아래로 안떨어지는 날이 있을수도있음)
- 그래서 상대적인 값으로 볼까 했는데?
- 기준을 ‘절반 이하로 떨어지기’로 잡는다고 치면
- news가
- 전날 12 -> 8로 감소
- 전날 3 -> 1.5로 감소
- 인 경우 1은 좋은 데이터지만 non selected 되어 라벨링되지않고 2는 별로인 데이터지만 selected 되어 라벨링되게된다.
- news가
결론: feature2는 일단 보류하기.