はじめに
当記事は生成AIによって執筆しています。内容の正確性には十分注意を払っていますが、誤った情報が含まれている可能性があります。実際にご利用の際は、公式ドキュメント等もあわせてご確認ください。
Databricksのような「データ取り込み → 変換 → 機械学習 → 推論 → 定期実行」の流れを、1台のWindows PCだけで完結させるデスクトップアプリ「ローカルレイクハウス(Local Lakehouse)」 を個人開発で作り、v0.1.1を公開しました。この記事では、何ができるのか、どう使うのか、どこが向いていてどこが向いていないのかを紹介します。
DuckDB・dbt・LightGBMといったローカルで動く道具は十分に強くなりましたが、それらを「1つの画面でつなぎ、実務の流れとして回す」部分は自前で組むことになりがちです。ローカルレイクハウスはその「つなぎ」を引き受けるアプリです。
対象読者
- DuckDBやdbtを個人や小規模チームの分析に使っていて、取り込み・学習・定期実行を1か所にまとめたい方
- Databricksのような統合環境の体験がほしいが、クラウドの費用や規模が見合わない方
- 手元のデータを外部に出さずに分析・機械学習したい方
この記事のゴール
- ローカルレイクハウスで何ができるかが分かる
- サンプルを動かすところまでの手順が分かる
- 自分の用途に合うかどうかを判断できる
ローカルレイクハウスとは
ワークスペース(PC上のフォルダ)を1つ開くと、その中でデータの取り込み、SQL、dbtによる変換、LightGBMによる学習と推論、ビジュアル分析、パイプラインの定期実行までを行えるデスクトップアプリです。データも処理もPCの中で完結し、サーバーは不要です。
- 開発元:黒猫研究所(個人開発)
- 動作環境:Windows 11(64ビット)
- 公式サイト:https://blackcatslab.jp/products/local-lakehouse
- ソースコード:現時点では非公開
主な特徴
- DuckDB + DuckLakeによるローカルDWH:データはParquet、カタログはSQLiteに置きます。書き込みジョブの実行中でもSQLエディタからの読み取りが止まりません
- dbtとLightGBMをアプリに内蔵:特徴量はdbtで作り、学習・評価・モデル登録・推論を画面から実行できます
- パイプラインの定期実行:cron・テーブルの時刻・手動の3種類の起動方法に対応し、タスクトレイに常駐して動きます
- AIエージェント(任意):取り込み設定・テーブル定義・ジョブ・dbtモデル・学習設定・推論設定を依頼から作り、検証と人の承認を経て登録します
似たツールとの違い
| ツール | 特徴 | ローカルレイクハウスとの違い |
|---|---|---|
| Databricks | クラウド上の統合データ基盤。大規模データと共同作業に強い | ローカルレイクハウスは1台のPCで完結し、クラウド費用がかからない。その代わり大規模データや複数人での共同作業は対象外 |
| DuckDB + dbt CLI | 軽量で高速。自分で組み合わせれば何でもできる | ローカルレイクハウスは取り込み・学習・推論・スケジュール実行・可視化までを画面とYAMLでつないだ状態で提供する |
| Jupyter Notebook | 試行錯誤に向く | ローカルレイクハウスは処理を「再実行できるジョブ」として残し、定期実行と来歴の記録までを前提にしている |
こんな課題を解決する
Before(ローカルの道具をバラバラに使う場合)
# 取得・取り込み・変換・学習を、それぞれ別のスクリプトとコマンドで回す
python fetch.py
python load_csv_to_duckdb.py
dbt build --select tag:features
python train.py
# 定期実行はOSのタスクスケジューラに個別に登録する
問題点:
- DuckDBのファイルは、あるプロセスが書き込み可で開いている間、他のプロセスから開けない。取り込みや学習の実行中は、SQLで中身を確かめられない
- どのファイルから何行入ったか、どのデータでどのモデルを学習したかの記録を自分で作る必要がある
- 学習用と推論用で特徴量の作り方が少しずつずれていく
After(ローカルレイクハウスの場合)
schema_version: 1
name: population_train
description: 公開版の架空人口データを取得・取り込み、特徴量を作成して学習する
steps:
- jobs/fetch_population.py
- loads/load_municipalities.yml
- loads/load_population.yml
- job: builtin:dbt
params: {command: build, select: 'tag:population_features'}
- ml/configs/population_growth.yml
改善点:
- 取得(Python)・取り込み(YAML)・変換(dbt)・学習(YAML)を1本のパイプラインとして実行し、手動・cron・テーブルの時刻のいずれでも起動できる
- 保存形式がDuckLakeなので、ジョブの実行中もSQLエディタやカタログから読める
- 取り込みはファイルのハッシュで二重取り込みを防ぎ、学習はテーブルのスナップショットIDと一緒に実験として記録される
導入手順
Step 1: インストール
公式サイト から「Windows版をダウンロード」でインストーラ(約142MB)を取得します。管理者権限は不要です。
コード署名を付けていないため、Microsoft Defender SmartScreenの警告が出ることがあります。ダウンロードしたファイルのSHA-256が公式サイトに載っている値と一致することを確かめてから、「詳細情報」→「実行」を選んでください。
SHA-256はPowerShellで確かめられます。
Get-FileHash .\local-lakehouse-0.1.1-x64-setup.exe -Algorithm SHA256
# v0.1.1 の値: 4cdf2a89c54e60bf55bf160256fdd5e5c8e83d1887d695f423920861e8122048
Pythonのランタイムはアプリに同梱されているので、別途Pythonを入れる必要はありません。新しい版は起動時に確認され、設定画面からインストールできます。
Step 2: サンプルのワークスペースを作る
起動したら「ワークスペース」画面の「新規作成」で 「人口予測サンプル(架空データ)」 を選び、空のフォルダを指定して「作成」を押します。
このサンプルは、公開配布元から架空の人口統計データ(1,747地域 × 2019〜2026年)を取得し、2027年の人口を予測して都道府県の地図に描くところまでを試せるワークスペースです。人口などの数値は独自に生成した架空のもので、実際の統計値や将来推計ではありません。
Step 3: パイプラインを実行する
「ジョブ」画面の「パイプライン」で population_train を選び、「今すぐ実行」を押します。
手元の環境(Core i7-12700)では、データの取得を含めて約1分20秒で5つのステップがすべて成功しました。
続けて「実験」画面で学習結果を確かめて「モデルに登録」(エイリアス production)し、パイプライン population_predict を実行すると、2027年の予測と可視化用のワークシートができあがります。
主な機能
ここからは、Step 3まで実行したサンプルの画面で主な機能を紹介します。
機能1: 取り込みとカタログ
CSV / TSVの取り込みは、ウィザードの結果を 取り込み設定YAML として保存し、再実行できるジョブにします。CP932(Shift_JIS)のCSVにも対応しています。取り込み先は raw スキーマに限定し、加工はdbtに任せる方針です。
schema_version: 1
name: load_population
source:
volume: landing
pattern: population_sample/population/*.csv
format: csv
options: {encoding: utf-8, delimiter: ',', header: true, newline: lf}
target: {table: raw.population, mode: merge, key: [municipality_code, year]}
columns:
year: {type: INTEGER}
municipality_code: {type: VARCHAR}
population: {type: BIGINT}
# ...(略)
on_duplicate_file: skip
on_error: abort
取り込んだテーブルには、取り込みID・元ファイルのパス・元ファイルのハッシュ・書き込み日時の列が自動で付き、「どのファイルから、いつ、何行入ったか」をあとから辿れます。
DuckLakeは主キー・一意制約・外部キーをサポートしないため、テーブル定義YAMLに「論理的な制約」として持たせ、dbtテストの自動生成と取り込み時のチェックで検証します。テーブル定義は、アプリが生成するExcelの定義書テンプレート(1ブック = 1テーブル)からも作れ、既存テーブルを定義書に書き出して修正し、再アップロードすると差分がALTER文として適用されます。
SQLエディタはMonaco Editorで、結果をそのまま探索(後述)に渡せます。
機能2: dbtによる変換とリネージ
dbt-core + dbt-duckdbを同梱しており、画面から build / run / test を実行できます。モデルの依存関係はリネージとして表示されます。
特徴量はdbtで作り、学習設定YAMLには「どのテーブルのどの列を使うか」の選択と設定だけを書きます。さらに 学習と推論で同じmartを使い、結果が未確定の行は target を NULL にして出力します。学習時は target IS NOT NULL で絞り、推論時は対象の行で絞るので、学習時と推論時で特徴量が食い違う事故(train/serve skew)が構造的に起きません。
機能3: 学習・実験管理・推論
LightGBMで学習し、評価指標・学習曲線・特徴量の重要度・使った設定を実験として記録します。学習に使ったテーブルのスナップショットIDも残るので、同じデータで学習し直せます。
成功した実験は「モデルに登録」でバージョン付きのモデルにでき、推論設定からは population_growth@production のように「モデル名@エイリアス」で参照します。推論結果はモデルのバージョンとスナップショットIDを付けて追記されるので、あとから実際の結果と突き合わせられます。
機能4: 探索(ビジュアル分析)
Tableau風の探索画面は、Graphic Walker を組み込んで作りました。集計はアプリがGraphic Walkerの要求をSQLに変換し、DuckDBの読み取り専用の接続で実行します。
サンプルでは、予測パイプラインの最後のジョブが探索用のワークシートを4つ作ります。都道府県の塗り分け地図もその1つです。
グラフの裏で実行されたSQLを表示してSQLエディタにコピーできるので、探索で見つけた集計をそのままdbtモデルの下書きにできます。
機能5: パイプラインのスケジュール実行
パイプラインは pipelines/<名前>.yml に1ファイル1定義で書き、起動方法を cron・テーブル駆動・手動から選びます。アプリはタスクトレイに常駐し、ログイン時の自動起動とデスクトップ通知にも対応しています。
テーブル駆動は、テーブルの各行の時刻カラムを基準にパイプラインを動かす仕組みです。たとえば「レースの締切15分前に、そのレースだけ再予想する」を、専用のコードなしで次のように書けます(仕様書の例)。
schema_version: 1
name: pre_race
trigger:
table: marts.race_schedule
time_column: deadline_at
offset: -15m
key: race_id
steps:
- job: jobs/fetch_before.py
params: { race_id: "{{ key }}" }
- job: builtin:dbt
params: { select: "+race_features", vars: "{race_id: '{{ key }}'}" }
- job: ml/predict/predict_race.yml
params: { race_id: "{{ key }}" }
on_missed: skip
timeout: 5m
notify_success: true
ジョブは別プロセスで実行し、ユーザーのスクリプトが落ちてもアプリ本体を巻き込みません。ジョブが書き込み先のテーブルを宣言するので、同じテーブルに書くジョブだけを直列化します。
機能6: AIエージェント(作成支援)
タイトルバーの「AI」から右パネルを開き、作るもの(取り込み設定・テーブル定義・ジョブ・dbtモデル・学習設定・推論設定)を選んで依頼を書くと、エージェントがカタログや既存のファイルを調べて 変更案 を作ります。ワークスペースのファイルを直接書き換えることはなく、アプリが検証した結果と差分を見て、人が承認したものだけが登録されます。
プロバイダはOpenAI / Gemini / Anthropic / Ollama(API)と、Claude Code / Codex(エージェントCLI)から選べます。次の画面は、ローカルのOllama(qwen3-coder:30b)にdbtモデルを作らせた例です。
検証結果に「許可されない上流があるため、実データでは build しません: raw.population」という警告が出ています。これは AI読み込み可否フラグ によるものです。テーブルやボリュームごとに deny(読ませない)/ local_only(ローカルのモデルだけ)/ external(外部に送ってよい)を設定でき、新しく作ったテーブルは deny になります。スキーマ情報(テーブル名、カラム名、型など)はフラグによらず渡しますが、データの中身はフラグが許す範囲でしか読ませません。この判定はプロバイダ抽象化層の1か所で強制しているので、どの機能から呼んでも素通りできません。
AIの実行は機械学習の実験と同じように記録され、プロバイダ・モデル・プロンプトの版ごとに一発合格率・承認率・コスト・応答時間などを比べられます。
Claude Codeの接続は個人利用に限ります。Anthropicが、承認なしにサードパーティの製品でclaude.aiのログインを提供することを認めていないためです。
実際に使ってみた所感
開発者自身が実務の分析基盤として使っている立場からの所感です。
良かった点
- 取得から予測・可視化までが1つのパイプラインになり、「あの処理はどのスクリプトだったか」を探さなくなった
- DuckLakeにしたことで、学習ジョブの実行中にSQLエディタでテーブルを覗けるようになった
- 学習と推論で同じmartを使う方針のおかげで、推論用の特徴量を別に作る手間と食い違いがなくなった
- AIエージェントは、検証と差分の承認を挟むので、ローカルの小さめのモデルでも安心して使える
イマイチな点
- 現時点ではWindows 11(64ビット)のみ。コード署名もないため、初回はSmartScreenの警告が出る
- スケジューラはアプリの起動中(タスクトレイ常駐中)だけ動く。PCを止めている間の実行には対応しない
- Excelファイルの取り込みは未対応(予定はベストエフォート)。S3互換ストレージへの対応は見送っている
- 1つのワークスペースは1つのプロセスだけが開く。複数人での共同作業は想定していない
向いているケース/向いていないケース
| ケース | 向き不向き |
|---|---|
| 個人や小規模チームで、CSVなどのデータを取り込んで定期的に学習・予測を回したい | ◎ |
| 手元のデータを外部のサーバーに送らずに分析したい | ◎ |
| dbtやLightGBMを試しに触ってみたい(サンプルですぐ試せる) | ○ |
| 数百GB以上のデータを扱う、複数人で同じ基盤を共同利用する | × |
| macOS / Linuxで使いたい | ×(現時点ではWindowsのみ) |
まとめ
- ローカルレイクハウスは、取り込み → dbt変換 → LightGBMの学習・推論 → 定期実行を、1台のWindows PCで完結させるデスクトップアプリ
- DuckLakeによる同時読み書き、学習と推論で同じmartを使う設計、検証と承認を挟むAIエージェントが特徴
- 大規模データや共同作業には向かないが、個人・小規模の分析を「回る形」にしたいなら試す価値がある
人口予測サンプルを選べば数分で一通りの流れを試せるので、ぜひ触ってみてください。










