2026/07/03
前回は
コスト構造を理解し,意思決定やコストマネジメントに役立てるためのコスト構造の推定を扱いました。
今回は,
企業のコスト構造を推定し,それを通して投資の判断や政策判断に役立てよう,というイメージです。
具体的には公表財務諸表データを使ったコストビヘイビア分析を扱います。
伝統的には,コストと活動量(売上高)は比例関係にあるとされてきた
だけど, Anderson, Banker, and Janakiraman (2003) は売上高の増加時におけるコストの増加率が,同額の売上高の減少時におけるコストの減少率より小さい場合があることを発見。
売上高の変化とコストの変化は単純な比例関係を想定していたけど,どうも違うみたいだ。
Balakrishnan, Petersen, and Soderstrom (2004)
公表財務データは基本的にすごく高いデータベースから入手します。
政府の提供するEDINETからもデータをとってくることができますが
等の問題から使い勝手が悪く研究目的で使われているのをみたことがありません。
今回は,小笠原先生(甲南大学)と早田さん(神戸大学の大学院生)が抽出し,教育目的で提供してくださっているEDINET経由で取得したデータを使います (小笠原 and 早田 2021) 。
| 変数名 | 内容 | 変数名 | 内容 |
|---|---|---|---|
| f1 | EDINETコード | x20 | 資本金 |
| f2 | 証券コード | x21 | 資本剰余金 |
| f3 | 会計期間終了日 | x22 | 利益剰余金 |
| f4 | 提出日 | x23 | 自己株式 |
| f5 | 当事業年度開始日 | x24 | 評価・換算差額等 |
| f6 | 当事業年度終了日 | y1 | 売上高 |
| x1 | 現金及び現金同等物の残高 | y2 | 売上原価 |
| x2 | 資産 | y3 | 売上総利益又は売上総損失 |
| x3 | 流動資産 | y4 | 販売費及び一般管理費 |
| x4 | 固定資産 | y5 | 給料及び手当 |
| x5 | 有形固定資産 | y6 | 減価償却費/販売費及び一般管理費 |
| x6 | 無形固定資産 | y7 | 研究開発費 |
| x7 | 投資その他の資産 | y8 | 営業利益又は営業損失 |
| x8 | 負債 | y9 | 営業外収益 |
| x9 | 流動負債 | y10 | 営業外費用 |
| x10 | 短期借入金 | y11 | 支払利息 |
| x11 | 1年内償還予定の社債 | y12 | 経常利益又は経常損失 |
| x12 | 1年内返済予定の長期借入金 | y13 | 特別利益 |
| x13 | 固定負債 | y14 | 特別損失 |
| x14 | 社債 | y15 | 税引前当期純利益又は税引前当期純損失 |
| x15 | 転換社債型新株予約権付社債 | y16 | 親会社株主に帰属する当期純利益又は親会社株主に帰属する当期純損失 |
| x16 | コマーシャル・ペーパー | y17 | 包括利益 |
| x17 | 長期借入金 | z1 | 営業活動によるキャッシュ・フロー |
| x18 | 純資産 | z2 | 減価償却費/営業活動によるキャッシュ・フロー |
| x19 | 株主資本 | z3 | 投資活動によるキャッシュ・フロー |
| z4 | 財務活動によるキャッシュ・フロー |
ufo <- ufo |>
rename(
id = f1,
code = f2,
end = f3,
submit = f4,
year_start = f5,
year_finish = f6,
cash = x1,
asset = x2,
current_assets = x3,
fixed_assets = x4,
tangible = x5,
intangible = x6,
other_assets = x7,
liability = x8,
current_liability = x9,
short_debt = x10,
bonds_due_within_1_year = x11,
long_term_debt_due_within_1_year = x12,
fixed_liability = x13,
bonds = x14,
convertible_bonds = x15,
commercial_paper = x16,
long_debt = x17,
net_worth = x18,
shareholders_equity = x19,
capital_stock = x20,
capital_surplus = x21,
retained_earnings = x22,
treasury_stock = x23,
valuation_and_translation_adjustments = x24,
sales = y1,
cogs = y2,
gross = y3,
sga = y4,
salary = y5,
depreciation = y6,
r_and_d = y7,
operating_income_loss = y8,
non_operating_income = y9,
non_operating_expenses = y10,
interest = y11,
ordinary_income = y12,
extraordinary_income = y13,
extraordinary_losses = y14,
income_before_income_taxes = y15,
net_income_attributable_to_owners_of_the_parent = y16,
comprehensive_income = y17,
cf_from_operating_activities = z1,
depreciation_expenses_cf = z2,
cf_investing = z3,
cf_financing = z4
)
ufo <- ufo |>
mutate(code = code / 10) |>
mutate(code = as.character(code))企業名が欲しかったので,日本証券取引所グループから持ってきた会社コードと企業名一覧データをくっつける
\(Cost\)を何らかの費用( Anderson et al. (2003) やそれに続く研究では販売費及び一般管理費 ),\(Sales\) を売上高とすると
\[\log \frac{Cost_{i,t}}{Cost_{i,t-1}} = \beta_0 + \beta_1 \log \frac{Sales_{i,t}}{Sales_{i,t-1}} + \beta_2 Dec_{i,t} \log \frac{Sales_{i,t}}{Sales_{i,t-1}} + \varepsilon_{i,t} \tag{1}\]
ただし,\(i\)は企業,\(t\)は年度を表し,\(Dec\) は企業の売上高が減少した場合に 1,そうでない場合に0を取るダミー変数。
つまり
\[\begin{cases} \log \frac{Cost_{i,t}}{Cost_{i,t-1}} = \beta_0 + \beta_1 \log \frac{Sales_{i,t}}{Sales_{i,t-1}} + \varepsilon_{i,t} & 増収時 \\ \log \frac{Cost_{i,t}}{Cost_{i,t-1}} = \beta_0 + (\beta_1 + \beta_2 ) \log \frac{Sales_{i,t}}{Sales_{i,t-1}} + \varepsilon_{i,t} & 減収時 \end{cases}\]
となる。ここで,\(\frac{Cost_{i,t}}{Cost_{i,t-1}}(\frac{Sales_{i,t}}{Sales_{i,t-1}})\)はコスト(売上高)の前年比,それにlogをとっているので,前年比コスト(売上高)の変化率,と解釈できる。
増収時と減収時の売上高の変化率に対するコストの変化率が違うかどうかを知りたいので,注目するのは,\(\beta_1\)(増収時)と\(\beta_1 + \beta_2\)(減収時)の差。
model <- lm(
dlogsga ~ dlogsales + dec_dlogsales,
data = data
)
m <- summary(model)
modelsummary(
list(model),
stars = stars,
estimate = "{estimate}{stars}",
align = 'ld',
fmt = fmt_decimal(digits = 2, pdigits = 3),
gof_map = c("nobs", "r.squared", 'adj.r.squared')
) |>
style_tt(i = 5, background = '#C6DBCE')| (1) | |
|---|---|
| (Intercept) | 0.02*** |
| (0.00) | |
| dlogsales | 0.49*** |
| (0.01) | |
| dec_dlogsales | -0.06*** |
| (0.01) | |
| Num.Obs. | 8390 |
| R2 | 0.403 |
| R2 Adj. | 0.403 |
その後の研究で,Bankerらは,このようなコストの非対称性が起こる理由を資源調整コストに求めるように(Banker and Byzalov 2014; Banker, Byzalov, Fang, and Liang 2018)
ある年の売上高が前年より下がったとしても,それに対応して,経営資源を削減できる?
この考えに従うと,固定費と直接費も,資源調整コストの大きさによって区分し直すことができる。
\(Y = \log X\) とは,「\(e^Y = X\)となる\(Y\)」のこと(\(e \approx 2.718\))。会計・経済データの分析では,底が\(e\)の自然対数を使うのが標準(以下,\(\log\)は自然対数を指す)。
対数には,掛け算・割り算を足し算・引き算に変換するという重要な性質がある。
\(\log X\)を\(X\)で微分すると
\[\frac{d \log X}{dX} = \frac{1}{X}\]
つまり,\(X\)が少しだけ(\(\Delta X\)だけ)変化するとき,対数の変化は
\[\Delta(\log X) \approx \frac{\Delta X}{X}\]
で近似できる。右辺は\(X\)の変化率(%)。だから対数の差は変化率を近似する。
説明変数・被説明変数のどちらに対数を使うかによって,モデルの型と係数\(\beta_1\)の意味が変わる。
| モデル | 式 | \(\beta_1\)の意味 |
|---|---|---|
| 線形 | \(Y = \beta_0 + \beta_1 X + \varepsilon\) | \(X\)が1単位増えると\(Y\)が\(\beta_1\)単位変化 |
| 対数線形(log-linear) | \(\log Y = \beta_0 + \beta_1 X + \varepsilon\) | \(X\)が1単位増えると\(Y\)が約\(100\beta_1\)%変化 |
| 線形対数(linear-log) | \(Y = \beta_0 + \beta_1 \log X + \varepsilon\) | \(X\)が1%増えると\(Y\)が約\(\beta_1/100\)単位変化 |
| 対数対数(log-log) | \(\log Y = \beta_0 + \beta_1 \log X + \varepsilon\) | \(X\)が1%増えると\(Y\)が約\(\beta_1\)%変化(弾力性) |
Andersonモデルは,このうち「対数対数(log-log)」型の考え方を,時点間の変化(差分)に応用したもの,と位置づけられる。
Andersonモデルの「対数差分」,つまり前年比\(\dfrac{X_t}{X_{t-1}}\)の対数が,なぜ%として読めるのか,4ステップで確認する。
① 成長率\(g_t\)を定義する(定義そのものが「前年比の変化率」)
\[g_t = \frac{X_t - X_{t-1}}{X_{t-1}}\]
② 定義を比率の形に書き直す
\[X_t = X_{t-1}(1+g_t) \ \Rightarrow\ \frac{X_t}{X_{t-1}} = 1+g_t\]
③ 対数を取る(ここまでは近似なし,対数の性質だけ)
\[\log X_t - \log X_{t-1} = \log \frac{X_t}{X_{t-1}} = \log(1+g_t)\]
④ 先ほど確認した近似を適用する(\(g_t\)が小さいとき)
\[\log(1+g_t) \approx g_t\]
\[Cost_{i,t} - Cost_{i,t-1} = \beta_0 + \beta_1 (Sales_{i,t} - Sales_{i,t-1}) + \varepsilon_{i,t}\]
\[\log Cost_{i,t} - \log Cost_{i,t-1} = \beta_0 + \beta_1 (\log Sales_{i,t} - \log Sales_{i,t-1}) + \varepsilon_{i,t}\]
対数の性質より \(\log X_{i,t} - \log X_{i,t-1} = \log \dfrac{X_{i,t}}{X_{i,t-1}}\)(割り算のログは引き算になる)。つまり下の式の左辺は,前年比\(\frac{Cost_{i,t}}{Cost_{i,t-1}}\)の対数そのもの。
上の式は金額そのものの変化,下の式(Andersonモデル)は対数差分。係数\(\beta_1\)の意味がまったく違う。
先ほど確認した近似(対数の差\(\approx\)変化率)を\(Cost\)と\(Sales\)の両方に当てはめると,対数差分同士の回帰係数\(\beta_1\)は弾力性(elasticity)として解釈できる。
\[\beta_1 \approx \frac{\%\Delta Cost}{\%\Delta Sales}\]
Andersonモデルの下方硬直性は,この弾力性が増収時(\(\beta_1\))と減収時(\(\beta_1+\beta_2\))で異なる,という主張だと言い換えられる。
set.seed(1)
n <- 400
sim_scale <- tibble(
firm_size = sample(c("小企業", "大企業"), n, replace = TRUE),
lag_sales = if_else(firm_size == "小企業", 1000, 100000),
g_sales = rnorm(n, mean = 0, sd = 0.1)
) |>
mutate(
sales = lag_sales * (1 + g_sales),
lag_cost = lag_sales * 0.6,
cost = lag_cost * (1 + 0.8 * g_sales + rnorm(n, sd = 0.02)),
diff_level = cost - lag_cost,
diff_sales_level = sales - lag_sales,
dlogcost = log(cost / lag_cost),
dlogsales = log(sales / lag_sales)
)
m_level <- lm(diff_level ~ diff_sales_level, data = sim_scale)
m_log <- lm(dlogcost ~ dlogsales, data = sim_scale)
modelsummary(
list("水準モデル" = m_level, "対数モデル" = m_log),
stars = stars,
estimate = "{estimate}{stars}",
gof_map = c("nobs", "r.squared")
)| 水準モデル | 対数モデル | |
|---|---|---|
| (Intercept) | -33.670 | -0.000 |
| (45.970) | (0.001) | |
| diff_sales_level | 0.481*** | |
| (0.006) | ||
| dlogsales | 0.797*** | |
| (0.010) | ||
| Num.Obs. | 400 | 400 |
| R2 | 0.933 | 0.938 |
真の関係は,売上高が1%変わればコストも0.8%変わる,で全企業共通に設定した。対数モデルの係数は\(\beta_1 \approx 0.8\)付近に収束するが,水準モデルの係数は企業規模構成に依存してブレる。
左(水準)では大企業と小企業で点の散らばる場所がまったく違う。右(対数差分)では,規模に関係なく同じ直線関係に乗る。
Andersonモデルが対数差分を使う理由は,単に変化率にしたいからだけではない。
下方硬直性の分析は,対数変換で弾力性を作り,交互作用でその弾力性を増減収で分割する,という2つの道具の組み合わせでできている。
重回帰分析では,独立変数を複数含められる。さらに,独立変数どうしの掛け合わせ(交互作用項)を加えると,「一方の効果がもう一方の値によって変わる」関係を推定できる。
直感的な例:勉強時間が点数に与える効果は,睡眠時間によって変わりそう。睡眠が十分なら,勉強した分だけ点数が伸びる。でも寝不足だと,同じだけ勉強しても身につきにくい。一方の変数(勉強時間)の効果が,もう一方の変数(睡眠時間)の水準によって変わる,これが交互作用。
\[Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \beta_3 (X_1 \times X_2) + \varepsilon\]
\(X_1\) の効果(\(Y\) を \(X_1\) で偏微分):
\[\frac{\partial Y}{\partial X_1} = \beta_1 + \beta_3 X_2\]
→ \(X_2\) の値によって \(X_1\) のスロープが変わる。
今分析した Anderson モデルは,実は交互作用モデルだった。
\[\Delta\log SGA = \beta_0 + \beta_1 \Delta\log Sales + \beta_2 (Dec \times \Delta\log Sales) + \varepsilon\]
\(Dec\) を0か1しかとらないので,式を展開すると:
\[\begin{cases} \Delta\log SGA = \beta_0 + \beta_1 \Delta\log Sales + \varepsilon & (Dec = 0\text{: 増収時}) \\ \Delta\log SGA = \beta_0 + (\beta_1 + \beta_2)\Delta\log Sales + \varepsilon & (Dec = 1\text{: 減収時}) \end{cases}\]
→ 2本の直線(傍きが増収・減収の2段階で切り替わる)
pred_and <- tibble(
dlogsales = seq(-0.3, 0.3, length.out = 100)
) |>
mutate(
inc = coef(model)["(Intercept)"] + coef(model)["dlogsales"] * dlogsales,
dec_line = coef(model)["(Intercept)"] +
(coef(model)["dlogsales"] + coef(model)["dec_dlogsales"]) * dlogsales
) |>
pivot_longer(inc:dec_line, names_to = "grp", values_to = "pred") |>
mutate(grp = if_else(grp == "inc", "増収時 (Dec=0)", "減収時 (Dec=1)"))
ggplot(pred_and, aes(x = dlogsales, y = pred, color = grp)) +
geom_line(linewidth = 1) +
geom_hline(yintercept = 0, linetype = "dashed", alpha = 0.4) +
geom_vline(xintercept = 0, linetype = "dashed", alpha = 0.4) +
labs(x = "売上高変化率(対数)", y = "販管費変化率(対数)",
color = NULL) +
theme_minimal()2本の直線の傾きの差 \(= \hat{\beta}_2\)
Rでの記法
lm(y ~ x1 * x2) は lm(y ~ x1 + x2 + x1:x2) と同じ。* で交互作用項・主効果の両方を自動包含。
\(Dec\)(0/1)を連続変数に置き換えると?
\[Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \beta_3 (X_1 \times X_2) + \varepsilon\]
\[\frac{\partial Y}{\partial X_1} = \beta_1 + \beta_3 X_2\]
→ \(X_2\) の値が変わるたびにスロープが変わる。無数の直線。
| 0/1 ダミー × 連続変数 | 連続変数 × 連続変数 | |
|---|---|---|
| スロープの種類 | 2本(0か1か) | 無数(\(X_2\) の値ごと) |
| 変化のしかた | 段階的に切り替わる | 連続的に変化する |
各変数から平均を引く:\(\tilde{X} = X - \bar{X}\)
例:試験の点数 \(Score\),学習時間 \(Study\),睡眠時間 \(Sleep\)
\[Score = \beta_0 + \beta_1 Study + \beta_2 Sleep + \beta_3 (Study \times Sleep) + \varepsilon\]
偏微分すると:
\[\frac{\partial Score}{\partial Study} = \beta_1 + \beta_3 \cdot Sleep\]
→ \(\beta_1\) は「\(Sleep = 0\)(睡眠ゼロ)のときの学習効果」← 非現実的
中心化:\(\tilde{X} = X - \bar{X}\)(平均を引く)
\[Score = \beta_0 + \beta_1 \tilde{Study} + \beta_2 \tilde{Sleep} + \beta_3 (\tilde{Study} \times \tilde{Sleep}) + \varepsilon\]
→ \(\beta_1\) は「\(Sleep\) が平均値のときの学習効果」← 解釈可能
| 係数 | 中心化後の意味 |
|---|---|
| \(\beta_1\) | \(Sleep\) が平均値のときの \(Study\) の効果 |
| \(\beta_2\) | \(Study\) が平均値のときの \(Sleep\) の効果 |
| \(\beta_3\) | \(Study\) の効果が \(Sleep\) 1単位増加でどれだけ変わるか |
\(\beta_3\) の値は中心化の前後で変わらない。変わるのは主効果の解釈のみ。
真のモデル:\(Score = 30 + 5 Study + 4 Sleep + 2 Study \times Sleep + \varepsilon\)
# 変数作成
set.seed(42)
n <- 300
sim <- tibble(
study = rnorm(n, mean = 4, sd = 1.5),
sleep = rnorm(n, mean = 6, sd = 1.2)
) |>
mutate(score = 30 + 5 * study + 4 * sleep + 2 * study * sleep + rnorm(n, sd = 8))
# 中心化
sim <- sim |>
mutate(
c_study = study - mean(study),
c_sleep = sleep - mean(sleep),
c_inter = c_study * c_sleep
)
# 回帰モデルの推定
m_raw <- lm(score ~ study + sleep + I(study * sleep), data = sim)
m_cent <- lm(score ~ c_study + c_sleep + c_inter, data = sim)
# 結果の表示
modelsummary(
list("中心化なし" = m_raw, "中心化あり" = m_cent),
stars = stars,
estimate = "{estimate}{stars}",
gof_map = c("nobs", "r.squared"),
coef_map = c(
"(Intercept)" = "切片",
"study" = "学習時間",
"c_study" = "学習時間",
"sleep" = "睡眠時間",
"c_sleep" = "睡眠時間",
"I(study * sleep)" = "交互作用",
"c_inter" = "交互作用"
)
)| 中心化なし | 中心化あり | |
|---|---|---|
| 切片 | 27.629*** | 120.542*** |
| (7.582) | (0.447) | |
| 学習時間 | 6.056*** | 16.583*** |
| (1.754) | (0.303) | |
| 睡眠時間 | 4.545*** | 11.545*** |
| (1.252) | (0.381) | |
| 交互作用 | 1.764*** | 1.764*** |
| (0.289) | (0.289) | |
| Num.Obs. | 300 | 300 |
| R2 | 0.933 | 0.933 |
\(\hat{\beta}_3\) は両モデルで一致。切片と主効果の係数のみ変化。
交互作用あり → ねじれた曲面。なし → 平らな平面。
「睡眠時間が異なる水準で,学習時間とスコアの関係はどう変わるか」
sleep_q <- quantile(sim$sleep, probs = c(0.1, 0.5, 0.9))
sleep_lab <- c("低 (10%ile)", "中央値", "高 (90%ile)")
pred_data <- tibble(
study = rep(seq(min(sim$study), max(sim$study), length.out = 50), times = 3),
sleep = rep(sleep_q, each = 50),
grp = rep(sleep_lab, each = 50)
) |>
mutate(score_hat = predict(m_raw, newdata = pick(study, sleep)))
ggplot(pred_data, aes(x = study, y = score_hat,
color = grp, group = grp)) +
geom_line(linewidth = 1) +
labs(x = "学習時間(時間)", y = "予測点数",
color = "睡眠時間の水準") +
theme_minimal()3本の直線の傾きが異なる → 交互作用の存在。傾きが等しければ交互作用はない。
コストの下方硬直性の研究は,販売費及び一般管理費(SG&A)を対象として研究されてきました。
一方で,販管費には何百,何千もの費目が含まれているとも言われます(Tracy and Tracy 2014)
経営者の戦略的な意思決定を捉えるためには,より細分化された費目を用いた分析も役に立ちそうです 。
以下の分析コードと説明内容をQuartoのqmdファイルで提出してください。分析コードは実行可能なようにR Code Chunkに書いてください。
2026 経営データ分析(会計)