9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

総務省統計局の家計調査データからチョコレートを分析する

Last updated at Posted at 2023-02-20

はじめに

前回の記事で総務省統計局から取得したデータを加工し、扱いやすくしました

加工結果はこちら

今回はこの加工したデータを使って、完全にバレンタインに遅れていますがチョコレートの分析を行います

例によって Livebook を使います

実装したノートブックはこちら

出典

以下のデータを加工して作成

総務省統計局ホームページ

家計調査(家計収支編) 時系列データ(二人以上の世帯)

https://www.stat.go.jp/data/kakei/longtime/index.html#time

  • 月 全品目(2015年改定)
  • 月 全品目(2020年改定)

(2023年2月20日に利用)

セットアップ

必要なモジュールをインストールします

Mix.install([
  {:explorer, "~> 0.5"},
  {:kino, "~> 0.8"},
  {:kino_vega_lite, "~> 0.1"},
  {:req, "~> 0.3"}
])

準備

Explorer を使うための準備をします

alias Explorer.DataFrame
alias Explorer.Series
require Explorer.DataFrame

alias によって Explorer. を省略できるようになります

require Explorer.DataFrame によって、データ解析時にクエリが使えるようになります

詳細は以下の記事を参照してください

データ取得

加工済データをダウンロードし、データフレームに読み込みます

household_df =
  "https://raw.githubusercontent.com/RyoWakabayashi/elixir-learning/main/livebooks/explorer/%E5%AE%B6%E8%A8%88%E6%94%AF%E5%87%BA%E7%B5%B1%E8%A8%88_%E5%93%81%E7%9B%AE%E5%B9%B4%E6%9C%88%E5%88%A5.csv"
  |> Req.get!()
  |> then(&DataFrame.load_csv!(&1.body))

Kino.DataTable.new(household_df)

year_month.png

データは品目分類毎、年月毎に世帯平均の支出金額を持っています

月次推移

符号 == "352" でチョコレートのデータだけを抽出します

choco_df = DataFrame.filter(household_df, 符号 == "352")

Kino.DataTable.new(choco_df)

月次推移を VegaLite でグラフ化します

month = Series.to_list(choco_df["年月"])
expenses = Series.to_list(choco_df["支出金額"])

VegaLite.new(width: 700, title: "チョコレート支出金額推移")
|> VegaLite.data_from_values(x: month, y: expenses)
|> VegaLite.mark(:line, tooltip: true)
|> VegaLite.encode_field(:x, "x", type: :temporal, title: "年月")
|> VegaLite.encode_field(:y, "y", type: :quantitative, title: "支出金額")

choco_graph_manth.png

かなり規則的な周期が見えます

各年に分けて、何月が毎年ピークになっているのか見てみましょう(見なくても分かるとは思いますが)

2015..2022
|> Enum.map(fn year ->
  df = DataFrame.filter(choco_df,  == ^year)

  month = Series.to_list(df["月"])
  expenses = Series.to_list(df["支出金額"])

  graph =
    VegaLite.new(width: 700, title: "チョコレート支出金額推移")
    |> VegaLite.data_from_values(x: month, y: expenses)
    |> VegaLite.mark(:line, tooltip: true)
    |> VegaLite.encode_field(:x, "x", type: :ordinal, title: "月")
    |> VegaLite.encode_field(:y, "y",
      type: :quantitative,
      title: "支出金額",
      scale: [domain: [0, 1500]]
    )

  {year, graph}
end)
|> Kino.Layout.tabs()

choco_graph_per_year.gif

毎年2月にピークを迎え、暑くなると落ち込んでいます

日本のチョコレート市場は明確にバレンタインに依存しています

また、新型コロナウィルスの影響が僅かに見て取れます

WHOのパンデミック宣言が2020年3月11日なので、2020年までのバレンタインに比べて、2021年、2022年のバレンタインの盛り上がりは控えめになっています

年次推移

では年次推移を見てみましょう

支出金額を年単位で集約します

year_choco_df =
  choco_df
  |> DataFrame.group_by("年")
  |> DataFrame.summarise(
    最小: min(支出金額),
    最大: max(支出金額),
    平均: mean(支出金額),
    合計: sum(支出金額)
  )

Kino.DataTable.new(year_choco_df)

choco_sum.png

直観的に分かるようにグラフ化してみます

まず合計の年次推移を見ます

year = Series.to_list(year_choco_df["年"])
expenses = Series.to_list(year_choco_df["合計"])

VegaLite.new(width: 700, title: "チョコレート年間支出金額推移")
|> VegaLite.data_from_values(x: year, y: expenses)
|> VegaLite.mark(:line)
|> VegaLite.encode_field(:x, "x", type: :ordinal, title: "年")
|> VegaLite.encode_field(:y, "y", type: :quantitative, title: "合計支出金額")

choco_graph_sum.png

合計支出金額は 2015年から2019年に上昇し、その後停滞もしくは微減しています

最小、最大、平均の推移も見てみましょう

各統計項目を重ねてグラフ化したいので、 DataFrame.pivot_longer でデータフレームの形を変えます

pivot_table =
  DataFrame.pivot_longer(
    year_choco_df,
    ["最小", "最大", "平均"],
    names_to: "統計項目",
    values_to: "統計値"
  )

Kino.DataTable.new(pivot_table)

choco_pivot.png

統計項目を色として、3種類の統計値を重ねて表示します

year = Series.to_list(pivot_table["年"])
items = Series.to_list(pivot_table["統計項目"])
values = Series.to_list(pivot_table["統計値"])

VegaLite.new(width: 700, title: "チョコレート年間支出金額推移")
|> VegaLite.data_from_values(x: year, items: items, values: values)
|> VegaLite.mark(:line)
|> VegaLite.encode_field(:x, "x", type: :ordinal, title: "年")
|> VegaLite.encode_field(:y, "values", type: :quantitative, title: "支出金額")
|> VegaLite.encode_field(:color, "items")

choco_graph_min_max_mean.png

これを見ると、2021年に最大がガクッと下がったのに対して、最小や平均は下がっていないことが分かります

つまり、バレンタインのようなイベントに集中して消費されていたのが、近年では年間通して食べられるようになったわけです

「チョコレート効果」や「GABA」のような健康志向の商品の売れ行きが好調のようです

菓子類内訳

では、菓子類全体の中でチョコレートはどれくらいの割合を占めているのでしょうか

大分類1、中分類8の菓子類データを抽出します

snack_df =
  DataFrame.filter(
    household_df,
    大分類 == "1" and
      中分類 == "8" and
      符号 != "-"
  )

Kino.DataTable.new(snack_df)

2022年12月時点の菓子類の各品目を支出金額の高い順に並べてみましょう

latest_snack_df = DataFrame.filter(snack_df,  == 2022 and  == 12)

items = Series.to_list(latest_snack_df["品目分類"])
expenses = Series.to_list(latest_snack_df["支出金額"])

VegaLite.new(width: 700, title: "菓子類支出金額")
|> VegaLite.data_from_values(x: items, y: expenses)
|> VegaLite.mark(:bar, tooltip: true)
|> VegaLite.encode_field(:x, "x", type: :nominal, title: "品目分類", sort: "-y")
|> VegaLite.encode_field(:y, "y", type: :quantitative, title: "支出金額")

snack_bar.png

他の菓子が圧倒的に多いですが、品目単体として見ると以下の順になっています

  • 1位: ケーキ
  • 2位: チョコレート
  • 3位: せんべい

支出金額で見ているため、単価の高いケーキが1位なのは納得です

そういった中、2位につけているチョコレートは素晴らしいと言えます

円グラフでも見てみましょう

VegaLite.new(title: "菓子類支出金額")
|> VegaLite.data_from_values(x: items, y: expenses)
|> VegaLite.mark(:arc, inner_radius: 50, tooltip: true)
|> VegaLite.encode_field(:color, "x", type: :nominal, title: "品目分類")
|> VegaLite.encode_field(:theta, "y", type: :quantitative, title: "支出金額")

snack_arc.png

ケーキの割合がかなり高いことが分かります

しかし、チョコレートもチョコレート菓子を合わせれば中々のものです

「チョコレート」と「チョコレート菓子」の違いはグリコが教えてくれます

例を挙げると、以下のように分かれています

  • チョコレート

    • 明治ミルクチョコレート
    • 森永ミルクチョコレート
    • ガーナチョコレート
    • ルックチョコレート
    • DARS
    • 紗々
  • チョコレート菓子

    • きのこの山
    • たけのこの里
    • コアラのマーチ
    • トッポ
    • ポッキー
    • チョコボール

菓子類全体の支出金額推移を見てみましょう

total_snack_df =
  DataFrame.filter(
    household_df,
    大分類 == "1" and
      中分類 == "8" and
      符号 == "-"
  )

Kino.DataTable.new(total_snack_df)
month = Series.to_list(total_snack_df["年月"])
expenses = Series.to_list(total_snack_df["支出金額"])

VegaLite.new(width: 700, title: "菓子類支出金額推移")
|> VegaLite.data_from_values(x: month, y: expenses)
|> VegaLite.mark(:line, tooltip: true)
|> VegaLite.encode_field(:x, "x", type: :temporal, title: "年月")
|> VegaLite.encode_field(:y, "y", type: :quantitative, title: "支出金額")

snack_graph.png

周期的に突出しているのは12月で、ケーキのクリスマス特需です

何となく、菓子類全体では上昇傾向になっていそうですね

では、菓子類全体に占めるチョコレートの割合=チョコレート率を見てみましょう

ついでにチョコレート菓子率と、チョコレートとの合計でチョコレート類率も算出します

choco_snack_df = DataFrame.filter(household_df, 符号 == "353")

ratio_df =
  total_snack_df[["年月", "支出金額"]]
  |> DataFrame.join(
    choco_df[["年月", "支出金額"]],
    on: ["年月"]
  )
  |> DataFrame.rename(["年月", "菓子類合計", "チョコレート"])
  |> DataFrame.join(
    choco_snack_df[["年月", "支出金額"]],
    on: ["年月"]
  )
  |> DataFrame.rename(["年月", "菓子類合計", "チョコレート", "チョコレート菓子"])
  |> DataFrame.mutate(
    チョコレート率: チョコレート / 菓子類合計,
    チョコレート菓子率: チョコレート菓子 / 菓子類合計
  )
  |> DataFrame.mutate(チョコレート類率: チョコレート率 + チョコレート菓子率)
  |> DataFrame.pivot_longer(
    &String.ends_with?(&1, "率"),
    names_to: "品目",
    values_to: "占有率"
  )

Kino.DataTable.new(ratio_df)

チョコレート率の推移をグラフ化します

month = Series.to_list(ratio_df["年月"])
items = Series.to_list(ratio_df["品目"])
ratio = Series.to_list(ratio_df["占有率"])

VegaLite.new(width: 600, title: "占有率推移")
|> VegaLite.data_from_values(x: month, y: ratio, color: items)
|> VegaLite.mark(:line, tooltip: true)
|> VegaLite.encode_field(:x, "x", type: :temporal, title: "年月")
|> VegaLite.encode_field(:y, "y", type: :quantitative, title: "占有率")
|> VegaLite.encode_field(:color, "color")

choco_ratio_graph.png

チョコレート菓子はそこまでバレンタインに依存していないことが分かります

チョコレート類率の最大値は2017年2月の 23.2% でした

こうして見ると、チョコレート類率はコロナ以前、2018年から減少傾向にありそうです

では菓子類全体の年次推移を見てみましょう

year_total_snack_df =
  total_snack_df
  |> DataFrame.group_by("年")
  |> DataFrame.summarise(合計: sum(支出金額))

Kino.DataTable.new(year_total_snack_df)
year = Series.to_list(year_total_snack_df["年"])
expenses = Series.to_list(year_total_snack_df["合計"])

VegaLite.new(width: 700, title: "菓子類年間支出金額推移")
|> VegaLite.data_from_values(x: year, y: expenses)
|> VegaLite.mark(:line, tooltip: true)
|> VegaLite.encode_field(:x, "x", type: :ordinal, title: "年")
|> VegaLite.encode_field(:y, "y", type: :quantitative, title: "合計支出金額")

snack_line.png

なんと、菓子類全体はコロナで下がるどころか上がっています

巣篭もり需要と値上げが要因でしょうか

チョコレート率の年次推移を見てみます

year_choco_snack_df =
  choco_snack_df
  |> DataFrame.group_by("年")
  |> DataFrame.summarise(合計: sum(支出金額))

year_ratio_df =
  year_total_snack_df[["年", "合計"]]
  |> DataFrame.join(
    year_choco_df[["年", "合計"]],
    on: ["年"]
  )
  |> DataFrame.rename(["年", "菓子類合計", "チョコレート"])
  |> DataFrame.join(
    year_choco_snack_df[["年", "合計"]],
    on: ["年"]
  )
  |> DataFrame.rename(["年", "菓子類合計", "チョコレート", "チョコレート菓子"])
  |> DataFrame.mutate(
    チョコレート率: チョコレート / 菓子類合計,
    チョコレート菓子率: チョコレート菓子 / 菓子類合計
  )
  |> DataFrame.mutate(チョコレート類率: チョコレート率 + チョコレート菓子率)
  |> DataFrame.pivot_longer(
    &String.ends_with?(&1, "率"),
    names_to: "品目",
    values_to: "占有率"
  )

Kino.DataTable.new(year_ratio_df)
year = Series.to_list(year_ratio_df["年"])
items = Series.to_list(year_ratio_df["品目"])
ratio = Series.to_list(year_ratio_df["占有率"])

VegaLite.new(width: 600, title: "占有率推移")
|> VegaLite.data_from_values(x: year, y: ratio, color: items)
|> VegaLite.mark(:line, tooltip: true)
|> VegaLite.encode_field(:x, "x", type: :ordinal, title: "年")
|> VegaLite.encode_field(:y, "y", type: :quantitative, title: "占有率")
|> VegaLite.encode_field(:color, "color")

choco_ratio_year_graph.png

チョコレート率はやはりコロナの影響が大きく、菓子類全般の伸びには追従できていないようですが、チョコレート菓子率が伸びています

チョコレート菓子は元からバレンタインの影響が少なく、焼きチョコなどの夏でも食べやすい商品もあります

ただし、支出金額なので値上げの影響も考えられます

元から安かったチョコレート菓子の場合、数円の値上げが大きく影響します

多少値上げしてもブラックサンダー愛好家は買い続けますが、ちょっと贅沢なチョコレートは買い控えるようになったのかもしれません

まとめ

総務省統計局のデータを見ることで、チョコレートに関して様々な視点で分析することができました

とりあえずチョコレートが食べたくなりました

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?