[내배캠] 데이터분석 6기/본캠프 기록

[본캠프 6일차] 팀플 주제 선정, 파이썬 코드카타, SQL 코드카타, SQL 공부, ADsP 공부

물맨두 2025. 2. 24. 17:47

 

다시 찾아온 월요일.

주말이 벌써 지나가버렸다는 소식이 믿기지 않지만 오늘도 오늘의 할 일을 성실히 하며 보내야 또 내일을 잘 보낼 수 있으니까 뭐라도 해봐야지!

 

주말이 벌써 지나가버렸다는 소식이 믿기지 않지만 오늘도 오늘의 할 일을 성실히 하며 보내야 또 내일을 잘 보낼 수 있으니까 뭐라도 해봐야지!

 

오늘 한 일은, 

  • 팀플 주제 선정
  • SQL 공부
    • [라이브 세션] SQL 3회차 수강
    • [라이브 세션] SQL 3회차 과제 풀기 및 제출
    • [코드카타] SQL 10문제 풀기 (21~30번)
  • 파이썬 공부
    • [코드카타] 파이썬 3문제 풀기 (32~34번)
  • [ADsP 자격증 챌린지] 3주차 수강하기

 


 

팀플 : 주제 선정

250224 기초 분석 팀 과제 안내 공지 중 일부

오늘은 월요일로, 기초 분석 팀 과제 주제가 주어지는 날이다.

이번 주 팀 과제는 주어진 4가지의 주제와 각 주제에 따라 제공된 데이터를 SQL을 활용해 EDA를 하는 것이다.

 

우리 조에선 '아마존 책 리뷰 데이터'와 '이커머스 이벤트 히스토리' 중 [이커머스]로 주제를 선정했고,

사용자의 제품 구매 시간, 구매 일자(요일)에 따른 구매 패턴을 분석해보고자 했다. 이를 기반으로 추후 어떤 방식으로 마케팅을 진행할지 전략을 수립한다는 가정을 세웠다. 

 

우선 나의 첫 EDA인 만큼 혼자서 EDA는 어떤 방식으로 접근하고, 데이터에 주어진 해당 정보들을 가지고서 무엇을 알아낼 수 있는지 등을 조사하는 시간이 필요하겠다.

 


 

파이썬 공부: 코드카타 풀기(32~34번)

033. 약수의 개수와 덧셈

두 정수 left와 right가 매개변수로 주어집니다. left부터 right까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return 하도록 solution 함수를 완성해주세요.

def solution(left, right):
    answer = 0
    count = 0
    for i in range(left, right+1):
        for ii in range(1, right+1):
            if i % ii == 0:
                count += 1
        if count % 2 == 0:
            answer += i
        else:
            answer -= i
    return answer

처음에는 위와 같이 코드를 작성했다.

그런데 샘플 케이스를 실행했을 때 결괏값이 기댓값과 일치하지 않아 중간에 print(answer)를 추가해 어떤 식으로 연산하고 있는지를 확인했다.

코드를 작성하면서 내가 의도한 바는,

  • for문 속 for문을 통해서 left~right 속 각 숫자들의 약수를 세서 count에 기록하고
  • count(=약수의 개수)가 짝수이면 그 숫자를 answer에 더하고, 아니면(=홀수) 그 숫자를 answer에서 빼도록

의도했다.

 

그런데 출력으로 찍힌 걸 보니 짝수일 때 잘 더해주다가 첫 번째 홀수가 등장해서 그 숫자를 빼기 시작하면

그 뒤에 오는 숫자는 약수의 개수가 짝수 개(2개, 4개 등)라서 다시 더해줘야 하는데 그렇게 연산하지 않고 계속 빼고만 있었다.

'왜 이러지?' 싶어서 이번엔 print(count)를 적어서 확인했다.

아... count가 그냥 누적으로 쌓이고 있었다. 그러니까 약수의 개수로 한 번 홀수 개가 들어가면 뒤에 짝수 개가 생겨도 여전히 count가 홀수인 상태여서 계속 빼기 연산이 된 것이다.

 

def solution(left, right):
    answer = 0
    for i in range(left, right+1):
        count = 0
        for ii in range(1, i+1):
            if i % ii == 0:
                count += 1
                
        if count % 2 == 0:
            answer += i
        else:
            answer -= i
    return answer

그래서 다음과 같이 count = 0을 for문 안에 정의해주며 시작하는 것으로 수정했더니 원하는 결과대로 연산했다.

 


 

SQL 공부①: 코드카타 풀기(21~30번)

024. 카테고리별 상품 개수 구하기

테이블에서 상품 카테고리 코드(PRODUCT_CODE 앞 2자리) 별 상품 개수를 출력하는 SQL문을 작성해주세요. 결과는 상품 카테고리 코드를 기준으로 오름차순 정렬해주세요.

SELECT SUBSTR(product_code, 1, 2) category,
       count(*) products
FROM product
GROUP BY 1
  • SUBSTR(컬럼명, 시작위치, 개수)
    • 조건으로 주어질 숫자를 하나만 입력하면 그 숫자에 해당하는 위치부터 끝까지 텍스트를 가져옴
    • 뒤에서부터 텍스트를 가져오고 싶다면 시작위치에 입력할 숫자를 음수로 적어줌

 

026. 입양 시각 구하기(1)

보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 09:00부터 19:59까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

SELECT HOUR(datetime) hour,
       COUNT(*)
FROM animal_outs
WHERE HOUR(datetime) between 9 and 19
GROUP BY 1
ORDER BY 1
  • HOUR(기준날짜) : 해당 날짜 데이터에서 시간만 추출

 

030. 자동차 종류별 특정 옵션이 포함된 자동차 수 구하기

 테이블에서 '통풍시트', '열선시트', '가죽시트' 중 하나 이상의 옵션이 포함된 자동차가 자동차 종류 별로 몇 대인지 출력하는 SQL문을 작성해주세요. 이때 자동차 수에 대한 컬럼명은 CARS로 지정하고, 결과는 자동차 종류를 기준으로 오름차순 정렬해주세요.

SELECT car_type,
       count(*) cars
FROM car_rental_company_car
WHERE options IN ('통풍시트', '열선시트', '가죽시트')
GROUP BY 1
ORDER BY 1

처음에는 위와 같이 작성했는데 cars 컬럼에 딱히 뜨는 값이 없었다.

options 컬럼에 데이터가 값이 들어가있는 형태가 각각 분리돼서 들어간 것이 아니라 쭉 열거해 입력됐기 때문에 정확히 일치하는 조건일 때만 사용 가능한 위의 쿼리로는 원하는 결과 테이블이 나오지 않았다.

SELECT car_type,
       count(*) cars
FROM car_rental_company_car
WHERE (options LIKE '%통풍시트%')
      OR (options LIKE '%열선시트%')
      OR (options LIKE '%가죽시트%')
GROUP BY 1
ORDER BY 1

그래서 위의 WHERE절은 LIKE와 OR를 사용해서 쿼리를 작성했다.

 


 

SQL 공부②: [예제로 익히는 SQL] 3회차 수강

오늘은 집계함수(SUM(), AVG(), COUNT(), MIN(), MAX() 등)와 GROUP BY절(+HAVING절), 그리고 서브쿼리까지 배웠다.

공부한 내용은 까먹기 전에 바로 과제를 하면서 익혀보도록 하자.

 


3회차 과제

1.  집계함수의 활용

조건1)
서버별, 월별 게임계정id 수를 중복값 없이 추출해주세요.
월은 첫 접속일자를 기준으로 계산해주세요. 월은 yyyy-mm의 형태로 추출해주세요.

힌트:
월을 추출하는 방법→날짜는 string(문자열) 형식으로 저장되어 있으므로, 문자열을 자르는 함수를 사용해주시면 좋겠죠? 😃

 

SELECT DISTINCT serverno,
       SUBSTR(first_login_date, 1, 7) month,
       count(game_account_id) game_account_id
FROM users
GROUP BY 1, 2
ORDER BY 1

월별 계정 수를 셀 때는 first_login_date를 사용했는데, 해당 데이터 형식이 날짜형 데이터가 아니라 문자열 데이터라서 SUBSTR() 함수를 사용해서 잘랐다.

이렇게 서버별로 월별 데이터를 확인할 수 있다.

 

2. 집계함수와 조건절의 활용

조건1) group by 를 활용하여 first_login_date별 게임캐릭터수를 중복값 없이 구하고,
조건2) having 절을 사용하여 그 값이 10개를 초과하는 경우의 첫 접속일자 및 게임캐릭터id 개수를 추출해주세요.
--조건1 충족을 위해 작성
SELECT DISTINCT first_login_date,
       count(game_actor_id) game_actor_cnt
FROM users
GROUP BY 1
ORDER BY 1
SELECT DISTINCT first_login_date,
       count(game_actor_id) game_actor_cnt
FROM users
GROUP BY 1
HAVING count(game_actor_id) > 10 --조건2 충족을 위해 HAVING절을 추가함
ORDER BY 1

HAVING절의 추가에 따라 달리 조회된 결과 테이블의 모습

 

3. 집계함수와 조건절의 활용2

조건1) group by 절을 사용하여 서버별, 유저구분(기존/신규) 게임캐릭터id수를 구해주세요. 중복값을 허용하지 않는 고유한 갯수로 추출해주세요.
조건2) 기존/신규 기준→ 첫 접속일자가 2024-01-01 보다 작으면(미만) 기존유저, 그렇지 않은 경우 신규유저
조건3) 또한, 서버별 평균레벨을 함께 추출해주세요.
SELECT DISTINCT serverno,
       IF(first_login_date<'2024-01-01', '기존', '신규') '유저 구분',
       COUNT(game_actor_id) game_actor_cnt,
       AVG(level) avg_level
FROM users
GROUP BY 1, 2
ORDER BY 1

조건2에서 언급된 기존 유저와 신규 유저의 '유저 구분' 컬럼을 IF() 함수를 이용해서 구했고,

COUNT(), AVG() 같은 집계 함수를 사용했으니 GROUP BY절을 서버 번호와 유저 구분에 따라서 게임 캐릭터 수와 레벨 평균을 구하도록 쿼리를 작성했다.

(ORDER BY는 요구하지 않았지만 내가 보려면 필요해서 계속 적는 중..)

 

4. 서브쿼리의 활용

조건1) 문제2번을 having 이 아닌 인라인 뷰 서브쿼리를 사용하여 추출해주세요.

힌트:
인라인 뷰 서브쿼리는 from 절 뒤에 위치하여, 마치 하나의 테이블 같은 역할을 했었습니다!
SELECT a.first_login_date,
       a.game_actor_cnt
FROM 
(SELECT DISTINCT first_login_date,
       count(game_actor_id) game_actor_cnt
FROM users
GROUP BY 1
ORDER BY 1) a
WHERE a.game_actor_cnt > 10

위의 문제2번의 내용을 HAVING절을 사용하지 않고 이렇게도 작성할 수 있다.

작성한 쿼리는 달라도 결과 테이블은 동일하게 조회된다.

이번에는 조건을 WHERE절로 주었다.

 

5. 서브쿼리의 응용

조건1) 레벨이 30 이상인 캐릭터를 기준으로, 게임계정 별 캐릭터 수를 중복값 없이 추출해주세요.
조건2) having 구문을 사용하여 캐릭터 수가 2 이상인 게임계정만 추출해주세요.
조건3) 인라인 뷰 서브쿼리를 활용하여 캐릭터 수 별 게임계정 개수를 중복값 없이 추출해주세요.
SELECT DISTINCT a.game_account_id,
       COUNT(a.game_actor_id) game_actor_cnt
FROM 
	(SELECT *
	FROM users
	WHERE level >= 30
	ORDER BY level) a
GROUP BY 1

우선 조건1 충족을 위해 서브쿼리를 사용해 전체 데이터 중 level 30 이상인 것들 중에서

게임 계정별 게임 캐릭터 수를 구해주었다.

 

SELECT DISTINCT a.game_account_id,
       COUNT(a.game_actor_id) game_actor_cnt
FROM 
	(SELECT *
	FROM users
	WHERE level >= 30
	ORDER BY level) a
GROUP BY 1
HAVING COUNT(a.game_actor_id)>=2

조건2에서 요구한 대로 HAVING절을 추가해 게임 캐릭터 수가 2개 이상인 데이터들만 조회되도록 했다.

 

SELECT b.game_actor_cnt,
       COUNT(b.game_account_id) game_account_cnt
FROM 
	(SELECT DISTINCT a.game_account_id,
	       COUNT(a.game_actor_id) game_actor_cnt
	FROM 
		(SELECT *
		FROM users
		WHERE level >= 30
		ORDER BY level) a
	GROUP BY 1
	HAVING COUNT(a.game_actor_id)>=2) b
GROUP BY 1
ORDER BY 1

그리고 마지막으로 조건2까지 만들어놓은 결과테이블을 다시 서브쿼리로 잡아놓고

그걸로 이번에는 게임 캐릭터 수에 따른 게임 계정 수를 조회하도록 쿼리를 작성한다.

그러면 게임 캐릭터가 2개인 게임 계정은 몇 개인지, 이런 식의 데이터를 볼 수 있다.

 


 

ADsP 공부: [ADsP 자격증 챌린지] 3주차 수강하기

데이터 분석 기획

분석 대상과 방법에 따른 4가지 분석 주제

  • 최적화(Optimization) : 해결해야 할 문제가 무엇인지, 분석 시 사용할 방법이 무엇인지 모두 알고 있음
  • 솔루션(Solution) : 해결해야 할 문제가 무엇인지 알곤 있지만 어떻게 분석해야 할지는 모름
  • 발견(Discovery) : 해결해야 할 문제도, 어떻게 분석해야 할지도 모두 모름
  • 통찰력(Insight) : 분석 대상이 무엇인지 모르지만 분석 방법은 알고 있음

목표 시점별 분석 기획

  • 당면한 과제를 언제 해결해야 하는지에 따라 분석 기획을 2가지 종류로 나눔
    • 과제 중심적 접근 방식 : 빨리 해결해야 하는 경우
      • 1차 목표 : Speed & Test
      • 과제 유형 : Quick & Win
      • 접근 방식 : Problem Solving ( 문제 해결을 위한 단기적인 접근 방식)
    • 장기적인 마스터플랜 방식 : 지속적인 분석 내재화를 위한 경우
      • 1차 목표 : Accuracy & Deploy
      • 과제 유형 : Long Term View
      • 접근 방식 : Problem Definition (분석 과제 정의를 위한 중장기적인 마스터 플랜 접근 방식)

분석 기획 시 고려 사항

  • 가용 데이터 고려
    • 분석의 기본이 되는 데이터를 확보할 수 있는지에 대한 고려가 필요
  • 적절한 활용 방안과 유스케이스의 탐색
    • “바퀴를 재발명하지 마라”는 격언처럼 기존에 잘 구현되어 활용되고 있는 유사 분석 시나리오 및 솔루션을 최대한 활용하는 것이 중요
  • 장애요소에 대한 사전 계획 수립
    • 분석을 수행할 때 발생 가능한 장애요소에 대한 사전 계획 수립 필요

 

분석 방법론

분석 방법론 개요

  • 방법론은 상세한 절차(Procedure), 방법(Methods), 도구와 기법(Tools & Techniques), 템플릿과 산출물(Templates & Outputs)로 구성
  • 기업의 합리적 의사결정을 방해하는 요소
    • 고정 관념 (Stereotype)
    • 편향된 생각 (Bias)
    • 프레이밍 효과 (Framing Effect)
  • 분석 방법론의 생성 과정
    • 개인의 암묵지가 형식화를 거쳐서 조직의 형식지가 되고
    • 형식지는 체계화되어 방법론을 만들고
    • 만들어진 방법론은 다시 개인에게 전파돼 내재화를 거쳐 암묵지가 되고

분석 방법론이 적용되는 업무 특성에 따른 모델 4가지

  • 폭포수 모델
    • 단계를 거쳐 순차적으로 진행되는 방법
    • 이전 단계가 완료되어야 다음 단계로 진행 가능
    • 문제 및 개선사항이 발견될 경우 바로 이전 단계로 돌아가 피드백 과정을 수행
  • 프로토타입 모델
    • 폭포수 모델의 단점을 보완하기 위해 점진적으로 시스템을 개발해 나가는 접근 방식
    • 고객의 요구를 완전히 이해하지 못하는 경우 프로토타입 모델 적용
    • 일부분을 먼저 개발하여 사용자에게 제공하고 이후 사용자의 요구를 분석, 정당성 점검, 성능을 평가하여 결과를 통해 개선 작업 시행
  • 나선형 모델
    • 반복을 통해 점진적으로 개발하는 방법
    • 프로토타입 모델과 유사하지만 사용자의 요구보다 위험요소를 사전에 제거한다는 것에 초점을 맞춤
    • 처음 시도하는 프로젝트에는 적용이 용이하지만 관리 체계를 효과적으로 갖추지 못하면 복잡도가 상승
  • 계층적 프로세스 모델
    • 일반적으로 분석 방법론은 계층적 프로세스 모델의 형태로 구성
    • 최상의 계층인 몇 개의 단계로 구성되어 있고 하나의 단계는 여러 개의 태스크로 구성되고 하나의 태스크는 여러 개의 스텝으로 구성되어 있음 (보통 5단계 사용)
      • 단계 : 프로세스 그룹을 통해 완성된 단계별 산출물 생성, 버전 관리 등을 통한 통제 필요
      • 태스크 : 단계를 구성하는 단위 활동, 물리적 또는 논리적 단위로 품질 검토의 항목이 될 수 있음
      • 스텝 : WBS의 워크패키지에 해당하고 입력 자료, 처리 및 도구, 출력 자료로 구성된 단위 프로세스
    • 스텝은 WBS(Work Breakdown Structure)의 워크패키지에 해당되며 ‘입력 자료, 처리 및 도구, 출력’으로 구성된 단위 프로세스

 


 

월요일은 유독 가혹하다. 그래도 어떻게 오늘치 공부를 꽤 했다.

내일은 [ADsP] 3주차 강의를 마저 들으면서 어떤 식으로 이번 주 팀 과제 기초 분석을 하면 좋을지 D Beaver에 SQL을 이리저리 작성해보면서 머리를 굴려봐야겠다.