5
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TitanicでPolarsに入門する

Last updated at Posted at 2024-08-22

この資料について

  • Polars Data Crunch #3 でのLT用の、Polars入門者向けの資料です
  • Kaggleでよく使われる、タイタニックのデータを題材にします
  • 内容自体は他の色んな方が書いていることのn番煎じですが、動画はまだないはず…!
  • 資料の立ち位置:網羅性✗、正確性✗、ひと通り触れる○
  • コード:Kaggle notebookGoogle colabGithub gist

タイタニックについて

image.png
https://www.behance.net/gallery/74714377/Titanic-Infographic/modules/434407837


タイタニックデータについて

  • Kaggleの入門用として、「誰が生き残ったか」を予測する課題がある
  • データ分析を始めて最初に触るデータがこれなケースも少なくない(はず)
  • 今回使うカラム
    • Survived: 生き残ったか
    • Sex: 性別
    • Pclass: 旅客クラス(1等、2等、3等)

polarsとは?

  • 早い、お手軽、書きやすいの三拍子が揃った話題のライブラリ
  • 詳しくはこちらを!

  • 本資料では、polarsを使った一番ベーシックな部分の処理を流れに沿って説明

データの読み込み

import polars as pl
df = pl.read_csv('https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')

データの表示

display(df)
# print(df)

image.png

  • 行数、列数も出力してくれる
  • 列ごとに型が決まってる

image.png


列を取り出してみよう

  • select で列を取り出すことができる
  • 列を指定するには、pl.col を使う2
  • 複数指定することで、複数列取り出すことも可能
df.select(pl.col("Sex"))

image.pngimage.png


条件に当てはまる行を取り出してみよう

  • filter でレコードの抽出ができる
  • ここでは、Sex という列が "male" であるようなレコードを取り出す
df.filter(pl.col("Sex") == "male")

image.pngimage.png


エクスプレッション

  • 先ほどの pl.col("Sex") == "male" の部分を、expressionと言う
  • エクスプレッションは、列に対して何かしらの操作を加えたものを返す、いわば関数のようなもの
  • 実は pl.Expr はどこでも使える → 先ほどと全く同じものを select で使ってみよう
df.select(pl.col("Sex") == "male")

image.png

  • → やや見にくいので、元のカラムと一緒に出力する

別のカラム名を付けよう

  • alias をExpressionに続けると、列名を変更できる3
  • ※同じ名前の列を複数持つことはできない
df.select(pl.col("Sex"), (pl.col("Sex") == "male").alias("is_male"))

image.png


応用例:男性の生存率を求めてみよう

  • filterselect を組み合わせて求められる
  • Polarsでは . を付けて、処理を続けて書くことが出来る
    • 上から順に処理される
  • 書き方のお作法としてよく見るものは以下2つ

image.pngimage.png

  • これが長く続くと凄く複雑なことをしているように見えるが、シンプルなパーツを組み合わせてるだけで、いわばレゴみたいなもの
  • mean() の振る舞いとして、先ほどと違い出力が1行に集約されていることが分かる

グループごとの集約

  • わざわざ男女それぞれについて行を抽出してそこから平均を算出しなくても、グループごとの集約が可能
  • Pclass ごとの生存確率を求めてみる
  • group_by("...").agg() を使う 4
df.group_by('Pclass').agg(
    pl.col("Survived").mean()
)

image.pngimage.png


集約を列として追加しよう

  • データフレームに列を追加する場合、select ではなく with_columns を用いる
    • 追加する列は、Expressionを用いて表現する
  • Pclass ごとの生存確率を追加してみよう
  • mean をグループごとに行うためには、over でグループを指定する。この際、先ほどと違って行数が減ることはないことに注意!
df.with_columns(
    pl.col("Survived").mean().over("Pclass").alias("生存確率")
)

image.png

image.pngimage.png


おまけ:提出してみよう

  • 性別、クラスごとの生存確率が平均よりも高い場合、1: "生存" と予測させてみる
# テストデータを読み込み
df_test = pl.read_csv('/kaggle/input/titanic/test.csv')

# trainデータを使って、性別。クラスごとの生存確率を算出
df_agg = df.group_by('Pclass', 'Sex').agg(
    pl.col("Survived").mean()
)

# 突合して、平均より高いか否かで算出
df_submission = (
    df_test
    .join(df_agg, on=["Pclass", "Sex"])
    .select(
        "PassengerId",
        (pl.col("Survived") >= pl.col("Survived").mean()).cast(pl.Int8)
    )
)
  • join: 他のデータフレームとの結合。結合Keyを on で指定する
  • cast: 型の変換。ここではBooleanのカラムを、整数に変換している

image.png


結果のファイル出力

df_submission.write_csv("submission.csv")
  • CSVファイルへの出力は to_csv ではなく、write_csv 5
  • これで、一番簡単なモデルを提出できます!
  • ちなみにスコアは 0.76555

image.png


Polarsのコードを書く時の頭の使い方

  1. 何の操作をやりたいかを考える(列を増やすか、行を絞るか、ソートするか、など)
  2. 1に該当するcontext (select, filter など) を書く
  3. () のなかに、まず pl.col と書く
  4. やりたいエクスプレッションを書く
  5. 以上を繰り返す

※あくまで1個人の感想です。


その他、おすすめの情報


参考


ありがとうございました


  1. もちろんみなさまの記事も参考にしています。ありがとうございます

  2. select では pl.col は使わないで、単に列名だけ記述してもいい。

  3. pl.col("Sex") もExpressionだし、pl.col("Sex") == "male" もそうだし、 (pl.col("Sex") == "male").alias("is_male")) 全体もExpressionnである

  4. Polarsでは単語ごとに _ で分けるという命名規則で設計されてるので、 groupby ではなく group_by

  5. read の対義語は to じゃなくて write !! ちなみにpandasからの変換は from_pandas ですし、pandasへの変換は to_pandas なので対応が取れています

5
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?