Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
『改訂新版前処理大全』の話と Apache Parquet の話 #TokyoR
Search
bob3bob3
June 08, 2024
Programming
0
600
『改訂新版前処理大全』の話と Apache Parquet の話 #TokyoR
『改訂新版前処理大全』のR言語版サンプルコードとApache parquetによる高速化の話。 #TokyoR
bob3bob3
June 08, 2024
Tweet
Share
More Decks by bob3bob3
See All by bob3bob3
RでPSM分析
bob3bob3
0
150
Rでコンジョイント分析 2024年版
bob3bob3
0
590
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
450
『データ可視化学入門』をPythonからRに翻訳した話(増強版)
bob3bob3
0
400
『データ可視化学入門』を PythonからRに翻訳した話
bob3bob3
1
480
qeMLパッケージの紹介
bob3bob3
0
1.5k
「国と音楽」 ~spotifyrを用いて~ #muana
bob3bob3
2
450
パーマーステーションのペンギンたち#3 探索的データ分析(EDA)編
bob3bob3
1
570
Redditで遊ぼう #TokyoR 106
bob3bob3
0
630
Other Decks in Programming
See All in Programming
組織に自動テストを書く文化を根付かせる戦略(2024秋版) / Building Automated Test Culture 2024 Autumn Edition
twada
PRO
8
3.3k
2024-10-01 dev2next - Observability for Modern JVM Applications
jonatan_ivanov
1
140
App Store Connect APIで 作業時間を増やそう
mot_techtalk
3
130
今日で分かる!カスタムコップの作り方
krpk1900
2
140
文化が生産性を作る
jimpei
3
610
急速に利用拡大を続ける飲食店向けサービスで 店内端末同士のローカル通信を追加設定なしで実現した話
whatasoda
0
140
MLOps in Mercari Group’s Trust and Safety ML Team
cjhj
1
130
自分だけの世界を創るクリエイティブコーディング / Creative Coding: Creating Your Own World
chobishiba
2
2k
How to debug Xdebug... or any other weird bug in PHP
dunglas
2
1.5k
CSC509 Lecture 07
javiergs
PRO
0
130
レイトレ合宿10 レンダラー紹介 / Renderer Introduction, Ray Tracing Camp 10
shocker_0x15
0
630
Serverless renderování Webových komponent
rarous
PRO
0
130
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
43
6.5k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
22k
A Tale of Four Properties
chriscoyier
156
22k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.8k
How to Ace a Technical Interview
jacobian
275
23k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
A better future with KSS
kneath
237
17k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
41
9.2k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
26
2k
For a Future-Friendly Web
brad_frost
174
9.4k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
355
29k
Transcript
『改訂新版前処理大全』の話と Apache Parquet の話 Tokyo.R #113 2024/06/08 @bob3bob3
『改訂新版前処理大全』 • 2018年に発売されてデータ分析界隈で 大きな話題となった『前処理大全』のアッ プデート版。 • データサイエンスに取り組む上で欠かせ ない前処理の効率的な処理方法を網羅 的に習得できる構成。 •
サンプルデータがApache Parquet形式 で提供されているのも特徴。 • 旧版ではR、Python、SQLを用いた実装 方法を紹介していたが、改訂新版では BigQuery準拠のSQL、最新バージョンの Pandas、Rの代わりに高速なPolarsに変 更しました。
『改訂新版前処理大全』 Rの代わりに高 速なPolarsに変 更しました。
というわけで、Rで『改訂新版前処理大全』 のサンプルコードを書いています。
例1
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 reservation(200万件、11列) hotel(5千件、39列)
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 reservation(200万件、11列) hotel(5千件、39列)
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 # Not Awesome reservation |> inner_join(hotel, by = "hotel_id")
|> dplyr::filter(hotel_type == "ビジネスホテル" & people_num == 1) # Awesome reservation |> dplyr::filter(people_num == 1) |> inner_join( hotel |> dplyr::filter(hotel_type == "ビジネスホテル") |> select(hotel_id), by = "hotel_id" )
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 # Not Awesome reservation |> inner_join(hotel, by = "hotel_id")
|> dplyr::filter(hotel_type == "ビジネスホテル" & people_num == 1) reservationとhotelをすべて結合してから条件指定によってデータの抽出を行っている。 また必要な列に絞らずhotelマスターのすべての列を出力している。
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 # Awesome reservation |> dplyr::filter(people_num == 1) |> inner_join(
hotel |> dplyr::filter(hotel_type == "ビジネスホテル") |> select(hotel_id), by = "hotel_id" ) reservationとhotelそれぞれを必要な行と列に絞ってからjoinしている。
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 Awesomeなコードの方が中央値で6倍 ぐらい速い。 joinする前にそれぞれのデータをできる 限り小さくしておくこと!
Apache Parquet による前処理の高速化
Apache Parquet による前処理の高速化 • Apache Parquet はオープンソースの列指向データファイルフォーマットで、効率的 なデータの保存と検索のために設計されています。 • 複雑なデータを一括処理するための高性能な圧縮とエンコード方式を提供し、多く
のプログラミング言語と分析ツールでサポートされています。 • Rではarrowパッケージで Apache Parquet を扱うことができます。
Apache Parquet による前処理の高速化 # データフレームとして reservation_df <- read_parquet( "https://github.com/ghmagazine/awesomebook_v2/raw/main/data/reservation.parquet" )
# Arrow Table として reservation_at <- read_parquet( "https://github.com/ghmagazine/awesomebook_v2/raw/main/data/reservation.parquet", as_data_frame = FALSE ) parquet形式のデータをarrowパッケージのread_parquet()関数で読み込む。 デフォルトではデータフレームとして読み込まれるが、引数に as_data_frame = FALSE を付けるとArrow Tableとして読み込まれる。
Apache Parquet による前処理の高速化 # データフレームの処理 reservation_df |> dplyr::filter(status != "canceled")
|> summarise(reservation_cnt = n(), .by = c(hotel_id, customer_id)) # Arrow Table の処理 reservation_at |> dplyr::filter(status != "canceled") |> summarise(reservation_cnt = n(), .by = c(hotel_id, customer_id)) |> collect() #この処理が加わっただけ ホテルごと顧客ごとの予約数の集計処理。 Arrow Table も tidyverse で処理できるが、最後に collect()を実行することで結果が得られる。
Apache Parquet による前処理の高速化 中央値で約35倍の速さ! Tidyverseのすべての機能が ApacheParquetで使えるわけではない ようですが、積極的に使っていきましょ う! eitsupiさんの以前の発表やuriboさんの 資料もご参考に。
Apache Parquet の資料 @eitsupi さん @uribo さん https://eitsupi.github.io/tokyorslide/tokyor_97 https://uribo.quarto.pub/hello-r-arrow/
例2
例2)予約履歴データに対象キャンペーン情報を付与 reservation(200万件、11列) campaign(30件、3列)
例2)予約履歴データに対象キャンペーン情報を付与 reservation(200万件、11列) campaign(30件、3列)
例2)予約履歴データに対象キャンペーン情報を付与 # Not Awesome reservation |> cross_join(campaign) |> dplyr::filter(reserved_at >=
starts_at & reserved_at <= ends_at) |> select(!c(starts_at, ends_at)) # Awesome campaign_expanded <- campaign |> rowwise() |> mutate(reserve_date = list(seq(date(starts_at), date(ends_at), by="day"))) |> unnest(reserve_date) reservation |> mutate(reserve_date = date(reserved_at)) |> left_join(campaign_expanded, by = "reserve_date",relationship = "many-to-many") |> select(!reserve_date)
# Not Awesome reservation |> cross_join(campaign) |> dplyr::filter(reserved_at >= starts_at
& reserved_at <= ends_at) |> select(!c(starts_at, ends_at)) 例2)予約履歴データに対象キャンペーン情報を付与 予約履歴にキャンペーンマスターをクロス結合、その後キャンペーン期間の行のみを抽 出。最後に不要な列を削除。
# Awesome campaign_expanded <- campaign |> rowwise() |> mutate(reserve_date =
list(seq(date(starts_at), date(ends_at), by="day"))) |> unnest(reserve_date) reservation |> mutate(reserve_date = date(reserved_at)) |> left_join(campaign_expanded, by = "reserve_date",relationship = "many-to-many") |> select(!reserve_date) 例2)予約履歴データに対象キャンペーン情報を付与 キャンペーンマスターにキャンペーン期間のすべての日付の列を追加。 日付をキーに予約履歴にキャンペーンマスターを結合。
例2)予約履歴データに対象キャンペーン情報を付与 Awesomeなコードの方がおよそ6倍速い!
全編はこちらで順次公開予定 https://morimotoosamu.github.io/awesomebook_v2/
Enjoy!