tag:crieit.net,2005:https://crieit.net/tags/%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9/feed 「データサイエンス」の記事 - Crieit Crieitでタグ「データサイエンス」に投稿された最近の記事 2023-06-03T18:02:29+09:00 https://crieit.net/tags/%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9/feed tag:crieit.net,2005:PublicArticle/18443 2023-06-03T18:02:29+09:00 2023-06-03T18:02:29+09:00 https://crieit.net/posts/ruby-pycall-datscience-100knocks Ruby + PyCall でデータサイエンス100本ノック(構造化データ加工編)をやってみた <p>まだ誰もやってなさそうだったのでやってみました。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/sonota88/100knocks-preprocess/tree/ruby-pycall">github.com/sonota88/100knocks-preprocess/tree/ruby-pycall</a></p> <p>オリジナルのリポジトリ <a target="_blank" rel="nofollow noopener" href="https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess">The-Japan-DataScientist-Society/100knocks-preprocess</a> をフォークして <code>ruby-pycall</code> ブランチを追加しています。</p> <p>GitHub でノートブックを閲覧したい場合はこちら:<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/sonota88/100knocks-preprocess/blob/ruby-pycall/docker/work/answer/ans_preprocess_knock_Ruby_PyCall.ipynb">https://github.com/sonota88/100knocks-preprocess/blob/ruby-pycall/docker/work/answer/ans_preprocess_knock_Ruby_PyCall.ipynb</a></p> <hr /> <p>解答例が複数ある場合など一部TODOにしている箇所がありますが、100問全部動かすことができました(私は Python版からコピペして書き換えただけなので、これは PyCall.rb がすごい! という話です)。</p> <p>一応筆者について書いておくと、データサイエンスに関しては入門者レベルです。データフレームという概念は一応知ってるとか、Jupyter Notebook を触ったことはあるが日常的に使っているわけではない、という感じの人です。Python, Pandas, NumPy のいずれにも詳しくありません。</p> <p>:::note</p> <p>ちなみに Ruby + RedAmber 版は heronshoes さんが作成中とのことです。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/heronshoes/items/962e312146dac8673b49">RedAmberで書いたらこうなる - pandasのquery - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://speakerdeck.com/heronshoes/the-adventure-of-redamber-a-data-frame-library-in-ruby?slide=43">The Adventure of RedAmber - A data frame library in Ruby - Speaker Deck</a> <ul> <li>RubyKaigi 2023</li> </ul></li> </ul> <p>:::</p> <h1 id="動かし方"><a href="#%E5%8B%95%E3%81%8B%E3%81%97%E6%96%B9">動かし方</a></h1> <p>リポジトリとブランチが違う以外はオリジナルの<a target="_blank" rel="nofollow noopener" href="https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess">データサイエンス100本ノック(構造化データ加工編)</a>の README で書かれている手順と同じです。</p> <pre><code class="sh">git clone --branch ruby-pycall https://github.com/sonota88/100knocks-preprocess.git cd 100knocks-preprocess docker compose up -d --build --wait </code></pre> <p><code>docker compose up</code> が完了するのを待ってからブラウザで <a target="_blank" rel="nofollow noopener" href="http://127.0.0.1:8888/">http://127.0.0.1:8888/</a> を開きます。</p> <p>左のメニューから <code>/work/answer/ans_preprocess_knock_Ruby_PyCall.ipynb</code> を選択してノートブックを開きます。</p> <p><a href="https://crieit.now.sh/upload_images/36b6f940e2f434c979b5ada813c8206f647b00eb4aee3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/36b6f940e2f434c979b5ada813c8206f647b00eb4aee3.png?mw=700" alt="image" /></a></p> <p>左側に Table of Contents を表示させておくと各問題に移動したいときに便利です。</p> <p><a href="https://crieit.now.sh/upload_images/7a727bbde73b2e30d4a57505e10347d2647b00fda1de4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7a727bbde73b2e30d4a57505e10347d2647b00fda1de4.png?mw=700" alt="image" /></a></p> <h1 id="メモ"><a href="#%E3%83%A1%E3%83%A2">メモ</a></h1> <h2 id="Ruby 向けのカスタマイズ"><a href="#Ruby+%E5%90%91%E3%81%91%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA">Ruby 向けのカスタマイズ</a></h2> <ul> <li>Python 版の Dockerfile をコピー+修正して Ruby 用の Dockerfile-ruby を用意する</li> <li>docker-compose.yml を修正して Dockerfile-ruby に切り替える</li> </ul> <p>やったのはこれだけですね。ここはほとんど手間がかかっていません。</p> <p>RubyData プロジェクトでメンテナンスされている <code>rubydata/datascience-notebook</code> という Docker イメージがありまして、</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/RubyData/docker-stacks">github.com/RubyData/docker-stacks</a></p> <p>これをベースイメージとして使うのがポイントです。自前でカスタマイズする必要がほとんどなく、たいへん助かりました。このイメージは便利なのでどんどん使わせてもらいましょう!(← この記事で一番強調したいのはここ)</p> <p>Python版の Dockerfile との差分はこんな感じ。</p> <pre><code class="diff">--- Dockerfile 2023-05-06 12:13:18.226946937 +0900 +++ Dockerfile-ruby 2023-05-06 12:13:18.242946463 +0900 @@ -1,5 +1,6 @@ -FROM jupyter/datascience-notebook:python-3.10.8 -#FROM jupyter/datascience-notebook:d53a302fbcd0 +# 2023-02-03 +FROM rubydata/datascience-notebook:24a7f04dfc46 + USER root ENV DEBCONF_NOWARNINGS yes @@ -29,4 +30,6 @@ && Rscript -e 'pak::repo_add(CRAN = "RSPM@2022-12-16"); pak::pak(c("DBI", "RPostgreSQL", "themis"))' \ && rm -rf Pipfile* /tmp/* /var/tmp/* +RUN pip install tabulate + HEALTHCHECK --interval=5s --retries=20 CMD ["curl", "-s", "-S", "-o", "/dev/null", "http://localhost:8888"] </code></pre> <p>ほぼベースイメージの差し替えだけで済んでいます。</p> <h2 id="DataFrame#query"><a href="#DataFrame%23query">DataFrame#query</a></h2> <p>Python版の解答例では DataFrame#query を使っている箇所がいくつかあるのですが、pandas.rb ではエラーになります(2023-05-13 時点)。そこで、次のように DataFrame#[] を使う方法で愚直に書き換えました。</p> <pre><code class="ruby"># P-004 Python版の解答例1 # df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \ # .query('customer_id == &quot;CS018205000001&quot; & amount &gt;= 1000') df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \ [(df_receipt['customer_id'] == "CS018205000001") & (df_receipt['amount'] >= 1000)] </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sonota88/items/7c81beca2c86fdf21556">PyCall.rb + Pandas: DataFrame#query の代わりにS式っぽく書けないか試してみた</a> という別記事で書いたように他の対策もありますが、今回は素朴に DataFrame#[] を使うだけにしました。なるべく素のまま書く方針です。</p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/mrkn/pycall.rb">mrkn/pycall.rb: Calling Python functions from the Ruby language</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://codezine.jp/article/detail/10251">Ruby-Pythonブリッジライブラリ「PyCall」を使ってRubyでデータ分析をしよう! (1/3)|CodeZine(コードジン)</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/RubyData/workshop-materials/blob/master/iruby_guides/users_guide.md">workshop-materials/users_guide.md at master · RubyData/workshop-materials · GitHub</a> <ul> <li>IRuby Notebook 入門用テキスト</li> </ul></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/stat/items/a383451e7f824e4c9627">PyCall Ruby版 Tips - Qiita</a></li> </ul> <h1 id="この記事を読んだ人は(ひょっとしたら)こちらも読んでいます"><a href="#%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A0%E4%BA%BA%E3%81%AF%EF%BC%88%E3%81%B2%E3%82%87%E3%81%A3%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%EF%BC%89%E3%81%93%E3%81%A1%E3%82%89%E3%82%82%E8%AA%AD%E3%82%93%E3%81%A7%E3%81%84%E3%81%BE%E3%81%99">この記事を読んだ人は(ひょっとしたら)こちらも読んでいます</a></h1> <ul> <li><p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sonota88/items/aeacaf0ec7957715cdff">Ruby+PyCall.rbでLibreOffice Calcのオートメーションをやってみた(Ubuntu 18.04)</a></p></li> <li><p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sonota88/items/b586e96f7805a5695a34">Galaaz を触ってみた(TruffleRuby + ggplot2 で散布図を描いてみた)</a></p></li> </ul> sonota486