2024年のまとめ

今年も1年間お疲れ様でした。あっという間の1年間でしたね。

この1年間はデータサイエンティストとして、そして技術系のブロガーとしては激動の1年間だったと思います。なんといってもLLMの発展の影響が色々なところに出てきました。そしてプライベートでも色々イベントの多い1年でした。

このブログのこと

このブログに関しては(少し遅れた日もありますが記事数は)なんとか目標通り週1本のペースを維持することができ、この記事で今年53本目になります。合計では671本になりました。

ただしその一方で、LLMの影響か?とも考えているのですがアクセス数は徐々に下がっています。自分の学習や調べ物を考慮しても、最初からAIに聞きそれを元に公式ドキュメントをあたる対応をとることが増え、他の人の記事を参照して調べるということがかなり減りました。
そして、おそらくそれは他の人たちも同じで、何か調べてこのブログがヒットするという機会が減っているのかなとも思います。

また、データサイエンティストとか機械学習とか統計学等々のブームはLLMを除いて落ち着いてきて、新規に流入してくる人も減ったのかなぁと感じています。LLMはほとんどの人にとっては、他社が開発したサービスを利用するだけですからね。

そういったわけで、アクセスいただいたユーザー数などのこのブログの指標は昨年の半分程度に落ちており、しかも年始から年末にかけて下降トレンドなので来年はもっと下がる見通しです。

僕個人としてもアクセス数などの指標をモチベーションにするのは避けるようになってきました。というのもそれらの指標を気にしているとダイレクトにモチベーションが下がってしまって記事の質が下がったり更新が遅れたりといったことにつながってしまっているからです。

記事を書くことが自分のスキルアップにつながっている感覚はあり、直近の転職ではこのブログの存在にも大いに助けられた感覚はあるのでなんらかの形で続けたいのですがなかなか難しいところですね。

このブログ以外の発信について

さて、このブログは低調ですが、この1年間はnoteにも月1本の記事を投稿してきました。こちらも年間12本の目標達成です。noteの方は会社の看板も背負ってますし業務に関することを書きやすいということもあり結構実践に踏み込んだ記事を揃えることができたと思います。

とはいえ、このブログが4~5本、noteが1本という更新はなかなかしんどかったですね。

項目反応理論のよりテクニカルな話をもっと書きたいと思ってはいるのですがそれはこのブログになるのかnoteになるのかは未定です。

お仕事の話

昨年転職して現職について1年半ほど経過しました。教育関係のデータサイエンティストとしてだいぶ仕事が板に付いてきたと思えます。データ基盤の各種ツールが手に馴染んてきたこと、人間関係がしっかりできてきたこと、メインウェポンの項目反応理論が思いのほか面白くて学んでいて楽しいことなどが良い要因です。

仕事に関しては、来年早々の共通テストが正念場なので気を引き締めていきたいです。

私生活の話

趣味でポーカーをやっているのですが、とある大会で順調に勝ち進んで韓国で行われた決勝戦に招待していただけたのが今年のハイライトでした。

その他、マーダーミステリーを数十本やったり街歩きの謎解きに参加したり、ボードゲームで遊んだり、美術館や博物館に行くようになったりと趣味が広がる1年間でした。

この調子で来年も楽しんでいきたいと思います。

来年に向けて

来年のこのブログの更新ですが、更新ペースに関して目標を設定するのは一旦やめようと思っています。生成AIの発展により個人が運営している技術ブログというものの存在価値もだいぶ下がっていると思いますし、実際ニーズがなくなっている実感があるからです。

とはいえ何かしらの更新はしようと思うので月1本くらいは何か記事書けたらいいなと思ってはいます。noteと合わせて月に2本は何かしらの発信がある計算です。

今までのような小ネタを書いてもいいですし、それこそキャリア系の著名な方々が書いてるようなキャリア系のポエムや読み物記事を書いても良いかもしれません。

キャリア論的なことを語りだすと自分の成長が止まるような気がしてこれまで書いてこなかったのですが、自分もそろそろ40代に突入するような年になっています。自分の成長だけ優先してるわけにもいかないので後進の方々にとって何かしら有意義な発信ができたらいいなと思います。特に前職では採用等もやっていて1000人近くの候補者を選考してたりしますし、メンバー育成等も担当していたのでその辺の経験からも何か書ければと。

それではみなさま、今年も1年間ありがとうございました。また来年もよろしくお願いいたします。

MySQLのデータのダンプとリストア

タイトルはMySQLですが、実際には AWS RDSのAurora (MySQL)を想定しています。

Aurora Serverless v2 への移行も見据えて、MySQLのデータの移行方法を調べました。dumpをとる専用のコマンドがあり、それでバックアップを取得してそれを戻せば良いようです。

ドキュメントはこちらになります。
参考: MySQL :: MySQL 8.0 リファレンスマニュアル :: 4.5.4 mysqldump — データベースバックアッププログラム

ドキュメントの一番下の方に例として一番シンプルなコマンドが載っています。

# データベース全体のバックアップを作成
shell> mysqldump db_name > backup-file.sql
# ダンプファイルをサーバーにロード
shell> mysql db_name < backup-file.sql

ただし、これはそのローカルサーバーにDBMSがあってパスワード等もかかってない場合に使うものなので、現実的にはDBのエンドポイント等を指定する必要があります。

# バックアップ
$ mysqldump -h <エンドポイント> -u <ユーザー名> -p --databases <データベース名> > aurora_backup.sql
# リストア
$ mysql -h <エンドポイント> -u <ユーザー名> -p < aurora_backup.sql

ダンプするときにデータベース名はスペース区切りで複数まとめて指定することもできます。

一方で、ダンプファイルにDB名の情報は含まれているので、リストアする時はDB名の指定は不要です。

–all-databases という全てのデータベースを対象とするオプションもありますが、システム情報的なDBまで含まれてしまうのでこれは使わず、自分で必要なDBを指定した方が安全だと思います。バージョンが違うDB間で移行するような時は特に注意が必要です。

最後に、ダンプを取るときに特にオプション等でタイムゾーンに関する設定をしなければ、datatime型のデータはタイムゾーンの情報を持たずにダンプされてしまいます。

移行前後のDB間でタイムゾーンが違うと異なる時間で解釈されるリスク等もあるので、先に設定を揃えておきましょう。

Amazon Aurora Serverless v2 がAUCの最小値を0に設定できるようになりました

Aurora Serverless v1のサポート終了が近づいてきた(が今では少しだけ延長されていますが)昨今ですが、v2 で遂に待ちに待った機能が追加されました。それがスケーリングの最小値を0にできるというものです。

リリース: Amazon Aurora Serverless v2 がゼロキャパシティへのスケーリングをサポート – AWS

以前の記事で Aurora Serveless v2 を検証したとき、キャパシティを0にできないことで僕は導入を断念してたんですよね。

参考: Amazon Aurora Serverless v2が出たので使ってみた

注意点としては、サポートされているDBのバージョンが少し限定されている点だけでしょうか。

引用すると、
0 ACU は Aurora PostgreSQL 13.15 以上、14.12 以上、15.7 以上、16.3 以上、Aurora MySQL 3.08 以上でサポートされています。
とあります。

MySQLは3.08以上なので今後新しいバージョンが出たらそれは順次対応していそうですね。

Aurora Serverless v2 で新規のデータベースを作成する画面に進むと確かに AUCのキャパシティが 0〜設定できるようになっていました!
これで僕らのような個人利用しているユーザーも本格的に v2に移行できますね。

Streamlit in SnowflakeにおけるSQLの結果取得について

今年から使いはじめた Streamlit in Snowflake についての記事です。

とはいえ、Sreamlit要素はほぼなく、Snowflake上で使うからこそ発生するSQLの結果の取得方法(=pandasのDataFrameとしての取得方法)をまとめておきます。

Streamlit in Snowflake の場合、Snowflkaeにログインして使いますので認証情報として現時点でログインしているセッションの情報が使えます。それを取得する専用の関数として、get_active_session があるので、これを呼び出すのが最初の準備です。

from snowflake.snowpark.context import get_active_session


# Snowflakeセッションの取得
session = get_active_session()

ここから下は 「query」という変数にSQL(SELECT)文が格納されている前提になります。

sessionの sql()というメソッドでSQLを発行し、結果を得ることができます。さらに、その結果は to_pandas() というメソッドを持っており、これを使うことでDataFrame型に変換できます。

結果を表示したい場合は streamlitの dataframeとかtableといったメソッドが使えますね。

# クエリの実行と結果の取得
result = session.sql(query).to_pandas()
st.dataframe(result)
st.table(result)

続いて、 SELECT文ではなく show columns や describe table のケースも紹介します。

こちらは sqlメソッドで発行できるのは同じなのですが、結果が to_padnas()メソッドを持っていません。

ここでは、collect() というメソッドを使います。

result = session.sql(query).collect()
st.dataframe(result)

簡潔ですが以上で Streamlit in SnowflakeでSQLを発行し結果をStreamlit内で使えるようになります。

Snowflakeで配列の値やカンマ区切り等の複合値を複数行に展開する方法

要するに第1正規化ができてないデータがあるときにそれを複数行に展開する方法です。

a,b,c みたいな文字列がデータにあるときにa, b, c をそれぞれ別行のデータに展開します。

これには lateral flatten という構文を使います。参考になるドキュメントはこちらです。
参考: FLATTEN | Snowflake Documentation

元々のデータが配列型の場合は split が不要になるのでその分を読み替えてください。
最初のwith句でダミーデータを生成して実験しています。

from 句で指定してるテーブルの後、joinで複数テーブルを結合している場合はそれらの一番最後にカンマを打ってから使う点に注意してください。また、 inputとか values とかも決まった単語ですのでそのまま使います。

with
dummy_data as (
    select
        1 as id,
        'a,b,c' as text
    union all select
        2 as id,
        None as text
    union all select
        3 as id,
        'd' as text
)

select
    id,
    value::varchar as text
from
    dummy_data, lateral flatten(input => split(text, ','))

これで、
id, text
1, a
1, b
1, c
3, d
という結果が得られます。

さて、id = 2のレコードについてはtextの値がNullだったので結果に出てきませんでした。
これがNullではなく空白文字列であれば、id=3のレコードと同様に行は作られたのですけどね。

このように展開する値がNullのレコードも残したい場合は、 outerオプションを使います。= でではなく => で trueに指定するSQLでは見慣れない記法ですが、次のような形になります。

with
dummy_data as (
    select
        1 as id,
        'a,b,c' as text
    union all select
        2 as id,
        Null as text
    union all select
        3 as id,
        'd' as text
)

select
    id,
    value::varchar as text
from
    dummy_data, lateral flatten(input => split(text, ','), outer => true)

そもそも正規化がちゃんと行われているデータだけ使えばいいのであれば滅多に使わない記法なのですが、残念ながら自分はよく使う場面が頻繁にあることと、その割になかなか覚えられなくて毎回調べているので今回記事にしました。