-
확률(Probability) 실전예제
10년치 편의점 판매 데이터 분석하기
-
1500만건
-
특정 상품을 정해 시간당 몇 개씩 팔리는 지 분석
-
확률실험 관측값(팔린갯수)를 확률변수로 사용 ★
-
확률변수 : 무작위 실험을 했을 때, 특정 확률로 발생하는 각각의 결과를 수치적 값으로 표현하는 변수
-
ex) 동전 2개를 던져 숫자가 나오는 경우의 확률변수 = [0, 1, 2] / 주사위 2개를 던져 나온 눈의 합의 평균을 구할때 확률변수 = [2~12]
시간당 판매갯수 확률변수로 분석하기
# 대량의 데이터 빠르게 library(data.table)
# 데이터 로드 - fread()로 data.frame 만들기 df <- fread('r-ggagi-data/example_conveniencestore.csv', encoding = 'UTF-8', data.table=F)
head(df)
Date sellproduct company payment margin <chr> <chr> <chr> <chr> <dbl> 1 2006-01-01 07:00:02 보가리스웨트 620미리리터(P) 동화오츠카㈜ 체크카드 0.11 2 2006-01-01 07:00:14 막스 500미리리터(캔) 블랙맥주㈜ 현금 0.04 3 2006-01-01 07:00:42 맛좋은우유 GT 1리터(팩) 서양유업㈜ 체크카드 0.13 4 2006-01-01 07:00:48 육개장사발탕면 86g(컵) ㈜낭심 신용카드 0.28 5 2006-01-01 07:01:14 제주도삼다수<U+00A0>2리터(P) ㈜낭심 신용카드 0.22 6 2006-01-01 07:01:24 경기도장수생막걸리 750미리리터(P) 경기도탁주제조협회 현금 0.30 # 표본 만들기 S <- df[sample(nrow(df), 5000), ]
str(S)
'data.frame': 5000 obs. of 5 variables: $ Date : chr "2013-07-13 08:10:25" "2007-02-27 11:58:21" "2011-04-01 20:02:11" "2013-04-07 08:17:57" ... $ sellproduct: chr "가스큐팩 1.6리터(P)" "핫개컨디션파워 100미리리터(병)" "팔성사이다<U+00A0>500미리리터(P)" "참이슬로 360미리리터(병)" ... $ company : chr "오비이락맥주㈜" "디제이제당㈜" "팔성음료㈜" "㈜잔루" ... $ payment : chr "체크카드" "교통카드" "교통카드" "현금" ... $ margin : num 0.09 0.3 0.04 0.06 0.32 0.25 0.21 0.25 0.29 0.08 ...
# 분석 상품 선택 - 가장 많이 팔린 상품 sort(table(S$sellproduct)) # 가스큐팩 1.6리터(P)
새로운라면큰사발 114g(컵) 바리스타라떼 250미리리터(컵) 26 40 딸기속우유 310미리리터(팩) 옥수수차 500미리리터(P) 42 42 조르지아오리지널 240미리리터(캔) 카페라떼와일드 200미리리터(컵) 42 42 팔성사이다<U+00A0>1.5리터(P) 가스라이트큐팩<U+00A0>1.6리터(P) 43 45 간다다프리미엄블렌드 275미리리터(캔) 구카카콜 250미리리터(캔) 46 46 비타528 100미리리터(병) 아이리시스<U+00A0>500미리리터(P) 46 46 TOP스위트블랙커피 275미리리터(캔) 우유속에카푸치노 310미리리터(팩) 48 48 가스 640미리리터(병) 가스큐팩 1000미리리터(P) 49 49 딸기짱우유 240미리리터(팩) 힘에이드마운틴블라스트 600미리리터(P) 49 49 아이리시스<U+00A0>2리터(P) 육개장사발탕면 86g(컵) 50 50 메지밀B 190미리리터(병) 맛좋은우유 GT 1리터(팩) 52 53 보가리스웨트 620미리리터(P) 경기도우유 200미리리터(팩) 53 54 막스 355미리리터(캔) 글라소비타민물공급<U+00A0>500미리리터(P) 54 55 세계콘 170미리리터 팔성사이다<U+00A0>500미리리터(P) 58 58 굿이브닝케어 100미리리터(병) 구카카콜 500미리리터(P) 63 86 마지막처럼 360미리리터(병) 구카카콜 1.5리터(P) 90 92 화이트 500미리리터((캔) 레잇비마일드 185미리리터(캔) 94 96 화이트피처 1.6리터(P)<U+00A0> 경기도우유 1리터(팩) 98 99 화이트 355미리리터(캔)<U+00A0> 야명808 140미리리터(캔) 102 103 막스 500미리리터(캔) 제주도삼다수<U+00A0>2리터(P) 104 104 경기도장수생막걸리 750미리리터(P) 먹스피쳐 1.6리터(P) 105 113 제주도사다수 500미리리터(P) 참이슬로 360미리리터(병) 115 158 핫개컨디션파워 100미리리터(병) 첨이슬fresh 360미리리터(병) 180 247 굿스맥주 500미리리터(캔) 굿스맥주 355미리리터(캔) 314 374 바나나멋우유 240미리리터(P) 가스큐팩 1.6리터(P) 420 508
# 가스큐팩 1.6리터(P) 시간당 판매 조사 #날짜 문자열 처리 library(stringr)
Warning message: "package 'stringr' was built under R version 4.0.2"
head(S$Date,3)
- '2013-07-13 08:10:25'
- '2007-02-27 11:58:21'
- '2011-04-01 20:02:11'
S$time <- str_split_fixed(S$Date, " ", 2)[,2] S$hour <- str_split_fixed(S$time, ":", 3)[,1] head(S, 1)
Date sellproduct company payment margin time hour <chr> <chr> <chr> <chr> <dbl> <chr> <chr> 11879271 2013-07-13 08:10:25 가스큐팩 1.6리터(P) 오비이락맥주㈜ 체크카드 0.09 08:10:25 08 # 가스큐팩 1.6리터(P) 추출 library(dplyr)
Warning message: "package 'dplyr' was built under R version 4.0.2" Attaching package: 'dplyr' The following objects are masked from 'package:data.table': between, first, last The following objects are masked from 'package:stats': filter, lag The following objects are masked from 'package:base': intersect, setdiff, setequal, union
S <- as_tibble(S) S2 <- filter(S, sellproduct == "가스큐팩 1.6리터(P)")
#S3 <- S[S$sellproduct == "가스큐팩 1.6리터(P)",] #head(S3) #S4 <- subset(S, subset = S$sellproduct == "가스큐팩 1.6리터(P)") #head(S4)
str(S2)
tibble [508 x 7] (S3: tbl_df/tbl/data.frame) $ Date : chr [1:508] "2013-07-13 08:10:25" "2008-05-05 22:31:16" "2012-05-05 10:26:03" "2012-02-12 09:05:33" ... $ sellproduct: chr [1:508] "가스큐팩 1.6리터(P)" "가스큐팩 1.6리터(P)" "가스큐팩 1.6리터(P)" "가스큐팩 1.6리터(P)" ... $ company : chr [1:508] "오비이락맥주㈜" "오비이락맥주㈜" "오비이락맥주㈜" "오비이락맥주㈜" ... $ payment : chr [1:508] "체크카드" "신용카드" "신용카드" "교통카드" ... $ margin : num [1:508] 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 ... $ time : chr [1:508] "08:10:25" "22:31:16" "10:26:03" "09:05:33" ... $ hour : chr [1:508] "08" "22" "10" "09" ...
# 시간대별 도수 : 윗줄 = 시간 / 아랫줄 = 판매된 갯수 freq <- table(S2$hour) freq
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 19 29 20 16 25 13 11 17 17 23 21 21 22 29 19 21 25 20 23 21 28 33 16 19
# 확률 변수 X 선택 rv <- as.vector(freq) rv <- rv[!duplicated(rv)] # 중복값 제거 rv <- sort(rv) rv
- 11
- 13
- 16
- 17
- 19
- 20
- 21
- 22
- 23
- 25
- 28
- 29
- 33
# 확률 변수별 비율 prv <- prop.table(rv) prv
- 0.0397111913357401
- 0.0469314079422383
- 0.0577617328519856
- 0.0613718411552347
- 0.0685920577617329
- 0.0722021660649819
- 0.075812274368231
- 0.0794223826714801
- 0.0830324909747292
- 0.0902527075812274
- 0.101083032490975
- 0.104693140794224
- 0.11913357400722
# 각각의 기대값 exps <- rv * prv exps
- 0.436823104693141
- 0.610108303249097
- 0.924187725631769
- 1.04332129963899
- 1.30324909747292
- 1.44404332129964
- 1.59205776173285
- 1.74729241877256
- 1.90974729241877
- 2.25631768953069
- 2.83032490974729
- 3.03610108303249
- 3.93140794223827
# 확률변수의 평균 = (확률변수 * 확률(비율))의 총합 sum(exps)
23.0649819494585
묶음행사 상품 판매 데이터 분석하기
-
이벤트 상품 8개 중 6개를 골라 세트 구입
-
중복해서 구입 가능 => 중복 조합
-
6개 세트에서 마진이 좋은 상품도, 나쁜 상품도 있음
-
마진의 기준 0.13
-
6개 상품의 마진이 0.13인 상품갯수의 확률변수 X = {0,1,2,3,4,5,6}
-
이때의 확률변수의 분포
# 이벤트 상품 목록 구하기 - 2000 eventlist <- c("구카카콜 250미리리터(캔)", "세계콘 170미리리터", "딸기속우유 310미리리터(팩)", "조르지아오리지널 240미리리터(캔)", "육개장사발탕면 86g(컵)", "카페라떼와일드 200미리리터(컵)", "핫개컨디션파워 100미리리터(병)", "비타528 100미리리터(병)")
# 세트판매 데이터 불러오기 event <- read.csv("r-ggagi-data/example_eventsale.csv", header=F) event <- as.list(event) # 리스트 1개당 1세트로 처리 event <- lapply(event, as.character) head(event,3)
- $V1
-
- '비타528 100미리리터(병)'
- '세계콘 170미리리터'
- '비타528 100미리리터(병)'
- '카페라떼와일드 200미리리터(컵)'
- '조르지아오리지널 240미리리터(캔)'
- '구카카콜 250미리리터(캔)'
- $V2
-
- '구카카콜 250미리리터(캔)'
- '딸기속우유 310미리리터(팩)'
- '핫개컨디션파워 100미리리터(병)'
- '딸기속우유 310미리리터(팩)'
- '육개장사발탕면 86g(컵)'
- '카페라떼와일드 200미리리터(컵)'
- $V3
-
- '구카카콜 250미리리터(캔)'
- '카페라떼와일드 200미리리터(컵)'
- '딸기속우유 310미리리터(팩)'
- '구카카콜 250미리리터(캔)'
- '비타528 100미리리터(병)'
- '딸기속우유 310미리리터(팩)'
length(event)
2000
# 마진율 가저오기 # 데이터 적재 library(data.table) DF <- fread("r-ggagi-data/example_conveniencestore.csv", encoding="UTF-8", data.table=F)
# 1000개 샘플링 S <- DF[sample(nrow(DF), 1000), ]
library(dplyr)
Warning message: "package 'dplyr' was built under R version 4.0.2" Attaching package: 'dplyr' The following objects are masked from 'package:data.table': between, first, last The following objects are masked from 'package:stats': filter, lag The following objects are masked from 'package:base': intersect, setdiff, setequal, union
# 상품별 요약 S2 <- S %>% filter(sellproduct == eventlist[1] | sellproduct == eventlist[2] | sellproduct == eventlist[3] | sellproduct == eventlist[4] | sellproduct == eventlist[5] | sellproduct == eventlist[6] | sellproduct == eventlist[7] | sellproduct == eventlist[8] ) %>% group_by(sellproduct) %>% summarise(margin=min(margin)) %>% # 상품별 마진은 동일 max()도 동일 mutate(marginTF=ifelse(margin > 0.13, 1, 0)) S2
`summarise()` ungrouping output (override with `.groups` argument)
sellproduct margin marginTF <chr> <dbl> <dbl> 구카카콜 250미리리터(캔) 0.10 0 딸기속우유 310미리리터(팩) 0.11 0 비타528 100미리리터(병) 0.20 1 세계콘 170미리리터 0.15 1 육개장사발탕면 86g(컵) 0.28 1 조르지아오리지널 240미리리터(캔) 0.27 1 카페라떼와일드 200미리리터(컵) 0.23 1 핫개컨디션파워 100미리리터(병) 0.30 1 install.packages('gtools')
package 'gtools' successfully unpacked and MD5 sums checked The downloaded binary packages are in C:\Users\205\AppData\Local\Temp\RtmpwVhmbA\downloaded_packages
library(gtools)
# 경우의 수 만들기 8개중 6개, 중복 가능 com <- combinations(length(eventlist), 6, eventlist, repeats.allowed = T) nrow(com)
1716
head(com, 3) # 판매되는 경우의 수 head(event, 3) # 판매된 데이터
A matrix: 3 × 6 of type chr 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 딸기속우유 310미리리터(팩) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 비타528 100미리리터(병) - $V1
-
- '비타528 100미리리터(병)'
- '세계콘 170미리리터'
- '비타528 100미리리터(병)'
- '카페라떼와일드 200미리리터(컵)'
- '조르지아오리지널 240미리리터(캔)'
- '구카카콜 250미리리터(캔)'
- $V2
-
- '구카카콜 250미리리터(캔)'
- '딸기속우유 310미리리터(팩)'
- '핫개컨디션파워 100미리리터(병)'
- '딸기속우유 310미리리터(팩)'
- '육개장사발탕면 86g(컵)'
- '카페라떼와일드 200미리리터(컵)'
- $V3
-
- '구카카콜 250미리리터(캔)'
- '카페라떼와일드 200미리리터(컵)'
- '딸기속우유 310미리리터(팩)'
- '구카카콜 250미리리터(캔)'
- '비타528 100미리리터(병)'
- '딸기속우유 310미리리터(팩)'
c <- NULL; for(j in 1:length(event)){ # 자료형 리스트 for(i in 1:nrow(com)){ # 자료형 데이터프레임 if(all(event[[j]] %in% com[i, ])){ c <- c(c, i) break() } } } head(c, 10)
- 236
- 193
- 48
- 54
- 158
- 236
- 1088
- 246
- 310
- 491
# 각 eventlist의 marginTF 값 적용 com2 <- com for(i in 1:length(eventlist)){ com2[com == eventlist[i]] <- S2[S2$sellproduct == eventlist[i],]$marginTF } com3 <- apply(com2, 2, as.integer) # 1 : 행(row) 단위 , 2 = 열(컬럼)단위
head(com, 3) head(com[com == eventlist[1]]) head(com2[com == eventlist[1]])
A matrix: 3 × 6 of type chr 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 딸기속우유 310미리리터(팩) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 구카카콜 250미리리터(캔) 비타528 100미리리터(병) - '구카카콜 250미리리터(캔)'
- '구카카콜 250미리리터(캔)'
- '구카카콜 250미리리터(캔)'
- '구카카콜 250미리리터(캔)'
- '구카카콜 250미리리터(캔)'
- '구카카콜 250미리리터(캔)'
- '0'
- '0'
- '0'
- '0'
- '0'
- '0'
# 구하는 확률변수 => 사건마다 마진이 있는 상품의 갯수 X = {0, 1, 2, 3, 4, 5, 6} rv <- rowSums(com3) # 행의 값 더하기
head(rv)
- 0
- 0
- 1
- 1
- 1
- 1
# 확률변수 마다 실제 판매된 제품 넣어서 도수 구하기 rv_table <- table(rv[c]) rv_table
0 1 2 3 4 5 6 2 26 302 840 682 142 6
addmargins(rv_table, margin = 1)
0 1 2 3 4 5 6 Sum 2 26 302 840 682 142 6 2000
# 상대적 판매 비율 => 확률 rv_prop_table <- prop.table(rv_table) rv_prop_table
0 1 2 3 4 5 6 0.001 0.013 0.151 0.420 0.341 0.071 0.003
# 시각화 library(ggplot2) library(ggthemes)
rv_df <- as.data.frame(rv_table)
rv_df
Var1 Freq <fct> <int> 0 2 1 26 2 302 3 840 4 682 5 142 6 6 ggplot(rv_df, aes(x=factor(Var1), y=Freq, fill=Var1))+ geom_bar(stat='identity')
게임데이터 기하분포로 분석하기 - 기하분포
-
기하분포 : K번째 성공할 확률 분포
-
게임밸런스 조절등에 사용
library(data.table)
# 데이터 로드 DF <- fread('r-ggagi-data/example_gamedata.csv', data.table = T) head(DF, 1)
Date2 memberID stage success <chr> <int> <chr> <lgl> 2015-02-15 00:00:00 376966 stage_01 TRUE # memberID 376966 자세히 보기 library(dplyr)
DF2 <- as_tibble(DF) DF2 %>% filter(memberID==376966)
Date2 memberID stage success <chr> <int> <chr> <lgl> 2015-02-15 00:00:00 376966 stage_01 TRUE 2015-02-17 19:55:05 376966 stage_02 FALSE 2015-02-23 16:22:43 376966 stage_02 TRUE 2015-02-27 17:45:02 376966 stage_03 FALSE 2015-03-02 16:35:11 376966 stage_03 FALSE 2015-03-14 01:03:07 376966 stage_03 TRUE 2015-03-15 02:27:46 376966 stage_04 FALSE 2015-03-16 20:56:15 376966 stage_04 FALSE 2015-03-21 20:43:40 376966 stage_04 FALSE 2015-03-27 20:39:32 376966 stage_04 FALSE 2015-04-01 18:05:47 376966 stage_04 FALSE 2015-04-02 11:42:09 376966 stage_04 FALSE 2015-04-06 15:38:38 376966 stage_04 TRUE 2015-04-06 18:40:32 376966 stage_05 FALSE 2015-04-13 20:51:45 376966 stage_05 FALSE 2015-04-14 12:03:54 376966 stage_05 FALSE 2015-04-18 22:34:56 376966 stage_05 FALSE 2015-04-23 14:52:28 376966 stage_05 FALSE 2015-04-29 02:17:15 376966 stage_05 FALSE 2015-05-01 02:44:45 376966 stage_05 FALSE 2015-05-08 18:02:48 376966 stage_05 FALSE 2015-05-11 21:11:03 376966 stage_05 FALSE 2015-05-12 19:17:20 376966 stage_05 FALSE 2015-05-18 17:41:19 376966 stage_05 FALSE 2015-05-23 13:18:11 376966 stage_05 FALSE 2015-05-27 02:47:06 376966 stage_05 FALSE 2015-05-28 17:28:18 376966 stage_05 FALSE 2015-05-29 18:36:09 376966 stage_05 TRUE 2015-06-02 15:58:40 376966 stage_06 FALSE 2015-06-04 11:10:49 376966 stage_06 FALSE ⋮ ⋮ ⋮ ⋮ 2015-08-27 18:17:13 376966 stage_07 FALSE 2015-09-04 15:43:18 376966 stage_07 FALSE 2015-09-06 00:10:19 376966 stage_07 FALSE 2015-09-08 22:36:30 376966 stage_07 FALSE 2015-09-12 15:53:02 376966 stage_07 FALSE 2015-09-22 20:29:17 376966 stage_07 FALSE 2015-10-08 23:02:45 376966 stage_07 FALSE 2015-10-11 20:47:07 376966 stage_07 FALSE 2015-10-11 22:42:49 376966 stage_07 FALSE 2015-10-13 01:53:08 376966 stage_07 FALSE 2015-11-01 18:54:00 376966 stage_07 FALSE 2015-11-02 20:48:09 376966 stage_07 TRUE 2015-11-08 05:26:15 376966 stage_08 FALSE 2015-11-08 22:04:22 376966 stage_08 FALSE 2015-11-10 18:28:01 376966 stage_08 FALSE 2015-11-14 10:30:45 376966 stage_08 FALSE 2015-11-16 01:46:49 376966 stage_08 FALSE 2015-11-20 14:14:02 376966 stage_08 FALSE 2015-11-22 10:46:00 376966 stage_08 FALSE 2015-11-22 21:58:43 376966 stage_08 FALSE 2015-11-23 15:17:33 376966 stage_08 FALSE 2015-11-24 00:46:42 376966 stage_08 FALSE 2015-11-30 08:21:37 376966 stage_08 FALSE 2015-12-01 08:04:59 376966 stage_08 FALSE 2015-12-07 11:41:08 376966 stage_08 FALSE 2015-12-07 20:15:47 376966 stage_08 FALSE 2015-12-11 06:22:44 376966 stage_08 FALSE 2015-12-27 22:17:13 376966 stage_08 FALSE 2015-12-28 15:53:05 376966 stage_08 TRUE 2015-12-31 13:10:58 376966 stage_08 TRUE # memberID 376966 stage 별 성공, 실패 DF2 %>% filter(memberID == 376966) %>% group_by(stage, success) %>% select(success) %>% summarise(count = n())
Adding missing grouping variables: `stage` `summarise()` regrouping output by 'stage' (override with `.groups` argument)
stage success count <chr> <lgl> <int> stage_01 TRUE 1 stage_02 FALSE 1 stage_02 TRUE 1 stage_03 FALSE 2 stage_03 TRUE 1 stage_04 FALSE 6 stage_04 TRUE 1 stage_05 FALSE 14 stage_05 TRUE 1 stage_06 FALSE 13 stage_06 TRUE 3 stage_07 FALSE 16 stage_07 TRUE 1 stage_08 FALSE 16 stage_08 TRUE 2 # 모든 사람들의 성공, 실패 구하기 SF <- DF2 %>% group_by(stage, success) %>% summarise(count = n()) SF
`summarise()` regrouping output by 'stage' (override with `.groups` argument)
A grouped_df: 16 × 3 stage success count <chr> <lgl> <int> stage_01 FALSE 60 stage_01 TRUE 500007 stage_02 FALSE 503610 stage_02 TRUE 500858 stage_03 FALSE 1071222 stage_03 TRUE 521440 stage_04 FALSE 2051331 stage_04 TRUE 721099 stage_05 FALSE 4263240 stage_05 TRUE 897753 stage_06 FALSE 6020643 stage_06 TRUE 1426092 stage_07 FALSE 7945384 stage_07 TRUE 515538 stage_08 FALSE 7999460 stage_08 TRUE 999984 # 시각화 library(ggplot2) library(ggthemes)
ggplot(SF, aes(x=factor(stage), y=count, colour=success, group=success))+ geom_line(size=0.7) + geom_point(size=4) + ggtitle('A사의 B게임 스테이지별 성공여부 그래프') + theme_wsj()
# 성공한 횟수만 따로 저장 SF2 <- SF %>% filter(success == T) SF2
stage success count <chr> <lgl> <int> stage_01 TRUE 500007 stage_02 TRUE 500858 stage_03 TRUE 521440 stage_04 TRUE 721099 stage_05 TRUE 897753 stage_06 TRUE 1426092 stage_07 TRUE 515538 stage_08 TRUE 999984 # 스테이지별 전체 횟수 구하기 SFT <- DF2 %>% group_by(stage) %>% summarise(total =n()) SFT
`summarise()` ungrouping output (override with `.groups` argument)
stage total <chr> <int> stage_01 500067 stage_02 1004468 stage_03 1592662 stage_04 2772430 stage_05 5160993 stage_06 7446735 stage_07 8460922 stage_08 8999444 # 성공 횟수와 전체 횟수를 합치기 SF3 <- cbind(SF2, total = SFT$total) SF3
stage success count total <chr> <lgl> <int> <int> stage_01 TRUE 500007 500067 stage_02 TRUE 500858 1004468 stage_03 TRUE 521440 1592662 stage_04 TRUE 721099 2772430 stage_05 TRUE 897753 5160993 stage_06 TRUE 1426092 7446735 stage_07 TRUE 515538 8460922 stage_08 TRUE 999984 8999444 # 스테이지마다 시도횟수 , 성공횟수 => 성공비율 구하기 SF4 <- SF3 %>% mutate(p = count/total) SF4
stage success count total p <chr> <lgl> <int> <int> <dbl> stage_01 TRUE 500007 500067 0.99988002 stage_02 TRUE 500858 1004468 0.49863012 stage_03 TRUE 521440 1592662 0.32740155 stage_04 TRUE 721099 2772430 0.26009638 stage_05 TRUE 897753 5160993 0.17394966 stage_06 TRUE 1426092 7446735 0.19150567 stage_07 TRUE 515538 8460922 0.06093166 stage_08 TRUE 999984 8999444 0.11111620 베르누이 시행 확인 => 이항분포, 기하분포
-
성공/ 실패
-
스테이지마다 같은 밸런스 => 성공확률 동일
-
누군가 성공이 다른 사람에게 영향 없음 => 독립
-
게임의 특성 상 기하분포 적용
-
n 번째에 스테이지를 성공할 확률은?
-
이번 스테이지는 5번만에 90% 유저가 성공하도록 하기
# stage_03 일 때 기하분포 x <- 1:15 y <- dgeom(x, 0.327) plot(x, y, type='h')
# 기하분포 값을 자세히 round(y, 3)
- 0.22
- 0.148
- 0.1
- 0.067
- 0.045
- 0.03
- 0.02
- 0.014
- 0.009
- 0.006
- 0.004
- 0.003
- 0.002
- 0.001
- 0.001
# 1번 실패 후 성공(첫번째 값) p(1-p)^k-1 0.327*(1-0.327)
0.220071
#누적 기하분포 확률값 pgeom(5, 0.327) # 실실실실성 pgeom(4, 0.327) # 실실실성
0.907084025666639
0.861937631005407
# 6번 실패 하고 성공할 확률 90% 만들기 # 0.9가 될때가 p값 구하는 함수 만들기 findp <- function(n, p){ for(i in 1:99){ a <- pgeom(n, 0.01*i) if(a > p){ print(paste0('n값이 ',n,'일 때')) print(paste0('p값 ',0.01*i,'을 사용하면')) print(paste0('확률 ',a,'이 나옵니다')) break() } } }
# 6번만에 90%가 성공하는 p값 => 게임밸런스를 0.327에서 0.29 findp(6, 0.9)
[1] "n값이 6일 때" [1] "p값 0.29을 사용하면" [1] "확률 0.90904879841609이 나옵니다"
-