Feat : HybridCharCNN + 다중 출처 학습셋 + OOD 평가 파이프라인#4
Open
kim-subsub wants to merge 5 commits into
Open
Conversation
CharCNN 본체는 보존하고 25개 URL-only feature를 late fusion으로 결합한 HybridCharCNN 추가. 학습/평가/추론 모두 동일한 compute_url_features를 사용해 일관성 확보. - features.py: URL feature 추출 + train mean/std 저장/로드 + 단일 URL 추론 벡터 조립 - model.py: HybridCharCNN(CharCNN sub-module 재사용 + tabular MLP) 추가 - dataset.py: feature_cols 지정 시 (url, feature, label) 반환, apply_normalization 추가 - train/evaluate/predict: HybridCharCNN + saved/feature_norm.json 사용 - preprocess: compute_url_features로 학습/추론 일관성 보장 - explain: tabular 분기 forward에 additional_forward_args 전달 - inspect_phiusiil.py: PhiUSIIL 컬럼/상관 점검용 일회성 스크립트 - THRESHOLD=0.2로 조정 (FN/FP 균형) URLSimilarityIndex는 라벨과 |corr|=0.86 cheat feature이라 FEATURE_COLS에서 제외. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
단일 데이터셋 의존(예: PhiUSIIL only)에서 오는 source bias를 줄이기 위해 PhiUSIIL+URLhaus+OpenPhish+PhishTank+Tranco를 합쳐 학습용 raw CSV를 만든다. 정적 도메인 위주 학습으로 query/path/token 패턴 일반화가 약했던 문제를 보완하기 위해 클래스별 5,000개의 동적 URL synthetic augmentation도 같이 섞는다. OOD 평가에서 발견한 오분류는 data/hard_examples/hard_examples.csv에 누적되며, 다음 학습 시 클래스별 HARD_EXAMPLES_MAX_PER_CLASS만큼만 섞어 재학습한다. - download_train_mixed.py: 출처별 fetch + 동적 augmentation + hard example merge - PhishTank app key는 URL-encode 처리, PhiUSIIL URL 컬럼은 _find_url_col 공유 - config: MIXED_*, DYNAMIC_AUG_PER_CLASS, HARD_EXAMPLES_* 설정 추가 - .gitignore: data/hard_examples/*.csv 추가 + .gitkeep 보존 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
같은 등록 도메인이 train/valid/test에 섞이면 모델이 도메인 자체를 외워버려 실제 일반화 성능보다 over-optimistic하게 측정될 수 있다. StratifiedGroupKFold로 도메인 단위 분할을 적용하고, hard example 도메인은 train fold에 고정해 OOD에서 잡힌 어려운 케이스가 다시 valid/test로 새지 않게 한다. - preprocess: _domain_group(eTLD+1 근사) + _domain_group_split 추가 - USE_DOMAIN_GROUP_SPLIT=True 기본, 10-fold로 1 fold=test, 1 fold=valid, 나머지=train - FORCE_HARD_EXAMPLES_TO_TRAIN=True로 hard_* source의 도메인 group을 train에 강제 - 도메인 group 수가 10 미만이거나 split이 비정상이면 row split로 폴백 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
학습용 raw에 들어가지 않은 URL만으로 평가셋(URLhaus+OpenPhish+PhishTank+Tranco)을 구성해 in-distribution 측정과 분리한다. threshold sweep으로 운영 임계값을 고를 수 있게 하고, 오분류는 hard example CSV로 누적해 다음 학습 사이클에 재투입한다. - download_ood.py: 학습 raw URL 제외한 OOD CSV 생성 - evaluate_ood.py: HybridCharCNN으로 점수 산출 + threshold sweep + 출처별 FN/FP 분포 + 점수 quantile + hard example 누적 저장 - config: OOD_CSV_PATH, OOD_SAMPLE_PER_CLASS, OOD_BENIGN_TOP_N 추가 - .gitignore: data/ood/*.csv 추가 + .gitkeep 보존 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
이슈 #3(tabular feature) + 다중 출처 학습셋 + 도메인 그룹 분할 + OOD 평가 도입에 맞춰 작업 가이드와 사용자 README를 업데이트한다. - CLAUDE.md: HybridCharCNN 구조, FEATURE_COLS 규칙, vocab/feature_norm 생애주기, USE_DOMAIN_GROUP_SPLIT, hard example 재학습 루프, 현재 baseline 수치 추가 - README: download_train_mixed -> preprocess -> train -> evaluate -> download_ood -> evaluate_ood 순으로 파이프라인 명시, predict의 단일 URL 사용법 정리 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
hck2025
reviewed
Apr 28, 2026
|
|
||
| keep_cols = [url_col, "label"] + FEATURE_COLS | ||
| df_out = df[keep_cols].copy() | ||
| df_out.rename(columns={url_col: "url"}, inplace=True) |
There was a problem hiding this comment.
코드를 실행하여 학습 데이터를 받아오고자 할 때 해당 라인의 조건문에 걸려서 계속 runtimeerror가 발생합니다.
Read
Searched for text FEATURE_COLS (**/charcnn-kit/src/**), 20 results
터미널 로그 분석 결과
현재 터미널 로그는 python src/download_phiusiil.py 실행 중 다음 지점에서 실패했습니다.
GET https://archive.ics.uci.edu/static/public/967/phiusiil+phishing+url+dataset.zip- 파일 다운로드, CSV 로드까지는 정상
- 그런데 다음 오류가 발생:
RuntimeError: PhiUSIIL CSV에 기대한 feature 컬럼이 없습니다- 누락된 컬럼:
['NoOfAtInURL', 'NoOfDashInURL', 'NoOfDotInURL', 'NoOfPercentInURL', 'PathLength', 'QueryLength', 'NoOfPathSegments', 'NoOfQueryParams', 'HasFragment']
의미
download_phiusiil.py는 PhiUSIIL 데이터셋에서 URL 문자열과 라벨뿐 아니라, 모델이 사용하는 탭형 특성(feature) 컬럼들도 함께 기대합니다.
하지만 다운로드한 원본 CSV에는 그 컬럼들이 없어서 스크립트가 중단된 것입니다.
결론
- 이 오류는 네트워크나 pip 문제가 아니라, download_phiusiil.py의 입력 데이터 형식 문제입니다.
- 스크립트가 기대하는
FEATURE_COLS가 원본 UCI CSV에 존재하지 않아서 실패했습니다.
다음 조치
- download_phiusiil.py가 기대하는 특성 컬럼을 생성하는 전처리 단계가 있는지 확인
- 아니면 config.py의
FEATURE_COLS를 수정하거나, 현재 UCI 데이터셋과 맞도록 스크립트를 업데이트해야 합니다 - 또는 download_phiusiil.py가 원래 의도한 PhiUSIIL 버전과 다른 CSV를 받고 있는지 확인하세요
요약: 로그의 핵심은 “원본 CSV에 필요한 feature 컬럼이 없어서 스크립트가 죽었다”입니다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
fusion으로 결합. 학습/평가/추론이 동일한
compute_url_features를 쓰도록 통일.URLSimilarityIndex는 |corr|=0.86 cheat feature이라 제외.PhishTank+Tranco 합성 학습셋. 클래스별 5,000개 동적 URL synthetic augmentation
추가. OOD 오분류는
data/hard_examples/에 누적되어 다음 학습에 재투입.StratifiedGroupKFold사용. hard example 도메인은 train에 고정.sweep + 출처별 FN/FP 분포 + 점수 quantile 출력.
현재 baseline (이슈 #3 기준)
Test plan
python src/download_train_mixed.py정상 실행 (네트워크 필요)python src/preprocess.py→ domain split log에서overlap=0확인python src/train.pyearly stopping 동작 +saved/feature_norm.json생성python src/evaluate.py지표 + FN/FP 출력 정상python src/download_ood.py→ 학습 URL 제외 OOD CSV 생성python src/evaluate_ood.pythreshold sweep + hard example 누적 저장python src/predict.py --url "https://example.com" --xai정상 응답