Ulangi analisis kohort BI Power menggunakan Python

Selamat siang, para pembaca! Alasan penulisan publikasi ini adalah webinar, yang saya lihat di Youtube. Dia didedikasikan untuk analisis kohort penjualan. Penulis menggunakan platform Power BI Desktop untuk bekerja dengan data. Saya tidak akan memberikan tautan ke video yang ditentukan sehingga artikel ini tidak dianggap sebagai iklan, tetapi dalam perjalanan narasi saya akan mencoba untuk membuat spoiler ke sumber asli untuk lebih menjelaskan logika keputusan saya sendiri. Webinar ini memberi saya ide bahwa akan menarik untuk mengulangi kemungkinan rumus DAX dengan fungsi perpustakaan Pandas.

Dua poin yang ingin saya fokuskan. Pertama, materi ini ditujukan untuk analis pemula yang baru saja mengambil langkah pertama dalam menggunakan bahasa pemrograman Python. Ideal jika pembaca terbiasa dengan platform analitik Power BI BI. Kedua, karena perhitungan DAX berfungsi sebagai sumber inspirasi, saya akan "menyalin" algoritma penulis sejauh mungkin, dan pasti akan ada keberangkatan dari paradigma pemrograman utama.

Dengan pengantar, itu saja. Ayo berangkat!

Kami akan melakukan semua perhitungan di lingkungan JupyterLab. Solusi laptop dapat ditemukan di ( tautan ).

Data dimuat ke Power BI menggunakan alat Power Query (sebenarnya, itu adalah editor visual yang menghasilkan pertanyaan dalam bahasa M). Aturan berikut harus diikuti selama pengembangan: semua preprocessing data harus dilakukan menggunakan Power Query, dan metrik harus dihitung menggunakan Power Pivot. Karena perpustakaan utama kami adalah Panda, kami segera menggunakan kemampuannya.

%%time
#   
path_to_data = "C:/Users/Pavel/Documents/Demo/"
# 
df = pd.read_csv(os.path.join(path_to_data, "ohortAnalysis_2016_2018.csv"), sep=";", parse_dates=["date"], dayfirst=True)

Kami akan menguji baris kode saat runtime untuk menetapkan bagian yang paling memakan waktu di masa depan. Untuk mengatur path lengkap ke file baca, gunakan perpustakaan os. Untuk mempermudah proses pengembangan laptop, Anda bisa melakukannya tanpa itu. Dataset itu sendiri disusun secara acak. Ada 1.048.575 baris dalam file CSV. Membaca data dengan fungsi read_csv () biasanya mudah. Cukup untuk menentukan pemisah kolom dan kolom dengan tanggal, jika ada, dalam array. Jika informasi itu diunggah dengan beberapa "fitur", maka Anda mungkin perlu mengkonfigurasi parameter tambahan, misalnya, menentukan pengodean untuk setiap kolom.

Fungsi head () akan sering digunakan dalam kasus ini untuk memantau secara visual kemajuan transformasi data. Semua kesalahan tidak dapat diputus, tetapi kekurangan yang jelas dapat diperbaiki di tempat.

Setelah memuat data ke dalam model, penulis webinar mengurutkan array data. Ini dilakukan untuk menambah kolom bantu dengan indeks. Dalam kasus kami, kolom ini tidak akan digunakan, tetapi data juga akan disortir agar lebih mudah mengontrol perhitungan bidang dalam tabel.

%%time
#  ,      
df.sort_values(["user_id","date"], inplace = True)

gambar

Pada langkah berikutnya, solusi pada platform Power BI mengusulkan untuk membuat tabel tambahan, data yang darinya akan ditarik ke dalam array utama. Membuat tabel dilakukan menggunakan fungsi SUMMARIZE (). Itu membuat tabel pivot dengan total agregat untuk grup yang dipilih: df_groupby_user = SUMMARIZE(df;df[user_id];"first_date_transaction";MIN(df[date]);"total_amount_user";SUM(df[amount]);"count_transaction_user";COUNT(df[amount]))

Perpustakaan Pandas memiliki fungsi counterpart - the groupby (). Untuk menerapkan groupby () cukup untuk menentukan kerangka data yang diperlukan, kolom yang dapat dikelompokkan, di akhir daftar kolom yang fungsi agregasi akan diterapkan. Hasil yang diperoleh direduksi menjadi format frame data biasa dengan fungsi reset_index (). Sebagai kesimpulan, ganti nama bidang.

%%time
#       user_id. 
df_groupby_user = df.groupby(by = ["user_id"]).agg({"date": "min", "amount": ["sum","count"]})
df_groupby_user.reset_index(inplace = True)
# 
new_columns = ["user_id","first_date_transaction", "total_amount_user","count_transaction_user"]
df_groupby_user.columns = new_columns

Selain metrik "tanggal pembelian pertama", jumlah transaksi per pelanggan dan jumlah total pembelian pelanggan untuk seluruh periode dihitung. Pengukuran tidak menemukan aplikasi mereka di laptop, tetapi kami tidak akan menghapusnya.

Kami kembali ke webinar. Metrik baru "tahun-bulan pembelian pertama" dihitung. Rumus DAX: first_transaction = FORMAT(df_groupby_user[first_date_transaction];"YYYY-MM")

gambar

Python menggunakan sintaks dt.strftime ('% Y-% m'). Anda akan menemukan penjelasan terperinci tentang cara kerjanya di publikasi online tentang bekerja dengan tanggal dan waktu dalam Python. Pada langkah ini, ada hal lain yang penting. Perhatikan waktu operasi.

Sama sekali tidak seperti kinerja panda (24,8 detik). Baris kode lebih lambat dari semua yang sebelumnya.
Daftar ini menjadi kandidat pertama untuk kemungkinan refactoring.

%%time
#  -
df_groupby_user["first_transaction"] = df_groupby_user["first_date_transaction"].dt.strftime('%Y-%m')

Saatnya untuk kembali ke webinar lagi. Ada gabungan tabel dengan bidang kunci. Kemudian bidang yang diperlukan ditarik ke tabel utama menggunakan fungsi RELATED (). Panda tidak memiliki fitur ini. Tetapi ada gabungan (), gabung (), concat (). Dalam hal ini, yang terbaik adalah menerapkan opsi pertama.

%%time
# 
df_final = pd.merge(df, df_groupby_user, how = "left", on = "user_id")

Setelah data dengan tanggal transaksi pertama jatuh ke tabel utama, Anda dapat menghitung delta. Kami menggunakan konstruk terapan (lambda x: ...) untuk menunjukkan dengan jelas seberapa intensif sumber daya proses ini (39,7 detik). Berikut adalah kandidat lain untuk penulisan ulang kode.

%%time
#   "    "
df_final["delta_days"] = df_final["date"] - df_final["first_date_transaction"]
df_final["delta_days"] = df_final["delta_days"].apply(lambda x: x.days)

Tabel utama sudah memiliki delta per hari, sehingga Anda dapat membagi data kolom menjadi kohort. Prinsip: 0 (yaitu, penjualan pertama ke pelanggan) - kohort 0; nilai lebih besar dari 0, tetapi kurang dari atau sama dengan 30 adalah 30; nilai lebih besar dari 30, tetapi kurang dari atau sama dengan 90 adalah 90, dll. Untuk tujuan ini, di DAX, Anda dapat menggunakan fungsi CEILING (). Ini membulatkan angka hingga bilangan bulat terdekat, kelipatan dari nilai dari parameter kedua.

gambar

Dalam Python, saya tidak menemukan fungsi matematika yang serupa, meskipun saya berencana untuk menemukannya di modul matematika (mungkin saya mencari dengan buruk). Karena itu, saya harus berkeliling dan menerapkan fungsi cut (). Setelah menyebarkan data ke dalam kohort, NaN dipetakan ke nilai numerik 0. Kami tidak dapat menyelesaikan masalah ini dengan menggunakan fungsi fillna (), karena kami berhadapan dengan data kategorikal. Pertama, Anda perlu menambahkan nilai baru ke kategori. Di akhir daftar kode ini, ubah tipe data menjadi int. Ini dilakukan agar di masa mendatang, saat membuat tabel pivot menggunakan bingkai data, kohort baru tidak muncul di akhir serangkaian nilai.

%%time
#  . 
cut_labels_days = [x for x in range (30, 1230, 30)]
cut_bins_days = [x for x in range (0, 1230, 30)]
df_final["cohort_days"] = pd.cut(df_final["delta_days"], bins = cut_bins_days, labels=cut_labels_days, right = True)
%%time
#     .   fillna   !
df_final["cohort_days"] = df_final["cohort_days"].cat.add_categories([0])
df_final["cohort_days"].fillna(0, inplace = True)
%%time
#     .   fillna   !
df_final["cohort_days"] = df_final["cohort_days"].cat.add_categories([0])
df_final["cohort_days"].fillna(0, inplace = True)
#    .    ,  "0"        ,     
#    .
df_final["cohort_days"] = df_final["cohort_days"].astype(int)

Menggunakan fungsi pivot_table (), kita mendapatkan tabel pivot yang diinginkan. Kami mendapatkan banyak kohort, sehingga hasilnya tidak dapat sepenuhnya ditampilkan di layar. Untuk menghindari hal ini, ketika memecahkan kasus nyata, Anda dapat mengambil interval waktu yang lebih singkat untuk analisis atau memperbesar rentang nilai kohort itu sendiri.

%%time
#  
df_pivot_table = pd.pivot_table(df_final, values=["amount"], index=["first_transaction"], columns=["cohort_days"], aggfunc=np.sum, fill_value = 0)

gambar

Di Power BI, Anda perlu menggunakan alat Matrix untuk membangun visualisasi seperti itu.

gambar

Tahap selanjutnya adalah merencanakan. Nuansa situasi adalah bahwa kita membutuhkan jumlah tersebut secara akrual. Di Power BI, cukup pilih item menu 'Tindakan cepat' yang diperlukan dan rumus DAX yang diperlukan akan dihasilkan secara otomatis. Dengan perpustakaan Pandas, situasinya sedikit lebih rumit. Kami menggandakan secara berurutan kelompok bingkai data yang ada dan menerapkan fungsi cumsum (). Karena hasilnya masih akan digunakan, kami akan membuat salinan bingkai data untuk membuat grafik. Akumulasi nilai penjualan cukup besar, jadi kami membagi nilainya dengan 1.000.000 dan membulatkan hasilnya menjadi dua digit setelah titik desimal.

%%time
#     amount
df_pivot_table_cumsum = df_final.groupby(by = ["first_transaction","cohort_days"]).agg({"amount": ["sum"]}).groupby(level=0).cumsum().reset_index()
df_pivot_table_cumsum.columns = ["first_transaction","cohort_days","cumsum_amount"]
%%time
#     
df_pivot_table_cumsum_chart = copy.deepcopy(df_pivot_table_cumsum)
#     ,       Y.
df_pivot_table_cumsum_chart["cumsum_amount"]=round(df_pivot_table_cumsum_chart["cumsum_amount"]/1000000, 2)

Kami menggunakan kemampuan perpustakaan untuk membangun grafik. Diagram dibuat hanya dalam satu baris kode, tetapi hasilnya tidak mengesankan. Grafik ini jelas kehilangan visualisasi pada platform BI mana pun. Anda dapat menghubungkan perpustakaan Plotly dan menyulap dengan add-on, tetapi ini adalah biaya tenaga kerja yang sama sekali berbeda dibandingkan dengan pendekatan yang ditunjukkan dalam video.

%%time
df_pivot_table_cumsum_chart.pivot(index="cohort_days", columns="first_transaction", values="cumsum_amount").plot(figsize = (15,11))

gambar

Mari kita membuat kesimpulan singkat.

Dalam hal perhitungan, pustaka Pandas mungkin menggantikan Power Pivot (DAX).

Kelayakan penggantian semacam itu tetap berada di luar percakapan.

DAX, seperti fungsi pustaka Python, melakukan pekerjaan dengan baik dalam melakukan operasi pada seluruh bidang tabel.

Dalam hal kecepatan, kesederhanaan dan kemudahan desain visualisasi, Power BI lebih unggul dari Panda. Menurut pendapat saya, grafik built-in (serta yang dibuat menggunakan matplotlib, perpustakaan seaborn) sesuai untuk digunakan dalam dua kasus: analisis ekspres sejumlah data untuk outlier, minima / maxima lokal, atau menyiapkan slide untuk presentasi. Pengembangan panel kontrol grafis sebaiknya diserahkan kepada solusi BI.

Itu saja. Semua kesehatan, keberuntungan dan kesuksesan profesional!

All Articles