Closed syleeie2310 closed 4 months ago
개념적으로 다음과 같이 구현하면 어느정도 빠르게 계산됨
select gmap_id1, gmap_id2, count(distinct user_id) user_id_cnts, count(distinct case when .....) rating_4_over_user_id_cnts from( select a.gmap_id as gmap_id1, b.gmap_id as gmap_id2, a.user_id, a.rating as rating1, b.rating as rating2 from a as a inner join a as b on 1=1 and a.user_id =b.user_id ) as t where 1=1 and gmap_id1 != gmap_id2 group by gmap_id1, gmap_id2
spark.sql = spark.dataframe.api
탐색
1개 몇건인지? 2개인게 몇건인지? ......
da_cluster에서 작업
아까 말하려고 했던 용어가 Cartesian Product 입니다. 검색하면 실질적으로 cross join 형태로 이해하시면 되고 제가 알려준 방식이 아래 형태랑 비슷하네요.
How to generate co-occurence datatable using either Spark SQL, Pyspark or R spark
계산 할 때 아이템 X 아이템 예상하는 기대값이 너무 커서 연산이 어려우면 리뷰가 동일한 월 기준으로 매긴 사람만 계산할 수도 있는데 그럼 join 조건에 추가하면 됩니다. 우선 리뷰가 많은 gmap_id 샘플로 100개 정도만 코드로 작업해서 확장하시는게 좋을 듯 해요
넵 확인했습니다 감사합니다~!
@syleeie2310 멘토님 작업하다가 질문이 생겨서 댓글남깁니다.
gmap_id1, gmap_i2, 같이 리뷰 매긴 사람 갯수, .5점 같이 매긴 사람, 4점 이상 같이 매긴 사람 에 해당하는 사람의 수를 카운트 하는데에는 cross join 까지는 하지 않고 self join만 해도 되는것 같은데, cross join 으로 해야하는 이유가 있나요?
@oh-bom 이걸 하는 이유를 알아야 어떤 데이터가 필요할지 알다보니 아래 27~28페이지 한번 보시구요! https://docs.google.com/presentation/d/1OIhY20PA1lFkjQpAZ-S5G3iB1IG67m1D/edit#slide=id.p36
gmap_id1, gmap_id2를 같이 매겼다는 기준이 동일한 사람이 둘 다 5점 매긴 케이스까지 한정할 수도 있고 날짜까지 한정할 순 있는데,
하와이로만 한정할 순 없다보니가 전체 데이터로 확장해야 되거든요.
아이템 X 아이템 갯수가 총 몇개 나오는지를 알아야 확장가능한데, 너무 많으면 계산 자체가 안되다보니깐 고민이 필요해요!
서포트, 리프트, confidence 개념 공부해서 데이터는 쳐내주세요.
@syleeie2310 안녕하세요 멘토님! support, lift ,confidence 개념 공부한후 코드 짜보면서 테스트해보던 중에 에러가 발생해서 연락드립니다.. 제가 처음에 하와이 데이터 중에서 item-to-item의 user_id 카운트가 500인 이상인 열들만 뽑아서 진행했을때는 aassociation_rules 구하는 코드가 잘 작동이 되었습니다!
전체 silver 데이터에서도 실험 해보려던 중,, 갑자기 같은 코드인데 에러가 뜨기 시작했고, 원인을 모르겠어서 남깁니다.. get_encoder()함수 or sample data 문제인것 같은데 둘다 이것저것 살펴봐도 이상없어보여서요!! ㅜㅜ 혹시 어디가 잘못된건지 도와주실수있을까요,,🥹
@oh-bom ~ 외부 라이브러리 사용하면 스파크가 아닌 python 라이브러리에 의존해서 처리하기 때문에, 해당 처리에서 pandas나 list로 처리될수 있기 때문에, 어차피 큰 데이터로 보기에 적절치 않아서요.
lift/confidence/support는 개념적으로 공부한 다음에 spark.sql로 구현하면 문제 없을거 같아요.
support = item1 & item2 리뷰 교집합 unique 유저수 / 전체 리뷰 유저수 unique confidence = item1 & item2 리뷰 교집합 unique 유저수 / item1 리뷰 유니크 유저수 lift = item1 & item2 리뷰 교집합 unique 유저수 / (item1 리뷰 유니크 유저수 * item2 리뷰 유니크 유저수)
이 방식에선 조금 변형한다면 각 숫자를 유니크 숫자로 해도 될거 같아요. 아래 참고! https://process-mining.tistory.com/34
lift/confidence/support도 하나의 방식이라 처음에 제시했던 방식은 단순 co-count를 구하는 방식 ( item1 & item2 리뷰 교집합 unique 유저수 ) 이거와 별도로 jacard 방식도 있습니다. ㄴ item1 & item2 리뷰 교집합 unique 유저수 / ( item1 리뷰 유니크 유저수 + item2 리뷰 유니크 유저수 - item1 & item2 리뷰 교집합 unique 유저수)
내일 다룰 예제 중에 하나에요.
그리고 spark.sql로 한다는건 꼭 쿼리가 아니라 함수로도 할 수 있는데 아래처럼 불러와도 되고 import pyspark.sql.functions as F
pandas로 해야 한다면 pyspark.pandas (ps)로 불러와서, 해당 lift,confidence,support를 pandas 문법에 맞게 코딩하셔야 합니다.
대신 외부 라이브러리는 mlxtend 는 pyspark.pandas용이 아니라 그냥 pandas 객체를 가지고 구현한거라 직접 짜야 될듯 해요.
네 감사합니다 !! 공부하다 보니까 support, lift, confidence의 보완을 위해, IS, CS 등도 활용한다는 글을 보았는데요 !! 우선 support, lift, confidence, jacard 이렇게만 직접 구현해보면 될까요?
@oh-bom IS, CS가 어떤건지 모르겠는데 다음에 본게 있으면 한번 링크까지 같이 공유해주시면 좋을 듯 해요!
우선 위에 있는 값들부터 co-count랑 같이 계산해둔 다음에 어떻게 활용할지 보시죠!
@syleeie2310 안녕하세요 멘토님 코드 구현을 해보면서 궁금했던 점 질문드립니다!
코드도 구현과정 피드백 한번 부탁드려요! 피드백 후에 지표값들 분포 확인하고, 다른 지역 데이터도 돌릴 수 있도록 함수화해두겠습니다! https://tacademykr-asacanalysis.cloud.databricks.com/?o=3001521127938963#notebook/320946710921421/command/4085356982797238
hr_lift=hr_confidence.withColumn("lift",col("co_count")/col("gmap_count1")*col("gmap_count2"))
별건 아닌데 숫자가 예상한것과 달라보여서 아래처럼 분모를 가로 묶어야 되지 않나 싶어서요! ㅎㅎ
hr_lift=hr_confidence.withColumn("lift",col("co_count")/(col("gmap_count1")*col("gmap_count2")))
support를 어떻게 정의하냐에 따라 조금 값은 달라질 수 있긴 할듯 해요.
보내주신 association rule 블로그에서도 나오긴 했지만 ㄴ수식으로는 n(X∪Y) / n(ALL) 이다. (상황에 따라서는 그냥 n(X∪Y) 만을 의미하기도 한다.)
만약 support 를 확률로 계산하면 n(all)의 값을 정의해야 될듯 하는데 그럼 unique user_id 갯수로 나누면 되지 않을까 싶기도 하고 모르겠네요?
한번 2가지 방식에 따라 값은 다를거 같은데 보시고~ @oh-bom 이 2개 중에 어떤 방식이 편할지 결정해서 써주세요!!
@syleeie2310 아 저근데 궁금한게 하나 더있습니다! support,lift,confidence 구할때 x 와 y의 교집합을 구해서 사용하잖아요 그런데 인터넷 설명글들에서는 n(x∩y) 로 표현을 안하고 n(XUY)로 표현한 경우가 많더라구요 의미적으로는 저도 n(x∩y) 라고 생각하고 코드를 짜긴 했지만, 다른 글들에서 n(XUY)로 표현한게 잘못 된건지 아니면 제가 덜 이해하고 있는 부분이 있는 것인지 궁급합니다!!
한번 2가지 방식에 따라 값은 다를거 같은데 보시고~ @oh-bom 이 2개 중에 어떤 방식이 편할지 결정해서 써주세요!!
그럼 support를
중에가 맞을까요?
지금 코드에서는 1번의 n(ALL)을
hr_unique=hr.dropDuplicates(["gmap_id","user_id"])
로 중복 제거 후, hr_unique.count()의 값으로 사용하였습니다!
formula가 support는 P(X,Y)로 표현되어 있는거 원래는 맞는거 같아요, 블로그에선 1) n(XUY)/n(ALL)를 하거나 2) n(XUY) 중에 쓰는데 n(XUY)의 의미가 여기에서 U가 X,Y의 합집합이라는 의미가 아니라 X와 Y가 동시에 등장한 건수로 formula 로 표현하는게 맞지 않나 생각드는데..
왜 저런 formula 로 표현했나 모르겠는데 장바구니 규칙은 트랜잭션 기준이 list(items)라서 저렇게 표현한거 같기도 하고. co-occurences matrix에서 계산할 때는 개념만 가져다가 써서 표현하는 formula가 다른거 같아요. 의미적으론 동일한거 같은데.
lift 때문에 support 를 이야기 한거긴 한데 @oh-bom 이 생각했을 때 좋은 방향으로 계산해주세요. :)
@syleeie2310 안녕하세요 멘토님,, 하와이랑 캘리포니아 리뷰로 지표들 계산해서 정리해보았습니다.. 지표간에도 값의 범위가 좀 달라서 어떻게 해야 더 잘 정리해서 볼수 있을지 조언 부탁드려도 될까요,,? 😿 https://www.notion.so/ohbom/4-association-rule-07fa8e28415b464498738402c6a7b6f9
동일 분기로 절반 정도 캘리포니아 8억개 이고 분기 별로 따로 저장 필요
confidence 1개만 저장하면 될듯
co-count 분포 정리하면 됨
confidence, lift, jacard, support 분포를 보여줄지?
저장해주세요 (캘리포니아)
@syleeie2310 안녕하세요 멘토님 현재 말씀 해주신 대로 연도-분기로 나눠서 다시 co-count를 계산했습니다. 또한 support, confidence, lift등 도 오류 수정해서 다시 계산했습니다. 이 값들을 테이블로 업로드하는것에 대해 질문드립니다. 아까 임시로 올렸던 테이블인데요 https://tacademykr-asacanalysis.cloud.databricks.com/explore/data/hive_metastore/test/california_cocount_over10?o=3001521127938963&tableDetailsTab=sample
네 1번 데이터에 컬럼 추가하면 좋겠네요. year, quarter는 컬럼을 분리해서 따로 저장해주셔도 좋을거 같긴 해요. (컬럼 3개로 year-quarter, year, quarter)
1번 데이터 갯수가 대략 몇개 정도 되었죠? 너무 크면 고민이긴 한데.. 우선 말씀해주세요~
2번은 1번 작업 하고나서 co-count 기준으로 필터링 해서 데이터 탐색할 때 support/confidence/lift 분포 보는건 자유롭게 하심 될듯 합니다.
@syleeie2310 다시 필터링 한결과는 co-count>5 필터링 :2091608(200만) co-count>10 필터링: 389502(38만) 입니다~
@syleeie2310 멘토님,,안녕하세요 발표자료 만들다가 이 글을 봤는데 https://tr.educoco.kr/25 lift값을 다시 구해야한다는 생각이 들어서 글 남깁니다
ift > 1, 두 품목이 서로 양의 관계
lift = 1, 두 품목은 서로 독립적인 관계 lift < 1, 두 품목은 서로 음의 상관관계
인데 왜 우리결과는 max가 1이지? 싶어서 공식을 다시 봤습니다 저희는 확률로 계산해서 안하고 그냥 개수로 식을 써서 사용했잖아요, support, confidence, jaccard는 확률로 접근하던 그냥 개수 카운트 해서 공식에 사용하던 값이 동일하게 나와서 상관이 없는 것 같습니다. 하지만 lift는 분모에 x인 경우와 y인 경우의 곱으로 들어가다 보니 ! 그걸 P(x) P(y)로 하느냐 n(x)n(y)에 따라 아래 사진 처럼 Lift값이 달라집니다. 그래서 지금 lift 구하는 식인 n(X∩Y) / n(X)* n(Y) 로 하면 1을 못넘는게 당연하고, 그렇게 되면 양의관계/음의관계/독립적인 관계를 파악할 수 없는 것 같습니다. 그래서 Lift의 +/- 을 기준으로 지표를 활용하기 위해서는, lift 만 확률로 계산하는 코드로 다시 수정하는게 맞다는 생각이 드는데 멘토님 의견 듣고 싶어서 댓글 남깁니다!!
gmap_id : 아이템
gmap_id1, gmap_i2, 같이 리뷰 매긴 사람 갯수, .5점 같이 매긴 사람, 4점 이상 같이 매긴 사람 ㄴ co-occurence 이라는 개념