Code › codeit-ai-sprint
데이터에서 머신러닝 엔지니어링까지
코드잇 스프린트 첫 수업에서 정리한 데이터 사이언스, MLOps, Python 기초의 전체 흐름
오늘은 코드잇 AI 엔지니어 스프린트 과정의 개강일이었다! 첫 시간은 OT로 시작했고, 오후 부터 데이터 사이언스와 머신러닝 엔지니어링이 어떤 흐름 위에 있는지 강사님께서 설명 해 주셨다.
수업은 데이터의 정의부터 시작했다.
데이터는 단순히 숫자나 문자로 표현된 정보만 뜻하지 않고 우리가 관찰하고 분석해서 의미 있는 정보를 추출할 수 있는 모든 형태의 정보, 예를 들면 이미지, 동영상, 텍스트, 클릭 로그, 센서 값처럼 형식은 달라도 분석할 수 있는 의미를 담고 있으면 데이터라고 부른다.
이런 데이터가 모여 있는 것을 데이터셋이라고 한다. 데이터셋 안에는 관찰 대상과 그 대상의 특성이 함께 들어 있고, 관찰 대상은 개체(Entity), 관찰치, 레코드, 샘플, 인스턴스라고도 부른다. 개체가 가진 특성은 속성(Attribute), 변수, 특징, 차원이라는 이름으로도 정리된다.
데이터의 저장
데이터를 다루는 흐름에서는 데이터 레이크와 데이터 웨어하우스가 나왔다.
데이터 레이크는 데이터를 선별하거나 정제하기 전에 먼저 모아두는 공간이다. 여러 시스템에서 발생한 클릭 로그, 센서 데이터, 외부 시장 데이터 같은 것들을 일단 한곳에 쌓아두지만, 이렇게 모인 데이터는 형식과 품질이 일정하지 않고 중복이나 결측치도 섞여 있어서 바로 분석하기 어려운 경우가 많다.
그래서 필요한 데이터를 정제하고 구조화해서 데이터 웨어하우스에 넣는다. 데이터 웨어하우스는 분석과 조회에 맞게 정리된 저장소다. 흐름으로 보면 데이터를 모으고, 옮기고, 저장하고, 정리하는 일은 주로 데이터 엔지니어링 영역이다. 그 뒤에 분석, A/B 테스트, 인공지능 모델링으로 이어지면서 데이터 사이언스 영역으로 넘어간다.
데이터 사이언스는 다양한 데이터로부터 지식과 인사이트를 추출하는 융합 분야다. 수학과 코딩도 중요하지만, 데이터만 잘 모은다고 끝나는 것도 아니고 모델만 잘 만든다고 끝나는 것도 아니다.
수업중에 강조하신 부분 중에 하나는 도메인 지식이다. 예를 들어 같은 매출 하락 데이터를 보더라도, 프로모션 종료 때문인지, 경쟁사 가격 인하 때문인지, 특정 채널 유입 감소 때문인지는 업무 맥락을 알아야 판단할 수 있다. 그래서 커뮤니케이션 능력도 중요하다. 모든 도메인을 전문가처럼 깊게 알 수는 없기 때문에 현업 담당자나 전문가와 대화하면서 맥락을 파악하여 분석을 하고, 그 결과를 다시 이해할 수 있게 전달해야 한다.
데이터는 많기만 해서는 안 된다
수업에서 기억에 남은 말 중 하나는 데이터가 무조건 많다고 좋은 것은 아니라는 점이었다.
쓰레기 데이터가 많으면 결과도 쓰레기가 된다. GIGO, Garbage In, Garbage Out이다. 모델 학습에서는 약간의 노이즈가 일반화 성능에 도움이 되는 경우도 있지만, 기본은 여전히 품질 좋은 데이터이다. 잘못된 값, 중복된 값, 편향된 데이터가 많이 들어가면 모델도 그 영향을 그대로 받는다.
아! 그리고 언급하고 싶은 부분이 또 있었다. 보통 머신러닝 성능이라고 하면 모델 구조나 알고리즘을 먼저 떠올리기 쉽지만, 실제 성능은 데이터 품질에서 크게 갈린다. 앤드류 응(Andrew Ng) 교수님이 데이터 중심 AI 관점에서 말한 부분이 있다고 해서 관련 자료를 찾아보니 Data-centric AI Resource Hub에서는 데이터 중심 AI를 “Data-centric AI is the discipline of systematically engineering the data used to build an AI system”이라고 정의하고 있었다. 모델을 고치기 전에, 모델이 배우는 데이터 자체를 체계적으로 다듬는 관점으로 이해했다.
데이터 직군의 역할 구분
역할 구분에서는 백엔드 엔지니어와 데이터 직군의 차이를 먼저 봤고, 백엔드 엔지니어는 주로 OLTP 영역을 다룬다. OLTP는 Online Transaction Processing의 약자로 서비스에서 발생하는 실시간 요청과 거래를 처리하는 시스템이며, 주문 생성, 결제, 회원가입, 게시글 작성 같은 작업이 여기에 들어간다.
데이터 엔지니어는 OLAP 영역을 많이 다룬다. OLAP는 Online Analytical Processing의 약자로, 분석을 위해 대량의 데이터를 모으고 조회하는 시스템이다. OLAP에서는 현재 데이터만 보는 것이 아니라 과거 데이터, 현재 데이터, 외부 데이터까지 함께 다루면서 전체 흐름을 파악하고, 데이터 양이 크기 때문에 대용량 분산 처리 시스템도 필요하다.
데이터 애널리스트는 SQL과 시각화 도구를 많이 사용하고, 필요하면 Pandas, Matplotlib, Seaborn 같은 Python 라이브러리도 사용한다. SQL만으로 하기 어려운 데이터 처리나 통계 계산, 시각화를 Python으로 보완하는 식이다. scikit-learn도 부분적으로 사용할 수 있다.
애널리스트는 과거와 현재를 설명하는 일을 주로 하며, 지난달 매출이 왜 떨어졌는지나 특정 지표가 어떤 구간에서 변했는지 분석한다. 데이터 사이언티스트는 여기서 한 걸음 더 나아가 예측과 자동화까지 다루고, 다음 달 매출을 예측하거나 사용자 프로파일링과 리타겟팅 모델을 만드는 일이 여기에 들어간다.
머신러닝 엔지니어가 하는 일
우리가 목표로 하는 역할은 머신러닝 엔지니어다.
머신러닝 엔지니어는 머신러닝 알고리즘을 실제 서비스에 적용하는 역할을 맡는다. 모델을 만드는 것에서 끝나는 게 아니라, 그 모델을 서비스에 통합하고 배포하고 관리하며 성능 최적화도 함께 다룬다. 그래서 이론적인 공부도 필요하다.
MLOps도 여기서 중요해진다. 모델은 한 번 학습하고 끝나는 것이 아니라 데이터를 계속 수집하고, 점검하고, 전처리하고, 다시 학습하고, 평가하고, 배포하는 흐름 안에서 운영된다.
정리하면 MLOps 파이프라인은 대략 이렇게 이어진다.
수집 → 점검 및 탐색 → 전처리 및 정제 → 모델링 및 훈련 → 평가 → 배포 → 다시 수집
실제 프로젝트에서는 FastAPI로 모델 API를 만들고, Docker로 실행 환경을 묶고, Kubernetes 같은 도구로 배포와 운영을 관리할 수 있다. 추론 성능 최적화가 필요하면 TensorRT 같은 도구도 사용할 수 있다.
머신러닝 리서처와의 차이도 짚었다. 리서처는 선형대수, 확률론, 통계 이론 같은 수학적 기반 위에서 새로운 알고리즘을 연구하거나 기존 알고리즘을 개선한다. 다만 완전히 새로운 알고리즘 연구는 빅테크 수준의 자본과 데이터, 컴퓨팅 자원이 필요한 경우가 많아서, 현실적으로는 기존 알고리즘을 개선하거나 응용하는 일이 많다고 했다.
Python을 쓰는 이유
Python은 AI 생태계에서 많이 쓰이는 언어다.
Python은 태생이 빠른 성능이 아니고 실행 성능만 보면 C++ 같은 언어가 더 빠르다. 그런데 Python은 머신러닝, 딥러닝, 데이터 전처리, 모델 배포 생태계가 잘 갖춰져 있다.
TensorFlow, PyTorch, Hugging Face 같은 AI 프레임워크를 사용할 수 있고, Pandas, NumPy, OpenCV, Seaborn 같은 데이터 처리 및 시각화 라이브러리도 풍부하다. 모델을 서비스로 만들 때는 FastAPI와 연결하기 좋고, Docker와 함께 배포하기도 편하다. 이번 과정에서는 PyTorch를 사용할 예정이다.
데이터의 여러 가지 분류
데이터의 유형도 정리했다.
정형 데이터는 고정된 필드와 엄격한 구조를 가진 데이터라서 데이터베이스 테이블이나 Excel 파일을 떠올리면 된다. 반정형 데이터는 일부 구조를 가진 데이터로, JSON이나 XML이 여기에 들어가며 완전히 표 형태는 아니지만 키와 값, 계층 구조를 가지고 있다.
비정형 데이터는 정해진 구조가 없는 데이터이고, 이미지, 동영상, 음성, 자유로운 텍스트가 여기에 해당한다. 현재는 비정형 데이터의 양이 압도적으로 많아서, AI는 이런 데이터에서 특징을 추출하거나 정형화된 정보로 바꾸는 데 많이 쓰인다.
데이터는 정성적 데이터와 정량적 데이터로도 나눌 수 있다.
정성적 데이터는 숫자 계산보다 어떤 속성이나 범주에 속하는지를 다룬다. 명목형과 순서형으로 나뉘는데, 명목형은 성별, 혈액형, 국적처럼 범주만 있고 순서가 없는 데이터다. 순서형은 만족도 5점 척도, 석차, 계급처럼 순서는 있지만 간격이 일정하다고 말하기 어려운 데이터다.
정량적 데이터는 숫자로 크기나 양을 나타내며 계산이 가능한 데이터다. 구간형은 값 사이의 간격은 일정하지만 절대 영점이 없고, 섭씨 온도나 날짜가 예시다. 비율형은 절대 영점이 있어서 값이 0이면 실제로 아무것도 없는 상태를 의미하며, 길이, 무게, 가격, 개수, 속도 등이 여기에 들어간다.
분석은 관찰에서부터 행동으로
데이터 분석은 데이터로부터 유의미한 정보를 추출하는 모든 과정이다. 데이터는 직관이나 감이 아니라 근거에 기반한 의사결정을 가능하게 한다.
분석 단계도 네 가지로 정리했다.
기술적 분석은 현재 무슨 일이 일어났는지를 설명한다. 예를 들면 환자의 체온이 39도이고 기침을 한다는 식이다. 진단적 분석은 왜 그런 일이 일어났는지를 설명하는 단계로, 검사 결과 바이러스 감염 때문에 열이 났다고 판단하는 일이 여기에 해당한다.
예측적 분석은 앞으로 어떤 일이 일어날지를 예측한다. 이대로 두면 내일 열이 더 오르고 폐렴으로 이어질 확률이 높다고 보는 식이다. 처방적 분석은 무엇을 해야 하는지를 제안하며, 해열제를 투여하거나 필요한 처치를 결정하는 단계까지 포함한다.
결국 데이터 분석은 관찰에서 시작해서 원인 파악, 예측, 행동 제안으로 나아간다.
전처리는 모델 앞에 있는 큰 작업이다
전처리에서는 Data Cleaning, Data Wrangling, Data Manipulation, EDA를 배웠다.
Data Cleaning은 잘못된 부분을 교정하거나 제거하는 작업이고, 잡음(Noise), 결측치(Missing Value), 이상치(Outlier), 중복값(Duplicate Value)을 다룬다. 잡음은 오류나 불필요한 데이터라서 필터링이나 평균값 사용으로 완화할 수 있다. 결측치는 값이 비어 있는 경우인데, 삭제하거나 평균값으로 채우거나 KNN 같은 방법으로 보정할 수 있고, 데이터가 충분히 많다면 결측치가 있는 행을 삭제하는 선택도 가능하다.
이상치는 다른 관측치와 다르게 데이터 분포를 벗어난 극단적인 값이다. 다만 이상치가 항상 오류는 아니어서, 센서 고장 때문에 발생한 값은 오류이면서 동시에 고장을 알려주는 중요한 신호일 수 있다. 트래픽 급증이나 매출 급등도 단순히 제거할 값이 아니라 분석해야 할 패턴으로 남겨야 하는 경우가 있다.
이상치 탐지에는 IQR 같은 통계적 방법을 쓸 수 있고, IQR은 1사분위수와 3사분위수 사이의 범위를 기준으로 일정 배수 이상 벗어난 값을 이상치 후보로 보는 방식이다. 통계 방식으로는, 정규분포를 가정한다면 평균에서 몇 표준편차 이상 벗어난 값도 함께 확인한다.
중복값도 조심해야 한다. 중복 데이터는 분석 결과를 왜곡할 수 있고, 머신러닝 모델이 같은 데이터를 반복 학습하면서 과적합을 일으킬 가능성도 있다.
Data Wrangling은 데이터를 분석 목적에 맞게 변형하고 구조화하는 작업이다. 공백을 식별하거나 채우고, 관련 없는 데이터를 제거하고, 형식을 통일한다. 예를 들어 이름이 “김철수”, “김 철수”, “김,철수”처럼 제각각 들어와 있다면 하나의 규칙으로 맞춰줘야 한다.
Data Manipulation은 데이터를 직접 조작해서 분석 목표에 맞는 데이터를 만드는 과정이다. 기존 데이터에서 파생 컬럼을 만들거나 조건에 따라 값을 변환하는 작업이 여기에 들어간다.
EDA, 탐색적 데이터 분석은 데이터를 먼저 살펴보면서 패턴과 관계를 찾는 작업이다. 기술 통계량을 계산하고 시각화를 통해 분포를 확인하며, 변수들 간 상관관계를 보는 것도 중요하다. 반대로 CDA, 확증적 데이터 분석은 가설을 먼저 세우고, 데이터를 수집한 뒤 통계적 분석으로 그 가설을 검증한다.
보이는 데이터만 보면 놓치는 것
시각화의 함정도 인상적이었다.
2차 세계대전 당시 총탄을 맞고 돌아온 비행기의 손상 위치를 보고, 총탄 자국이 많은 부분을 보강해야 한다고 생각한 사례가 있다. 하지만 실제로 중요한 것은 돌아온 비행기만이 아니라 돌아오지 못한 비행기였고, 총탄 자국이 많은 부분은 맞아도 귀환할 수 있었던 부위일 수 있다. 오히려 총탄 자국이 적은 엔진이나 조종석 쪽이 치명적인 약점일 수 있다는 점에서, 이 사례는 보이는 데이터만 보면 빠진 데이터가 무엇인지 놓칠 수 있다는 생존자 편향을 보여준다.
Python 실습에서 기억에 남은 것
마지막에는 Colab에서 Python 기초 실습도 했다.
강의 중에 어떤 분이 질문을 주셨는데, 기억에 남는 것은 -13 // 4의 결과가 왜 -4인지였다. Python에서 // 연산자는 소수점 이하를 단순히 버리는 연산이 아니라 floor division이라서 결과를 음의 무한대 방향으로 내린다.
-13 // 4 # -4
-13을 4로 나누면 -3.25가 나오고, 여기서 내림을 하면 -3이 아니라 -4가 된다. 양수에서는 13 // 4가 버림되어 3이 자연스럽지만, 음수에서는 헷갈릴 수 있다.
문자열 처리는 그냥 쉽게 지나칠 수 있는 부분이긴 한데 파이썬은 내부 동작이 어떤지 문득 궁금해져서 찾아봤다.
"Hello" + " " + "World"
이 코드는 결과적으로 “Hello World”라는 새 문자열을 만든다. Python의 문자열은 immutable이라 한 번 만들어진 문자열 내부 값을 바꾸지 않는다. 그래서 문자열을 더할 때 기존 문자열을 수정하는 것이 아니라 새로운 문자열 객체를 만든다.
다만 위 예시처럼 문자열 리터럴끼리 더하는 코드는 Python이 컴파일 단계에서 하나의 상수 문자열로 최적화할 수 있다. 반대로 변수에 들어 있는 문자열을 반복해서 더하면 매번 새 문자열이 만들어질 수 있어서, 메모리 낭비가 심해질 수 있으므로 반복적으로 문자열을 합칠 때는 보통 리스트로 담아둔 뒤 join()으로 한번에 할당해서 문자열을 사용하는 식으로 쓴다.
Python의 들여쓰기 규칙도 다시 확인했다. Python은 중괄호 대신 들여쓰기로 코드 블록을 구분한다. if, for, while, def, class처럼 콜론으로 끝나는 줄 다음에는 같은 블록 안의 코드가 일정한 들여쓰기 기준을 가져야 한다. 들여쓰기가 스타일이 아니라 문법이라는 점이 Python의 특징이다.
첫날 수업을 마치고
첫날 수업은 OT와 데이터 사이언스와 머신러닝 엔지니어링의 전체 흐름을 잡는 시간이었다. 같은 팀이 된 팀원들도 만났는데, 앞으로 친하게 잘 지냈으면 좋겠다 :)
오늘은 강의를 연속으로 쭉 듣느라 일단은 놓칠까봐 적어보았는데, 사실상 강의 내용은 자료로도 존재하고, 이걸 다 적는것은 크게 의미도 없고 비효율적이라 앞으로는 적당히 내가 흥미가 있었거나 새롭게 알게 된 사실 등을 위주로 적어보려고 한다.