# 1) Weekly Retention을 구하는 쿼리를 바닥부터 스스로 작성해보세요 WITH base AS ( SELECT DISTINCT user_id, event_name, DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime, user_pseudo_id FROM advanced.app_logs WHERE event_date BETWEEN '2022-08-01' AND '2023-08-03' ), first_diff_of_week AS ( SELECT *, DATE_DIFF(event_week, first_week, WEEK) AS diff_of_week FROM ( SELECT DISTINCT user_pseudo_id, DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week FROM base ) ), user_counts AS ( SELECT diff_of_week, COUNT(DISTINCT user_pseudo_id) AS user_cnt FROM first_diff_of_week GROUP BY diff_of_week ) SELECT diff_of_week, user_cnt, ROUND(SAFE_DIVIDE(user_cnt, first_cnt), 3) AS retention_rate FROM ( SELECT *, FIRST_VALUE(user_cnt) OVER(ORDER BY diff_of_week) AS first_cnt FROM user_counts ) ORDER BY diff_of_week # 2) Retain User를 New + Current + Resurrected + Dormant User로 나누는 쿼리를 작성해보세요. # 신규유저(New) : 제품을 처음 사용하는 유저 # 기존유저(Current) : 제품을 지속적으로 사용하는 유저 # 복귀유저(Resurrected) : 과거에 사용 -> 비활성 -> 다시 제품을 사용한 유저 # 휴면유저(Dormant) : 일정 기간 제품을 사용하지 않은 비활성화 사용자 WITH base AS ( SELECT DISTINCT user_id, DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, DATE_TRUNC(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul'), WEEK(MONDAY)) AS event_week, user_pseudo_id FROM advanced.app_logs WHERE event_date BETWEEN '2022-08-01' AND '2023-08-03' ), user_activity AS ( SELECT user_pseudo_id, event_week, LAG(event_week, 1) OVER(PARTITION BY user_pseudo_id ORDER BY event_week) AS prev_week, MIN(event_week) OVER(PARTITION BY user_pseudo_id) AS first_week FROM base ), user_classification AS ( SELECT user_pseudo_id, event_week, CASE WHEN event_week = first_week THEN 'New' WHEN prev_week IS NOT NULL AND DATE_DIFF(event_week, prev_week, WEEK) = 1 THEN 'Current' WHEN prev_week IS NOT NULL AND DATE_DIFF(event_week, prev_week, WEEK) > 1 THEN 'Resurrected' ELSE 'Dormant' END AS user_type FROM user_activity ) SELECT event_week, user_type, COUNT(DISTINCT user_pseudo_id) AS user_count FROM user_classification GROUP BY ALL ORDER BY event_week, user_type # 3) 주어진 데이터에서 어떤 사람들이 리텐션이 그나마 높을까요? WITH base AS ( SELECT DISTINCT user_id, DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, DATE_TRUNC(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul'), WEEK(MONDAY)) AS event_week, user_pseudo_id FROM advanced.app_logs WHERE event_date BETWEEN '2022-08-01' AND '2023-08-03' ), user_activity AS ( SELECT user_pseudo_id, event_week, LAG(event_week, 1) OVER(PARTITION BY user_pseudo_id ORDER BY event_week) AS prev_week, MIN(event_week) OVER(PARTITION BY user_pseudo_id) AS first_week FROM base ), user_classification AS ( SELECT user_pseudo_id, event_week, CASE WHEN event_week = first_week THEN 'New' WHEN prev_week IS NOT NULL AND DATE_DIFF(event_week, prev_week, WEEK) = 1 THEN 'Current' WHEN prev_week IS NOT NULL AND DATE_DIFF(event_week, prev_week, WEEK) > 1 THEN 'Resurrected' ELSE 'Dormant' END AS user_type FROM user_activity ), user_counts AS ( SELECT event_week, user_type, COUNT(DISTINCT user_pseudo_id) AS user_count FROM user_classification GROUP BY ALL ORDER BY event_week, user_type ) SELECT event_week, DATE_DIFF(event_week, first_week, WEEK) AS weeks_after_first_week, user_type, user_count, cohort_users, ROUND(SAFE_DIVIDE(user_count, cohort_users), 3) AS retention_rate FROM ( SELECT DATE(event_week) AS event_week, DATE(MIN(event_week) OVER()) AS first_week, user_type, user_count, MAX(CASE WHEN user_type = 'New' THEN user_count END) OVER(PARTITION BY DATE(event_week)) AS cohort_users FROM user_counts ORDER BY event_week, CASE user_type WHEN 'New' THEN 1 WHEN 'Current' THEN 2 WHEN 'Resurrected' THEN 3 WHEN 'Dormant' THEN 4 END ) 2022-08-01 ~ 2023-08-03 기간으로 설정하여, 개인적인 의견으로 Retain User를 쪼개 보았습니다. 배달어플은 유저들의 사용 간격이 짧다고 생각하기 때문에, 주의 주기로 리텐션으로 설정했습니다. 저는 바로 전 주에 사용했고, 그 다음주에 사용했다면 기존유저(Current)로 설정했습니다. 2주 이상 텀을 두고 다시 사용했다면 복귀유저(Resurrected)로 설정했습니다. 처음 들어가고 사용하지 않았다면 휴면유저(Dormant)로 설정했습니다. 주차마다 '신규/기존/복귀/휴면' 유저를 새로 계산하는 쿼리입니다. 데이터를 살펴보면, 1) 신규유저(New) : 제품을 처음 사용하는 유저 출시(2022-08-01을 출시기간으로 생각하면)로부터 현재(2023-01-16 => 0803으로 설정했지만 0116까지가 끝입니다.)까지의 신규유저 수의 변화를 살펴보겠습니다. 런칭부터 10주까지의 신규유저의 수는 주춤한 경우도 있지만 평균 4~500명 정도 증가했습니다. 하지만, 11주에 4000명 대에서 3100명으로 900명이 급감한 이후로 계속 하락세를 타고 24주차 현재 신규 가입자의 수는 500명 남짓하고 있습니다. 11주차부터의 마케팅 효과는 빛을 보지 못하고 있는 것 같습니다. 코호트 리텐션 시각화를 보자면, 2) 기존유저(Current) : 제품을 지속적으로 사용하는 유저(바로 전 주와 이번 주) 출시로부터 현재까지 줄곧 주차마다의 신규유저 대비 기존유저의 비율이 증가하고 있습니다. 특히, 24주차에 가입한 신규유저 대비 기존유저의 비율은 76%나 차지하고 있습니다. 시간이 흐름에 따라 점차 어플이 안정화되면서 신규유저들이 만족을 느끼는 비율이 늘어가고 있다고 보입니다. 3) 복귀유저(Resurrected) : 과거에 사용 -> 비활성화 -> 다시 제품을 사용한 유저(2주 후 복귀) 복귀유저는 12주차를 분기로 13주차부터는 신규가입자보다 복귀유저의 수가 많아지기 시작했습니다. 24주차에는 신규유저 대비 복귀유저는 6배가 많습니다. 복귀유저가 기존유저로 안정되는 현황을 추출할 수 있는 쿼리는 조금 더 연구해 보겠습니다. 4) 휴면유저(Dormant) : 일정기간 제품을 사용하지 않은 비활성화 사용자 신규유저 대비 휴면유저는 꾸준히 늘어가고 있습니다(휴면유저가 누적됨). 24주차 신규가입자의 5.7배가 휴면유저 입니다. # 4) Core Event를 'click_payment'라고 설정하고 Weekly Retention을 구해주세요 WITH base AS ( SELECT DISTINCT user_id, DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime, user_pseudo_id FROM advanced.app_logs WHERE event_date BETWEEN '2022-08-01' AND '2023-08-03' AND event_name = 'click_payment' ), first_week_and_diff AS ( SELECT *, DATE_DIFF(event_week, first_week, WEEK) AS diff_of_week FROM ( SELECT DISTINCT user_pseudo_id, DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week FROM base ) ), user_counts AS ( SELECT diff_of_week, COUNT(DISTINCT user_pseudo_id) AS user_cnt FROM first_week_and_diff GROUP BY diff_of_week ORDER BY diff_of_week ) SELECT diff_of_week, user_cnt, ROUND(SAFE_DIVIDE(user_cnt, cohort_users), 3) AS retention_rate FROM ( SELECT *, FIRST_VALUE(user_cnt) OVER(ORDER BY diff_of_week) AS cohort_users FROM user_counts ) ORDER BY diff_of_week
안녕하세요 선생님. 이전 두 질문에 대한 답변이 많은 도움이 되었습니다. 감사합니다. 2133번 문제의 DP 1번 풀이에서 O(N^2) 풀이를 소개해주셨는데 아래와 같이 dp 테이블을 갱신할 때 sum_dp 테이블을 같이 갱신을 해주면 시간복잡도가 O(N)으로 줄일 수 있지 않나 싶어 질문드립니다. N = int(input()) if N % 2 != 0: print(0) else: n = N//2 dp = [1] * (n+1) sum_dp = [1] * (n+1) for i in range(1,n+1): dp[i] = sum_dp[i-1] * 2 + dp[i-1] sum_dp[i] = sum_dp[i-1] + dp[i] print(dp[-1]) 그리고 이건 다른 종류의 질문인데 혹시 그래프 부분이 실제로 코테에 많이 등장하나요? 제가 조금 급하게 준비하고 있는 상태라 이론을 필수 알고리즘2까지만 들어도 될지 아니면 그래프까지 다 들어야될지 고민중입니다. 조언 주시면 감사하겠습니다!
위의 코드를 그대로 입력하고 baseline 코드까지 문제가 없다가 label에서 다음과 같은 에러가 발생했습니다. KeyError Traceback (most recent call last) /usr/local/lib/python3.10/dist-packages/pandas/core/indexes/base.py in get_loc(self, key) 3804 try: -> 3805 return self._engine.get_loc(casted_key) 3806 except KeyError as err: index.pyx in pandas._libs.index.IndexEngine.get_loc() index.pyx in pandas._libs.index.IndexEngine.get_loc() pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() KeyError: 'Gender' The above exception was the direct cause of the following exception: 아래는 입력한 코드입니다. 어떤 부분이 문제일까요? ㅠㅠ #label from sklearn.preprocessing import LabelEncoder for col in cols : le = LabelEncoder() train[col] = le.fit_transform(train[col]) test[col] = le.transform(test[col]) train[cols].head()
안녕하세요 카일스쿨님:) 강의 마지막에 선택과제(?)로 주신 집계데이터 pivot쿼리 작성해봤습니다. 쿼리를 작성하면서, 지금은 피봇할 컬럼이 많지 않아서 하나하나 피봇해주는 것으로 진행했는데 이게 최선일지가 의문이 들어서요, 피봇하는 컬럼 조건이 다를 뿐 과정은 동일해서 공통으로 적용할 수 있는 방법이 있을 것 같은데 제가 잘못 이해하고 있는 것인지, 아니면 피봇을 항상 이런식으로 진행해야 하는 것인지도 같이 질문드립니다. 감사합니다:) with base as ( select event_date ,event_timestamp ,event_name ,user_id ,user_pseudo_id ,max(if(param.key = 'firebase_screen',param.value.string_value,null)) as `firebase_screen` ,max(if(param.key = 'food_id',param.value.int_value,null)) as `food_id` ,max(if(param.key = 'session_id',param.value.string_value,null)) as `session_id` from advanced.app_logs , unnest(event_params) as param where 1=1 and event_name in ('screen_view','click_payment') and event_date >= '2022-08-01' and event_date <= '2022-08-18' group by all order by 1 ) , before_pivot as ( select event_date ,concat(event_name,'-',firebase_screen) as `event_name_with_screen` ,case when event_name = 'screen_view' and firebase_screen = 'welcome' then 1 when event_name = 'screen_view' and firebase_screen = 'home' then 2 when event_name = 'screen_view' and firebase_screen = 'food_category' then 3 when event_name = 'screen_view' and firebase_screen = 'restaurant' then 4 when event_name = 'screen_view' and firebase_screen = 'cart' then 5 when event_name = 'click_payment' and firebase_screen = 'cart' then 6 end as `step_number` ,count(*) as cnt from base where 1=1 group by 1,2,3 having step_number is not null ) select event_date ,max(if (event_name_with_screen = 'screen_view-welcome',cnt,null)) as `screen_view-welcome` ,max(if (event_name_with_screen = 'screen_view-home',cnt,null)) as `screen_view-home` ,max(if (event_name_with_screen = 'screen_view-food_category',cnt,null)) as `screen_view-food_category` ,max(if (event_name_with_screen = 'screen_view-restaurant',cnt,null)) as `screen_view-restaurant` ,max(if (event_name_with_screen = 'screen_view-cart',cnt,null)) as `screen_view-cart` ,max(if (event_name_with_screen = 'click_payment-cart',cnt,null)) as `click_payment-cart` from before_pivot group by all order by 1
안녕하세요. dir 이나 __all 관련해서,,, print(sklearn.__all__) 은 알겠는데요. 그 다음,,, from sklearn.ensemble import RandomForestClassifier 여기서,, randaomforestclassifier 이게 생각이 나지 않을때 이걸 찾을 수 있는 방법은 없는지요?
안녕하세요, 작업형3을 공부하던 중 궁금한 점이 생겨 문의드립니다. 어떤 상황에서 T검정, 카이제곱 검정, 회귀분석, 분산분석(ANOVA)를 수행하는건지 명확히 분류가 잘 안 되는데 위와 같이 T검정, 카이제곱 검정, 회귀분석, 분산분석 중 어떤 것을 수행할지는 문제에서 주어지는 사항일까요? 감사합니다!
train = pd.read_csv('/kaggle/input/working8-2/churn_train.csv') test = pd.read_csv('/kaggle/input/working8-2/churn_test.csv') target = train.pop('TotalCharges') train = pd.get_dummies(train) test = pd.get_dummies(test) from sklearn.model_selection import train_test_split X_tr,X_val,y_tr,y_val = train_test_split(train, target, test_size=0.2, random_state=2022) from sklearn.metrics import mean_absolute_error from sklearn.ensemble import RandomForestRegressor rf = RandomForestRegressor(random_state=2022, max_depth=7, n_estimators=600) rf.fit(X_tr,y_tr) pred = rf.predict(X_val) answer = rf.predict(test) rf.predict(X_val)까지는 잘 예측이 되어, 866.4986350062683의 값을 얻었습니다. 그리하여 마지막으로 본 test파일을 예측하여 제출하려고 하는데, 계속해서 오류가 발생하네요 ㅠㅠㅠ 아래는 에러 코드입니다. ValueError Traceback (most recent call last) Cell In[97], line 14 12 rf.fit(X_tr,y_tr) 13 pred = rf.predict(X_val) ---> 14 answer = rf.predict(test) File /opt/conda/lib/python3.10/site-packages/sklearn/ensemble/_forest.py:981, in ForestRegressor.predict(self, X) 979 check_is_fitted(self) 980 # Check data --> 981 X = self._validate_X_predict(X) 983 # Assign chunk of trees to jobs 984 n_jobs, _, _ = _partition_estimators(self.n_estimators, self.n_jobs) File /opt/conda/lib/python3.10/site-packages/sklearn/ensemble/_forest.py:602, in BaseForest._validate_X_predict(self, X) 599 """ 600 Validate X whenever one tries to predict, apply, predict_proba.""" 601 check_is_fitted(self) --> 602 X = self._validate_data(X, dtype=DTYPE, accept_sparse="csr", reset=False) 603 if issparse(X) and (X.indices.dtype != np.intc or X.indptr.dtype != np.intc): 604 raise ValueError("No support for np.int64 index based sparse matrices") File /opt/conda/lib/python3.10/site-packages/sklearn/base.py:548, in BaseEstimator._validate_data(self, X, y, reset, validate_separately, **check_params) 483 def _validate_data( 484 self, 485 X="no_validation", (...) 489 **check_params, 490 ): 491 """Validate input data and set or check the `n_features_in_` attribute. 492 493 Parameters (...) 546 validated. 547 """ --> 548 self._check_feature_names(X, reset=reset) 550 if y is None and self._get_tags()["requires_y"]: 551 raise ValueError( 552 f"This {self.__class__.__name__} estimator " 553 "requires y to be passed, but the target y is None." 554 ) File /opt/conda/lib/python3.10/site-packages/sklearn/base.py:481, in BaseEstimator._check_feature_names(self, X, reset) 476 if not missing_names and not unexpected_names: 477 message += ( 478 "Feature names must be in the same order as they were in fit.\n" 479 ) --> 481 raise ValueError(message) ValueError: The feature names should match those that were passed during fit. Feature names unseen at fit time: - customerID_CUST0001 - customerID_CUST0002 - customerID_CUST0006 - customerID_CUST0007 - customerID_CUST0008 - ... Feature names seen at fit time, yet now missing: - customerID_CUST0000 - customerID_CUST0003 - customerID_CUST0004 - customerID_CUST0005 - customerID_CUST0009 - ...
>> views 컬럼에 결측치가 있는 데이터(행)을 삭제하고, f3 컬럼의 결측치는 0, silver는 1, gold는 2, vip는 3 으로 변환한 후 총 합을 정수형으로 출력하시오<< 이 문제를 풀이할 때, 강사님이 말씀해주신 것처럼 문제를 풀었는데 답 밑에 이런 문구들이 표기됩니다. 133 <ipython-input-34-9be3d2c84afd>:11: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)` df['f3'] = df['f3'].replace('silver',1).replace('gold',2).replace('vip',3) 이렇게 표기되어도 정답 인정은 되는 것인지 궁금합니다.
학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! 질문과 관련된 영상 위치를 알려주면 더 빠르게 답변할 수 있어요 먼저 유사한 질문이 있었는지 검색해보세요 안녕하세요! 열심히 한강의씩 듣고있는 수강생입니다. 항상 너무 자세히 설명도 너무 잘 해주셔서 감사합니다. 일원분산분석 수강중 melt를 진행하고 이렇게 나온것까지는 이해가 됐습니다! 혹시 분산분석테이블에서 ols를 할 때 종속, 독립을 넣어야하는데 어떻게 구분해야할지가 문득 궁금해져서 질문을 남기게 되었습니다..! 보통은 맨 우측에있는 부분을 종속변수로 알면 될까요?
#text= text.replace("파이썬", "머신러닝").replace("분석기사", "분석을 위한") 에서 여러단어 변경 시 유의사항으로 앞에서 부터 실행돼서 파이썬부터 머신러닝으로 바꿔야 한다고 말씀하셨는데 앞에서 부터 실행되면 분석기사부터 바꿔야되는 거 아닌가요? 왜냐면 text = 빅데이터 분석기사 파이썬 공부 순이라서. 앞에서 부터 실행된다는게 분석기사부터 바뀌는게 아닌가 하는 생각이 들어서 여쭤봅니다. #text= text.replace("분석기사", "분석을 위한").replace("파이썬", "머신러닝") 으로 바꿔서 실행해보니 '빅데이터 분석을 위한 머신러닝 공부' 라는 값이 도출됩니다.