랜덤 트리 임베딩(Random Trees Embedding)이란? AI에서 트리의 도착 잎을 이진 특징으로 바꾸는 방법
TL;DR
랜덤 트리 임베딩은 정답 라벨 없이 만든 여러 무작위 트리에서 입력이 도착한 잎을 0과 1의 특징으로 표현하는 방법입니다. 트리마다 해당 잎의 한 칸만 1로 표시하고 그 블록들을 이어 붙입니다. 예측값을 평균하는 랜덤 포레스트와 달리 뒤 모델에 전달할 입력을 만듭니다. 트리 수·깊이·실제 잎 수와 희소 출력을 구분하고 같은 숲과 인코더를 새 입력에도 재사용합니다.
핵심 3줄 요약
- 핵심 1
한 트리에서 한 칸만 켜집니다. 도착한 잎의 위치를 표시하며 잎 번호를 연속 수치처럼 사용하지 않습니다. - 핵심 2
라벨 없이 입력 공간을 나눕니다. 업무 정답을 예측하는 일은 이진 특징 뒤의 분류기 등이 맡습니다. - 핵심 3
출력 열 수는 실제 잎 수의 합입니다. 최대 깊이로 계산한 상한과 학습 뒤 만들어진 열 수는 다릅니다.
이 글에서 다룰 내용
- 랜덤 트리 임베딩의 한 문장 정의
- 두 트리로 확인하는 잎과 이진 코드 예시
- 비지도 분할과 원-핫 연결의 작동 순서
- 트리 수·깊이·희소 출력과 저장 속성
- 랜덤 포레스트·특징 해싱·의미 임베딩과의 차이
- 선형 분류에 연결하는 실전 체크리스트
- 자료 의존성·재학습·메모리와 누수의 주의점
랜덤 트리 임베딩을 한 문장으로 정의하면 무엇인가요?
랜덤 트리 임베딩은 입력 공간을 여러 무작위 트리로 나누고 도착한 잎을 트리별로 원-핫 인코딩해 연결하는 비지도 특징 변환입니다.
영문명은 Random Trees Embedding이며 무작위 트리 임베딩이라고도 부릅니다. scikit-learn은
RandomTreesEmbedding
클래스로 제공하며 사용자 가이드에서는 Totally Random Trees Embedding으로 소개합니다. 이 글은 확인한 1.9.1 문서와 구현을 기준으로 설명합니다.
잎은 트리의 분기를 따라 내려간 마지막 노드입니다. 원-핫 인코딩은 가능한 잎마다 전용 열을 두고 해당 잎의 열만 1로 표시하는 방식입니다. 여러 트리의 열을 서로 다른 블록으로 붙이므로 첫 트리의 잎 번호와 둘째 트리의 같은 번호를 하나의 열에 섞지 않습니다.
한 줄 정리: 여러 트리가 입력을 어느 영역에 넣었는지 기록한 이진 벡터입니다. 이 벡터 자체에 클래스 확률이나 문장의 뜻이 들어 있다고 가정하지 않습니다.
쉬운 예시로 이해해 볼까요?
감자나라ai님이 숫자 입력을 두 트리로 변환한다고 가정해 보겠습니다. 원리 설명을 위해 첫 트리는 0.4, 둘째 트리는 1.5를 경계로 고정합니다. 각 트리는 왼쪽·오른쪽 잎을 하나씩 가지며 경계 이하이면 왼쪽으로 보냅니다. 실제 학습이 뽑은 경계값이라는 뜻은 아닙니다.
출력 열은 첫 트리 왼쪽, 첫 트리 오른쪽, 둘째 트리 왼쪽, 둘째 트리 오른쪽의 순서입니다. 원본 한 열이 네 열의 코드로 바뀌며 각 행에는 트리 수와 같은 두 개의 1이 들어갑니다.
- 입력 0.2는 두 트리 모두 왼쪽이므로
[1, 0, 1, 0]입니다. - 입력 0.8은 첫 트리 오른쪽·둘째 트리 왼쪽이므로
[0, 1, 1, 0]입니다. - 입력 2.0은 두 트리 모두 오른쪽이므로
[0, 1, 0, 1]입니다.
0.2와 0.8의 코드 내적은 1이고, 0.2와 2.0의 내적은 0입니다. 같은 잎을 공유한 트리의 개수를 센 결과입니다. 트리 수 2로 나누면 각각 0.5와 0이지만 이는 설명용 공유 비율이며 정답 확률은 아닙니다. 자기 내적은 2이므로 기본 코드의 길이가 1인 것도 아닙니다.
이 값들은 Python 표준 라이브러리로 고정 경계와 원-핫 규칙을 계산해 확인했습니다. 설치하지 않은 scikit-learn을 실행한 결과나 분류 성능 수치는 아닙니다. 입력 0.2와 0.3은 같은 코드를 얻으므로 이 코드만으로 원래 숫자를 정확히 복원하지 못합니다.
쉬운 예시: 원본에서의 거리 크기보다 여러 분할에서 같은 칸을 공유했는지가 코드에 남습니다. 경계를 조금 넘어도 코드가 바뀌고 같은 영역 안에서는 입력이 달라도 코드가 같습니다.
왜 AI에서 랜덤 트리 임베딩이 중요한가요?
비선형 영역 정보를 새 특징으로 전달합니다
원본 값에 직선을 그어 나누기 어려운 관계라도 여러 잎의 조합으로 표현한 공간에서는 다른 분류 경계를 만들 수 있습니다. 뒤의 선형 모델이 이진 특징에 가중치를 배우면 원본 입력에서는 조건 분기에 따른 비선형 예측이 됩니다. 변환이 유용한지는 보지 못한 자료에서 평가합니다.
입력 표현과 예측 학습을 분리합니다
변환기는 업무 정답을 요구하지 않고 입력의 영역 구분을 만듭니다. 생성된 코드를 분류기 등에 전달할 수 있지만 라벨이 없어도 분류 정답을 자동으로 알아낸다는 뜻은 아닙니다. 공식 예제도 변환 뒤 BernoulliNB 또는 로지스틱 회귀를 따로 학습합니다.
핵심 인사이트: 트리 앙상블이 언제나 예측 평균만 반환하는 것은 아닙니다. 여기서는 잎의 위치를 다음 학습 단계의 재료로 사용합니다.
랜덤 트리 임베딩은 어떤 순서로 작동하나요?
1. 입력 자료로 무작위 분할 숲을 만듭니다
확인한 구현은 내부에서 균일 난수 목표값을 만들고 ExtraTreeRegressor들을 학습합니다. 사용자가 넘긴 업무 라벨
y
는 무시합니다. 내부 난수 목표가 있다는 사실과 실제 클래스 정답을 사용한다는 주장은 다릅니다. 기본 구현은 부트스트랩을 끄며 입력 자료와 성장 조건이 트리 구조에 영향을 줍니다.
2. 각 입력이 도착한 잎 번호를 구합니다
apply(X)
는 각 행을 숲의 모든 트리에 통과시켜 잎 번호를 반환합니다. 결과 모양은 행 수 × 트리 수입니다. 번호는 해당 트리 안의 노드 식별자이며 잎 사이의 거리나 순위를 뜻하지 않습니다. 내부 분기 노드도 번호를 사용하므로 잎 번호가 연속되지 않을 수 있습니다.
3. 잎을 원-핫 인코딩해 이어 붙입니다
학습할 때
one_hot_encoder_
가 트리별 잎 목록과 출력 열 대응을 저장합니다.
transform(X)
는 저장된 숲의 잎 번호를 같은 인코더로 바꿉니다. 열 수는 실제 잎 수를 모두 더한 값이고 각 행에는 트리마다 하나씩 1이 남습니다.
실전 팁: 원본 특징, apply의 잎 번호 표, transform의 이진 특징을 따로 비교하세요. 행 수가 같아도 세 출력의 열 수와 의미는 다릅니다.
주요 설정과 결과는 어떻게 읽나요?
트리 수와 최대 깊이는 역할이 다릅니다
n_estimators
는 트리 수이며 기본값은 100입니다.
max_depth
는 한 트리의 최대 깊이이며 기본값은 5입니다. 깊이 제한만으로 가능한 최대 잎 수를 계산할 수 있지만 모든 가지가 끝까지 자라지는 않습니다. 실제 출력 모양을 학습 뒤 확인합니다.
예를 들어 트리 10개와 최대 깊이 3이면 전체 잎 수의 상한은 80입니다.
max_leaf_nodes
를 따로 제한했다면 그 조건도 봅니다.
min_samples_leaf
는 양쪽 자식에 남을 최소 표본 수를 제한하므로 깊이를 허용했어도 분할이 멈출 수 있습니다. 나무 수와 출력 차원을 같은 숫자로 읽지 않습니다.
sparse_output은 저장 형식을 정합니다
기본
sparse_output=True
는 CSR 희소 행렬을 반환합니다. 거짓으로 바꾸면 밀집 배열을 반환하지만 잎의 뜻이나 원-핫 규칙이 달라지는 것은 아닙니다. 희소 형식도 값·열 번호·행 경계와 숲 자체를 저장하므로 메모리가 들지 않는다고 표현하지 않습니다.
random_state는 재현 조건의 일부입니다
정수
random_state
는 내부 난수 목표와 분할 난수 생성에 관여합니다. 같은 시드만으로 다른 훈련 자료에서도 같은 숲이 나온다고 보장하지 않습니다. 훈련 입력·행 순서·파라미터·라이브러리 버전도 함께 보관합니다. 새 행의 변환에는 저장된 숲을 그대로 사용합니다.
저장 속성은 숲과 인코더를 함께 봅니다
estimators_
는 학습된 트리 목록,
one_hot_encoder_
는 잎의 열 대응을 담습니다.
n_features_in_
은 원본 입력 열 수입니다.
get_feature_names_out()
의 이름에는 트리와 잎 식별자가 들어가며 실제 출력 열을 살피는 데 사용합니다. 입력 열 수를 출력 열 수로 오해하지 않습니다.
랜덤 트리 임베딩과 헷갈리는 용어는 무엇이 다른가요?
랜덤 포레스트·엑스트라 트리는 정답을 예측합니다
랜덤 포레스트와 엑스트라 트리 분류·회귀기는 업무 정답으로 학습하고 여러 예측을 결합합니다. 여기서는 실제 정답 없이 숲을 만들고 잎 코드만 출력합니다. 지도학습 숲에서도 잎을 특징으로 뽑을 수 있으나 그때는 정답을 본 변환이므로 별도의 평가 설계가 필요합니다.
특징 해싱은 이름을 고정 칸에 보냅니다
특징 해싱은 문자열 특징 이름을 해시 함수로 정해진 칸에 대응시킵니다. 랜덤 트리 임베딩은 수치 입력에 따라 학습한 분할을 지나 잎 전용 열을 얻습니다. 공식 예제 제목의 Hashing을 보고 사전 학습 없는 FeatureHasher와 같은 API라고 생각하지 않습니다.
의미 임베딩·차원 축소와 출력 목적이 다릅니다
이진 잎 표현은 문장 의미를 배우는 언어 모델의 조밀 임베딩과 다릅니다. 또한 대개 높은 차원의 희소 공간으로 옮기는 변환입니다. 공식 동심원 예제는 그 뒤에 TruncatedSVD를 적용해 두 좌표로 시각화합니다. 두 좌표를 만든 단계와 트리의 원래 이진 출력은 구별합니다.
비교 정리: 예측 평균, 문자열 해시 칸, 트리의 잎 코드, 의미 벡터는 서로 다른 출력입니다. 이름의 랜덤·해싱·임베딩보다 실제 변환 규칙으로 판단합니다.
실전에서는 어디에 쓰이나요?
원본 선형 모델과 변환 뒤 모델을 비교합니다
공식 앙상블 특징 예제는 RandomTreesEmbedding과 로지스틱 회귀를 파이프라인으로 연결합니다. 원본 선형 모델, 트리 기반 모델과 같은 분할에서 비교할 수 있습니다. 예제의 특정 데이터와 설정에서 얻은 점수나 실행 시간을 다른 업무의 성능 보증으로 옮기지는 않습니다.
복잡한 입력 구분을 살펴봅니다
동심원 예제는 여러 무작위 분할을 거친 희소 코드를 만들고 분류와 시각화를 보여 줍니다. 원본에서 가까운 점이 여러 트리의 잎을 공유할 가능성을 이용합니다. 그렇다고 모든 가까운 점이 같은 코드를 얻거나 모든 의미상 비슷한 항목이 가깝다고 보장하지는 않습니다.
랜덤 트리 임베딩을 적용할 때 어떤 순서로 확인하나요?
1. 분할과 원본 입력 계약을 고정합니다
훈련·검증·최종 테스트를 먼저 나누고 예측 시점에 얻을 수 있는 열만 사용합니다. 결측 처리와 범주 표현 등 앞의 전처리도 훈련 부분에서 맞춥니다. 시계열이나 같은 사람의 반복 기록이라면 시간·집단 관계에 맞춰 나눕니다. 라벨을 쓰지 않는 단계라고 테스트 입력을 미리 합쳐 학습하지 않습니다.
2. 작은 표에서 행과 활성 칸을 점검합니다
입력 행 수가 유지되는지, 출력 열 수가 실제 잎 수의 합인지 확인합니다. 행마다 1의 개수가 트리 수와 같은지도 봅니다. apply의 각 열이 어느 트리에 해당하는지 대조하면 잎 번호를 그대로 수치 모델에 넘기는 실수를 찾기 쉽습니다. 희소 출력은 작은 일부만 배열로 펼쳐 확인합니다.
3. 전체 파이프라인의 품질과 비용을 평가합니다
전처리·트리 변환·뒤 모델 전체를 파이프라인으로 묶고 그 전체에 교차 검증을 적용합니다. 깊이·트리 수·잎의 최소 표본 수와 뒤 모델의 규제를 검증 자료에서 고릅니다. 최종 테스트는 선택이 끝난 뒤 사용합니다. 실제 열 수·저장 크기·지연과 중요한 클래스의 오류를 함께 남깁니다.
사용할 때 무엇을 주의해야 하나요?
라벨이 없어도 자료를 학습합니다. 무작위 분할도 입력값의 범위와 분할 가능한 표본에 의존합니다. 미리 전체 자료로 숲을 만든 뒤 검증하는 방식은 새로운 입력에 적용하는 조건과 다릅니다. 비지도라는 설명을 학습이 없다는 의미로 바꾸지 않습니다.
깊이와 밀집 변환의 비용을 함께 봅니다. 깊이를 늘리면 가능한 잎 수가 빠르게 커집니다. 앞의 트리 10개·깊이 3 예시는 최대 80열이지만 표본 수에 따라 실제 열 수는 적을 수 있습니다. 큰 결과에
toarray()
를 호출하면 대부분 0인 칸까지 저장하므로 원본이 작다고 안심하지 않습니다.
재학습 뒤에는 같은 열이라고 가정하지 않습니다. 숲을 다시 만들면 잎과 열 대응이 바뀔 수 있습니다.
warm_start=True
로 나무를 추가하는 일도 뒤 모델의 입력 계약에 영향을 줍니다. 뒤 모델의 계수를 예전 열 위치에 그대로 붙이지 말고 변환기와 예측기를 한 버전으로 관리합니다.
출력으로 원인이나 보안을 증명하지 않습니다. 내부 난수 목표를 사용한 숲의
feature_importances_
를 업무 정답에 대한 중요도로 읽지 않습니다. 잎 코드는 원본값을 완전히 복원하지 못하지만 그 사실이 개인정보 보호나 익명화의 증명도 아닙니다. 원자료와 모델에 필요한 접근·보관 정책은 별도로 적용합니다.
주의: 트리 수를 늘려도 독립 성능이 반드시 좋아지지는 않습니다. 변환이 성공했는지, 뒤 예측이 맞는지, 비용이 허용되는지를 따로 확인합니다.
자주 묻는 질문
Q1. 정답 라벨 없이 분류 결과까지 나오나요?
아닙니다. 변환기는 업무 라벨 없이 잎의 이진 표현을 만듭니다. 그 표현으로 분류하려면 뒤에 분류기를 학습합니다. 내부 난수 목표값을 실제 정답으로 혼동하지 않습니다.
Q2. 트리 10개면 출력도 10열인가요?
apply가 돌려주는 잎 번호 표는 10열입니다. transform의 이진 출력은 각 트리의 잎마다 열을 두므로 실제 잎 수의 합만큼입니다. 이 예시의 깊이 3 조건에서는 최대 80열입니다.
Q3. 결과가 희소하면 입력보다 항상 작나요?
그렇지 않습니다. 한 행에서 활성 칸은 적지만 전체 열 수, 행 수, 희소 인덱스와 숲 저장 비용을 함께 봅니다. 뒤 모델의 계수도 확인해야 하며 밀집 배열로 바꾸면 메모리 부담이 커집니다.
Q4. 새 입력이 오면 다시 fit해야 하나요?
저장한 변환기의 transform을 사용합니다. 새로 fit하면 같은 이름의 열도 다른 영역을 나타낼 수 있습니다. 숲과 잎 인코더, 앞의 전처리 및 뒤 모델을 함께 보관합니다.
Q5. 같은 잎이면 같은 정답이라는 뜻인가요?
같은 트리의 분할 규칙에서 같은 영역에 도착했다는 뜻입니다. 실제 라벨을 기준으로 그 영역이 완전히 동질적이라고 보장하지 않습니다. 같은 코드를 얻는 서로 다른 입력도 있습니다.
Q6. 랜덤 트리 임베딩은 차원 축소인가요?
기본 변환은 많은 잎의 고차원 이진 특징을 만듭니다. 시각화를 위해 TruncatedSVD 같은 별도 축소를 이어 붙일 수 있지만 그 후속 출력과 원래 잎 코드를 구분합니다.
출처
마무리
랜덤 트리 임베딩은 정답 없이 만든 숲의 도착 잎을 이진 코드로 바꿉니다. 트리별 예측을 평균하는 모델이나 문자열을 고정 칸에 넣는 해시와 다르며 실제 출력 열 수는 학습된 잎 수의 합입니다.
처음에는 두 트리의 도착 잎과 원-핫 블록을 직접 대조해 보세요. 이후에는 트리 수·깊이·잎 크기와 뒤 모델을 함께 검증하고 새 입력에는 같은 변환을 적용합니다. 숲을 키울 때도 독립 품질과 운영 비용을 함께 확인합니다.
