今年は良いお金の使い方が出来たか振り返る by dbt

dbt Advent Calendar 2023 の 14日目の記事になります。
長らくウォッチしてたカレンダーだったのでコミットできて嬉しい✌ qiita.com

タイトルからお察しかもですが、支払明細を整理・集計する "俺々家計簿" 的なものを dbt + duckdb + (Python) で作るお話です。

「ちゃんとお金を使えているか?」

日々の生活において非常に意識的かつ積極的にクレカや電子決済払いをしているタイプです。
最近は小さなスーパーや飲食店でもQRコード決済があり、友人同士の飲み会でもPayPay送金をするため本当に現金を使うシーンが限られてきました。
それらの電子決済情報はマネーフォーワード(マネフォ)に連携しておけば非常に細かい支払いも含めて全て電子的に記録・後からまとめて取得が可能になります。この記事ではそうして得られた2023年1月~11月の約1000件ほどの取引データをdbtで処理して中身を振り返るお話です。(dbtは仕事でもよく使うツールなので、もっと仲良くなるために趣味でも使ってみたかっただけです。)

元々は細かく家計管理をしたい性格ではなく、マネフォのトップにでる「資産総額」が大きく減ったりしなければokくらいの雑さでしか管理をしていません。
どちらかというと、漠然と未来に貯金をするわけではなく、「現在の生活の幸福度を上げるようなお金の使い方ができているか」「お金を良い経験に変えられているか」などを振り返るために今回の趣味開発をしてみようと思いました。

A面として実装の方法、B面ではその集計結果を元に今年は何にお金を使ったのかの振り返りポエムを書きました。

この記事ではdbtの基本部分はいろいろすっ飛ばしていますが、もし興味を持ちご自身でも動かしてみたいと思われたときはこちらの記事内容を事前に履修すれば簡単に理解・構築できると思います!

参考: ローカル環境のみ利用したdbtチュートリアル - Zenn

また、ここではMacOSで動かすことを前提としています。

もくじ

マネーフォワードから支払い明細データを取得する

可能な限りすべての支払い履歴を取得したいと考えたとき、やはりマネーフォワードが一番便利です。自分は有料プラン(月440円ほど)に入っているため、以下のことができます。

  • ありとあらゆる口座・クレカ・その他金融関係サービスをマネフォに連携しまくる
  • マネフォ形式に整形された履歴をcsvで一括ダウンロードする

マネフォのすごいところは連携先のサービスの多さで、メガバンクはもちろん、マイナーな地方銀行CoinCheckビットコイン)、証券口座、iDeCoの年金口座など、ありとあらゆるサービス連携ができます。

また、今回重要な点は、それらの複数の連携先から取得できる情報を「共通のフォーマット」で一括ダウンロードできる点です。これがなかったら各サービスサイトをスクレイピングするなどが必要だったのでさすがにやりませんでした。マネフォ様々。

duckDBをインストールする

今回取り扱うのは個人的な決済データであるため、ここではBigQueryなどのクラウドにデータをあげず、ひとまずローカルで取り扱うことにしてみます。無料かつローカル、そしてdbtと組合せて使うのに評判がいいのは DuckDB みたいです。

参考:  🦆🦆🦆🦆🦆🦆DuckDB入門🦆🦆🦆🦆🦆🦆 - Zenn

DuckDBはpython版とCLI版のどちらでも利用できます。今回はCLI版を入れました。

$ brew install duckdb
$ ./duckdb #起動

csvをDuckDBにロードする

マネフォから取得したcsvファイルのunicodeはcp932になっています。DuckDBはutf-8しか受け取れないため、DuckDBの外でunicode変換を行う必要があります。

import pansdas as pd

df = pd.read_csv('収入・支出詳細_2023-10-01_2023-10-31.csv', encoding='cp932') 
df.to_csv('kakeibo_20231001.csv', index=False, encoding='utf-8')

また、DuckDB CLIPythonでも)はデフォルトでは in-memory にテーブルを保存するため、CLIを終了するとデータは消えてしまいます。データを永続化するには、起動時にファイルを指定する必要があります。

ここでは例として kakeibo.duckdb というファイル名にします。

$ ./duckdb kakeibo.duckdb

DuckDBが起動したら、プロンプトの先頭が "D" となります。
sqlを発行してcsvファイルをテーブルとして保存します(最後のセミコロンを忘れない)

D create table kakeibo_20231001 as select * from read_csv_auto('kakeibo_20231001.csv');

保存できたか確認します。

D select * from kakeibo_20231001;

DuckDB からは cmd + d で抜けれます(DBサーバーのシャットダウン)。終了しても保存したテーブルは消えません。

その他、存在するテーブルの確認 show tables; や テーブルの削除 drop table <テーブル名>; もできます。

dbtのインストール

dbt-core と、 今回は DuckDBを操作するため dbt-duckdb をインストールします。

$ pip install dbt-core dbt-duckdb

dbtの初期設定

dbt init コマンドでdbtのプロジェクトを作成します。ここでは kakeibo_dbt というプロジェクト名にしてみます。
「使用するdatabaseは duckdbか?」と聞かれるので 1 と回答します。

$ dbt init kakeibo_dbt

Which database would you like to use?
[1] duckdb

すると一連のdbtファイルが自動で作成されます。

次に、dbtをインストールすると ~/.dbt/ という隠しフォルダが作られているので、その中にある profile.yml ファイルを編集し、databaseの場所を指定します。
kakeibo_dbt というプロジェクト名で dbt init したので、ファイルにはすでに以下が書かれているかもしれません。(なかったら作る)

kakeibo_dbt:
  outputs:
    dev:
      type: duckdb
      path: dev.duckdb
      threads: 1

    prod:
      type: duckdb
      path: prod.duckdb
      threads: 4

  target: dev

これを以下に書き換えます。path のところを kakeibo.duckdb がある場所に書き換えます。

kakeibo_dbt:
  outputs:
    dev:
      type: duckdb
      path: /Users/ysdyt/git_repositories/kakeibo_app/kakeibo.duckdb
      threads: 1

    prod:
      type: duckdb
      path: prod.duckdb
      threads: 4

  target: dev

これにより dbt がどのduckdb のdatabaseを見に行けばよいかわかるようになりました。

dbt の開発をする

dbtのお作用や基本的な使い方はこちらの記事を参考にしてください(とてもわかりやすいです!)。
ここでは主要なファイルを中心に説明します。

参考: ローカル環境のみ利用したdbtチュートリアル - Zenn

model の開発 - Staging層

今回は以下の様に、models フォルダ以下に staging, dwh, mart フォルダを作り、その下にモデルファイルを作成しています。

まず、データソースをインポートする Staging 層です。
ソース・ファイルを指定する schema_staging.yml の内容は以下。

version: 2

sources:
  - name: main
    description: "kakeibo-model"
    tables:
      - name: kakeibo_20231101
      - name: kakeibo_20231001
      - name: kakeibo_20230901
      - name: kakeibo_20230801
      - name: kakeibo_20230701
      - name: kakeibo_20230601
      - name: kakeibo_20230501
      - name: kakeibo_20230401
      - name: kakeibo_20230301
      - name: kakeibo_20230201
      - name: kakeibo_20230101

今回は1月から11月までの一月ごとに支払い明細のファイルを作成したため、面倒ですが一つつずテーブルを作っています。(1月から11月までまとめてマネフォでcsv出力をして1ファイルにしたほうが楽ではあるが、今回は1ヶ月ごとにデータ確認しながら行ったため。)
ここで指定している -name main とは DuckDB テーブルのスキーマ名を表しています。DuckDB CLI上で select * from information_schema.tables; を実行することでテーブルのスキーマを確認できます。

次に、stg_moneyforward_master.sql にて実際にデータの読み込みと、カラム名の変換だけを行います。

with 
src_moneyforward_master as (
  select * from {{ source('main', 'kakeibo_20231101') }} 
  union all
  select * from {{ source('main', 'kakeibo_20231001') }}
  union all
  select * from {{ source('main', 'kakeibo_20230901') }}
  union all
  select * from {{ source('main', 'kakeibo_20230801') }}
  union all
  select * from {{ source('main', 'kakeibo_20230701') }}
  union all
  select * from {{ source('main', 'kakeibo_20230601') }}
  union all
  select * from {{ source('main', 'kakeibo_20230501') }}
  union all
  select * from {{ source('main', 'kakeibo_20230401') }}
  union all
  select * from {{ source('main', 'kakeibo_20230301') }}
  union all
  select * from {{ source('main', 'kakeibo_20230201') }}
  union all
  select * from {{ source('main', 'kakeibo_20230101') }}
),

final as (
  select
    計算対象::string as valid_frag
    , 日付::string as payment_date
    , 内容::string as detail
    , 金額(円)::int64 as price
    , 保有金融機関::string as financial_institution
    , 大項目::string as category
    , 中項目::string as sub_category
    , メモ::string as memo
    , 振替::string as transfer
    , ID::string as id
  from src_moneyforward_master
)

select * from final

マネフォからダウンロードしたcsvファイルの元々のカラム名は上記のような日本語カラム名になっているため扱いやすいように変換します。DuckDBでは 計算対象::string のような書き方で型変換します。
今回特に必要になるのは 日付, 内容, 金額, 保有金融機関 あたりのカラムになります。例えばこんな感じです。

  • 日付: 支払日を指す。2023-11-25 など。
  • 内容: 何にお金を払ったか。 マクドナルドモバイルオーダー など。
  • 金額: 支出の場合は -720 などのマイナス表記になる。
  • 保有金融機関: 決済方法。 三井住友カード など。クレカや銀行名、その他 Amazon.co.jp などのサービス名が並ぶことも。

Staging層ではゴミデータのクレンジングなどは行わず、一旦全てのデータをインポートするだけにします。

model の開発 - DWH層

Staging層の次はDWH層でデータの加工などを行います。目的に併せてデータを集約したりしますが、ここでは簡単に 有効な収入 を集めるモデルである dwh_income と、 有効な支出 である dwh_expense モデルを作ってみることにします。

dwh_income モデルは以下のような感じです。0円より大きい金額を収入とみなしざっくりと抽出したのち、細かくゴミデータを除外していきます。

with 
import_moneyforward_master as (
  select * from {{ ref('stg_moneyforward_master') }}
),

logical_income as (
  select
    *
  from import_moneyforward_master
  where
    price > 0
),

clean_income as (
  select
    payment_date
    , detail
    , price
    , financial_institution
    , 'income' as label
  from logical_income
  where
    not (financial_institution = 'Amazon.co.jp') -- Amazonのポイントやギフト券は収入としてカウントしない。Amazonからのプラスは全部弾く。
    and not (detail = 'チャージ チャージ&ペイでチャージ,Visa LINE Payクレジットカード' and financial_institution = 'LINE Pay') -- LINE Payのキャンペーン的なものを除外
    and not (detail = '送金受取' and financial_institution = 'LINE Pay')
 (※ もろに人の名前付き口座名などがでてくるため適宜削除しました)

    -- hoge銀行に対するプラスへの対応
    and not (detail = '定額自動入金' and financial_institution = 'hoge銀行') -- 住宅ローン用の口座なので収入としてカウントしない

    -- fuga銀行に対するプラスへの対応
    and not (detail = '利息' and financial_institution = 'fuga銀行') -- 銀行からの利息は面倒なので収入としてカウントしない

    -- 楽天関係のプラスへの対応
    and not (financial_institution = '楽天市場(my Rakuten)') -- 楽天市場でクーポン利用するとプラスが発生するので除外

  order by payment_date
),

final as (
  select * from clean_income
)

select * from final

さてここからが"家計簿集計"の真に面倒くさい部分です。

今回 "収入"としてカウントしたいのは、本業である会社からの給与や、その他本業外からの仕事収入だけにしたいとします。なのでそれ以外の "収入ぽくみえるもの" はゴミデータとして where文で除外したいです。

"収入っぽく見えるゴミデータ"とは、マネフォデータにおいては、例えば銀行間の振替送金や楽天市場, Amazon でのギフト券利用があります。これらは "収入" ではないものの、データ上は 「プラスのお金」としてカウントされます。これらを除外したいため、支払い内容や保有金融機関などを見て、細かく条件を特定して where文で消していきます。面倒くさくはあるのですが、マネフォ側である程度文字列を正規化してくれているおかげもあり、地道に書き出せばすんなり終わったりもします。

これが完了したあとのきれいになった出力は、意図したどおりの "収入一覧" が並んでおり壮観です。月々の給与額はもちろん把握していますが、1年分が1レコードずつ整然と並び、一目瞭然となると軽く感動します(1年よく頑張ったなぁ、みたいな)

全く同じ要領で、dwh_expense モデルも作ります。0円以下の金額を支出とみなしざっくりと抽出したのち、同じく細かくゴミデータを除外していきます。

with 
import_moneyforward_master as (
  select * from {{ ref('stg_moneyforward_master') }}
),

logical_expense as (
  select
    *
  from import_moneyforward_master
  where
    price <= 0 -- kindle unlimitedの書籍などは0円表示になるため、0円も含める
),

clean_expense as (
  select
    payment_date
    , detail
    , price
    , financial_institution
    , 'expense' as label
  from logical_expense
  where 
    not (detail = 'AMAZON.CO.JP' and financial_institution = '三井住友カード') -- Amazon primeカードでの支払い。Amazonの二重引き落としになっているので除外する
    and not (detail = '口座振替' and financial_institution = 'hoge銀行') -- hoge銀行への口座振替。住宅ローンの二重引き落としになっているので除外する
    and not (detail = 'ラクテンカ-ドサ-ビス' and financial_institution = '楽天銀行') -- 楽天カードの合計額が楽天銀行からの引き落とされている。楽天カード支払いの各レコードが別にあるため二重引き落としになっているので除外する
  order by payment_date
),

final as (
  select * from clean_expense
)

select * from final

支出データ側で除外したいレコードの多くは「二重引き落とし」に相当するデータです。

マネフォでは、例えば Amazonのアカウントを連携することで買い物データがそのままマネフォに連携されます。具体的な「購入商品名」もマネフォ側が知ることができ情報もリッチになり便利です。一方で、そのAmazonの支払いを行ったクレカ会社からの決済額レコードも別途マネフォに記録されるため、一つの買い物に対して見た目上は二重の引き落としが発生しているような状態になります。今回はAmazon連携側のリッチなレコードを残し、クレカ会社側のレコードを除外するような処理を行っています。これと似たような処理を他の口座やサービスに対して行っています(除外条件を書く→結果を確認する→除外したいレコードを見つける→それを除外する条件を書く→ ... を満足するまで繰り返す)

余談ですが、マネフォなどの家計管理アプリがいまいちどっぷり使えないのはこれらの例外処理的なものを"良い塩梅"にやりきれないところかなと思っています。自分自身の口座間送金は相殺しててほしいし、上記のような二重引落しっぽいレコードも裏でいい感じにしておいてほしい、でも当然利用者によって残したい/残したくないの意図が違うので一律のルールや機能を強いるわけにもいかないというジレンマがあるのかなと思っています(いや、それはお前がアプリ機能を使いこなせてないだけやで、でしたらすみません。。)

model の開発 - Mart層

最後に、きれいになった収入・支出データを読み込んでjoinして終了です。

{{ config(
  materialized='external', 
  location='/Users/ysdyt/git_repositories/kakeibo_app/export_data/mart_kakeibo_result.csv',
  format='csv'
) }}

with 
import_income as (
  select * from {{ ref('dwh_income') }}
),
import_expense as (
  select * from {{ ref('dwh_expense') }}
),

logical_union as (
  select * from import_income
  union all
  select * from import_expense
),

final as (
  select * from logical_union
)

select * from final

ここでは最終的なデータを csvファイルとして location の場所に別途出力するようにしています。

データを可視化する

せっかくなのでdbt特化型のBIである LightDash を使おうと思いました、が、どうやらLightDashが対応しているDatabaseの中にまだ DuckDB は含まれていないようでしたので泣く泣く撤退。
LightDashは、dbtで定義したmodelやmetricsをそのまま可視化することができるという特徴があり、まだまだ可視化方法は限られていて貧弱なようですが、見た目はLookerライクなので使いやすそうです。ubieさんも積極的に採用・利用されているそうです。

いくつか記事を参考にしましたが、以下あたりがわかりやすかったです。

ここでは大人しくPythonでいくつか集計・可視化します。そしてここからが個人的な1年間のお金の使い方振り返りポエムパートです。
(いろいろ生々しいのでぼんやり色々ボカシます。)

収支の累積の可視化

データがキレイなので収支の推移も簡単に出せます。その月時点での累積金額もプロットすると、トータルで赤字なのかどうか一目瞭然なので節約意識が高まる。。

import pandas as pd

df = pd.read_csv('mart_kakeibo_result.csv')

# label列がincomeの行だけ抽出する
df_income = df[df['label'] == 'income']

df_income['payment_date'] = pd.to_datetime(df_income['payment_date']) 
df_income = df_income.groupby(pd.Grouper(key='payment_date', freq='M')).sum().reset_index() # payment_dateを月ごとに集約する
df_income['payment_date'] = df_income['payment_date'].dt.strftime('%Y-%m') # payment_dateを月のみにする

df_income.rename(columns={'price': 'price_sum'}, inplace=True)
df_income['label'] = 'income'

# label列がexpenseの行だけ抽出する
df_expense = df[df['label'] == 'expense']

df_expense['payment_date'] = pd.to_datetime(df_expense['payment_date'])
df_expense = df_expense.groupby(pd.Grouper(key='payment_date', freq='M')).sum().reset_index()
df_expense['payment_date'] = df_expense['payment_date'].dt.strftime('%Y-%m')

df_expense['price'] = df_expense['price'].abs() # price列をプラスにする
df_expense.rename(columns={'price': 'price_sum'}, inplace=True)
df_expense['label'] = 'expense'

# df_incomeとdf_expenseを縦に結合する
df_income_expense = pd.concat([df_income, df_expense])

import plotly.graph_objects as go
from plotly.subplots import make_subplots

fig = make_subplots(specs=[[{"secondary_y": True}]]) # 2軸プロットにするときに必要

# 収入・支出の棒グラフ
fig.add_trace(go.Bar(x=df_income_expense[df_income_expense['label'] == 'income']['payment_date'],
                     y=df_income_expense[df_income_expense['label'] == 'income']['price_sum'],
                     name='income'))
fig.add_trace(go.Bar(x=df_income_expense[df_income_expense['label'] == 'expense']['payment_date'],
                     y=df_income_expense[df_income_expense['label'] == 'expense']['price_sum'],
                     name='expense'))
# 収入累積・支出累積の折れ線グラフ
fig.add_trace(go.Scatter(x=df_income_expense[df_income_expense['label'] == 'income']['payment_date'],
                         y=df_income_expense[df_income_expense['label'] == 'income']['price_sum'].cumsum(),
                         name='income_cumsum',
                         line=dict(color='blue', width=2)),
                         secondary_y=True)
fig.add_trace(go.Scatter(x=df_income_expense[df_income_expense['label'] == 'expense']['payment_date'],
                        y=df_income_expense[df_income_expense['label'] == 'expense']['price_sum'].cumsum(),
                        name='expense_cumsum',
                        line=dict(color='red', width=2)),
                        secondary_y=True)

fig.update_layout(title = '収入と支出の推移',
                  xaxis = dict(
                          dtick = 'M1',
                          tickformat='%_y年%_m月',  # 表示フォーマット
                          ),
                  yaxis=dict(
                          title='金額',
                          tickformat=',d' #3桁区切りの数字にする
                          ),
                  yaxis2=dict( # 2軸目の設定
                          title='累積金額',
                          tickformat=',d',
                          showgrid=False,
                          ),
                  legend=dict(
                          bgcolor='white',
                          bordercolor='gray',
                          borderwidth=1,
                          ))
fig.show()

こんな感じのグラフが出せます。(数字とグラフの形はさすがにダミーにしてます)

大きな買い物ランキング

金額が大きい順に並べて眺めてみます。(※住宅ローンや積立投資などのルーティンな支出は除く)

import pandas as pd

df = pd.read_csv('mart_kakeibo_result.csv')
# 支出のレコードのみ抽出
df_expense = df[df['label'] == 'expense']
# 金額が大きい順に並び替える
df_expense.sort_values('price').head(10)

1位. 航空機チケットtoハワイ
6月末に大分遅めな新婚旅行でハワイに行ったときの飛行機代でした。このときが1ドル=144円と円高まっしぐらだったので飛行機も高かったんだ。。

2位. サーフボード(&ウェットスーツなども一式)
去年末に藤沢に引っ越し、海までチャリで15分の距離になったのでサーフィンを始めたときに買ったやつでした。今年の夏は長かったため海も人だらけでデビューするには大混雑な年でした。元を取るために来年も続けないと(冬もやらないと上手くならないとずっと言われている...えぇ...)

3位. 電動チャリ
10年前くらい乗ったロードバイクをついに手放し、人生初の電動チャリ。シェアサイクルで乗ったときの楽さが忘れられずPayPayのポイント還元のときに奮発して購入したやつだった。湘南スタイルよろしく、サーフボードが積載できるように改造しました✌

4位. 京都のホテル1週間分
3月に転職をしたのでその前に1ヶ月弱ほど有給がありました。何をしようかなと思ったときに京都で意味もなくブラブラしたいなということで宿泊してました。いやー、意味のもなく京都ぶらぶらめっちゃ楽しかった。湘南・京都・福岡がいつか住みたい街top3。

5位. 人間ドック
お年頃だし癌家系なのでいよいよちゃんと受けるかーということでやったやつ。高かったなー。ひとまず何も見つからず安心。悪名高いバリウム検査もやり"人生"を体験した。来年からは胃カメラにする。

6&7位. エアコン2台
年末に引っ越した後もケチってエアコンを買ってなかったが流石に夏は無理だろうと人生で初めてエアコンを買った。賃貸でデフォで付いてたあれが、買う+設置工賃がとても高いのだと初めて知って悲鳴を上げた

8位. 長野 Earthboat宿泊
Earthboat | 地球を肌で感じるサウナ付きタイニーホテル というのがある。以前宿泊した素敵なサウナハウスのオーナーが新規に立ち上げたビジネスで、サウナ好きとしては気になっていたのでソッコーで予約して行ってきた。オススメです。

9位. 航空機チケットto台湾
8月に台湾に行ったときの飛行機代。台湾なんて何回行っても良いですからね〜

あとはバラバラしたガジェットなどでした。

2023年は引っ越ししたり転職したりした関係で、そもそも収入も支出もかなりお金関係がガラガラしていた年なのでした。
奥さんとの旅行やアクティビティー、健康や家のことにお金を使ってたようなのでなかなか良いお金使いだったんではないかなと。
良いか悪いかさておき、趣味100%のデカい買い物とかもしてみたい(ファッション趣味の人がこだわりの服を買ったり、車好きの人が念願の車を納車したりしてるの人生楽しそうだなと思う)

今後

こうして結果を眺めてみるとアプリを超えて自作するのもやはり有益だなと感じました。これがデータ設置と dbt run コマンドだけで実行できるのがとても便利です。あとはいろいろあった手動部分も自動化したい。これらをクラウドに持っていき、1週間に一度位で自動実行してLINEに自動プッシュしてくれる君などを作ってみようかなと思います。プライベートデータで好き勝手に自分のためだけの道具を作るのは楽しいですね✌

ネットスーパー立ち上げの裏でデータの人は何をやってるの?

この記事は10X創業6周年アドベントカレンダーの22日目の記事になります。

昨日はFinance・Accounting部のHiroki Maeharaさんが、「FP&Aはイノベーションのガイド役」という記事を公開されていますので是非ご覧ください!

また、昨日6/26が10X社ちょうど創業6周年、ネットスーパーアプリStailerのリリースから3年経ったそうです🎉 振り返れるものが増えていくのは幸せですね!

世はPodcast大航海時代

そんなネットスーパービジネスを展開する10X社ですが、一部界隈では「Podcastの会社」として有名です(僕調べ)

などなど、10X社およびその社員により、為になったり笑えたりする柔剛揃ったいろんなタイプのPodcastが日々発信されています。

こういった 業界への貢献意欲、自己開示の積極性、発信を通しての自己理解,自己研鑽などを楽しみつつ積極的に行われているところ、透明性の高さが僕が10X社(とその社員の方々)を大好きなところの一つです :)

個人の趣味Podcastを始めました

そんな僕も6月で入社三ヶ月を迎えました。

そしてこのタイミングでのアドベントカレンダー企画、せっかくなので22日の本回は、(Podcastの会社らしく)、Podcastにてお届けします!

僕もPodcastガチ勢の一人として、前職では、データ分析に関する話題を話すPodcastをやっていたので、同じようなノリでいろんな界隈の人とまたお話したいなと思い、界隈.chat という趣味の個人podcastを始めました。始めたばかりなのでぜひフォローしてください!

 

今回のおしゃべりのお相手は、僕も所属するグロース本部 データプロダクト部 部長の 天神林さん(@tenjimn)です👏 

改めて、

  • 僕たちがネットスーパービジネスの立ち上げにおいて日々脳みそを捻っている「データの仕事」とはどんなものか
  • ネットスーパー分野においてそれはどう難しい仕事なのか
  • 部署名にもなっている「データプロダクト」とは何か
  • 「データプロダクトマネージャー」とはどう新しい肩書なのか

などを、「入社当時の何もわかってなかった自分」に聞かせたかったぜという感じでおしゃべりしました。

界隈.chat | Podcast on Spotify


天神林さんは 6/10回にて、今回のPodcast内容をさらに詳細に書かれた重厚な記事を書かれています。今回のPodcastはこの記事の導入として聞いてもらえると嬉しいです。

また、同じくデータプロダクト部の野口さん(@tnoguchi15)が書かれたデータプロダクトの成果物"商品マスタ"についての記事も合わせてどうぞ!

 

10X社のネットスーパーのデータ利活用、データプロダクト、データプロダクトマネージャー について興味をもってくださったらぜひお話しましょう〜〜〜!(この声の二人がそのままでてきます笑)

[共通]カジュアル面談 / 株式会社10X

 

このpodcastの続きを自分にも喋らせろ!というアツいおしゃべり好きの方も 界隈.chat ゲスト大歓迎です!(ハッシュタグ #kaiwaichat もしくはお気軽に DM ください!)

 

明日は10X社 3人目社員のソフトウェアエンジニア 石田さん(@wapa5pow)から『10XにSWEとして0->1->10の環境にいたからこそわかる問題の傾向と対策』という記事が公開予定です。タイトルでわかる、絶対に面白いやつやで。

(改めて、本企画の全部の記事はこちら!↓)

Google Domains + GitHub PagesでPodcast番組HPを作ってApple Podcastへ登録する

qiita.com

前回書いた記事ではスタードメイン(Netowl)で取得した .fm ドメインgithub pagesに適応するときの手順を書いたが、今回はgoogle domainsで取得した場合の手順をメモ。

今回は「界隈.chat」という番組名のページを作成したかったので、google domainsで kaiwai.chatドメインを取得した。.chat ドメインは4600円/年なので .fm ドメイン(12000円/年)よりお安い。

yattecastテンプレートをforkして編集する

r7kamura.github.io

  • こちらのテンプレートをforkしてくる。(実際のgithubページはこちら
    • 今回は kaiwaichat というレポジトリ名にした
    • 「settings」>「pages」

  • Branch のところで master /(root) を選択してsaveする
  • しばらくすると「GitHub Pages」のところに「ここにページ公開したで」とURLが出てくる
    • 今回だと https://ysdyt.github.io/kaiwaichat/ となる

  • アクセスするとデフォルトの画面が見える。たったこれだけでwebページの公開ができるのでgithub pages(とyattecastテンプレート)は大変便利 :)  - (特に独自ドメインを当てなくても良いならここで終了となる)

google domains側の設定

  • 先程公開したgithub pagesに独自ドメインを当てていく作業。まずはgoogle domainsにアクセス
  • 事前に購入しておいたドメイン(今回の場合だと kaiwai.chat)を選択し、左メニューにある「DNS」を選択

  • 上記画面のとおりに情報を入力する
    • (Aレコードの値はgithub公式ページから参照した)
    • 1つ目の方の設定での「ホスト名」は空でよい(自動でドメイン kaiwai.chat が埋められるため)
    • 2つ目の方の設定での「データ」部分は ysdyt.github.io とする
      • つまり [github ID].github.io となるように入力する
      • ここを ysdyt.github.io/kaiwaichat とかにするとドメインが正しく当たらないので注意!自分はここにハマって時間を溶かした…
  • 全部入力できたら「保存」。以下のように確定される。

    • (2つ目の「データ」の最後になぜか . が入るが気にしなくてok)
  • DNSが通っていることを確認する

    • ローカルのターミナルなどで dig kaiwai.chat +noall +answer コマンドを打つ
    • 以下のような結果が帰ってきたらok
  • ここまでの設定がうまくいっていたらgithubのリモートレポジトリのコードの中に CNAME ファイルが自動で作成されている(こういうファイル

    • 中身は kaiwai.chat という文字列が入っているのみ
    • (※これはリモートだけに反映されているため、この段階までにすでにgit cloneしてコードをローカルに持っていた場合は一度 git fetch origin master してリモートの編集内容をローカルに取り込む(CNAMEファイルをローカルに持っていくる)必要がある。)

github側の設定

  • 再度githubの当該のレポジトリにて「settings」>「pages」へ
  • 「Custom domain」のところに(今回で言えば)ドメインkaiwai.chat)を入力しSave
    • その下にある「Enforce HTTPS」にチェックが入ってなかったらチェックする
      • これでセキュアな https://~ になる

  • DNS Check in progress → DNS Check in successful とでたら完了

  • 独自ドメインでwebページを公開できるところまで一行もコードを書かずに出来た。便利。あとは当該のレポジトリのコードをgit cloneしてきて編集して画面を整えたりエピソードを追加していく。
    • 詳細は別途

ここまでの参考: GitHub Pages に Google Domains で購入した独自ドメインを設定する - もやし丸の備忘録

Apple podcastへの登録

  • 以下へアクセスし自分のApple IDとパスワードでログインする https://podcastsconnect.apple.com/

  • すでに番組を公開している人は番組が表示されるが、今回は新規登録なので「+」ボタン>「新番組」をクリック

  • RSSフィードがある番組を追加する」をチェックして次へ
  • RSSフィードhttps://kaiwai.chat/feed.xml というふうに、番組ページURL + /feed.xml と登録する。このファイルはyattecastテンプレートが自動で作成してくれているのでとりあえずこのURLを指定すればok
  • 以下のように申請があがり、しばらくは待ち状態になる。申請が通ると登録したメアドにメールがくる。どれくらい時間がかかるかは不明であるが、自分の場合は5日ほどで申請がおりた。

  • 申請が降りるとApple Podcastページで検索を書けると番組が見つかるようになる
    • 申請が降りるとiTunesのURLが発行される。これを _config.ymlitunes_podcast_url: にも書いておけば、番組ページのfooter部分からitunesに飛ぶためのボタンを表示してくれるようになる。

ブレインパッドでの8年間を振り返って

新卒から約8年勤めたブレインパッドを3月に退職しました。

「受託分析」という生存/スケールが難しい事業分野で、ブレインパッド社は着々と大きくなり、そこでデータサイエンティストとしてファーストキャリアを過ごせたことは今後の僕の仕事への価値観/方法論に大きく影響を与えたのだろうと思っています。
なので8年経って思い至ったことを忘れないうちにブログにメモしておこうと思います。
新しい職場でこの考えをアップデートしたり壊したりしていきたい。

僕がいた2015年~2023年の激動のデータ/AI分野の業界の流れについてはこちらのpodcastでも話したので良かったら聞いてください🙂

open.spotify.com

※なお、全ての行末には「知らんけど」が省略されていることをご了承ください。

 

データ分析の仕事

「問題の抽象化・構造化」の価値がますます高くなっている

  • 単発の問題に回答を出すことよりも、複数の/広い範囲の問題を抽象化/構造化し、それに優先順位をつけるという仕事が非常に重要になっている
    • 各現場で各自が日夜頑張って仕事している。しかしそれは”ローカル最適化”している場合が多く、頑張った割に成果が出ない現場が少なくない
    • 必要なのはちょっと高い視点から横串に問題を整理する活動、グローバル最適化とか問題の抽象化とか言われるもの
      • しかし、人間は”グローバル最適化”問題を解くのが非常に苦手(未来はこの部分をAI的なものが担うと思っている)
  • データ分析者こそ問題の抽象化に取り組むべき。スキル/立ち位置共にそれができる一番近い位置にいる。
    • データ分析の人には各現場で発生する具体的なユースケース(要望や課題)が嫌というほど集まっている(データが発生しないビジネスがほぼ存在しなくなってきているため)
    • 複数の現場からあげってくる似たユースケースを知る機会が多い。それらをまとめて抽象化/共通化する(グローバル最適化する)ことが大きな価値となる
    • 局所最適して万事解決なデータ分析はほぼ無く、データは余裕で部署レベルを超え複雑に利用されている。越境や横断が当然求められる
  • 他にも、深いドメイン知識がないと取り組めない問題でも、抽象化/型化することでドメイン知識がない人(その道X年の正社員じゃない業務委託の人など)でも対処できる問題になったりする。問題の整理/抽象化はビジネスのスケール・本質化のためにも本当に尊い活動。

「現実がこい」: DXとはなんだったのか

社内勉強会で「現実がこい」というパンチラインを発した人がいた。これは「DX: デジタル化してトランスフォーメーションする」のではなく、「トランスフォーメーションするために現実(Real)をイジる」という主旨の発言だと思っている。

DeepLが英訳しやすい日本語を書き、stable diffusionがピンとくる呪文をつぶやき、whisperが聞き取りやすい話し方に気をつけ、ChatGPTから適切な回答を引き出しやすい質問を投げる。個人のレベルでやっている「機械によしなにやってもらうために人間側の挙動を変える」ことを、ビジネスでもやるということ。ビジネスになると急に、「人間の活動が複雑すぎてどうしようもないから機械側が合わせろ」となっている。

真のDXとは、従来の人間のワークフロー(現実)をデジタル化することではなく、デジタル化するために人間のワークフローを徹底的に整理/変更することを指すと思っている。DよりもT(transform)がキモ。現実側をtransformしてデジタルに寄せる、現実がデジタルに来るべき。 コンピュータをツールとして利用するのではなく、コンピュータそのものに労働をさせないといけない。「労働力」に昇華するまで自動化を頑張らないといけない。

ここで必ず出てくるのが「デジタル化ができない」という声。現場では「これは絶対に自動化できない」というフレーズを100万回聞くが、「人間が責任をとるべき箇所だから自動化できない(ex.食料品質管理, 医療領域 等)」以外の理由ならどんなに大変でも地道にハードネゴシエーションして機械自動化のための体制へちょっとずつでも変更するしかない。現実はそれが唯一の道だと思う。実はデジタル化できるものが非常に多いし、できないならその作業をいっそ捨てるという選択肢もある。ここを極限まで考え、判断をつけるというのがデータ分析者に求められる”リーダーシップ”の一つだと思っている。

現代こそ「理想からの逆算」が必要

正直、現代の生活はもはや十分過ぎるほど便利である。これ以上なにを望むんだという気さえする。ビジネスは基本的には「誰かの問題の解決」を行う営みであるならば、一般市民が日常生活で「解決したい」と感じる問題は見つかりにくくなっている。

それに伴い、おおよそ解決したはずの過去の問題を現代もこねくり回してるだけとなった仕事も増えている。「なんのためにやってるんだろう」「これ本当に意味があるのか」と思う場面が増えている。なので逆算思考が必要になる。

逆算志向では、「現状の課題の解決」からスタートするのではなく、「100点満点の未来」「Xの未来は斯くあるべし」という出来るかどうかもわからない”強い理想”を出発点にする。スティーブ・ジョブズiPhoneのような。大きな不満が無くなり、過去の延長の仕事が少なくない日本ではこの志向のほうがむしろ必要なのかもしれない。おそらくDXがうまくいかない企業はこういった”強い理想”がまだ持てていないことも大きいと思う。

データ分析は現代における「水戸黄門の印籠」

組織で動く以上、「合意形成」は非常に重要である。

人間は活動の大部分を勘と経験で行っており、ちょっと怪しいな?というところにだけ特に論理的推論を組み立てているように見える。論理的に考えることは大部分の人間には難しいので「納得感」「肌感覚」という勘や経験に近いものが大事にされている。それらのロジカル&肌感覚の両方で人を納得させる(合意をとる)には恐ろしくコストがかかり、ましてや多様な意見を包摂することを目指す現代の組織でコンセンサスをとるための納得コストはもうほぼ誰も払えないところまで来ているように見える。そして組織は硬直化し、意思決定すらできなくなってきている。

現代における納得コストが最も低い道具が「データ」である。データに語らせれば新人の仕事でも偉い人が耳を貸し、肌感覚人間を黙らせることもできる。これはめちゃくちゃ凄いことに思える。

これはまるで水戸黄門が印籠を出せば誰もが黙るというあのシーンに似ている。印籠に逆らって意見を通す方がコストが高いと誰もが理解できるから(ちなみに、同じ働きをする最も原始的な道具は”血筋”だった)。データはとんでもない道具になってしまったなぁ。

一方で、「データは根拠(説明能力)が強すぎる」という悩ましい問題もある。
データ分析者が気をつけたいのは、データの力や全能感に酔いしれ、「データこそ真実!正確!あとはカス!」となること。アニメ「サイコパス 」でも、全知全能AIシステムが効率と合理性を理由に民意を無視し施策を強制的に押し通そうとするのに対して、主人公が「歴史に敬意を払いなさい」と嗜めるシーンがある。 大企業でも一見無意味なシキタリには背景や文脈があり、回り回ってそれが最も合理的だったりその組織にとって最善なことが意外にある。人間の創意工夫の歴史は馬鹿にできない。データの力に溺れてそれらを軽視すると痛い目に会う。 また前項で「理想からの逆算(=強いビジョン)が大切」と書いたが、ビジョンは往々にしてファクトが弱く、説明能力でデータ分析の結果に負けてしまいビジョン無き局所最適の蛸壺に陥るというのを何度も見てきた。これを打開するには意思決定者(=ビジョンを打ち出す人であるべき)がデータ分析(印籠パワー)の功罪を深く理解しておく必要がある。

ちなみに、企業の意思決定における「サイエンス(データ分析)」「アート(斯くあるべしというビジョン)」「クラフト(過去の実験の歴史)」のパワーバランスの重要性について興味がある人はこちらの本がとてもおすすめ。

amzn.to

 

牛刀割鶏: 「最適」を選ぶ難しさ

知識をたくさん持っていることと、”最適”な手法を選択できる能力は別物という話。

昔、某案件にて、膨大な時間と知恵を総動員して作った深層学習モデルを、先輩が数日で作った枯れた機械学習モデルが精度面で肉薄するという、ある意味でゾッとする出来事があった(簡単な方法で出来たなら今までの無駄な時間をどうするとクライアントから怒られる) 結果、このシチュエーションではとにかく精度の高さを優先する(かつ、PRのために深層学習モデルが好ましい)となり事なきを得た。

この手の話はとてもよくあることで、実際に「最適な手法を選ぶ」作業は想像よりもややこしく現場によって常に「最適」が異なる。精度や実行速度などのわかりやすい指標だけではなく、PRの派手さ・既存システムとの連携難易度・現場関係者のリテラシー・現場の稼働可能人数・予算/工数 など、非明示なパラメーターの機微に大きく影響される。これらは知識の多さよりもコミュニケーションの多さ, 裏の意図を汲み取る空気を読む力みたいなものがモノを言う場合も多い。

この出来事をみて、ベネズエラ人の先輩が教えてくれた中国の故事が「牛刀割鶏(鶏を捌くのに牛用の包丁はいらない)」だった。

タスクが難しいほど高度な武器が必要ではなく、なぜタスクが難しいのかをまず疑い、その構成要素を理解し分解して、まずは最小構成の手段でやってみる。「もっと簡単な方法があるとおもうんだけどな〜」「先にやるべきことがあると思うんだけどな〜」と自問自答する癖はこの経験から来ている。

プロジェクトマネージャーという役割

マネージャー志向: どこまでを自分のコントローラブルな範囲としたいか

データ分析者がマネジメント層になりたくないというのが多くの企業で課題らしい。

データ分析やエンジニアリングは現場で手を動かすのがあまりにも楽しいので、相対的にマネジメントのほうが楽しくなさそうに(外側からは)見えるのは仕方ない。

マネジメントと一口に言っても、プロジェクトのマネジメントなのかピープルマネジメントも含むのかなどいろんな要素が絡むのでこれもまた外からみてマネジメントの仕事がよくわからなくなってる要因になってる。

エウレカ社の奥村さんがマネジメントの難しさや楽しさについてnoteを書かれている。

note.com

僕が共感したのは、「組織や仕事についてのモヤモヤを直接自分が裁量を持って関わるほうが実は心理的にヘルシー」という部分。

データ分析を仕事にしている人は、改善志向や責任感が強い人が多い印象なので、「飲み会でグチグチ仕事の文句を言ってるだけの自分が嫌い」という人は少なくないのではと思う。そういう人は実はマネジメントをやるほうが一定イキイキ働けるのではと思っている。

腹落ちしてない指示やtop downな命令による失敗はムカつくが、自分が考えて、自分がメンバーに指示して、それでも失敗したら自分の反省しか残らない。こちらのほうが実は余程メンタルに健全だし何より成功しても自己肯定感が上がるし、失敗しても学びを得られるので結果的に得をするのは自分とも言える人が多いのではと思う。

メンバー、PM、組織マネージャーでコントローラブルな範囲は当然増えていく。

メンバーは特定のタスクだけについてコントローラブルに見えるが、本当はそれすらもPMの意向で変えられるので実は実質的にメンバーがコントローラブルなものは何もない(どれくらい裁量が渡されるかはPM次第という意味で)。

PMはプロジェクトについてコントローラブルに見えるが受託分析は実は違うと感じる。メンバーに対してコントローラブルなので範囲は少し増えてはいるが、プロジェクトについてはクライアントの鶴の一声でガラポンされるので受託PMでもコントローラブルではない。「PMはそこもコントローラブルにするためにクライアントと”パートナー”になるべき」といわれるが、それは受託会社側の理想論であり、クライアント側はなんだかんだやはりそこまで期待していない場合が少なくない。受託PM側が「ガラポンが納得できないのであなたの上司にかけ合わせてください、説得してみせます」と言われてもクライアントも困ることは目に見ている。僕が受託分析の限界だと感じているのはこのあたりかもしれない。受託分析ではなんだかんだ解決できる問題のスコープが狭い。

もっと本質的な問題解決をしたいなら、当該企業の社員になり、その社内でもっとコントロール範囲の広い(偉い)ポジションを取るしかないのではと思う。データ分析者はもっと組織内のポジションを上がって意思決定層に発言権を得なければ意味のある仕事ができないという話は Data Analyst Meetup Vol.10 でも強く語られている。

偉くなってコントローラブルな範囲が増えるとストレスが増えるというが、少ないからこそストレスが増えるという人もいる。データ分析者はとりあえずポジティブにPMポジションを目指して体験してみるのが良いとは思う(ダメだったら気楽にその時に考えよう)

PM育成の難しさ: 向き不向きが大きく現れる

  • (様々な意見があることを理解しつつ、)データ分析に趣向がある人を”教育”して一人前のPMにすることはほとんど現実的ではないかもと思っている派
  • プロジェクト/プロダクト/人の管理 に対する”マネジメント”と呼ばれるタスクには、人によって性格なども含めた向き不向きがあるように思える
  • そしてその向き不向きは大卒年齢くらいにはほぼ決まっているように感じる。その段階で「向いてなさそう」という人はやっぱり向いていない可能性が高い。もちろん努力によってできなくはないが、ヒソカのいうメモリの無駄遣い 的な状態になり本人もツライ。そうなりがちなのがマネジメントという役割な気がする。
  • 育成としてできることといえば、向いている人に対してはごちゃごちゃ言わない/邪魔をしない/ストレッチな挑戦の場を提供しサポートする/既知の知見はバンバン与える くらい。そして向いていない人には強いてPMをやらせることをしないことがお互いの為に良いと思う。
  • ただし、PMにも様々なレベルがあり、1.小規模PM(メンバー ~1,2人)、2.中規模PM(メンバー ~3,4人)、3.大規模PM(メンバー 全部で10人前後)があるとして、小規模PMは向き不向き関係なく全員やってみるべき。
    • PMがどういう気持ち, 何を気にするのかわかる。仮に向いていなくてPMを辞めたとしてもこの経験は必ず活きる。
    • 2,3からは向いてない人には努力でどうこうするには圧倒的にコスパとメンタルに悪いため向いている人だけチャレンジすれば良い。しかし、社歴が増えるほど多くの企業では「どれだけデカい案件のPMができるか」が評価の大きなところを占めるっぽいのでレベル1で留まる代わりに評価は渋くなる覚悟が必要になる。大規模PMはできないが技術力は組織の中でもtopN%に入る、的な生き方が評価される会社なら良いがそれは会社に寄る。
  • マネジメント気質みたいなものは不思議で、一定の性癖のようなものに感じる。仕切りたがり・当事者意識/使命感意識が謎に高い・人に指図されるのが嫌・自信家、承認欲求が一定以上高い などなどの、仕事とは関係ないその人の性格にも大きく依存している気がする。めちゃくちゃ端的には、学校などで”学級委員長”をやったことがあるようなタイプが謎にそういう気質を持っていたりするような印象がある(しらんけど)

良い問題がチームをリードする: PMは問題を言語化してナンボ

akirachiku.com

「PMの最も大切なスキルのうちの一つは影響力によって向かう方向を示していく事である」というフレーズがある。自分もこれに同意する。

ここでいう”影響力”とはその人がこれまでに培ってきたもののことを指し、それは技術力だったり、コミュニケーション力だったり、その人が得意な武器なら何でもよくて、それを使って”良い問題”を示しチームのテンションを上げ、解決を目指す。

”良い問題”の定義の方法もその時々によって違う。僕の好きな話に「リーダーシップとマネジメントは違う」というやつがある。

大体の案件においてPMが示すべき”良い問題”は「マネジメント」側に書かれていること、つまり”複雑性の縮減”を実行するために生まれる場合がほとんどと思う。ただ、分析のPJにおいては「やってみんとわからんな〜」という意味で、”不確実性への対応” をやったり、「データでなんかできませんか」と依頼され ”あるべき姿を示す” など「リーダーシップ」側のことをやっている場合も少なくない。どちらが得意か、テンションが上がるかというのも人によって異なる。分析PJは目指すべき方向、可能な選択肢がとても多い。 だからこそ「こっちに進むぞ」という明確な意思表示がとても重要で、PJがコケるorつまらないものになるか否かはPMの示す「向かう方向次第」な部分がけっこうある。

分析PJはともすればすぐに脇道に逸れる。なので「向かうべき方向」は必ず目に付く場所に置き、定期的に振り返る必要がある。「その場その場で喋って伝える」はダメで、言葉はすぐに霧散する。テキストに書き出して誰でもいつでも見れるようにすることが本当の「言語化」。パターンや説明することが多すぎて書いてるとキリが無いという気持ちになる。わかる。でもそれがPMの必須の仕事なので。

組織

All you need is “企業文化”: 「いいやつ」と働く

ブレインパッドのデータサイエンス部の好きだったところの一つは「ヤバい人」がいないところだった。 話しかけても塩対応されることはないし、教えて欲しいとお願いすると1を聞いて10教えてくれる。最高だった。これはなぜかなと考えたがまだ自分のなかでは上手い回答が見つけられていない。僕が特に好きだった人たちは「社会に貢献したい」「自身のスキルを伸ばしたい」「データ活⽤の促進を通じて持続可能な未来をつくるの理念が好き」という点が良く共通していた印象があるのでこのあたりに何かある気はしている。

いろいろな技術的課題も、ビジネス的課題も、結局は ”人間関係が良いかどうか” に帰着している気が年々増している。

人間関係の良さを作るためには一定の人間的同質性を共有していること、そしてそれによってコンセンサスコストが低いことが必要っぽいが、同質過ぎてもダメっぽいので難しい。それらを含む、組織の雰囲気を伝える定量化できない微妙な塩梅のパラメータを醸し出しているのが「企業文化」というやつっぽい。企業文化が存在すると、この組織に入るとどういう人は幸せになってどういう人はそうならないかがわりとはっきりとわかる。Netflix社にも「頭はいいけど嫌な奴、お断り」という文化があるらしい。

確かに転職活動をしていて、はっきりと企業文化を伝えてくるところとそうじゃないところがあって面白かった。人が減る日本にとって優秀な人の獲得はますます難しくなっていくが、なぜか優秀な人ほど「なんとなく会社の雰囲気が良さそうだったから」という曖昧な入社理由な人が多い印象がある。はっきり言って外から見る程度でその会社が良いかどうかは給料の多寡や社員の在職年数くらいでしか察することができない。でも実際にはそれを最低条件とした上で「いい人と働けそうな”雰囲気”を感じられたか」に尽きる。

「なんとなく雰囲気が良い」はおそらく理詰めで作れるものではなく、ぼんやりできあがるものでもなく、一部の人たちが中心となって発している”熱”がじんわりと時間をかけて周囲にも伝搬して薫ってきているものと思う。この熱源を特定し、冷水をかけないことが組織において重要。これからもいい人たちと働きたい。

大企業における空気を読んだ越権: アホのフリをしてどんどんやっちゃう

大人社会には良い意味でも悪い意味でもグレーゾーンが存在し、グレーゾーンを触るときは「言うな聞くな」というお作法が存在する。偉い人は立場上、「XXしてもいいですか?」と聞かれるとダメと答えざるを得ないときがあるし、また、グレーゾーンにも関わらず堂々とOKだと言いふらす行為も目を瞑ることができなくなる。

アホのフリをして(わかっているがわかっていないフリをして)やっちゃうというのも、停滞する空気感が漂う場から変化するためには一定必要になる場面がある。ポイントはアホの「フリ」であり、空気を読む(”アウト”と”グレーゾーン”の境界線に見当がついている)ことである。本当にアホなことをするとヤバいので、このニュアンスがピンとこない人にはオススメしない。

何かを変えるために必要なのは具体的な「行動」のみである。そして、現体制に対し真正面から膨大なコストを払ってヘトヘトになりながら行動して途中で力尽きるよりも、グレーゾーンのお作法を守って具体的な行動を積み重ねて切り開かれた道が結果的に正道となることもある。

ただ、この方法を全面的に奨励するわけではない。停滞した現場で新たに何かをスタートさせるときには一定役に立つが、ある程度長期スパンの視野を持っておかないと死ぬしめちゃくちゃ組織の迷惑になる

 

業界/キャリア

データ分析者がロードマップをつくる

草野社長がよくお話されている&こちらのnote(日本のAI導入効果がアメリカの7分の1程度しかないのはなぜなのか)でも言及されているように日本のデータ活用の課題は、

外部ベンダの力なしにはプロダクトの企画、開発を行うことができない

リーダー層に、プロダクトマネージャー型の人材が不足している

7割超の企業でDX推進のビジョン・ロードマップがない

あたりというのは現場の肌感覚としても実感している。

つまり端的には我々のようなデータ分析者が

  • 受託(=外部ベンダ)としてではなく、事業会社に入り、
  • 発言権と実行権があるポジションに就き、
  • AI活用のビジョンロードマップを我々が引いて推進する

ことだと思う。僕は前項のような理由で受託分析には掘れる限界があると思うので事業会社に行ってみようと思う。

これまでの案件経験から、とくに3つ目の「ビジョン・ロードマップがない」というのが最もクリティカルな課題と感じている。

ロードマップがないため全体最適ができず、過去の延長として各現場で効果の高くない個別最適を頑張っているというように見える。「生産性が低い」はこれのことだと思う。 特に最近の事業ロードマップにはデータ戦略が不可欠であるが、これははっきり言ってデータ分析経験者しか立案ができないのではないかと思う。なのでデータ分析者は組織の中でもっと偉くなってロードマップをひいて推進できるポジションまで上がらないと企業の推進・立て直しは難しいのではと思う。僕は以下のツイートに全面的に賛成している。データ分析者は現場の課題解決で終わらず、会社の戦略に口出ししてナンボだと感じる。

 

妄想未来: 定量化できないものの価値が見直される

「データ化できないが重要なのでどうにかしたい(分析して改善したい)」というニーズが増える気がする。

何を言ってるかわからねーと思うが僕もわからない。ただこの分野にとても関心がある。具体例を一つ出すとこれ系の話。例えばコミュニティーのハブになっているような人でも金銭貢献などわかりやすい評価指標が確認できなければ需要ではない(いなくても問題ない)とみなされるような話。

togetter.com

資本主義がうまく駆動しない領域があることが目立ってきている。

資本主義は「定量できること」が前提なので、資本主義がぶっ壊れた世界では定量化できないものがなんとかして人間に認知可能な状態にされ大事にされそう。

定量データ分析をしていた人だからこそ、非定量分析の方法も検討できるはず。定量化できるものはほとんどがAIによって自動運用・管理されるが、定量化できない世界を人間がより大切に感じて守っていくというのが次の世界線になりそう(SFの世界です)

定量化できないのでこれらの活動はお金にはならない。ただ、FIREした億り人やIPOした起業家など、経済的には一度人生が”あがった”人は金銭的制約から外れるとどうやら「お金換算されないが中長期的に必ず社会に対して価値がありそうなこと(わかりやすいものだとコミュニティ活動、教育事業、自然保護等)」に精を出す傾向がある。人類にとってもその方が幸福な未来に見えるけどどうでしょうね。

同時期に退職された優秀なデータサイエンティストの先輩も「生物の多様性を守る」ことの価値をビジネス側にどうやって示すかというお仕事をされるそう。今は99%の人がピンとこないと思うが、おそらくこういった「お金にならないしデータ化が困難だけどどうにかして改善したいこと」系の仕事が今後は増えていくと思っている。

DSのネクストキャリアのひとつ: Data Product Manager へのお誘い

僕はキャリア論について本当に興味がないのと、実際になにもわからん、わからんし結局は各自そのときに好きなことをやったら良いと思ってる派。

そんな自分でもちょっと面白そうだなと思って次の職場(10X社)でチャレンジするのが Data Product Manager(DPM)というポジションなのでその宣伝をしたいと思う。同志が見つかると嬉しい。

DPMや、Data as Product という考え方については次のスライドがわかりやすい。

speakerdeck.com

 

約三行要約

  • データがプロダクトに並んで重要になった。かつてはデータはプロダクトの付属品だった。今は違う。データ単体で販売されたり、むしろプロダクトよりも蓄積されたデータの方が価値があると見られるプロダクトも出てきた。
  • PdMと並び、DPMというポジションが確立しつつある。DPMはプロダクトが生成するデータの価値をさらに高めることを専門に動く特化型PM職種の一種。
    • PdMは忙しいのでデータの世話まで見きれない、かつデータ活用は専門知識が必要なのでそもそもPdM一人に背負わせるのは酷すぎる。
    • 現実的にはデータ部分だけでもPdMからもう少し切り離す必要があり、それをDPMが担う。
  • 各機能や各担当チームの中では局所的にデータ利活用が進んでいても、全体を見るとデータの不整合が発生しているということはよくある。DPMはプロダクト全体を中長期の視点でも考え、データの不整合が発生しないように目を光らせる人。
    • データの不整合への対応というだけではなく、企業戦略とも合致し、中長期で変更に強いデータパイプライン/データ基盤を作っていく役目。これはデータ分析者かつビジネス側ともツーカーで会話できるより高いスキルが必要となる。(現在の日本の大企業はこのあたりが決定的にできていないと感じる)

「転職するなら事業会社いきたいなー、でも特にやりたいこととかドメインはないんだよなー」という人はもしかすると上記のような観点でデータに携わるDPMというポジションは刺さるかもしれない。新分野でまだベストプラクティスなども溜まってないので新たな学びがたくさんあるようにも感じる。特に最後の「企業の戦略に合わせてデータ活用できるためのデータパイプラインを設計する」というミッションは並のデータ人材では難しく、「ビジネスとのすり合わせ」と「手を動かすデータ分析」の両方をやってきた人じゃないと難しいのではと思ったりする。問題が難しい分、きっと解く楽しさがあるはず。

PdMはプロダクトの次の方針をチームに説明するためにデータ分析の結果を示してチームをリードする。なのでデータアナリストがPdMになるのはシナジーがあると思っていたが、DPMのほうがさらにデータ分析キャリア側から越境しやすいかもしれない。

これからのビジネスでは、GPTのような汎用的大規模言語モデルをいくつか組み合わせたものをどこの会社でも当たり前かつコア機能として利用するようになると思っている。それに伴い、各企業がもつ独自データで追加学習した各社オリジナルのAIを各社独自に作る流れがあると思う。DPMが綺麗なデータやパイプラインを作っていると、それがそのまま企業AIを育てる揺りかごになるかもと妄想している。今後のビジネスの中核となる企業AIはDPMが育てるのかもしれない(しらんけど)

 

と、途中でさらっと書きましたが次は10X社でデータプロダクトマネージャーとして働きます!楽しみ!

 

(P.S)

大昔から、データサイエンスの部では退職者が最後に何かしら卒業発表をしていくというお遊びイベントをやるのですが、今回は僕とほぼ同時期に9年目の先輩も退職という古参メンバーx2名の合同イベントとなり、オンライン/オフライン併せて100名くらいの人たちに追い出ししてもらった。

 

そもそも8年もいるなんて自分が一番思っていなかったのでなんだか実家を出て一人暮らしを始めるときの寂しい気持ちを思い出した…

創業19年目を迎えたブレインパッドは、僕の退職直後に社長交代のビッグニュースも流れ、これからまたもう一段階組織も進化するのだと思う。節目のタイミングに退職となり後追いでまたなんだか感慨深い気持ちになってしまった。

僕にとってとても充実したファーストキャリアになりました。「元ブレインパッドの人やっぱりすごいな」と業界で言われるように新しい職場でも頑張りたい。

最終発表イベントの後にみんなで:)

最終日に貰った19年記念お菓子

リーダーシップとマネジメントは違う

「良いマネージャーとは」という話をするときに、「良いリーダー(またはリーダーシップ)」の話を混ぜて話されていることがあるが、その2つは本質的に全然別物だという話

open.spotify.com

 

出典は早稲田大学ビジネススクールの杉浦教授のものらしい

2022年振り返り

1月

雪山(北横岳)に登った

 

spacemarketでサウナ付きの自宅を借りてサウナパーティーした

 

2月

家の近くに最高のサウナを見つけてアホほど通う

 

昔作ったアプリを全部イチからpythonで再実装。友人の結婚式で使ってもらう実績解除。

 

退職時の寄せ書きが味気なくて嫌だったので、「声の退職祝い」を作ってプレゼントした。地味にめちゃくちゃ良いサービスだと思う

 

「千年婚姻届」についてビジコンで発表。学生部門として賞をもらったビジコンで、今度は招待講演として発表させてもらった。婚姻届はこちらから購入できます

speakerdeck.com

 

学会発表。仕事の一部が学会で発表された。

 

3月

α7Ⅳ買った。動画をたくさん撮るようになった。やはり写真よりも残る情報量が多いので動画の方が好き

 

mameya kakeruとても良かった。今年は清澄白河に行くことが多かった

 

4月

オフィス移転。コロナ期間をのぞいても6年は毎日通っていた白金台のオフィスだが感慨は意外に無かったな...

 

長野の最高のサウナx2に行ってきた

www.youtube.com

 

5月

鎌倉で指輪を自作し、島根 出雲市役所で自作の千年婚姻届を提出してきた(旅行vlogを年内にupしようとしたらタイムオーバー)

 

6月

雷が鳴るほどの土砂降りのなか、水芭蕉シーズンの尾瀬にいってきた。尾瀬の山小屋にサウナができるらしいのでまたトライしたい

 

新オフィス初出社。夜景が綺麗な六本木一丁目のオフィス

 

B43で家計管理を始めた。今年一番の体験のサービス。重宝している。

 

8月

オートキャンプすずらんの川サウナが最高だった、おすすめ

 

9月

白馬に登った。下山後に宿泊したホテル五龍館のサウナが今年のベストサウナだった、絶対にまた行きたい

 

大学時代の友人とヤッホーfmというpodcastを始めた(が、かなり更新をサボっている)

 

10月

Data Analyst Meetup Vol.10を開催した。オンライン/オフライン合わせて700人弱の申し込みとなるマンモスイベントとなった。内容は一部podcastで公開した

 

パートナーが骨折。緊急手術のすえ長野の病院にそのまま3週間入院することに(今は無事退院)。山場での事故は山岳事故扱いになり警察への報告が義務付けられているらしい、そしてyahooニュースへ...。人生いつ何が起こるかわからないという気持ちを新たにした。あと保険は大切。

 

11月

5月から家を探し始め、紆余曲折あって藤沢市に家を買って引っ越した。藤沢は大学院生のときに住んでいた時ぶり。骨折につきまだウロウロできていないが、夏になったら湘南ライフを満喫したい。

 

12月

自作キーボード沼にハマってしまった。抱いて寝れるほどとても気に入っている

 

(おまけ)podcastの更新

始めてから3年経つ白金鉱業.FMを今年も13本更新していた、エラい!我ながら無くなったら惜しい番組、良い番組だと思うことが継続の秘訣かもしれない。できるだけ頑張って放送を続けたい。

音声認識モデルwhisperの全モデル文字起こし比較

OpenAIの音声認識モデルWhiper、いやー、まじですごすぎて感動しました。

配信中のpodcast番組 白金鉱業.FMを頑張って文字起こしするために、この記事とか、この記事とかでかなり真面目に既存文字起こしAPIの精度などを比較していましたが、もう今回は比べるまでもなく本当に雲泥の差です。ほぼ一言一句正確に文字起こしできます。GCP, AWS, Azureの文字起こしAPIは文字起こし精度が体感30~60%くらいでしたが、whisperは90%超えている印象です。もう笑うしかないです。

最初に結論

whisperは異なるモデルサイズが5種が利用可能であり、文字起こし精度と処理時間の両方を考慮するとどれ使うのがベストかということについては、文字起こしの目的に寄るかなという感じです。

【ニーズ1】 ざっとどんな話してるのかの概要さえつかめれば良い、見た目の綺麗さとか問わない。細かい文字起こしミスも気にしない。なんらかの事情で早く文字起こし結果が欲しい → デフォルトの small モデルを使えば良さそう

【ニーズ2】 数時間単位で時間かかっても良い、句読点等も含めできるだけ見た目もキレイに文字起こしして欲しい → large モデルを使いましょう

他のモデルは品質と処理時間がどっちつかずなので選択肢に入らない印象です。small or largeの2択ですね。

それぞれ、正確にどれくらいのクオリティーがあるのかを知りたいかたは続きをお読みください。

インストール

基本的にはpip一発で入ります

pip install git+https://github.com/openai/whisper.git

実行方法

実行もとても簡単。

whisper コマンドが使えるようになっているので、python以外にコマンドラインでも試せます。ファイル形式はm4aなども可です。

whisper hoge.mp3 --language Japanese --model base

特に languageを指定しなくても自動で言語が識別されるのもすごいところ。

利用できる学習済みmodelサイズは tiny, base, small, medium, largeの順に5種類があり、largeに近いほどダウンロードされるファイルを大きく、認識にかかる時間は長く、認識精度は良くなります。

特にモデルを指定しない場合はデフォルトでは small モデルが使用されます。

コマンドラインでの結果は以下のような見やすい形式で表示されます。

[00:00.000 --> 00:04.260] では今回のお題は最近話題の
[00:04.260 --> 00:06.500] ステーブルディフィュージョンに並んでというか
[00:06.500 --> 00:09.000] 続きてというかで話題の
[00:09.000 --> 00:13.500] ビスパーさんのお話の技術解析を同じく
[00:13.500 --> 00:16.000] 広化先生からお願いしたいと思います
[00:16.000 --> 00:17.800] よろしくお願いします
[00:17.800 --> 00:18.100] そうですね
[00:18.100 --> 00:20.160] ちょうどステーブルディフィージョンとが
[00:20.160 --> 00:24.560] 早ったその週とか次の週とかに

ちなみに、 --task translate オプションを付けると文字起こしした日本語をそのまま英訳変換もしてくれます。便利。

pythonインターフェースでは以下のように3行書くだけ。簡単過ぎる。ここまで来るとAWSなどの文字起こしクラウドAPIを使うよりも逆に簡単なんですよね。(API認証とか、指定のファイルをクラウドにアップロードするところが手間と思えてくるため)

import whisper
model = whisper.load_model("base")
result = model.transcribe('hoge.mp3', verbose=True, language='ja')

返してくれる結果 result には、dict形式で textsegments という情報が格納されており、text は認識されたテキスト全文、segments は何分から何分まで何を話したかという詳細情報が入っています。 発話位置まで正確に知りたいなら segments の情報を使い、とにかくテキスト全文が欲しいだけという場合は text だけ取ってくれば良いです。

結果

5つのモデルの出力結果を比べながら、文字起こし品質の差分はどういったところに現れるか、驚いたところを紹介していきます。

ちなみに、whisperはいまのところ話者分離(AさんとBさんのどっちが何を喋ったか)は行えないので、話者の区別なく音声内容をひたすら文字起こしするということをしています。

今回は白金fmの第60回、まさに今回の主題であるwhisperの論文について解説した回を対象に文字起こししました。podcast用に音声は編集してけっこう綺麗にしているつもりです。これだけクリアにして下駄を履かせているのだから流石に頑張ってほしいという期待を込めて。

open.spotify.com

音源自体の長さは31m5s。ちょうどmtg一回分の長さといったところです。

先に処理時間についてまとめた結果が以下。M1MacローカルのCPUで計算しています。マシンスペックによって処理時間は変わりますが、モデル間の相対関係は変わらないはずなので参考値として。

(CPUでの)処理時間だけでみると、smallモデルまではインプットする音源長よりも短い時間で文字起こし処理が完了するようです。一方、mediumとlargeはそれぞれ2倍、5倍の時間を要します。かけた時間に比例してどれだけ文字起こし品質が向上するかが見どころです。

では肝心の文字起こし品質について各モデルごとの結果です。

tinyモデルの結果

31minの音源に対して3minという爆速で処理が終わっています。(ちなみに、GCPAWSの文字起こしAPIも同じくらいの処理時間でした)

実際の文字起こし結果はこちら。

https://raw.githubusercontent.com/shirokane-kougyou/shirokane-kougyou.github.io/master/materials/060_whisper_tidy.txt

一瞬、「イケるか?」という気持ちになりますが、ちょっと読み進めると全然意味がわかりませんね。体感としては半分も合ってないような気がします。

また、論文内でも課題として指摘されていた意味のない繰り返しが出現したりする箇所も見つかります

よく音声系の人たちが画像出してるあの納み歌、模様模様模様みたいな画像を見せて

(ちなみにこれでもAWSGCPの文字起こしAPIよりも全然良い結果だとは感じます)

baseモデルの結果

tinyに続き7minという爆速で処理完了させるbaseモデルです。

文字起こし結果は以下。

https://raw.githubusercontent.com/shirokane-kougyou/shirokane-kougyou.github.io/master/materials/060_whisper_base.txt

結果としては、tinyモデルとどんぐりの背比べという感じです。tinyよりも正確に単語認識できる箇所もあれば、逆にtinyで合っていたのにbaseで間違うという単語も散見されます。

音源にない語が挿入されたり繰り返されたりする加減はtinyよりも悪いような気すらします。

カンマーのウムだったり全て面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い面白い個別の笑顔 笑顔手キストその feelings cons靈魂騎郷審柱カンetes本申し抜けてその個人個人階打電気エ practiced特定敵批判ietまたハマ樋木岩馬五花近小浟vi configurations越が同いってこれによって

普通にtinyとbaseは品質が悪すぎて日本語文字起こしでは使えんなぁという印象ですが、敢えて使いみちを考えるのであれば、例えば音源が膨大にあって、「雰囲気だけでもいいからこれらの膨大な音源から名詞wordcloudをサクッと作ってくれ〜」というときは使えるかもしれません。(そもそもwordcloudは何か有益なものを見ている気持ちになるだけの情報量ほぼ無の可視化なので合ってようが間違ってようが比較的どうでもいいやつなので)

smallモデルの結果

インプット音源のだいたい半分くらいの時間で処理を終わらせてくれたsmallモデルです。whisperのデフォルトではsmallモデルが使われているので、見せてくれよデフォルトのチカラってやつを!

文字起こし結果は以下。

https://raw.githubusercontent.com/shirokane-kougyou/shirokane-kougyou.github.io/master/materials/060_whisper_small.txt

これはいい感じです!頭から読んでいっても意味わかるなーという気がしてきます。句読点が無いので読みにくいのは間違いないですが、なんの話をしているかは大分わかってくるのではないでしょうか。さすがデフォルトモデルいいぞデフォルトモデル。

ここは間違ってるだろうなと感じるところもかなりまだありますが人間が脳内補正可能な範囲かなと。この品質がインプット音源のだいたい半分くらいの時間でサッと自動で出てくるのなら使い方にも寄りますが御の字ではないでしょうか。

そしてtinyやbaseで見られた意味不明の繰り返しなども見つかりません。

処理時間と文字起こし品質の両方を考えたときに、このモデルをwhisperのデフォルトに指定されているのもとても納得感があります。

mediumモデルの結果

いやー、これまでの文字起こしAPIたちと比較してもうsmallモデル見せてもらっただけで胸がいっぱいですよ…という気持ちを持ちつつ、まだ見てみたいその先を。

mediumからは音源時間よりも長く処理時間を食うので完全に精度を追い求める旅です。smallとの差分としてどこが変わってくるのか。

文字起こし結果は以下。

https://raw.githubusercontent.com/shirokane-kougyou/shirokane-kougyou.github.io/master/materials/060_whisper_medium.txt

いやー、もうここからは日本語文字起こしの新世界です。発音した音は全部文字起こしされているレベルです。マジか。感動です。

句読点がないので読みにくさは残りますが、個々の単語認識精度が着実に上がっている印象です。

small, medium
ステーブルディフュージョン → stable diffusion
オープンAI → Open AI
シークエンス2シークエンス → Sequence to Sequence

カタカナ英語発音を英語と認識してくれるようになっています。スゴイ。

もうlargeの結果を見るのが怖くなってきました、まだ上があるの?

largeモデルの結果

もう笑ってしまう結果です。綺麗すぎて嘘でしょ?って思ったのでlargeモデルの結果は音声と聴き比べながら一言一句確認してみました。

赤マークがwhisperの間違い箇所です。もう間違いを探すほうが難しいレベルです。体感的には95%以上合ってるのでは?という感じです。これがAIってやつか。

docs.google.com

largeモデルからはなんと句読点も付与されます。おかげで圧倒的に読みやすくなりました。これを見ちゃうと5倍時間がかかったとしてもlargeで文字起こしして欲しいとなりそうです。そしてこの処理時間はもちろんGPUを使うともっと短くなるはずです。

以下はちゃんと認識されててびっくりした文字列たち

Stable Diffusion
Whisper
OpenAI
Automatic Speech Recognition
BigSSL
Sequence to Sequence

BigSSL, OpenAIなどは固有名詞認識されるようになりました。そして "Whisper"も英語表記になりました。

また、日本語会話で無意識に口走る「ええっと」「まぁ」「あのー」「へー」「あっ」「うん」などを見事なまでに”よしなに”消しています。かつ、過剰に消しすぎている印象もない。そのおかげもあり文字起こしテキストが極めて自然に”読める”ようになっています。
改めて細かく見比べてみると、smallモデルにはまだそのままこれらの語が文字起こしされており、mediumで減り、largeでほぼ完全によしなに消えているという印象です。

「じかんかけるしゅうはすう」の発音を「時間×周波数」に文字起こししているのも賢すぎます。 句読点を打つ位置も自然すぎる。ちょっと区切りながら「this, is, a...」と話したところも正確に句読点打ってくるので笑ってしまいました。人間より正しく句読点打ててそう。

ここまでくるとスーパーヒューマンレベル(人間超え)という宣伝文句も納得ですね。ふつうにこの結果を「頑張って全文文字起こししましたー」と人間に渡されても気づかないんじゃないですかね。

話者分離はいまのところできないようですが、最近だとzoomなどでも話者個々の音声ファイルを別々に保存できるので、別々に音声認識かけて、会話自体は後からガッチャンコして復元すれば良さそうです。そのように話者分離自体はモデル外で工夫の余地があるので、むしろ句読点等を高精度に付与可能になったのが嬉しいですね

まとめ

日本語音源の文字起こしはwhisper 一択、とりあえず脳死でこれを使っておけという時代がやってきました。

最初に【ニーズ1】の人はsmallモデル、【ニーズ2】の人はlargeモデルを使おうと書きましたが、largeの品質が圧倒的に高いのでコスパ度返しで何でもかんでもlargeで文字起こししたいという気持ちになりますねわかります。

パッと思いつく利活用として、社内の議事録などこれで文字起こしすれば?というのがありますが、今回のlargeの文字起こし結果と実際の音源を聞いてもらうととわかる通り、今回の話者のように淀みなく論理的に話を進めている印象の会話ででも、それでも書き言葉としては読みにくく、口語と書き言葉にはかなり差があることが改めてわかります。whisperは聞こえている音を片っ端から文字起こしし、要約的なことは一切しないので当たり前といえば当たり前ですが。

podcast大好き人間として、高品質な日本語音声文字起こしをかなりの低コストで実現する技術ができたことで、podcastの全文文字化・全文検索・類似番組の検索 などが技術的かつ実用的に可能になりました。検索が可能になったことで番組内容に合致する音声広告なども検討しやすくなると思うので、更にpodcastの市場性は広がるのではないでしょうか。そちらの方向も楽しみです。

高精度文字起こし・発話位置・句読点付与がwhisperによってほぼ解決したのだとしたら、あと残りの日本語音声認識に対する技術ニーズってなんですかね(詳しくない)。ぱっと思いつくのは、

  • ノイズが多い音源での認識
  • 話者分離
  • リアルタイム文字起こし
  • 感情推定(日本語はangry以外の推定がまだまだ弱いらしい)
  • 好みの声の推定系(可愛い声、イケボ的な)

とかでしょうか?アツいですね。

追記

こういう高精度なモデルがでるとエンジニアは意地悪したくなるもの…

この記事を公開後に、社内から寄せられた「おれもこういう実験やってみた」という面白事例が届いたので紹介です

カタカナ英語 完全制覇 whisperくん

実験者が作成した低クオリティーな英作文をカタカナ英語(俗に言うJapanese English)で朗読してwhisperで文字起こし。

languageを非明示にすると日本語と判定され上手く文字起こしできなかったが、language="en" にするとなんと原稿との一致率は驚異の100%

おそらく、英語データセットにはいろんな国の人が話す"綺麗ではない英語"もたくさん含まれており、それを学習しているから堅牢性が高いのではと想像します。カタカナ英語なんてAIからするとただのノイズであって「本質情報を学習しているワイには簡単に識別できまっせ」という感じなんでしょう。

せんでんせんでん

機械学習/AI、データサイエンスビジネスについて話すニッチなpodcast番組「白金鉱業.FM」をやっています。フォローよろしくおねがいします。

twitter.com