프로젝트 5주차 타임라인 (Mon Jan 26 2026)


[11] Single-Model Cascade (Modified Framework)

Before After
CatBoost, LightGBM, MLP, XGBoost를 혼합한 복합 Ensemble 구조
구조 설명은 가능했으나, 코드 레벨에서는 각 모델의 역할 경계가 명확하지 않음
Recall과 Precision 최적화 목적이 하나의 decision 흐름에 혼재됨
모델 수를 축소하고 Stage별 역할을 명확히 분리
Ensemble Complexity를 감소
Cascade 흐름과 Decision Logic의 명확성을 강화

 

1. High-Recall Screening (CatBoost Only)

목적: False Negative를 최소화하여 epitope일 가능성이 있는 후보를 최대한 보존
코드 기반 설계: CatBoost 단독 사용 - categorical feature에 대한 자연스러운 처리, 안정적인 recall 성능 확보
출력: binary decision이 아닌 확률 score S₁만 생성
변경 이유: feature scaling이 불필요하며 categorical feature 비중이 높은 현재 feature set에 최적
📌 Stage 1은 classifier가 아니라 filter로 정의되며 prediction이 아닌 candidate space reduction을 목표로 함

 

2. Precision-Focused Refinement (XGBoost Only)

목적: Stage 1을 통과한 후보 중 False Positive를 제거하여 wet-lab validation 비용을 최소화
코드 기반 설계:
XGBoost 단독 학습, 학습 데이터는 Stage 1 통과 샘플만 사용
출력:
확률 score S₂ 생성

변경 이유: hard negative 구분 능력이 뛰어나며 feature interaction 포착에 강함, precision 최적화에 유리

📌 Stage 2는 balanced classifier가 아니며 recall은 이미 Stage 1에서 확보된 상태로 간주함

 

3. Final Candidate Selection:
Stage 1과 Stage 2의 score를 연속적으로 활용하여 최종 score FS를 산출
FS 기준으로 후보 중 상위 N개의 epitope을 high-confidence candidate로 정의
후보 수는 wet-lab 실험이 가능한 규모로 제한


 문제 설명 solution.py
#127 이 보드게임은 격자모양 게임판 위에서 말을 움직이는 게임으로, 시작 위치에서 출발한 뒤 목표 위치에 정확하게 멈추기 위해 최소 몇 번의 이동이 필요한지 말하는 게임입니다.

이 게임에서 말의 이동은 현재 위치에서 상, 하, 좌, 우 중 한 방향으로 게임판 위의 장애물이나 게임판 가장자리까지 부딪힐 때까지 미끄러져 움직이는 것을 한 번의 이동으로 정의합니다.

"."은 빈 공간을, "R"은 로봇의 처음 위치를, "D"는 장애물의 위치를, "G"는 목표지점을 나타냅니다.

이때 최소 움직임은 7번이며 "R" 위치에서 아래, 왼쪽, 위, 왼쪽, 아래, 오른쪽, 위 순서로 움직이면 "G" 위치에 멈춰 설 수 있습니다.

게임판의 상태를 나타내는 문자열 배열 board가 주어졌을 때, 말이 목표위치에 도달하는데 최소 몇 번 이동해야 하는지 return 하는 solution함수를 완성해주세요. 만약 목표위치에 도달할 수 없다면 -1을 return 해주세요.
def solution(board):
     que = []
     for x, row in enumerate(board):
          for y, each in enumerate(row):
               if board[x][y] == 'R':
                    que.append((x, y, 0))
     visited = set()
     while que:
          x, y, length = que.pop(0)
          if (x, y) in visited:
               continue
          if board[x][y] == 'G':
               return length
          visited.add((x, y))
          for diff_x, diff_y in ((0, 1), (0, -1), (1, 0), (-1, 0)):
               now_x, now_y = x, y
               while True:
                    next_x, next_y = now_x + diff_x, now_y + diff_y
                    if 0 <= next_x < len(board) and 0 <= next_y < len(board[0])  
                                                                   and board[next_x][next_y] != 'D':
                         now_x, now_y = next_x, next_y
                         continue
                    que.append((now_x, now_y, length + 1))
                    break
     return -1

+ Recent posts