프로젝트 개요
학습 결과를 사람이 읽을 수 있는 조건과 규칙으로 표현하는 기호 머신러닝 프로젝트입니다. 속성값과 정답을 입력하면 조건을 차례로 확인해 분류하는 결정 트리를 만들고, 관계가 성립하는 예제와 성립하지 않는 예제를 입력하면 그 차이를 설명하는 FOIL 규칙을 학습합니다. 여기서 양성은 관계가 성립하거나 참인 경우, 음성은 그렇지 않은 경우를 뜻합니다.
예를 들어 그래프의 연결 정보를 바탕으로 “두 지점 사이를 이동할 수 있는가”를 판단하는 규칙을 찾습니다. 규칙과 사실을 표현하는 논리 프로그래밍 언어인 Prolog를 사용하고, 실행 환경인 SWI-Prolog를 Python에 연결했습니다. 결정 트리는 참으로 판단한 분기 경로를 논리식으로 바꾸며, 관계 학습은 어떤 규칙이 입력에 적용됐는지 확인할 수 있습니다.
과제에서 제공한 코드 골격과 데이터 생성 도구를 바탕으로 결정 트리의 종료 조건과 속성 선택, 논리식 변환 및 FOIL의 후보 생성과 규칙 탐색을 구현했습니다. 핵심 설계 문제는 읽을 수 있는 가설의 정확도와 복잡도를 함께 판단하고, 관계 규칙 탐색의 완료 여부와 실패 원인을 명확히 구분하는 것이었습니다. 이를 위해 기준 구현과 경로별 깊이 제어를 적용한 변형을 비교하고, 데이터의 역할을 분리한 평가와 명시적인 탐색 한도를 사용했습니다.
핵심 결과
아래의 균형 정확도는 양성 예제를 맞힌 비율과 음성 예제를 맞힌 비율을 같은 비중으로 평균한 값입니다. 한쪽 정답이 많은 데이터에서도 두 종류를 얼마나 잘 구분하는지 보여줍니다. 정확도는 학습에 사용하지 않은 예제를 따로 남겨 평가하는 홀드아웃 방식으로 측정했습니다. 관계 탐색의 완료 건수는 정해 둔 시간과 탐색 횟수 안에 학습을 끝낸 조건 수이며, 모든 정답을 맞힌 건수와는 다릅니다.
- 검증으로 선택한 모델의 균형 정확도
- 76.25%
- 같은 240개 평가 조건에서 기준 my-dtl 64.08% 대비 12.17%p 상승
- 입력 묶음의 예측 시간 감소율 중앙값
- 68.31%
- 같은 학습 모델 12개에서 논리식과 트리의 예측 12,288개 일치
- 관계 규칙 탐색 완료
- 26 / 30
- 동일한 최종 그래프 조건에서 기본 탐색 20개에서 두 단계 탐색 26개로 증가
- 결정 트리 비교 평가
- 2,160회
- 9개 비교 조건을 240개 합성 조건에서 평가, 모델 평가 실패 0회
같은 조건의 학습기에는 동일한 정답 규칙과 데이터 분할, 학습 정답을 일부러 바꾼 잡음 위치를 적용합니다. 아래에서 난수 시드는 무작위 데이터 생성과 분할 등을 재현하기 위한 시작값입니다. 여러 시드를 사용하면 우연히 만들어진 한 데이터에만 유리한 결과인지 살펴볼 수 있습니다. 보존한 잡음 실험에는 학습에 사용한 예제가 포함되어 있으므로 해당 수치를 홀드아웃 성능과 직접 비교하지 않습니다. 최종 평가는 검증 단계에서 정한 설정으로 수행하며 정확도뿐 아니라 트리의 노드 수와 깊이, 실행 비용도 함께 확인합니다.
| 비교 조건 | 평가 균형 정확도 | 평균 노드 수 | 학습 중앙값 (ms) |
|---|---|---|---|
| 다수 클래스 기준 | 50.00% | 1.00 | 미측정 |
기준 dtl |
69.88% | 306.90 | 1.7880 |
기준 my-dtl |
64.08% | 26.31 | 1.0639 |
corrected-dtl |
69.89% | 306.86 | 2.5890 |
gain-ratio |
69.96% | 307.18 | 2.6833 |
depth-limited |
69.89% | 270.13 | 2.7792 |
gain-depth |
69.96% | 270.13 | 2.8472 |
사전 대표 gain-depth-tuned |
76.25% | 104.56 | 2.6235 |
pruned-dtl |
77.81% | 57.12 | 4.0584 |
표의 다수 클래스 기준은 입력과 무관하게 학습 데이터에서 더 많은 정답만 선택하는 비교 기준입니다. 나머지는 같은 데이터로 학습한 결정 트리의 변형이며, 노드 수는 트리를 구성하는 판단 지점과 최종 결론의 개수로 모델 복잡도를 보여줍니다.
최종 점수가 가장 높은 pruned-dtl도 지원하며 결과를 모두 공개합니다. 대표는 개발 홀드아웃에서 선택한 gain-depth-tuned입니다. 최종 평가 결과를 본 뒤 대표를 바꾸면 평가셋까지 모델 선택에 사용하게 되므로 사전 선택을 유지했습니다. 대표의 기준 my-dtl 대비 차이는 12.17%p, 시드별 평균 차이 열 개로 계산한 95% 구간은 10.27–14.08%p입니다. %p는 두 백분율을 뺀 퍼센트포인트이고, 95% 구간은 반복 조건에 따른 평균 차이 추정의 불확실성을 나타냅니다.
대표의 학습 시간 중앙값은 2.6235ms이며 검증으로 깊이를 고르는 비용은 별도 평균 17.8389ms입니다. 중앙값은 측정값을 크기순으로 정렬했을 때 가운데에 놓이는 값입니다. 서로 다른 요약 통계를 합산한 총시간으로 제시하지 않습니다. 여러 입력을 한 묶음으로 처리하는 배치 예측의 시간 감소율 68.31%는 같은 학습 규칙을 논리식으로 평가하는 경로와 보관한 트리로 평가하는 경로의 비교이며 학습 시간 단축과 구분합니다.
해결하려던 문제
데이터에서 분류 기준을 찾더라도 어떤 조건이 판단을 만들었는지 살펴볼 수 있어야 한다고 생각했습니다. 결정 트리는 속성에 따른 분기를, 논리 규칙은 관계가 성립하는 근거를 표현합니다. 두 학습 방식에서 판단 기준을 찾고 실행 가능한 논리 표현으로 남기는 것이 프로젝트의 출발점입니다.
기준 my-dtl은 분할 기준인 이득비와 트리 전체의 성장을 세는 공유 카운터를 사용합니다. 한 가지를 확장한 횟수가 다른 가지에도 영향을 주는 공유 카운터는 각 분기 경로의 깊이를 제한하는 방식과 다르므로, 속성 선택과 복잡도 제한의 효과를 분리해 볼 필요가 있었습니다. 학습 시간이 줄어도 정확도가 낮아지는 조건이 있었으며, 학습 예제가 포함된 잡음 평가와 단일 시드 중심의 비교만으로는 새로운 예제에 대한 성능을 판단하기 어려웠습니다.
따라서 기준 구현과 비교할 변형에서는 분기 선택, 복잡도 제한 및 평가 데이터의 역할을 분리했습니다. FOIL에는 규칙 탐색이 진행되지 않거나 질의가 오래 걸릴 때 실패 원인을 구분해 확인할 수 있도록 탐색과 질의 예산을 명시했습니다.
학습 구조와 구현
- 개념과 예제
속성 조합 또는 Prolog 사실과 양성 및 음성 관계 생성
- 데이터 분리
학습과 설정 선택에 쓸 검증 및 최종 평가 역할 구분
- 판단 규칙 학습
속성 분기를 가진 결정 트리 또는 조건과 결론을 연결한 논리 규칙
- 판단 과정 확인
입력의 분기 경로와 논리식 또는 일치한 학습 규칙 출력
- 결과 보존
예측값과 복잡도, 시간, 시드 및 실패 상태 기록
| 학습기 | 속성 선택 | 복잡도 조절 |
|---|---|---|
기준 dtl |
정보 이득 | 보존한 기준 구현 |
기준 my-dtl |
이득비 | 공유 성장 카운터 |
corrected-dtl |
정보 이득 | 입력 검사와 결정적 분기를 적용한 비교 기준 |
gain-ratio |
이득비 | 기본값은 깊이 제한 없음 |
depth-limited |
정보 이득 | 실제 경로별 최대 깊이 |
gain-depth |
이득비 | 실제 경로별 최대 깊이 |
pruned-dtl |
정보 이득 | 검증 예제로 학습 후 가지치기 |
정보 이득은 속성으로 데이터를 나눈 뒤 정답의 불확실성이 얼마나 줄었는지 나타내고, 이득비는 이를 분할 자체의 정보량으로 나눈 선택 기준입니다. 깊이는 트리의 시작점인 루트에서 최종 결론인 리프까지 거치는 연결 수입니다. 가지치기는 학습한 트리에서 불필요한 분기를 줄이는 과정이며, 검증 정확도가 같으면 더 작은 트리를 선택합니다. 최종 평가 예제는 이 선택에 전달하지 않습니다. 비교 변형의 학습기는 트리와 노드 수, 규칙 수 및 개별 입력의 분기 경로를 함께 제공합니다.
FOIL은 parent(X, Y)처럼 관계를 표현하는 술어로 후보 조건을 만들고, 양성 예제를 설명하면서 음성 예제를 제외하도록 규칙을 구체화합니다. 결과는 “이 조건들이 참이면 이 관계가 성립한다”는 Horn 절로 표현합니다. 입력 바인딩은 규칙의 변수에 실제 대상을 대응시킨 값으로, 어떤 입력에 어떤 규칙이 적용됐는지 보여줍니다. 재귀 관계는 유한 그래프에서 이미 계산한 질의 결과를 저장해 재사용하는 테이블링을 사용하며, 학습 문맥을 종료하면 임시 목표 규칙과 불러온 지식을 정리합니다.
기본 탐색은 조건 하나를 추가했을 때 바로 구분 능력이 좋아지는 후보를 선택합니다. 두 단계 탐색은 그런 후보가 없을 때, 단독으로는 이득이 없는 첫 조건과 다음 조건을 함께 살펴 결합 효과를 찾습니다. 탐색 예산은 이 과정에 허용한 시간과 후보 평가 수, 질의 수 등의 상한입니다.
실험과 검증
예측의 정확도를 비교하는 실험과 프로그램이 의도대로 실행되는지 확인하는 테스트를 구분했습니다. 회귀 테스트는 코드를 수정한 뒤에도 기존 동작이 유지되는지 확인하는 검사이며, 통과 개수가 곧 예측 정확도를 뜻하지는 않습니다.
| 평가 영역 | 확인하는 내용 |
|---|---|
| 결정 트리 비교 | 등록 학습기 7개와 다수 클래스 및 검증 깊이 선택을 더한 9개 조건 |
| 데이터 분리 | 학습 예제, 설정 선택용 검증 예제와 최종 평가 예제의 중복 방지 |
| 정확도와 복잡도 | 최종 예측값, 깊이와 노드 수, 양성 규칙 및 조건 수 |
| 실행 비용 | 학습과 예측 시간, 실행 환경과 반복별 측정값 |
| 관계 학습 | 도달 가능한 관계와 불가능한 관계, 순환과 단절 및 자기 연결 |
| 실패 처리 | 후보 소진과 탐색 예산 초과, 질의 오류와 정리 오류 구분 |
| 배포 검증 | 소스 ZIP을 풀어 Windows와 Linux에서 각각 통합 5/5단계 통과 |
| 회귀 테스트 | 전체 153개 중 Windows 151개 통과와 권한 관련 2개 건너뜀, Linux 153개 통과 |
| 고정 기본 실행 | 두 기준 트리 각각 4/4개, 관계 홀드아웃 71/71개 정답과 정상 종료 |
개발 단계는 시드 0–4의 40개 조건에서 후보 정책을 비교했습니다. 최종 평가는 선택 기록과 평가할 코드를 식별하는 소스 해시를 고정한 상태에서 시드 100–109의 240개 조건을 실행했습니다. 학습과 내부 검증의 비율은 각각 60%와 20%이며 나머지가 홀드아웃입니다. 깊이는 내부 검증에서, 대표 정책은 별도 개발 홀드아웃에서 선택하므로 최종 평가 데이터가 설정 선택에 사용되지 않습니다.
재현 검증은 같은 컴퓨터의 Windows와, Windows 안에서 Linux를 실행하는 WSL의 Ubuntu 24.04에서 배포후보 ZIP을 풀어 실행했습니다. 모든 단계의 종료 코드와 네이티브 표준 오류까지 확인했으며 다른 물리 컴퓨터에서의 독립 인증과는 구분합니다. 최종 ZIP은 문서와 검증 근거를 추가한 배포본이며 검증한 실행 코드의 해시는 같습니다. 통합 검증 기록에서 실행 환경과 파일을 대조할 수 있습니다.
관계 학습은 선형 연결과 순환, 단절, 조밀한 비순환 그래프 및 자기 연결의 다섯 유형에서 노드 수 8개와 16개, 시드 200–202를 조합한 30개 조건입니다. 모든 노드에 자기 연결을 명시하고 독립적인 너비 우선 탐색으로 정답을 만듭니다. 연결 사실은 학습에 제공하므로 알고 있는 그래프에서 관계 쌍을 복원하는 평가이며 새로운 그래프로의 전이 평가가 아닙니다.
두 단계 탐색이 완료된 26개 조건의 관계 쌍은 1,566개 중 1,563개 정답으로 99.81%였습니다. 실제로는 도달할 수 없는데 가능하다고 판단한 거짓 양성은 0개, 도달할 수 있는데 불가능하다고 판단한 거짓 음성은 3개입니다. 이 정확도는 완료 조건만의 수치이며 미완료 4개를 포함한 전체 성공률로 해석하지 않습니다. 기본 탐색도 유지하고 두 단계 탐색은 선택 옵션으로 제공합니다.
완료 20개와 26개의 비교에서는 두 탐색 정책에 같은 수명 관리와 오류 처리 및 예산 처리를 적용했습니다. 보존된 FOIL 코드와의 버전 비교가 아니라 탐색 정책만 바꾼 비교로 해석합니다.
보존한 과제 보고서에는 시간 단축 44–80%와 일부 고잡음 조건의 정확도 상승 19.1%p가 기록되어 있습니다. 학습과 평가가 겹치는 절차의 수치이므로 홀드아웃 일반화 성능의 근거로 사용하지 않습니다. 이 표와 분리된 데이터 평가의 결과는 각각의 문서와 원시 기록에서 절차를 대조할 수 있습니다.
오류 분석과 설계의 한계
| 확인할 문제 | 설계와 비교 방법 |
|---|---|
| 하나의 공유 카운터를 깊이로 사용 | 공유 카운터 기준과 경로별 깊이를 재귀 인자로 전달하는 변형 비교 |
| 잡음 평가에 학습 예제가 포함됨 | 학습과 검증 및 최종 평가 데이터를 분리 |
| 알고리즘마다 달라질 수 있는 입력 | 같은 조건에서 데이터와 잡음 위치를 공유 |
| 정확도만으로 모델 판단 | 노드 수와 깊이, 규칙 길이 및 측정 비용 함께 분석 |
| FOIL 탐색의 무진행과 긴 질의 | 탐색 및 질의 예산을 두고 실패 종류를 명시 |
| 학습 규칙의 확인이 어려움 | 분기 경로와 논리식, 일치한 Horn 절 및 입력 바인딩 제공 |
규칙을 짧게 만드는 것이 언제나 정확도를 높이지는 않습니다. 깊이를 제한하면 잡음에 대한 민감도가 줄어들 수 있지만 정답을 표현하는 분기까지 제거할 수 있습니다. 개선이 없는 실험도 기록하고 추가 확대를 중단하며, 각 변형의 적용 범위를 결과에 맞춰 설명합니다.
대표 정책의 유형별 균형 정확도는 모든 지정 조건을 만족해야 참이 되는 논리곱에서 95.08%, 소수의 조건 묶음 중 하나라도 만족하면 참이 되는 희소 논리식에서 91.01%, 참인 관련 입력 수가 홀수이면 참이 되는 배타적 논리합 XOR에서 68.74%, 무작위 정답 대조군에서 50.20%입니다. 구조를 가진 유형에서는 학습할 수 있지만 독립적인 무작위 정답까지 예측하는 것은 아니며, XOR도 다른 구조화 유형보다 어려운 조건으로 남았습니다. 명시한 깊이 후보와 가지치기 비교를 마친 뒤 추가 설정 탐색은 중단했습니다.
평가는 생성 속성 데이터와 유한 관계 예제를 대상으로 합니다. 외부 실무 데이터에서의 일반화 성능이나 모든 Prolog 프로그램의 종료를 보장하지 않습니다. 학습한 규칙의 일치 설명도 Prolog 내부의 완전한 증명 트리와는 구분합니다.
규칙 확인과 재현 방법
입력을 바꾸며 학습한 규칙 확인하기에서 A와 B 및 C를 직접 선택하면 실제 트리의 분기 경로와 논리식의 예측을 비교할 수 있습니다. 입력 여덟 개 전체로 학습한 설명용 모델이며 새로운 성능 평가 결과는 아닙니다. 다운로드 ZIP의 한국어 페이지는 서버 없이 오프라인으로도 열립니다.
다운로드 ZIP에는 Python 코드와 고정한 의존성 목록, 데이터 예제, 실행 도구와 보존한 과제 기록이 포함됩니다. Python 3.12와 함께 Windows에서는 SWI-Prolog 9.2.9 x64를, Ubuntu 24.04에서는 시스템 패키지 9.0.4를 사용합니다. 전체 런타임을 설치한 뒤 projects/symbolic-machine-learning에서 실행하며 정확한 설치 파일과 연결 설정은 한국어 재현 문서에 안내합니다.
python -m pip install -r requirements.lock.txt
python tools/run_checks.py --output-dir outputs/verification
통합 검증은 배포 파일과 실제 PySwip 질의, 회귀 테스트 및 두 학습 경로를 실행하고 네이티브 프로세스가 정상 종료하는지도 검사합니다. 새 폴더 또는 빈 폴더에 결과를 보관하며 보존한 과제 기록을 덮어쓰지 않습니다. 벤치마크 실행 명령과 데이터 분리 절차는 저장소의 한국어 재현 문서에서 안내합니다. 명령행 실행에서는 결정 트리와 FOIL 관계 학습을 모두 사용할 수 있습니다.
소스 코드와 실험 자료
- 소스 코드와 실험 및 검증 ZIP
- GitHub 저장소
- 기호 머신러닝 구현
- 영어 설명, 한국어 설명
- 구조와 지원 범위, 재현 및 파일 검증
- 비교 실험 전체 결과, 원시 실험 보고서
- 실행 환경과 배포 검증
- 보존한 과제 실험 보고서, 기준 코드 스냅샷
저장소 문서는 영어를 기본으로 한국어도 제공합니다. 같은 저장소의 자동 추론과 논리 프로그래밍 프로젝트 및 원본 참고 자료는 과제 맥락을 확인하는 자료이며, 기호 머신러닝의 학습 실행에는 별도 의존성이 아닙니다.
소스 코드와 실험 및 검증 ZIPGitHub에서 소스 코드 보기

