Laravelと機械学習を組み合わせた需要予測システムの実装方法を解説。中小企業が在庫管理コストを30%削減した実例とコードを紹介します。
こんな悩み、ありませんか?
「仕入れすぎて倉庫に在庫が山積み」「逆に欠品が続いて機会損失が痛い」「担当者の勘と経験に頼った発注では限界を感じている」——在庫管理は中小企業の経営課題のなかでも、特に根深いテーマです。
実は、この問題をLaravelとAI(機械学習)を組み合わせた需要予測システムで解決した事例が増えています。特別な大規模インフラは不要で、既存のLaravelアプリに段階的に組み込めるのが最大の特長です。本記事では、神奈川県内の食品卸売業者(従業員30名)への導入事例をベースに、実装の流れと具体的なコードをご紹介します。
なぜ「勘と経験」では限界があるのか
在庫管理が属人化する構造的な問題
多くの中小企業では、ベテラン担当者が「先月これだけ売れたから今月もこのくらい」という形で発注量を決めています。しかしこのアプローチには、いくつかの致命的な盲点があります。
- 季節変動の見落とし: 年間の売上パターンを複数年にまたいで分析する習慣がない
- 外部要因への対応の遅れ: 天候・イベント・SNSトレンドなどが需要に与える影響を即時に反映できない
- 担当者の異動・退職リスク: ノウハウが属人化しており、引き継ぎが困難
- SKU数の増加: 取り扱い品目が増えると、人間の認知処理能力では正確な需要把握が追いつかない
弊社が支援した食品卸売業者では、担当者の退職をきっかけに発注精度が急落し、廃棄ロスと欠品が同時多発するという最悪の状況に陥っていました。導入前後の状況を整理すると、次のようになります。
この数字を見れば、在庫管理の非効率がいかに経営の足を引っ張っているかが一目瞭然です。
システム全体の構成と実装フロー
アーキテクチャの概要
今回採用したのは、**Laravel(バックエンドAPI)+ Python(機械学習モデル)+ MySQL(実績データ)**の三層構造です。Pythonの予測モデルをLaravelからHTTPで呼び出す形にすることで、既存のLaravelアプリへの影響を最小限に抑えながらAI機能を追加できます。
flowchart TD
A[販売実績データ MySQL] --> B[Laravelデータ収集バッチ]
B --> C[Python予測APIサーバー]
C --> D[Prophet / XGBoostモデル]
D --> E[予測結果をMySQLへ保存]
E --> F[Laravel管理画面で可視化]
F --> G[発注推奨メール自動送信]ステップ1:過去の販売データを整形するLaravelコマンド
まずは蓄積された販売実績データを機械学習に使える形に整えるArtisanコマンドを作成します。
<?php
// app/Console/Commands/ExportSalesDataForAI.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\SalesRecord;
use Illuminate\Support\Facades\Storage;
class ExportSalesDataForAI extends Command
{
protected $signature = 'ai:export-sales {--days=365 : 取得する日数}';
protected $description = '需要予測用に販売データをCSVエクスポートする';
public function handle(): int
{
$days = (int) $this->option('days');
$since = now()->subDays($days)->toDateString();
$records = SalesRecord::query()
->selectRaw('DATE(sold_at) as ds, product_id, SUM(quantity) as y')
->where('sold_at', '>=', $since)
->groupByRaw('DATE(sold_at), product_id')
->orderBy('ds')
->get();
$csv = "ds,product_id,y\n";
foreach ($records as $row) {
$csv .= "{$row->ds},{$row->product_id},{$row->y}\n";
}
Storage::disk('local')->put('ai/sales_export.csv', $csv);
$this->info("エクスポート完了: {$records->count()} 件");
return Command::SUCCESS;
}
}
ステップ2:Python側の予測APIを構築
Facebook製のProphetを使ったシンプルな予測APIをFastAPIで構築します。Prophetは季節性・休日効果を自動的に考慮してくれるため、中小企業の実装コストを大幅に抑えられます。
# prediction_api.py
from fastapi import FastAPI
from pydantic import BaseModel
from prophet import Prophet
import pandas as pd
from typing import List
app = FastAPI()
class PredictRequest(BaseModel):
product_id: int
periods: int = 30 # 予測する日数
@app.post("/predict")
def predict(req: PredictRequest):
df = pd.read_csv("/data/sales_export.csv")
product_df = df[df["product_id"] == req.product_id][["ds", "y"]]
if len(product_df) < 30:
return {"error": "データが不足しています(最低30日分必要)"}
model = Prophet(
yearly_seasonality=True,
weekly_seasonality=True,
daily_seasonality=False
)
model.fit(product_df)
future = model.make_future_dataframe(periods=req.periods)
forecast = model.predict(future)
result = forecast[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail(req.periods)
return result.to_dict(orient="records")
ステップ3:LaravelからAI予測を取得して保存
<?php
// app/Services/DemandForecastService.php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use App\Models\DemandForecast;
use App\Models\Product;
class DemandForecastService
{
private string $apiBase;
public function __construct()
{
$this->apiBase = config('services.forecast_api.url', 'http://localhost:8001');
}
public function fetchAndStore(Product $product, int $periods = 30): bool
{
$response = Http::timeout(30)->post("{$this->apiBase}/predict", [
'product_id' => $product->id,
'periods' => $periods,
]);
if ($response->failed() || isset($response->json()['error'])) {
\Log::warning("需要予測取得失敗", ['product_id' => $product->id]);
return false;
}
$forecasts = $response->json();
// 既存の予測データを削除して上書き
DemandForecast::where('product_id', $product->id)
->where('forecast_date', '>=', now()->toDateString())
->delete();
$insertData = array_map(fn($f) => [
'product_id' => $product->id,
'forecast_date' => $f['ds'],
'predicted_qty' => max(0, (int) round($f['yhat'])),
'lower_bound' => max(0, (int) round($f['yhat_lower'])),
'upper_bound' => (int) round($f['yhat_upper']),
'created_at' => now(),
'updated_at' => now(),
], $forecasts);
DemandForecast::insert($insertData);
return true;
}
}
このサービスクラスをSchedulerで毎日深夜に全商品に対して実行するよう設定すれば、翌朝には最新の発注推奨量がダッシュボードに表示された状態になります。
// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
// 毎日深夜2時に需要予測を更新
$schedule->command('ai:export-sales')
->dailyAt('02:00');
$schedule->command('ai:update-forecasts')
->dailyAt('02:30')
->emailOutputOnFailure('[email protected]');
}
よくある失敗パターンと対処法
中小企業向けにAI需要予測を導入してきた経験から、繰り返し見てきた失敗を正直に共有します。
導入の費用感とスケジュール感
気になるコストについても現実的な数字をお伝えします。
| 項目 | 内製 | 弊社への外注 |
|---|---|---|
| 初期開発費用 | エンジニア人件費のみ(月60〜80万×3〜4ヶ月) | 80〜150万円(規模による) |
| 構築期間 | 3〜6ヶ月 | 6〜10週間 |
| インフラ費用(月額) | 自社管理のためノウハウが必要 | 1〜3万円(AWS/GCP利用) |
| 保守対応 | 内部で対応(属人化リスク) | 月次定額サポートあり |
| 予測精度チューニング | 都度対応(スキル要求大) | 継続改善込みで対応可能 |
食品卸売業者の事例では、初期投資を約6ヶ月で回収できる見通しが立ちました。廃棄ロスと機会損失の削減額だけで月間約50万円の改善が確認できています。
このAI技術、御社の業務にも導入できます
AI導入・業務自動化
ChatGPT活用や業務自動化など、最新のAI技術を御社に合わせてご提案します
※ 通常1営業日以内にご返信します
まとめと次のステップ
Laravelと機械学習を組み合わせた需要予測は、「大企業だけが使える特別な技術」ではありません。既存のLaravelアプリに段階的に組み込める現実的なアプローチであり、正しく実装すれば在庫管理コストの大幅な削減が見込めます。
まず取り組むべきことを以下のチェックリストで確認してください。
「データはあるけど、どこから手を付ければいいか分からない」「自社の状況でどこまで実現できるか相談したい」という方は、ぜひFivenine Designにご相談ください。20年以上のLaravel開発実績をもとに、御社の既存システムを活かした現実的なAI導入プランをご提案します。