묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)
일부 일치하는 문자 변경 함수에서 str 뜻
기억하기 쉽게 이해하려는데, str이 어떤 단어 앞자리인가요
-
해결됨[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)
이원분산분석
1from statsmodels.formula.api import ols from statsmodels.stats.anova import anova_lm model = ols('토마토수 ~ C(종자) * C(비료)', data=df).fit() anova_lm(model)2import statsmodels.api as sm from statsmodels.formula.api import ols model = ols('토마토수 ~C(종자)*C(비)', data=df).fit() anava_table=sm.stats.anova_lm(model) print(anava_table)1 과 2를 보면from statsmodels.formula.api import ols 는 같고import statsmodels.api as sm과from statsmodels.stats.anova import anova_lm이다른데요.. 구글링해보고 고민해봐도 모르겠어요.결과값은 같은데..무슨차이일까요?
-
미해결Go Hard to Unreal Engine
리메이크 된 강의가 따로 있는건가요?
지금 듣고 있는걸 계속 들어도 되는건지 궁금해요
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
ROI Pooling Layer이 SPP Layer보다 성능이 뛰어난 이유가 궁금합니다.
SPP Layer의 경우 여러 Spatial Bins를 사용하여 이미지의 작은 부분부터 큰 부분까지의 정보를 취합하는 것으로 이해했습니다. 또한 ROI Pooling Layer의 경우 SPP Layer에서 Level이 1인 Bins만 적용하는 것으로 이해했습니다. 여기서 의문이 드는 것이 여러 정보를 종합적으로 취합한 SPP Layer가 ROI Pooling Layer보다 성능이 뛰어날 것으로 (직관적으로) 생각이 드는데, Fast RCNN에서 ROI Pooling을 선택한 이유가 궁금합니다. 실험적인 결과로 ROI Pooling을 선택했겠지만, ROI Pooling이 SPP Layer보다 Object Detection에서 우수한 성능을 보이는 이유가 궁금합니다!
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
혹시 다음 강의 대략 언제쯤 완료되시는지 알 수 있을까요??
안녕하세요, 강의 정말 인상깊게 봤습니다!! 다른 글에서 다음 강의로 Combine 관련 내용으로 제작중이라고 하셨는데, 대략 언제쯤 다음 강의 제작이 끝나시는지 궁금하여 이렇게 글을 남깁니다. 강의 나오면 바로 구매할 예정입니다! 감사합니다.
-
미해결BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝스터디 1주차 과제] ARRAY, STRUCT 연습 문제/ PIVOT 연습문제/ 퍼널 쿼리 연습 문제
ARRAY, STRUCT 연습문제-- 1)영화별 장르를 unnest해서 보여줘라. SELECT title, genre FROM advanced.array_exercises CROSS JOIN UNNEST(genres) AS genre; --2) 영화별 배우와 배역을 보여줘라. 배우와 배역은 별도의 컬럼으로 나와야 한다. SELECT title, ac.actor, ac.character FROM advanced.array_exercises CROSS JOIN UNNEST(actors) AS ac; --3. 영화별로 배우, 배역, 장르를 출력해라. SELECT title, actor.actor, actor.character, genre FROM `advanced.array_exercises` CROSS JOIN UNNEST(actors) as actor CROSS JOIN UNNEST(genres) as genre; --4. 앱 로그 데이터의 배열을 풀어라 SELECT user_id, event_date, event_name, user_pseudo_id, event_param.key, event_param.value.string_value, event_param.value.int_value FROM `advanced.app_logs` CROSS JOIN UNNEST(event_params) AS event_param PIVOT 연습문제-- 1. 유저별 주문금액의 합계를 poviot해라. -- SELECT -- order_date, -- SUM(IF(user_id = 1, amount, 0)) AS user_1, -- SUM(IF(user_id = 2, amount, 0)) AS user_2, -- SUM(IF(user_id = 3, amount, 0)) AS user_3 -- FROM `advanced.orders` -- GROUP BY order_date -- ORDER BY order_date; -- 2. 날짜별 유저들의 주문금액의 합계를 pivot해라. -- SELECT -- user_id, -- SUM(IF(order_date = '2023-05-01', amount, 0)) AS `2023-05-01`, -- SUM(IF(order_date = '2023-05-02', amount, 0)) AS `2023-05-02`, -- SUM(IF(order_date = '2023-05-03', amount, 0)) AS `2023-05-03`, -- SUM(IF(order_date = '2023-05-04', amount, 0)) AS `2023-05-04`, -- SUM(IF(order_date = '2023-05-05', amount, 0)) AS `2023-05-05` -- FROM advanced.orders -- GROUP BY user_id -- ORDER BY user_id; -- 3. 사용자별, 날짜별 주문이 있다면 1, 없다면 0으로 pivot해라. -- SELECT -- user_id, -- MAX(IF(order_date = '2023-05-01', 1, 0)) AS `2023-05-01`, -- MAX(IF(order_date = '2023-05-02', 1, 0)) AS `2023-05-02`, -- MAX(IF(order_date = '2023-05-03', 1, 0)) AS `2023-05-03`, -- MAX(IF(order_date = '2023-05-04', 1, 0)) AS `2023-05-04`, -- MAX(IF(order_date = '2023-05-05', 1, 0)) AS `2023-05-05` -- FROM advanced.orders -- GROUP BY user_id -- ORDER BY user_id; --4. key값을 column으로 pivot해라 SELECT user_id, event_date, event_name, user_pseudo_id, IF(key = 'food_id', IF(string_value IS NOT NULL, string_value, CAST(int_value AS STRING)), NULL) AS food_id FROM advanced.app_logs_unnest # app_logs 테이블을 unnest한 결과는 자주 쓰일 듯 싶어 app_logs_unnest 테이블을 따로 생성했다. WHERE event_name = 'click_cart' AND event_date = '2022-08-01'; 기억할 것IF 조건문을 사용할 때, TRUE일때의 값과 FALSE일때의 값의 데이터 타입이 같아야 한다. PIVOT 연습문제 4번을 풀 때 food_id를 PIVOT하는 과정에서 IF(key = 'food_id', IF(string_value IS NOT NULL, string_value, int_value AS STRING), NULL)와 같이 표현했었다. KEY값에 따라 string_value와 int_value중 타입에 맞는 하나의 컬럼에만 값이 있었고, 처음에는 이를 명시적으로 적기보다 범용적으로 사용될 수 있도록 하는게 더 좋지 않을까 싶었다. 값이 있는 컬럼의 값을 사용하자는 의도로 IF(string_value IS NOT NULL, string_value, int_value AS STRING)라고 표현했고 다음과 같은 에러를 만났다.No matching signature for function IF for argument types: BOOL, STRING, INT64. Supported signature: IF(BOOL, ANY, ANY) at [55:23]에러를 피하고자 CAST를 이용했는데 데이터 타입을 억지로 바꾸기보다는(추후에 숫자형 데이터로 대소 비교를 한다던지 나열을 한나던지의 상황이 있을 수 있으니..) 명시적으로 표현하는 것을 마냥 피할것은 아니겠다는 생각을 했다.특별한 문자(예약어, 숫자)를 ALIAS로 설정하려면 back tick(`)으로 감싸줘야한다.퍼널 쿼리 연습문제-- 퍼널 별 유저 수 집계(2022-08-01 ~ 2022-08-18) -- welcome -> home -> good category -> restaurant -> cart -> 주문하기 클릭 /* event_data | event_name_with_screen | stemp_number | cnt 의 컬럼 형태로 만들것 */ -- 처음 작성했던 쿼리 -- SELECT -- event_date, -- CASE -- WHEN event_name = 'screen_view' AND string_value = 'welcome' THEN CONCAT(event_name, '-', string_value) -- WHEN event_name = 'screen_view' AND string_value = 'home' THEN CONCAT(event_name, '-', string_value) -- WHEN event_name = 'screen_view' AND string_value = 'food_category' THEN CONCAT(event_name, '-', string_value) -- WHEN event_name = 'screen_view' AND string_value = 'restaurant' THEN CONCAT(event_name, '-', string_value) -- WHEN event_name = 'screen_view' AND string_value = 'cart' THEN CONCAT(event_name, '-', string_value) -- WHEN event_name = 'click_payment' AND string_value = 'cart' THEN CONCAT(event_name, '-', string_value) -- END AS event_name_with_screen, -- CASE -- WHEN event_name = 'screen_view' AND string_value = 'welcome' THEN 1 -- WHEN event_name = 'screen_view' AND string_value = 'home' THEN 2 -- WHEN event_name = 'screen_view' AND string_value = 'food_category' THEN 3 -- WHEN event_name = 'screen_view' AND string_value = 'restaurant' THEN 4 -- WHEN event_name = 'screen_view' AND string_value = 'cart' THEN 5 -- WHEN event_name = 'click_payment' AND string_value = 'cart' THEN 6 -- END AS step_number, -- COUNT(event_date) AS cnt -- FROM `advanced.app_logs_unnest` -- WHERE -- event_date BETWEEN '2022-08-01' AND '2022-08-18' -- GROUP BY ALL -- ORDER BY event_date, step_number -- ============================================= -- 정석 쿼리 WITH base AS( SELECT event_date, event_timestamp, event_name, user_id, user_pseudo_id, platform, MAX(IF(event_param.key = "firebase_screen", event_param.value.string_value, NULL)) AS firebase_screen, MAX(IF(event_param.key = "food_id", event_param.value.int_value, NULL)) AS food_id, MAX(IF(event_param.key = "session_id", event_param.value.int_value, NULL)) AS session_id FROM `advanced.app_logs` CROSS JOIN UNNEST(event_params) AS event_param -- WHERE -- event_date = "2022-08-01" -- event_date BETWEEN "2022-08-01" AND "2022-08-18" -- AND -- event_param.key IN ("screen_view", "click_payment") -- AND -- event_param.value.string_value IN ("welcome", "home", "food_category", "restaurant", "cart") GROUP BY ALL ), filter_event_and_concat_event_and_screen AS( SELECT * EXCEPT(event_name, firebase_screen), CONCAT(event_name, "-", firebase_screen) AS event_name_with_screen, DATETIME(TIMESTAMP_MICROS(event_timestamp), "Asia/Seoul") AS event_datetime FROM base WHERE event_date BETWEEN "2022-08-01" AND "2022-08-18" AND event_name IN ("screen_view", "click_payment") AND firebase_screen IN ("welcome", "home", "food_category", "restaurant", "cart") ) SELECT event_date, event_name_with_screen, -- event_datetime, -- user_pseudo_id, CASE WHEN event_name_with_screen = 'screen_view-welcome' THEN 1 WHEN event_name_with_screen = 'screen_view-home' THEN 2 WHEN event_name_with_screen = 'screen_view-food_category' THEN 3 WHEN event_name_with_screen = 'screen_view-restaurant' THEN 4 WHEN event_name_with_screen = 'screen_view-cart' THEN 5 WHEN event_name_with_screen = 'click_payment-cart' THEN 6 ELSE NULL END AS step_number, COUNT(DISTINCT user_pseudo_id) AS cnt FROM filter_event_and_concat_event_and_screen GROUP BY ALL HAVING step_number IS NOT NULL ORDER BY event_date, step_number기억할 것각 컬럼에 어떤 값이 있는지 잘! 확인하자.event_name_with_screen 부분을 CASE WHEN으로 처리하며 '이게 진정 맞을까......' 싶긴 했었었다. 왜인지 초반에 컬럼값 확인할 때 WHERE 절에 IN 구문으로 확인했을때 원하던 결과로 나오지 않아 CASE WHEN으로 직접 처리했었는데.. 실수였다. (아마 string_value만 IN연산으로 확인하고 섣부른 판단을 했던게 아닐지 싶다.)CASE WHEN 구문에서 전체를 포함하도록 조건을 구성하지 않으면 WHEN에 해당하지 않는 부분은 NULL값으로 생성된다.처음 쿼리를 짜고 CNT 컬럼의 값을 확인했을 때 event_name_with_screen과 step_number에 왜 NULL값이 있는지 당황스러웠다. 이미 있는 데이터에 새 컬럼을 만든 것이니 조건에 해당되지 않는 부분은 값이 없어 NULL로 남아있다는 사실...!DATETIME 함수를 이용하여 "Asia/Seoul" 처리하기새까맣게 잊고있었다. 까먹지 말자~!항상 데이터를 뽑아 어떤 내용을 확인하고 싶은 건지를 생각하자.문제에 맞는 쿼리를 짜고 작성된 쿼리의 결과가 잘 나오는지에만 급급했던 거 같다. 이 강의를 듣는 목적은 데이터 분석에 대한 감 잡기!지 쿼리 잘 짜기!는 아니었으니까..!(물론 SQL 실력 향상은 필요한 부분..!!) 스스로 고민해보는 시간을 꼭! 갖도록 해보자.
-
미해결BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝스터디 1주차 과제] ARRAY, STRUCT 연습 문제/ PIVOT 연습문제/ 퍼널 쿼리 연습 문제
1) ARRAY, STRUCT 연습문제1-1)SELECT title, genre FROM advanced.array_exercises CROSS JOIN UNNEST (genres) as genre ORDER BY title;1-2)SELECT title, actor.actor, actor.character FROM advanced.array_exercises CROSS JOIN UNNEST(actors) as actor ORDER BY title;1-3)SELECT title, actor.actor, actor.character, genre FROM advanced.array_exercises CROSS JOIN UNNEST(genres) as genre CROSS JOIN UNNEST(actors) as actor ORDER BY 1,2,3;1-4)SELECT user_id, event_date, event_name, user_pseudo_id, event_param.key, event_param.value.string_value, event_param.value.int_value FROM advanced.app_logs CROSS JOIN UNNEST(event_params) as event_param WHERE event_date = '2022-08-01';2) PIVOT 연습문제2-1) 1) SELECT order_date, SUM(IF(user_id = 1, amount, 0 )) AS user_1, SUM(IF(user_id = 2, amount, 0 )) AS user_2, SUM(IF(user_id = 3, amount, 0 )) AS user_3 FROM advanced.orders GROUP BY 1 ORDER BY 1;2-2)SELECT user_id, SUM(IF(order_date = '2023-05-01', amount, 0)) AS `2023-05-01`, SUM(IF(order_date = '2023-05-02', amount, 0)) AS `2023-05-02`, SUM(IF(order_date = '2023-05-03', amount, 0)) AS `2023-05-03`, SUM(IF(order_date = '2023-05-04', amount, 0)) AS `2023-05-04`, SUM(IF(order_date = '2023-05-05', amount, 0)) AS `2023-05-05` FROM advanced.orders GROUP BY 1 ORDER BY 1;2-3)SELECT user_id, MAX(IF(order_date = '2023-05-01', 1, 0)) AS `2023-05-01`, MAX(IF(order_date = '2023-05-02', 1, 0)) AS `2023-05-02`, MAX(IF(order_date = '2023-05-03', 1, 0)) AS `2023-05-03`, MAX(IF(order_date = '2023-05-04', 1, 0)) AS `2023-05-04`, MAX(IF(order_date = '2023-05-05', 1, 0)) AS `2023-05-05` FROM advanced.orders GROUP BY 1 ORDER BY 1;2-4)SELECT event_date, event_timestamp, event_name, event_timestamp, user_pseudo_id, MAX(CASE WHEN event_param.key = 'firebase_screen' THEN event_param.value.string_value END) as firebase_screen, MAX(CASE WHEN event_param.key = 'food_id' THEN event_param.value.int_value END) as food_id, MAX(CASE WHEN event_param.key = 'session_id' THEN event_param.value.string_value END) as session_id, FROM advanced.app_logs CROSS JOIN UNNEST(event_params) as event_param WHERE event_date = '2022-08-01' GROUP BY ALL 3) 퍼널 쿼리 연습 문제WITH main as ( SELECT event_date, concat(event_name,'-', event_param.value.string_value) AS event_name_with_screen, CASE WHEN event_name = 'screen_view' AND event_param.value.string_value = 'welcome' THEN 1 WHEN event_name = 'screen_view' AND event_param.value.string_value = 'home' THEN 2 WHEN event_name = 'screen_view' AND event_param.value.string_value = 'food_category' THEN 3 WHEN event_name = 'screen_view' AND event_param.value.string_value = 'restaurant' THEN 4 WHEN event_name = 'screen_view' AND event_param.value.string_value = 'cart' THEN 5 WHEN event_name = 'click_payment' AND event_param.value.string_value = 'cart' THEN 6 END AS step_num, count(distinct user_pseudo_id) AS cnt FROM advanced.app_logs CROSS JOIN UNNEST(event_params) as event_param WHERE event_date between '2022-08-01' AND '2022-08-18' AND event_param.key = 'firebase_screen' AND event_name IN ("screen_view",'click_payment') GROUP BY 1,2,3 HAVING step_num IS NOT NULL ) SELECT event_date, SUM(IF(step_num = 1, cnt, 0)) AS `screen_view-welcome`, SUM(IF(step_num = 2, cnt, 0)) AS `screen_view-home`, SUM(IF(step_num = 3, cnt, 0)) AS `screen_view-food_category`, SUM(IF(step_num = 4, cnt, 0)) AS `screen_view-restaurant`, SUM(IF(step_num = 5, cnt, 0)) AS `screen_view-cart`, SUM(IF(step_num = 6, cnt, 0)) AS `click_payment-cart` FROM main GROUP BY 1 ORDER BY event_date
-
미해결BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[인프런 빅쿼리 빠짝스터디 1주차] ARRAY, STRUCT, PIVOT,퍼널 쿼리
연습 문제(1) Array, Struct-- 1) array_exercises 테이블에서 각 영화(title)별로 장르(genres)를 UNNEST해서 보여주세요 SELECT title, genre # genres 아님 FROM `advanced.array_exercises` CROSS JOIN UNNEST(genres) AS genre처음에 'title'을 기준으로 묶여 있길래 UNNEST의 요소로 'title'을 넣으려 함 → ERROR생각해보니 CROSS JOIN이 목적이므로 개별 값을 가지는 'genres'를 기준으로 UNNEST-- 2) array_exercises 테이블에서 각 영화(title)별로 배우(actor)와 배역(character)을 보여주세요. 배우와 배역은 별도의 컬럼으로 나와야 합니다 SELECT title, actor, character FROM `advanced.array_exercises`, UNNEST(actors)CROSS JOIN 대신 ','를 통해 UNNEST를 시도해 봄 -- 3) array_exercises 테이블에서 각 영화(title)별로 배우(actor), 배역(character), 장르 (genre)를 출력하세요. -- 한 Row에 배우, 배역, 장르가 모두 표시되어야 합니다 SELECT title, ae2.actor, ae2.character, genre FROM ( SELECT title, actor.actor, actor.character, genres FROM `advanced.array_exercises` AS ae, UNNEST(actors) AS actor ) AS ae2, UNNEST(genres) AS genre-- 강의 코드 SELECT title, actor.actor, actor.character, genre FROM `advanced.array_exercises` AS ae, UNNEST(actors) AS actor, UNNEST(genres) AS genreUNNEST 두번해야해서 서브쿼리로 해결하려 시도 → 서브 쿼리 안하고 UNNEST 두번 사용 가능실행 순서 : FROM → JOIN → SELECTcmd + D : 다음 해당 항목 같이 선택 → 반복되는 단어 쉽게 수정 가능-- 4) 앱 로그 데이터(app_logs)의 배열을 풀어주세요 SELECT user_id, event_date, event_name, user_pseudo_id, EV.key, EV.value.string_value, EV.value.int_value FROM `advanced.app_logs` AS al, UNNEST(event_params) AS EV-- 강의 코드 SELECT event_date, event_timestamp, event_name, event_param.key AS key, event_param.value AS value, user_id FROM `advanced.app_logs`, UNNEST(event_params) AS event_param WHERE event_date = "2022-08-01"WHERE에 조건을 넣어 연산량 낮출 수 있음event_params로 UNNEST했을때 value값만 사용해도 string, int 둘다 표시됨 (2) PIVOTparquet : 대용량 데이터를 효율적으로 저장하고 처리하기 위해 설계된 컬럼 기반의 저장 형식공통 사항 : 행과 열에 대한 정의가 한번에 떠오르지 않았음-- 1) orders 테이블에서 유저(user_id)별로 주문 금액(amount)의 합계를 PIVOT해주세요. -- 날짜(order_date)를 행(Row)으로, user_id를 열(Column)으로 만들어야 합니다 SELECT order_date, SUM(IF(user_id=1, amount, 0)) AS user_1, SUM(IF(user_id=2, amount, 0)) AS user_2, SUM(IF(user_id=3, amount, 0)) AS user_3, FROM `advanced.orders` GROUP BY order_date ORDER BY order_dateNULL과 0은 다르다서브쿼리 이용한 방법도 있음(집계 후 PIVOT)-- 2) orders 테이블에서 날짜(order_date)별로 유저들의 주문 금액(amount)의 합계를 PIVOT 해주세요. -- user_id를 행(Row)으로, order_date를 열(Column)으로 만들어야 합니다 SELECT user_id, SUM(IF(order_date="2023-05-01", amount, 0)) AS `2023-05-01`, SUM(IF(order_date="2023-05-02", amount, 0)) AS `2023-05-02`, SUM(IF(order_date="2023-05-03", amount, 0)) AS `2023-05-03`, SUM(IF(order_date="2023-05-04", amount, 0)) AS `2023-05-04`, SUM(IF(order_date="2023-05-05", amount, 0)) AS `2023-05-05`, FROM `advanced.orders` GROUP BY user_idAS에서 “ ”(따옴표) 대신 (백틱) 사용ANY_VALUE : 그룹화 할 대상 중에 임의의 값을 선택한다(NULL 제외) 따라서 나머지 값들이 NULL이거나 값이 확정적일 때 사용-- 3) orders 테이블에서 사용자(user_id)별, 날짜(order_date)별로 주문이 있다면 1, 없다면 0으로 PIVOT 해주세요. -- user_id를 행(Row)으로, order_date를 열(Column)로 만들고 주문을 많이 해도 1로 처리합니다 SELECT user_id, MAX(IF(order_date="2023-05-01", 1, 0)) AS `2023-05-01`, MAX(IF(order_date="2023-05-02", 1, 0)) AS `2023-05-02`, MAX(IF(order_date="2023-05-03", 1, 0)) AS `2023-05-03`, MAX(IF(order_date="2023-05-04", 1, 0)) AS `2023-05-04`, MAX(IF(order_date="2023-05-05", 1, 0)) AS `2023-05-05`, FROM `advanced.orders` GROUP BY user_id조건문에서 행 별로 주문 있으면 1, 없으면 0 설정한 뒤 MAX 조건 걸어줌 → 최종적으로 값이 있으면 1횟수일 경우에는 SUM-- user_id = 32888이 카트 추가하기(click_cart)를 누를때 어떤 음식(food_id)을 담았나요? => 쿼리 작성이 어려움 -- => key를 Column으로 두고, string_value나 int_value를 Column의 값으로 설정하는 것이 필요 SELECT user_id, event_date, event_name, event_timestamp, ANY_VALUE(IF(event_param.key="firebase_screen", event_param.value.string_value, NULL)) AS `firebase_screen`, ANY_VALUE(IF(event_param.key="food_id", event_param.value.int_value, NULL)) AS `food_id`, ANY_VALUE(IF(event_param.key="session_id", event_param.value.string_value, NULL)) AS `session_id`, FROM `advanced.app_logs`, UNNEST(event_params) AS event_param WHERE (event_date = "2022-08-01") AND (event_name = "click_cart") AND (user_id = 32888) # 선택 사항 GROUP BY user_id, event_date, event_name, event_timestamp문제를 봤을 때 문제가 원하는게 무엇인지 한번에 파악되지 않았음32888의 click cart 행위에만 집중하는 것으로 판단GROUP BY ALL 을 통해 한번에 해결 가능(3) 퍼널 쿼리WITH base AS ( SELECT user_id, user_pseudo_id, event_date, event_name, event_timestamp, platform, ANY_VALUE(IF(event_param.key="firebase_screen", event_param.value.string_value, NULL)) AS `firebase_screen`, ANY_VALUE(IF(event_param.key="food_id", event_param.value.int_value, NULL)) AS `food_id`, ANY_VALUE(IF(event_param.key="session_id", event_param.value.string_value, NULL)) AS `session_id`, FROM `advanced.app_logs`, UNNEST(event_params) AS event_param WHERE event_date BETWEEN "2022-08-01" AND "2022-08-18" GROUP BY ALL )event_name과 event_params가 연결되어야 하므로 우선 UNNEST 필요하다고 생각함 → 이전에 사용했던 쿼리문 그대로 사용 후 WITH하지만 이후 과정에서 CONCAT 함수를 떠올리지 못해 진행이 불가했음), concat_event_screen AS ( SELECT * EXCEPT(event_name, firebase_screen, event_timestamp), CONCAT(event_name, "-", firebase_screen) AS event_name_with_screen, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime FROM base )이후에 concat_event_screen이라는 이름으로 테이블 재가공 해줌CONCAT을 통해 event_name-firebase-screenevent_timestamp 알아보기 쉽게 바꿔준 후 제거SELECT event_name_with_screen, CASE WHEN event_name_with_screen = "screen_view-welcome" THEN 1 WHEN event_name_with_screen = "screen_view-home" THEN 2 WHEN event_name_with_screen = "screen_view-food_category" THEN 3 WHEN event_name_with_screen = "screen_view-restaurant" THEN 4 WHEN event_name_with_screen = "screen_view-cart" THEN 5 WHEN event_name_with_screen = "click_payment-cart" THEN 6 ELSE NULL END AS step_number, COUNT(DISTINCT user_pseudo_id) AS cnt FROM concat_event_screen GROUP BY ALL HAVING step_number IS NOT NULL # CASE-WHEN에서 포함되지 않는 행위는 제거CASE-WHEN 이용해서 step_number 컬럼 만들어줌COUNT + DISTINC 이용해 해당 퍼널에 진입한 고유 유저 수 세주기퍼널이 아직 익숙하지 않아 혼자서 해결할 수는 없었음+) 일자별SELECT event_date, event_name_with_screen, CASE WHEN event_name_with_screen = "screen_view-welcome" THEN 1 WHEN event_name_with_screen = "screen_view-home" THEN 2 WHEN event_name_with_screen = "screen_view-food_category" THEN 3 WHEN event_name_with_screen = "screen_view-restaurant" THEN 4 WHEN event_name_with_screen = "screen_view-cart" THEN 5 WHEN event_name_with_screen = "click_payment-cart" THEN 6 ELSE NULL END AS step_number, COUNT(DISTINCT user_pseudo_id) AS cnt FROM concat_event_screen GROUP BY ALL HAVING step_number IS NOT NULL # CASE-WHEN에서 포함되지 않는 행위는 제거 ORDER BY event_date간단한 EDA지금까지 배운 것을 바탕으로 간단한 데이터 탐색 및 분석행 개수 → 731873행2022-08-01(월) ~ 2023-01-20(금) 의 데이터user_id 고유 개수 → 49678pseudo_user_id 고유 개수 → 52823event_params → 22개아래 표는 전체 기간에 대한 각 event_params별 개수 총합(내림차순)-> 개수가 같은 항목들이 존재-> 앱 작동 흐름에 대해 알 필요 있어 보임event_date에 따른 pseudo_user_id 고유 개수 그래프-> 8월부터 10월 중순까지는 이용자수가 늘어나는 추세-> 이후 안정기 들어서면서 일정한 주기로 반복되는 형태느낀점보통 데이터 분석 프로젝트를 하면 Python이나 R을 통해 진행했기에 아직 쿼리문이 생소함머릿속으로는 대충 어떤 식으로 데이터를 건드려야겠다는 생각이 들긴 하지만, 표현이 잘 안되는 경우가 많아서 까다로웠던 것 같음업무 경험이 없는 입장에서 퍼널 분석 같은 것들은 실제로 해본적이 없는데, 비교적 이해하기 쉽게 알려주신 것 같음
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
이체 로직 관련 질문이 있습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]계좌 이체 로직 중public void accountTransfer(String fromId, String toId, int money) throws SQLException { Member fromMember = memberRepository.findById(fromId); Member toMember = memberRepository.findById(toId); memberRepository.update(fromId, fromMember.getMoney() - money); memberRepository.update(toId, toMember.getMoney() + money); } String sql = "UPDATE member SET money = ? WHERE member_id = ?";이렇게 멤버를 db에서 찾아와서 getMoney 하고 이체할 금액만큼 증감해서 update를 수행하도록 한 이유가 무엇인지 궁금합니다. public void accountTransfer(String fromId, String toId, int money) throws SQLException { memberRepository.update(fromId, -money); memberRepository.update(toId, money); } String sql = "UPDATE member SET money = money + ? WHERE member_id = ?" 이런 식으로 update sql문 내에서 현재 금액에서 이체 금액만큼 증감하도록 하고 update문만 호출하는 것이 더 간편하고 안전한 방법이 아닌가 궁금증이 생겨서 질문 글을 올립니다!
-
해결됨직장인에게 꼭 필요한 파이썬-아래아한글 자동화 레시피
[강의 개선 의견] 실습용 파일이 미리 준비되도록 강의 전개순서 개선 건의
"1-6. [응용] 폴더에 있는 한글 파일을 모두 열기" 관련입니다. 일단 일코님의 설명대로 한 두 번 그대로 성공하고 나면, 강의 내용이 잘 이해가 됩니다. 하지만 초반에는 저 같은 왕초보의 경우 그대로 결과가 나타나지 않거나 실습 조건이 동일하게 마련되지 않으면 헤매게 됩니다. ■ 개선의견 1이 강의에서는 1.hwp ~ 100.hwp 파일이 들어 있는 "반복작업" 폴더가 있다고 가정하고 실습을 진행하는데요. 물론, 1.hwp 파일을 다운로드 가능하게 되어 있지만..1.hwp ~ 100.hwp 파일을 다 만들어 내는 것이 선행되어야 그대로 실습이 가능한데, 그 파일을 만드는 것은 강의 초반이 아니라 후반에 배치되어 있습니다. 제 의견은, 1.hwp ~ 100.hwp 파일을 만들어 내는 부분을 앞에 배치하고, 설명에서는 "이 코드는 아직 안배운 내용이 포함 되므로, 이대로 실습해서 1.hwp ~ 100.hwp 를 만드는 게 부담스러운 학습자는 이 부분을 SKIP하고 진행하세요."라고 한다던가, 아울러,"만약 SKIP하고 진행하실 분들은 1.hwp ~ 100.hwp 파일이 들어 있는 압축파일(zip)을 다운로드 받아서 진행하시면 됩니다."라고 안내하면서, 해당 압축파일의 다운로드도 제공해 주시는 게 어떨까 합니다. ■ 개선의견 2또 하나는, 작업 디렉토리의 강제 설정을 위한 코드 예시도 추가로 설명에 넣어 주셔도 좋을 거 같습니다.os.chdir(r"C:\Users\user\Desktop\반복작업")파이참으로 실습 시 작업 디렉토리는 '반복작업' 폴더가 아닌 경우가 대부분으로 왕초보는 요걸로 또 막힐 수 있습니다. ■ 마치는 글이미 잘 만들어 주신 강의이지만 왕초보의 더 매끄러운 이해를 위한 제안을 드리는 것이니, 꼭 반영하지는 않으셔도 되지만.. 왕초보는 이런 어려움도 있구나.. 정도로 이해해 주시면 감사하겠습니다. 간단한 것도 실행되면 큰 즐거움을 느끼면서 틈틈이 강의 따라하고 있습니다. 감사합니다.
-
미해결BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[인프런 빅쿼리 빠짝스터디 1주차] ARRAY, STRUCT 연습 문제/ PIVOT 연습문제/ 퍼널 쿼리 연습문제
연습문제(1) ARRAY, STRUCT-- 1) array_exercises 테이블에서 각 영화(title)별로 장르(genres)를 UNNEST해서 보여주세요 # 쿼리를 작성하는 목표, 확인할 지표 : 평면화 # 쿼리 계산 방법 : UNNEST # 데이터의 기간 : # 사용할 테이블 : array_exercises # Join KEY : # 데이터 특징 : SELECT title, genre FROM advanced.array_exercises CROSS JOIN UNNEST(genres) AS genre; -- 2) array_exercises 테이블에서 각 영화(title)별로 배우(actor)와 배역(character)을 보여주세요. 배우와 배역은 별도의 컬럼으로 나와야 합니다 # 쿼리를 작성하는 목표, 확인할 지표 : 영화별 배우와 배역 평면화 # 쿼리 계산 방법 : UNNEST # 데이터의 기간 : # 사용할 테이블 : array_exercises # Join KEY : # 데이터 특징 : 배우와 배역은 별도의 컬럼으로 나와야 합니다 SELECT title, actor.actor, actor.character FROM advanced.array_exercises CROSS JOIN UNNEST(actors) AS actor; -- 3) array_exercises 테이블에서 각 영화(title)별로 배우(actor), 배역(character), 장르 (genre)를 출력하세요. 한 Row에 배우, 배역, 장르가 모두 표시되어야 합니다 # 쿼리를 작성하는 목표, 확인할 지표 : 배우, 배역, 장르 # 쿼리 계산 방법 : UNNEST # 데이터의 기간 : # 사용할 테이블 : array_exercises # Join KEY : # 데이터 특징 : 한 Row에 배우, 배역, 장르가 모두 표시되어야 함 SELECT title, actor.actor, actor.character, genre FROM advanced.array_exercises CROSS JOIN UNNEST(actors) AS actor CROSS JOIN UNNEST(genres) AS genre; -- 4) 앱 로그 데이터(app_logs)의 배열을 풀어주세요 # 쿼리를 작성하는 목표, 확인할 지표 : 앱 로그 데이터 평면화 # 쿼리 계산 방법 : UNNEST # 데이터의 기간 : # 사용할 테이블 : app_logs # Join KEY : # 데이터 특징 : event_params안에 ARRAY와 STRUCT 구조가 공존하고 있고 값이 string_value와 int_value 두 종류로 나뉨 확인 필요!! SELECT user_id, event_date, event_name, user_pseudo_id, event_param.key, event_param.value.string_value, event_param.value.int_value FROM advanced.app_logs CROSS JOIN UNNEST(event_params) AS event_param WHERE event_date = "2022-08-01";(2) PIVOT-- 1) orders 테이블에서 유저(user_id)별로 주문 금액(amount)의 합계를 PIVOT해주세요. 날짜(order_date)를 행(Row)으로, user_id를 열(Column)으로 만들어야 합니다 # 쿼리를 작성하는 목표, 확인할 지표 : # 쿼리 계산 방법 : MAX, IF, GROUP BY # 데이터의 기간 : # 사용할 테이블 : orders # Join KEY : # 데이터 특징 : SELECT order_date, SUM(IF(user_id = 1, amount, 0)) AS user_1, SUM(IF(user_id = 2, amount, 0)) AS user_2, SUM(IF(user_id = 3, amount, 0)) AS user_3, FROM advanced.orders GROUP BY ALL ORDER BY order_date; -- 2) orders 테이블에서 날짜(order_date)별로 유저들의 주문 금액(amount)의 합계를 PIVOT 해주세요. user_id를 행(Row)으로, order_date를 열(Column)으로 만들어야 합니다 # 쿼리를 작성하는 목표, 확인할 지표 : # 쿼리 계산 방법 : SUM, IF, GROUP BY # 데이터의 기간 : # 사용할 테이블 : orders # Join KEY : # 데이터 특징 : SELECT user_id, SUM(IF(order_date = "2023-05-01", amount, 0)) AS `2023-05-01`, SUM(IF(order_date = "2023-05-02", amount, 0)) AS `2023-05-02`, SUM(IF(order_date = "2023-05-03", amount, 0)) AS `2023-05-03`, SUM(IF(order_date = "2023-05-04", amount, 0)) AS `2023-05-04`, SUM(IF(order_date = "2023-05-05", amount, 0)) AS `2023-05-05` FROM advanced.orders GROUP BY ALL ORDER BY user_id; -- 3) orders 테이블에서 사용자(user_id)별, 날짜(order_date)별로 주문이 있다면 1, 없다면 0으로 PIVOT 해주세요. user_id를 행(Row)으로, order_date를 열(Column)로 만들고 주문을 많이 해도 1로 처리합니다 # 쿼리를 작성하는 목표, 확인할 지표 : # 쿼리 계산 방법 : MAX, IF, GROUP BY # 데이터의 기간 : # 사용할 테이블 : orders # Join KEY : # 데이터 특징 : SELECT user_id, MAX(IF(order_date = "2023-05-01", 1, 0)) AS `2023-05-01`, MAX(IF(order_date = "2023-05-02", 1, 0)) AS `2023-05-02`, MAX(IF(order_date = "2023-05-03", 1, 0)) AS `2023-05-03`, MAX(IF(order_date = "2023-05-04", 1, 0)) AS `2023-05-04`, MAX(IF(order_date = "2023-05-05", 1, 0)) AS `2023-05-05` FROM advanced.orders GROUP BY ALL ORDER BY user_id; -- 연습문제 4) app_log를 pivot하기 # 쿼리를 작성하는 목표, 확인할 지표 : app_log 데이터 PIVOT 테이블로 변경 # 쿼리 계산 방법 : UNNEST, MAX, IF, GROUP BY # 데이터의 기간 : 2022-08-01 # 사용할 테이블 : app_logs # Join KEY : # 데이터 특징 : event_params안에 ARRAY와 STRUCT 구조가 공존하고 있고 값이 string_value와 int_value 두 종류로 나뉨 확인 필요!! WITH base AS( SELECT user_id, event_date, event_name, event_timestamp, user_pseudo_id, MAX(if(event_param.key = "firebase_screen", event_param.value.string_value, NULL)) AS firebase_screen, MAX(if(event_param.key ="food_id", event_param.value.int_value, NULL)) AS food_id, MAX(if(event_param.key ="session_id", event_param.value.string_value, NULL)) AS session_id FROM avdanced.app_logs CROSS JOIN UNNEST (event_params) AS event_param WHERE event_date ='2022-08-01' GROUP BY ALL ) SELECT event_date, COUNT(user_id) AS cnt FROM base WHERE event_name = 'click_cart' GROUP BY ALL;(3) 퍼널 ( Funnel )# 쿼리를 작성하는 목표, 확인할 지표 : screen_view-welcome, screen_view-home, screen_view-food_category, screen_view-restaurant, screen_view-cart, click_payment-cart 순서대로 step_number를 지정하고 퍼널 분석하기 # 쿼리 계산 방법 : MAX, IF, UNNEST, CASE WHEN # 데이터의 기간 : 2022-08-01 ~ 2022-08-18 # 사용할 테이블 : app_logs # Join KEY : # 데이터 특징 : event_params안에 ARRAY와 STRUCT 구조가 공존하고 있고 값이 string_value와 int_value 두 종류로 나뉨 확인 필요!! WITH base AS (SELECT event_date, event_timestamp, event_name, user_id, user_pseudo_id, platform, MAX(IF(event_param.key = "firebase_screen", event_param.value.string_value, NULL)) AS fire_screen, -- MAX(IF(event_param.key = "food_id", event_param.value.int_value, NULL)) AS food_id, MAX(IF(event_param.key = "session_id", event_param.value.string_value, NULL)) AS session_id FROM advanced.app_logs CROSS JOIN UNNEST(event_params) AS event_param WHERE event_date BETWEEN "2022-08-01" AND "2022-08-18" GROUP BY ALL ), fiter_event_and_concat_event_and_screen AS ( -- event_name + screen (필요한 이벤트만 WHERE 조건에 걸어서 사용) SELECT * EXCEPT(event_name, fire_screen, event_timestamp), CONCAT(event_name, "-", fire_screen) AS event_name_with_screen, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime FROM base WHERE event_name IN ("screen_view", "click_payment") ) -- step_number + COUNT -- step_number : CASE WHEN을 사용해 숫자 지정 SELECT event_name_with_screen, CASE WHEN event_name_with_screen = "screen_view-welcome" THEN 1 WHEN event_name_with_screen = "screen_view-home" THEN 2 WHEN event_name_with_screen = "screen_view-food_category" THEN 3 WHEN event_name_with_screen = "screen_view-restaurant" THEN 4 WHEN event_name_with_screen = "screen_view-cart" THEN 5 WHEN event_name_with_screen = "click_payment-cart" THEN 6 ELSE NULL END AS step_number, COUNT(DISTINCT user_pseudo_id) AS cnt FROM fiter_event_and_concat_event_and_screen GROUP BY ALL HAVING step_number IS NOT NULL WHERE user_pseudo_id = "1350836585.3421064109" -- 일자별 SELECT event_date, event_name_with_screen, CASE WHEN event_name_with_screen = "screen_view-welcome" THEN 1 WHEN event_name_with_screen = "screen_view-home" THEN 2 WHEN event_name_with_screen = "screen_view-food_category" THEN 3 WHEN event_name_with_screen = "screen_view-restaurant" THEN 4 WHEN event_name_with_screen = "screen_view-cart" THEN 5 WHEN event_name_with_screen = "click_payment-cart" THEN 6 ELSE NULL END AS step_number, COUNT(DISTINCT user_pseudo_id) AS cnt FROM fiter_event_and_concat_event_and_screen GROUP BY ALL HAVING step_number IS NOT NULL ORDER BY event_date;배운점ARRAY와 STRUCT 라는 조금은 생소할 수 있는 데이터 타입과 이를 어떻게 하면 평면화로 풀고 어떻게 데이터를 처리할 수 있을지를 조금은 알 수 있었고BigQuery로 생각보다 많은 부분을 할 수 있구나 생각이 들면서 이를 프로젝트에 연결시키면 어떨까 하는 재밌는 고민이 생긴거 같다 BIgQuery를 배우고 싶은데 어떤 데이터로 어떻게 다뤄야 할지 막막했던 찰라에 많은 것을 배울 수 있던 1주차 였다
-
미해결10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
3-Q 질문
http://boj.kr/5cc22e317fde47e8b77e3ffe89d2194a위와같이 풀어봤는데 효율측면에서 거리가 초과된다면 탐색을 그만하게 했습니다. 강사님 코드와 비교해봤을때 좀 더 효율적이라 할 수 있나요? 아니면 같은 효율일까요?
-
미해결개발자를 위한 쉬운 도커
docker commit error
맞게 잘 쓴것 같은데 에러가 납니다... 왜그러는지 여쭤봐도 될까요!
-
미해결스마트시트 사용하기 A to Z
리포트 상에서 Conversation하는 방법
안녕하세요 리포트 상에서 Conversation을 하면 상대방이 리포트가 아닌 시트로 들어가져 대화를 하게 되더라고요 시트 내용을 보여주고 싶지 않은데 리포트안에서 만 대화할 수 있는 방법이 있을까요?
-
미해결파이썬 기초 라이브러리부터 쌓아가는 머신러닝
제가 뭘 틀린걸까요??ㅠ
(사진)
-
미해결딥러닝 CNN 완벽 가이드 - TFKeras 버전
입력 이미지 크기
안녕하세요.좋은 강의 잘 듣고 있습니다! 중간에 궁금한 점이 생겨서 질문 남깁니다. 현재, 사전 학습된 모델의 가중치를 불러와서 파인 튜닝을 진행하고 있습니다. 이 과정에서 입력 이미지 크기에 따라 실험을 진행중인데, VGG16의 입력 이미지 크기는 기본값이 224x224로 알고 있습니다. 만약, 제가 가진 데이터가 128x128의 형태를 띄고 있는 이미지라면, input_size를 128x128로 구성해줘도 기존의 사전 학습된 가중치를 불러와 쓸 수 있지 않나요? 기존의 DNN과 달리 CNN 모델들은 필터에 가중치를 적용하여 계산하므로 입력 이미지 크기에 상관없이 사전 학습된 가중치를 불러와 사용할 수 있다고 생각합니다. 제가 생각한게 맞는지 궁금해 질문 남깁니다. 감사합니다. 또한, 만약 제 생각이 틀리다면 위와 같이 128x128 이미지를 입력 사이즈로 주었을 때, 모델은 이를 어떻게 224x224로 만들어 학습하는지 궁금합니다. 감사합니다.
-
미해결스프링 배치
Multithread step과 AsyncItemProcessor
read 작업이 무겁고(느림) processor 작업에는 I/O(api call 등,,)가 많다고 가정했을때 Multithread step(reader는 스레드안전)과 AsyncItemProcessor를 함께 사용해도 문제가 없을까요??Multithread step 자체도 별도의 스레드 풀에서 동작하고AsyncItemProcessor도 다른 스레드 풀에서 작동하고reader(reader는 스레드안전)에서 데이터를 가져올때 이미 작업범위가 정해져있기 때문에 동시성으로 부터도 안전해 보여서요!
-
해결됨Next + React Query로 SNS 서비스 만들기
modal에 intercept routes를 사용하는 이유?
안녕하세요 제로초님 modal을 구현하고있는데 궁금증이 생겨 질문드립니다.modal을 구현할 때 intercepting routes를 사용하는 이유가 궁금합니다. 단순히 parallel로만 띄우면 안되는건가요? 아래는 제가 구현한 코드예시입니다.https://github.dev/datoybi/next-playgroundsimple-modal1은 parallel routes만 사용하였고, simple-modal2는 parallel routes + intercepting routes를 사용하였습니다.두개 다 구현을 해보았는데 새로고침을 해도 둘의 결과값이 같습니다.무엇때문에 intercepting routes를 사용하는 건가요? 미리 감사합니다!
-
미해결AWS(Amazon Web Service) 입문자를 위한 강의
RDS 실습 1부 - connect.php
최근에 강의를 수강 하시는 분들은 connect.php 접속 시 500에러가 나옵니다.강의를 촬영하실 때의 php버전과 수강시기의 버전이 달라서 생기는 문제인데요.[25-Oct-2024 06:38:59 UTC] PHP Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /var/www/html/connect.php:8에러내용을 살펴보면 mysql_connect() 함수를 찾을 수 없어서 일어나는 문제입니다.아래는 connect.php를 동작가능하게 수정한 코드입니다. 이미지를 우클릭 후 '새 탭에 이미지 열기' 하시면 원본을 보실 수 있습니다.
-
해결됨오브젝트 - 기초편
객체지향 설계 관련하여 궁금한것이 있습니다.
안녕하세요. 우선 저는 제 자신이 자바로 개발을 진행하고 있지만, 객체지향을 완전히 알고있는지에 대해 의문을 가진채 해당 강의를 접하게 되었고, 많은 생각과 깨달음을 얻고 있습니다. 감사합니다.그리고 궁금한것이 있어 글을 쓰게 되었습니다. (사실 완강을 하지 않은 상태이긴합니다 ㅠ) 개발 설계 방식이야 다양할것이라 생각이 드는데, 보통 스프링 기준으로..프레임워크 내에서 패키지 설계를 진행할때 단순 관리 기능 개발 기준으로 보면, 레이어드 아키텍처와 유사한 방식으로 설계를 많이 진행하지 않을까라는 생각이 조심스럽게 듭니다. (물론 아닐수도 있습니다 ㅠㅠ)그리고 보통은 절차지향으로 생각하여 ERD 설계후 이를 스프링 프로젝트 내에 레이어드 아키텍처를 설계하여 (대충 controller-service-repository(JPA 사용시))작업을 진행할것이라 생각이 듭니다. 그리고 service 에는 필요한 repository 들을 왕창 주입받는 형태로 설계될것이라 생각이 듭니다. 저는 여기서 궁금한것이 이러한 상황(레이어드 아키텍처)에서 강의의 오브젝트 개념을 녹이고 싶다면패키지 구조를 어떻게 정의하는것이 마땅할지 문득 궁금해졌습니다. 예를들면 entity 패키지와는 별개의 다른 domain 패키지(책임을 일부 갖는 역할)를 만들어 service 패키지에서 해당 domain 패키지(책임을 일부 갖는 역할)를 주입받아 사용하는 방식으로 설계를 해야하는지 등이 궁금합니다. 질문을 작성하면서도 정답이 없으려나 싶기도 합니다. 무튼 감사합니다. 완강하겠습니다!!