Analisis produk dalam praktik dengan R

Bermasalah

Meta manajemen produk modern adalah tentang manajemen berbasis data.





Setiap orang menginginkan pendekatan analitis dan kemampuan untuk membuat keputusan tentang tumpukan data produk yang tersedia. Namun pada kenyataannya, ada kekurangan informasi tentang bagaimana tepatnya melakukan ini. Alat apa yang digunakan, bagaimana membuat keputusan, dan bagaimana menjelajahi data. Saya ingin membagikan secara tepat aspek praktis dari masalah ini dalam format satu kasus.





Bagian pengantar

Awal tahun 2020, Anda adalah manajer produk biasa yang ditawari untuk mengembangkan produk pinjaman di negara lain. Tawaran sudah diterima, dokumen sudah selesai, saatnya mulai bekerja. 





Hal pertama yang terlintas dalam pikiran adalah melihat apa yang terjadi dengan ekonomi produk. Dan bagaimana produk tersebut berperilaku secara umum.





Setelah beberapa hari, pertemuan di mana Anda diminta untuk menjawab beberapa pertanyaan:





  1. Sekarang kita membayar untuk menarik klien 695494. Berapa biaya yang bisa diterima untuk menarik kita? Apakah masuk akal untuk menaikkan biaya per pelanggan untuk mendapatkan lebih banyak volume?





  2. Seberapa sehat ekonomi portofolio dan dinamika apa yang ada di sini dan saat ini?





  3. Kami baru-baru ini mengubah pendekatan terhadap ukuran masalah dan mulai mengeluarkan cek yang lebih kecil pada pinjaman pertama. Bagaimana hal ini memengaruhi produk?





Secara umum, pertanyaan jelas yang harus dapat dijawab oleh setiap pemilik produk. 





. , , : LTV, CAC . , , , .





. ( ), ( ) ( ).





, , . .





- , .





. , , . .





, , : R ,Rstudio,dbeaver( ). , .





, .   select * from transactions t .





Rows: 2,226,532
Columns: 10
$ borrower_id          2, 2, 2, 6, 6, 12, 12, 12, 12, 16, 20, 20, 20, 20, 22, 23, 23, 33, 33, 39, 39, 36, 36
$ con_id               1, 1, 1, 2, 2, 4, 4, 4, 4, 5, 7, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13
$ disbursement_date    2017-11-23, 2017-11-23, 2017-11-23, 2017-11-24, 2017-11-24, 2017-11-27, 2017-11-27, …
$ prolongations_count  1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
$ loan_type            "pdl", "pdl", "pdl", "pdl", "pdl", "pdl", "pdl", "pdl", "pdl", "pdl", "pdl", "pdl", "…
$ date                 2017-12-15, 2017-11-23, 2017-12-06, 2017-11-24, 2017-12-25, 2017-12-29, 2017-11-27, …
$ type                 "Payments::Transaction::ContractAddTransaction", "Payments::Transaction::DisburseTran…
$ amount               250000, 1000000, 1200000, 2500000, 3500000, 1040000, 1500000, 10000, 1470000, 1500000
$ id                   325, 2, 127, 5, 587, 557500, 557499, 557504, 557507, 17, 182865, 182874, 182869, 1828
$ deleted_at           NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
      
      



. ( , - ).





, , . (disbursment_date). (prolongations_count) - . . "" .





- (ContractAdd- , DisburseTransaction - ).





. ( ): , -> -> -> .





: .





, .





( , 0.00003 ).





  • : , , , , .





  • R, , 2 . data table. tidyverse( )





.





. ( z_type am):





lk %>% data.table()->lk1 #    data table

lk1[,':='
(z_type=z_type<-fifelse(
#     -     
 type=='Payments::Transaction::ContractAddTransaction','add','disb'),
am=amount*fifelse(z_type=='add',1,-1))][1:20,c(-1,-11,-8,-6)] #  
lk1[disbursement_date<'2020-01-01' & date<='2020-03-01',c(-1,-11,-8,-6)]->lk1
glimpse(lk1) #   
      
      



$ borrower_id          2, 2, 2, 6, 6, 12, 12, 12, 12, 16, 20, 20, 20, 20, 22, 23, 23, 33, 33, 39, 39, 36, 36$ con_id               1, 1, 1, 2, 2, 4, 4, 4, 4, 5, 7, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13$ disbursement_date    2017-11-23, 2017-11-23, 2017-11-23, 2017-11-24, 2017-11-24, 2017-11-27, 2017-11-27, …
$ prolongations_count  1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1$ date                 2017-12-15, 2017-11-23, 2017-12-06, 2017-11-24, 2017-12-25, 2017-12-29, 2017-11-27, …
$ amount               250000, 1000000, 1200000, 2500000, 3500000, 1040000, 1500000, 10000, 1470000, 1500000$ id                   325, 2, 127, 5, 587, 557500, 557499, 557504, 557507, 17, 182865, 182874, 182869, 1828$ z_type               "add", "disb", "add", "disb", "add", "add", "disb", "add", "add", "disb", "disb", "ad…
$ am                   250000, -1000000, 1200000, -2500000, 3500000, 1040000, -1500000, 10000, 1470000, -150…
      
      



, .





. , :





lk1[,.(total_in_mln=sum(am*for_ex)/1e6),.(z_type)]
      
      



total_in_mln





add





58.33176





disb





-45.49114





: (add) (disb). .





, :





lk1[!is.na(disbursement_date)&z_type=='disb',
.(sum=sum(am*for_ex*-1,na.rm = T)/1e6),
.(date=floor_date(disbursement_date,'month',))][,
ggplot(.SD,aes(date,sum,label=round(sum,2)))+
geom_col(fill=polar_night[2])+ff+tt+
  geom_text(aes(y=sum+0.1),col=aurora[1])+
  labs(x=' ',y='   ',
  title='   ')]
      
      



, . .





, .





- , . 





. , ( ) . 





, , :





lk1[][,':='( min_date=min(disbursement_date)),.(borrower_id)][,#     
c("gen",'dif'):=.(floor_date(min_date,'1 month'),as.numeric(date-min_date))][, #               
n:=uniqueN(borrower_id),][, #  
  .(sum=sum(am*for_ex),n=unique(n)),
  .(dif)
][order(dif)][,":="(bal=bal<-sum/n,cum=cumsum(bal))][,
    ggplot(.SD,aes(dif,cum))+ # 
   geom_line()+
   tt+ff+
        labs(x='  ',y='  USD',col='',
        title='LTV      ')+
   scale_y_continuous(breaks = seq(-200,200,20),
   labels =paste0('$',seq(-200,200,20),'k' ))+
   scale_x_continuous(breaks = seq(0,1000,20))  ]
      
      



LTV c . .





, , , . , , .





, 24 . ( ):





lk1[,':='( min_date=min(disbursement_date)),.(borrower_id)][,
c("gen",'dif'):=.(floor_date(min_date,'1 month'),as.numeric(date-min_date))][,
n:=uniqueN(borrower_id),.(gen)][,
  .(sum=sum(am*0.00003),n=unique(n)),
  .(gen,dif)#     
][order(gen,dif)][,
":="(bal=bal<-sum/n)][,':='(cum=cumsum(bal),m_dif=max(dif)),
.(gen)][dif<=m_dif-30 & gen %between% c('2018-01-01','2021-03-31')][,
 ggplot(.SD,aes(dif,cum,col=factor(gen)))+
 geom_line()+
 facet_wrap(~factor(year(gen),levels = c(2019,2018)),nrow=2)+tt+ff+
 labs(x='  ',y='  USD',col='',
 title = 'LTV      ')+
 scale_y_continuous(breaks = seq(-200,200,20),
 labels =paste0('$',seq(-200,200,20),'k' ))+
 scale_x_continuous(breaks = seq(0,1000,20))+
 geom_hline(yintercept = 695494*for_ex,color='red',size=1)+
 geom_hline(yintercept = 0,color='dark red',linetype='dashed')+
 geom_text(inherit.aes = F,aes(x=as.Date(600),
 y=695494*for_ex+3,group=1),label='   = $20.86',
 col='red',size=6)+tt+ff+
 theme(legend.text = element_text(size=20),
       legend.title = element_text(size=25))+
  guides(colour = guide_legend(override.aes = list(size=10)))]

      
      



- ( ), :





  1. , - .





  2. , .





  3. 0, .





  4. , , .









  1. . , (150 180).





  2. . , 2018 , . “” 10-40 . 2019 : .





  3. 40 60 . . , , 120-150 3





  4. 90 , .





,





1. 695494. ? , ?





- , - . - 40-60 . $20.8 (695494* 0.00003)





- , . - . 





- - . 





2. ?





, . - 100+ . 





.





3. . ? 





- . - .





Tugas manajer produk adalah membuat keputusan. 2,2 juta baris berbicara tentang apa yang terjadi. Analisis semacam itu memakan waktu dari 30 menit hingga beberapa jam, tergantung pada pengetahuan tentang area subjek dan kotoran dalam data. Analisis ini hanya membutuhkan data mentah dan perangkat lunak sumber terbuka.





Beberapa lusin baris kode, sedikit akal sehat dan keekonomian produk jelas, dihitung dan kesimpulan ditarik.





Beberapa penilaian dan kesimpulan yang lebih penting dengan mudah dikumpulkan dari data yang sama, tetapi tentang mereka dalam waktu yang bersamaan.








All Articles