Apache Nifi
Nifi를 설치하고
- 기본은 https 접속임 conf/nifi.properties
- 기본은 single user 접속임. 사용자 설정가이드
- 사용자 비번은 12자리 이상이며 설정했으면 한 번 리스타트 해야 적용됨.
gcp web_analytics sample schema
GCP의 Web Analytics 샘플 데이터셋은 BigQuery에서 제공되는 Google Analytics 360 샘플 데이터로, 다음 테이블에 존재합니다:
bigquery-public-data.google_analytics_sample.ga_sessions_*
이 데이터는 Google Analytics의 방문 세션(ga_sessions)을 기준으로 구성되어 있으며, **중첩된 구조 (RECORD)**와 **반복 필드 (REPEATED)**를 포함합니다.
🧩 샘플 스키마 요약 (상위 수준)
✅ 기본 필드
| 필드명 | 타입 | 설명 |
|---|---|---|
fullVisitorId |
STRING | 고유 방문자 ID |
visitId |
INTEGER | 세션 ID |
visitNumber |
INTEGER | 방문 순서 (ex: 첫 방문 = 1) |
visitStartTime |
INTEGER | UNIX timestamp |
date |
STRING | YYYYMMDD 형식 날짜 |
✅ RECORD 필드 (중첩 구조)
trafficSource (RECORD)
| 필드명 | 타입 |
|---|---|
| source | STRING |
| medium | STRING |
| campaign | STRING |
| keyword | STRING |
| adContent | STRING |
device (RECORD)
| 필드명 | 타입 |
|---|---|
| browser | STRING |
| operatingSystem | STRING |
| isMobile | BOOLEAN |
| deviceCategory | STRING |
geoNetwork (RECORD)
| 필드명 | 타입 |
|---|---|
| continent | STRING |
| country | STRING |
| city | STRING |
totals (RECORD)
| 필드명 | 타입 |
|---|---|
| visits | INTEGER |
| hits | INTEGER |
| pageviews | INTEGER |
| bounces | INTEGER |
| transactions | INTEGER |
| transactionRevenue | INTEGER |
✅ hits 필드 (REPEATED RECORD)
1개의 세션 내 여러 행동(페이지뷰, 이벤트 등)이 기록됩니다.
rmse가 낮다는 것은 어떤 의미인가?
RMSE(Root Mean Square Error)가 낮다는 것은 다음과 같은 의미를 갖습니다:
✅ 1. 예측 정확도가 높다
- RMSE는 예측값과 실제값 사이의 평균적인 오차 크기를 나타냅니다.
- 따라서 RMSE가 낮다는 것은:
- 모델의 예측값이 실제값과 더 가깝다는 뜻이고,
- 모델이 정확한 예측을 하고 있다는 것을 의미합니다.
✅ 2. 큰 오차가 적다
- RMSE는 오차를 제곱해서 평균을 내기 때문에, 큰 오차일수록 더 큰 패널티를 받습니다.
- 따라서 RMSE가 낮다는 것은:
- 단순히 평균 오차가 작은 것뿐 아니라,
- **큰 오차(이상치)**가 별로 없다는 의미도 됩니다.
✅ 3. 모델이 과적합(Overfitting)되지 않았을 수 있다
- 훈련 데이터에서 RMSE가 낮고, 검증 데이터에서도 낮다면 → 모델이 잘 일반화되었다는 신호입니다.
❗주의할 점
- RMSE는 단위에 민감하므로, 다른 모델들과 비교할 때는 반드시 같은 단위/데이터 기준에서 비교해야 합니다.
- RMSE만 보고 성능을 판단하는 것은 위험할 수 있으니, MAE, R², 잔차분석 등과 함께 보는 것이 좋습니다.
예시로,
WHERE RAND() < 0.001
WHERE RAND() < 0.001은 SQL에서 **표본 추출 (sampling)**을 할 때 자주 사용하는 패턴입니다. 이 조건의 의미는 다음과 같습니다:
✅ 의미
WHERE RAND() < 0.001
RAND()는 0과 1 사이의 난수를 반환합니다.RAND() < 0.001은 약 0.1% 확률로 TRUE가 됩니다.- 따라서 이 조건을 만족하는 약 0.1%의 행(row) 만 필터링되어 결과에 포함됩니다.
✅ 용도
- 테스트용 샘플 데이터 추출
- 대용량 테이블에서 분석하거나 디버깅할 때 전체 데이터를 쓰지 않고 일부만 뽑기 위함
- 랜덤 서브셋 생성
- 데이터 균형 확인, 속도 향상 등
✅ 예제
SELECT *
FROM big_table
WHERE RAND() < 0.001;
→ big_table에서 무작위로 약 0.1% 행을 추출합니다.
CREATE_MODEL 진행상태 확인
BigQuery에서 create model을 실행 후
This query will process 41.76 MB (ML) when run. Depending on the model type and training data size, the training job can take minutes or even hours.
이런 메시지가 하단에 출력되고는, 이 녀석이 진행중인지 도통 알수가 없는 상태가 되어, 혹시나 하고 진헹상태를 찾아볼수 있는가 싶었지만.
SELECT
job_id,
state,
creation_time,
start_time,
end_time,
error_result
FROM
`region-us`.INFORMATION_SCHEMA.JOBS_BY_USER
WHERE
job_type = 'QUERY'
AND statement_type = 'CREATE_MODEL'
ORDER BY
creation_time DESC
LIMIT 10;
역시나 결과가 안 나온다.
ML.FEATURE_CROSS
좋은 질문입니다!
ML.FEATURE_CROSS()와 CONCAT()는 비슷한 결과를 내지만, 목적과 내부 처리 방식에서 차이가 있습니다.
✅ 공통점
둘 다 **여러 문자열 피처를 결합(cross)**해서 새로운 하나의 피처를 만듭니다.
예:
CONCAT('US', '_', 'mobile') → 'US_mobile'
ML.FEATURE_CROSS(['US', 'mobile']) → 'US_mobile'
❗ 차이점 요약
| 항목 | ML.FEATURE_CROSS() |
CONCAT() |
|---|---|---|
| 목적 | 머신러닝 특화: 교차 피처 생성 | 일반적인 문자열 연결 |
| 자동 최적화 | 내부적으로 범주형 피처로 자동 처리 | 단순한 문자열, 모델에선 수치형 취급될 수도 |
| 입력 타입 제한 | STRING 또는 BYTES만 허용 | 다양한 타입 지원 (숫자, 날짜 등 가능) |
| 모델 의도 표현 | “이건 feature crossing이다"라고 명시적 표현 | 단순 연결 → 모델이 교차 피처인지 모름 |
| 해시 처리 지원 | 내부적으로 가능 (옵션 없음, 향후 지원 가능) | 없음 |
🧠 실전 팁
- 모델에 교차 피처임을 명확히 알리고 싶을 때 →
ML.FEATURE_CROSS()사용 - 그냥 텍스트 가공이나 임시 출력용 →
CONCAT()사용
✅ 예제 비교
-- 교차 피처로 학습 시
ML.FEATURE_CROSS([country, device_category]) AS crossed_feature
-- 단순 문자열 가공 (모델은 수치형으로 오해할 수도 있음)
CONCAT(country, '_', device_category) AS crossed_feature
둘 다 같은 문자열 'US_mobile'을 만들지만, 모델이 인식하는 방식은 다릅니다.
Data Dredging
좋은 질문입니다.
“Data Dredging”(데이터 채굴, 또는 p-hacking)은 통계와 데이터 과학에서 아주 위험한 오류이자 비윤리적인 실수 중 하나입니다.
📌 Data Dredging이란?
Data Dredging이란,
의미 있는 결과를 찾기 위해 데이터를 반복적으로 분석해서 우연히 나온 통계적 유의성을 발견하는 행위입니다.
즉,
- 원래 가설도 없이
- 데이터 안에서 아무 의미나 찾아보려다
- 우연히 나오는 “그럴듯한” 결과에 의미를 부여하는 것.
🎯 왜 문제가 될까?
| 문제점 | 설명 |
|---|---|
| 🎲 우연한 발견 | 수많은 분석 중 일부는 단순히 우연히 유의하게 나올 수 있음 |
| 📈 잘못된 인사이트 | 실제로는 관련이 없는 변수 사이에 잘못된 관계가 발견됨 |
| 💥 재현 불가 | 다른 데이터셋에서는 다시 같은 결과가 안 나옴 |
| 📉 모델 과적합 위험 | 학습 데이터에만 맞춘 결과 → 일반화 성능 저하 |
🧪 예시
예를 들어:
Principal Component Analysis (PCA)
좋습니다!
Principal Component Analysis (PCA) — 바로 정확하고 깔끔하게 정리해드리겠습니다.
🎯 PCA란?
**PCA (주성분 분석)**는 고차원 데이터를 저차원으로 압축하면서,
데이터의 가장 중요한 특징(분산)을 최대한 보존하는 차원 축소(dimensionality reduction) 기법입니다.
즉,
- 데이터를 요약하면서
- 정보 손실을 최소화하고
- 새로운 축(Principal Components) 을 찾는 방법입니다.
🚀 PCA를 쓰는 이유
| 목적 | 설명 |
|---|---|
| 차원 축소 | feature 수가 많으면 계산이 느리고 과적합(overfitting) 위험 → 줄여서 효율적으로 만듦 |
| 노이즈 제거 | 덜 중요한 축을 제거하면서 데이터의 핵심 구조를 보존 |
| 시각화 | 고차원(>3D) 데이터를 2D/3D로 투영해서 쉽게 볼 수 있게 함 |
| 속도 향상 | 학습이나 추론 시 feature 수 줄여서 처리 속도 빠르게 |
📚 쉽게 예시
예를 들어:
Bucketized Feature + Crossed Feature
좋은 질문입니다!
GCP (특히 Vertex AI Feature Store나 BigQuery ML에서) “bucket type feature“은 매우 자주 나오는 개념인데, 쉽게 정리해드릴게요.
🎯 “Bucketized Feature"란?
**연속적인 숫자형 feature(numeric feature)**를 구간(buckets)으로 나눠서, 범주형(categorical) feature처럼 처리하는 방식입니다.
Bucket type은 GCP에서는 주로
- Feature Store feature schema 정의 시,
- BigQuery ML 모델 훈련 시 (
TRANSFORMATIONS)
사용됩니다.
🚀 왜 bucket 처리를 할까?
| 이유 | 설명 |
|---|---|
| 비선형성 표현 | 숫자값 자체보다 “어느 구간에 속했는지"가 더 중요한 경우 많음 (예: 나이, 가격 등) |
| 모델 복잡도 감소 | 작은 숫자 차이를 신경 쓰지 않고 구간 단위로 학습 |
| 해석 용이성 증가 | 모델 결과를 사람이 이해하기 쉬워짐 (“나이 30~39세 그룹”) |
| Outlier(이상치) 영향 감소 | 너무 큰 숫자에 덜 민감하게 만듦 |
📚 쉽게 예시
| 원래 값 (연속형 숫자) | Bucket 처리 결과 |
|---|---|
| 22 | 20–30 구간 (bucket 2) |
| 27 | 20–30 구간 (bucket 2) |
| 35 | 30–40 구간 (bucket 3) |
| 47 | 40–50 구간 (bucket 4) |
| 82 | 80–90 구간 (bucket 8) |
- 예를 들어, 나이(age) 를 10살 단위 버킷으로 나누는 식입니다.
✨ GCP 용어로 구체적으로 말하면
- Feature Store나 BQML에서는 feature type을 정의할 때
"bucketized"옵션을 줄 수 있습니다.
예시:
Overfitting
좋은 질문입니다!
모델 학습(Machine Learning Training) 과정에서 자주 듣는 “Overfitting (오버피팅)“에 대해 명확히 설명드릴게요.
🎯 Overfitting(오버핏)이란?
모델이 학습 데이터(training data)에 너무 과하게 맞춰져서, 새로운 데이터(test/unseen data)에는 잘 일반화되지 못하는 현상입니다.
즉,
- 학습 데이터에서는 정확도가 매우 높지만,
- 실제로 새로운 데이터에 적용하면 성능이 급격히 나빠지는 문제입니다.
🚀 쉽게 예를 들면
- 학생이 기출문제만 외워서 시험을 치면 기출에는 만점이지만,
처음 보는 문제는 전혀 못 푸는 것과 비슷합니다.
(공부를 “문제의 패턴"을 이해한 게 아니라 “문제 자체"만 외운 거죠.)