「データ収集 (data collection)」は問いに答えるために必要な観測値を、 設計に基づいて取得する工程。 標本抽出設計・調査票設計・センサー設計・ログ設計・スクレイピング・API 取得などが含まれる。 本ページでは無作為抽出・層化抽出・クラスター抽出・調査票設計のコツ・観察データと実験データの違い・収集段階で混入する選択バイアスへの対処を整理する。
これらのキーワードは「設計 → 抽出 → 取得 → バイアス点検」というデータ収集の標準フローを構成する。 設計段階の選択が結論の妥当性を決める。
🍰 まずはやさしく
データ収集は材料集めのようなものです。
正しい分析や予測をするために使います。
部活のアンケートで意見を集めることです。
データの集め方と注意点を読みましょう。
目的に応じてデータを集めるプロセス
データ収集 ── 分析・予測・意思決定のために、 目的に応じてデータを系統的に取得するプロセスの総称。 「どのデータを、 どこから、 どう、 どれだけ集めるか」を設計する活動。
🍰 まずはやさしく
データ収集は分析の最初のステップです。
全体の質を決めるために使います。
スマホのアプリで記録をつけることです。
収集が後の工程にどう影響するか読みましょう。
データ収集はデータ分析パイプラインの最上流。 ここでの選択が、 下流すべて(前処理、モデリング、結論)の品質を決定づけます。 「Garbage In, Garbage Out」── 入口に何を入れるかが、 出口の質を支配します。
統計学では 標本理論 として、 計算機科学では ETL/ELT として、 ビジネスでは 市場調査 として、 異なる伝統で発展してきました。 本ページは横断的に概観します。
🍰 まずはやさしく
データ収集は必要な情報を探す作業です。
問いへの答えを出すために使います。
学校の購買で人気の商品を調べることです。
集め方の種類と失敗例について読みましょう。
データ収集は「分析の問い (Question) を起点に、 必要な観測・サンプル・ログを どこから、 誰が、 いつ、 どんな粒度で 取るかを決めて取得する工程」。 SSDSE-B-2026 のように既製の公的統計を使うか、 アンケート・センサ・スクレイピングで新規取得するかで、 必要な技術・倫理判断・コストが大きく変わる。 ここで集めたものが分析の質の上限を決めるため、 取れた量よりも 母集団と取得方法 の設計が最重要となる。
以下では、 公的統計の二次利用 (SSDSE / e-Stat / OECD)、 アンケート設計、 Web スクレイピング、 IoT センサ、 アクセスログという 5 つの代表的収集経路を比較し、 それぞれの母集団定義・サンプリング設計・倫理判断 (個人情報・robots.txt・GDPR) を整理します。 「Convenience sampling で偏った標本のまま全国を語る」「ログのタイムゾーン混在に気づかず日次集計が崩れる」など、 収集段階での失敗が後段すべてを汚染する典型例も順に辿ります。
「日本人の平均的な朝食」を調べる、 という課題を例に:
違いは「母集団を代表するか」「欠落しがちな声をどう拾うか」の意識。 これがデータ収集設計のすべてです。
| 分類 | 代表例 | コスト | 代表性 | 速報性 |
|---|---|---|---|---|
| 公的統計 | e-Stat, SSDSE, 国勢調査 | 無料 | 高(悉皆/確率標本) | 低(年次) |
| 商用パネル | マクロミル, Nielsen | 高 | 中(自社の標本) | 中 |
| IoT/センサー | スマートメーター, ウェアラブル | 機器コスト+通信 | 中(設置箇所依存) | 高(リアルタイム) |
| Web/API | REST API, GraphQL | 無料〜中 | 提供者次第 | 高 |
| スクレイピング | requests + BeautifulSoup | 無料(規約遵守) | 低〜中 | 中 |
| アンケート | Google Forms, Qualtrics | 中 | 設計次第 | 中 |
| SNS | X, Reddit API | 無料〜高 | 低 | 高 |
| トランザクション | POS、 ECサイト | 自社なら無料 | 顧客のみ | 高 |
| 行政オープン | 政府CIO, RESAS | 無料 | 高 | 低〜中 |
🍰 まずはやさしく
データ収集は情報を集める仕組みのことです。
正確な結果を出すために使います。
買い物で値段を比べることです。
集める時のルールや条件について読みましょう。
目的に応じてデータを集めるプロセス
英語名 Data Collection。
この用語を理解・使用するときは、 次のような前提を意識してください:
「何件集めれば足りるか?」を決める基本式(比率推定の場合):
$$ n = \frac{z^2 \cdot p (1-p)}{e^2} $$
$z$=信頼水準に対応する標準正規分位(95% なら 1.96)、 $p$=母比率の事前推定値(不明なら 0.5)、 $e$=許容誤差。 例えば「±3% で 95% 信頼」なら $n = 1.96^2 \cdot 0.25 / 0.03^2 \approx 1067$ 件。 全国意識調査の標本数 1000〜2000 件はこの式で説明できます。
層別抽出・多段抽出ならさらに少なくて済むこともあるし、 小集団分析(部分集合のみで結論)なら逆に多く必要。 平均推定の場合は分散 $\sigma^2$ を使った別式:$n = z^2 \sigma^2 / e^2$。
| 手法 | 説明 | 向く場面 |
|---|---|---|
| 単純無作為抽出 | 名簿から完全ランダム | 母集団リストがある |
| 層別抽出 | グループ別の比率を保つ | 分散が大きく異なる層 |
| 系統抽出 | k 件おきに抽出 | 名簿が並んでいる |
| クラスター抽出 | 地域単位など群で抽出 | 広域調査でコスト削減 |
| 便宜抽出 | 取りやすい人を抽出 | 予備調査のみ |
データ収集 (Data Collection) は単なる「集める作業」ではなく、 母集団 (Population) からの確率的抽出として数学的に定式化されます。 SSDSE-B-2026 は 47 都道府県を悉皆 (全数) 収集していますが、 民間調査やセンサーログは通常サンプルです。 ここでは抽出設計の数式を 5 段階で示します。
$$P(s) = \frac{1}{\binom{N}{n}}, \quad \forall s \in \mathcal{S}_n$$
数式を言葉で読み解く: 「サイズ $n$ のすべての標本 $s$ が等確率で選ばれる」。 47 都道府県から 10 件抽出するなら、 すべての $\binom{47}{10} = 13{,}884{,}156$ 通りが等確率。 推定が単純な一方、 重要な小規模集団 (鳥取・島根等) が抽出されない危険あり。
$$n = \sum_{h=1}^{H} n_h, \quad n_h = n \cdot \frac{N_h \sigma_h}{\sum_{k} N_k \sigma_k}$$
数式を言葉で読み解く: 「母集団を層 (地方・規模・年齢層など) に分け、 層内のばらつき $\sigma_h$ が大きい層により多くサンプルを割く」(ネイマン配分)。 SSDSE-B 風に解釈すれば「人口の多い県は分散が大きいので関東は多めに抽出」。
$$\hat{\theta} = \frac{N}{n} \sum_{i=1}^{n} \theta_i$$
数式を言葉で読み解く: 「自然な集まり (クラスタ = 都道府県・学校・店舗) をまず抽出し、 その中の全員を調査」。 47 都道府県から 5 県を抽出→その全市町村を悉皆。 訪問コストが激減する一方、 同じクラスタ内は似ているので有効サンプルは小さい。
$$s_k = a + (k-1) \cdot \frac{N}{n}, \quad k = 1, 2, \ldots, n$$
数式を言葉で読み解く: 「最初の位置 $a$ を乱数で決め、 以後 $N/n$ おきに抽出」。 47 都道府県から 5 件なら $47/5 \approx 9.4$ 県おき。 周期性のあるデータでは偏る危険。
国勢調査・労働力調査は「都道府県 → 市区町村 → 国勢統計区 → 世帯 → 個人」の多段抽出。 各段で抽出確率の積が個人の包含確率になり、 加重で母集団推定する。
調査票への回答率は通常 60-80%。 残りは無回答 (Non-response) で、 これを放置するとバイアス発生。 ロジスティック回帰で「回答する確率」をモデル化し、 逆数で重み付ける手法が標準。
$$\log \frac{\Pr(R_i=1 \mid X_i)}{1 - \Pr(R_i=1 \mid X_i)} = \beta_0 + \beta_1 X_{i1} + \cdots + \beta_p X_{ip}$$
数式を言葉で読み解く: 「回答する確率の対数オッズは、 個人属性 (年齢・地域・性別) の線形和でモデル化」。 SSDSE-B 風に解釈すると「都道府県と人口で回答率が予測できる」と仮定し、 各観測値を $1/\hat{p}_i$ で重み付ける。
これにより「東京の高齢者は回答率高、 沖縄の若年層は低」というような系統的差異を補正できる。 ただし「回答しないことが結果と独立 (MAR 仮定)」が満たされる必要がある (Missing At Random)。
調査の前段階で「何人に聞けば十分か」を見積もる式です。 比率 $p$ を信頼水準 $1-\alpha$、 許容誤差 $E$ で推定する場合:
$$n = \frac{z_{\alpha/2}^2 \cdot p(1-p)}{E^2}$$
数式を言葉で読み解く: 「許容誤差 $E$ を小さくしたいほど、 また信頼水準 $1-\alpha$ を高くしたいほど、 必要サンプル $n$ は大きくなる」。 95% 信頼水準・許容誤差 5% で支持率を推定するなら $n = 1.96^2 \cdot 0.25 / 0.05^2 \approx 384$ 人。
$$n_{\text{adj}} = \frac{n}{1 + (n-1)/N}$$
$N$ が小さいときは少ない人数で十分。 SSDSE-B-2026 の文脈で「全国 1.26 億人から 384 件で十分」、 「鳥取県 54 万人から 383 件で十分」と、 母集団サイズが大きく違っても必要 $n$ は大差なし。
データ収集を「事前知識を事後知識へ更新するプロセス」として捉えると、 ベイズの定理が骨格になります。
$$p(\theta \mid D_{\text{new}}) = \frac{p(D_{\text{new}} \mid \theta) \cdot p(\theta \mid D_{\text{old}})}{p(D_{\text{new}})}$$
数式を言葉で読み解く: 「新規データ $D_{\text{new}}$ を得ると、 パラメータ $\theta$ の信念分布は事前分布 $p(\theta \mid D_{\text{old}})$ から事後分布 $p(\theta \mid D_{\text{new}})$ に更新される」。 SSDSE-B-2026 (2023 年) を観測することで、 SSDSE-B-2025 から得ていた信念がアップデートされる。
この観点で「データ収集はもう十分か?」を判定できる: 新規データを 1 件追加しても事後分布がほとんど動かなくなれば収集を止めてよい。 ベイズ最適停止 (Bayesian Optimal Stopping)。
| 手法 | コスト | 代表性 | 頻度 | 適例 |
|---|---|---|---|---|
| 悉皆調査 | 超高 | 完全 | 低 (5 年/回) | 国勢調査・SSDSE |
| 標本調査 | 中 | 高 (設計次第) | 中 | 家計調査・選挙世論 |
| 実験 | 中-高 | 内部妥当性高 | 単発-連続 | 医薬品試験・A/B テスト |
| 観察 | 中 | 中 | 連続 | フィールドワーク |
| Web ログ | 低 | 偏在 | リアルタイム | EC サイト |
| API | 低 | 提供者次第 | 高頻度 | 天気・金融・SNS |
| スクレイピング | 低 | 低 (構造変化に脆い) | 中 | 価格比較・ニュース |
| センサー | 中 (初期高) | 空間限定 | 超高頻度 | IoT・スマートシティ |
「データ収集とは、 不確実性を減らすために確率的に世界を観測する行為であり、 そこに倫理・法律・設計の三位一体がある」。
データ収集はテキスト DL や API 叩きだけが手段ではありません。 調査法(survey)・観察法・実験法・スクレイピング・センサーログの 5 系統があり、 それぞれにバイアスと倫理が伴います。 SSDSE-B-2026 のような公的統計も「全数調査ベース+推計」で、 単純なランダムサンプリングではない点が落とし穴。
無作為標本平均の標準誤差は $SE = \sigma/\sqrt{n}$ で、 n を 4 倍にして初めて SE が半分になる。 信頼区間幅は 2zSE で、 n=400 と n=10,000 では幅が 5 倍違う。 「サンプル多い=精度高い」は √n 効果という非線形の代償付き。
SSDSE-B-2026 から無作為に n=10 県を抽出して総人口平均を求めると 全 47 県平均(≈2,646,000 人)からの SE は σ/√10。 県別人口の SD は約 2,800,000 のため SE ≈ 885,000 と非常に大きく、 「少数県の平均」では実態を表せない。
🎯 このコードでやること: SSDSE-B-2026 を読み込み、 全 47 県平均と n=10 ランダム抽出の標本平均を比較し、 サンプリング誤差を可視化する。 pandas.DataFrame.sample で抽出。
📥 入力データ: SSDSE-B-2026 (data/raw/SSDSE-B-2026.csv) 47 県の総人口列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=1, encoding='cp932') df = df[df['年度'] == 2023]; pop = df['総人口'] # 最新年度に絞り総人口列を取得 true_mean = pop.mean() true_sd = pop.std() # n=10 ランダム抽出を 1000 回繰り返して標本平均の分布を観察 sample_means = [pop.sample(10, random_state=i).mean() for i in range(1000)] sample_se = np.std(sample_means) theory_se = true_sd / np.sqrt(10) print(f"母集団平均(全 47 県) = {true_mean:,.0f}") print(f"母集団 SD = {true_sd:,.0f}") print(f"n=10 標本平均の SE 実測 = {sample_se:,.0f}") print(f"理論 SE = σ/√n = {theory_se:,.0f}") print(f"95% CI 幅(n=10) = ±{1.96*sample_se:,.0f}") |
📤 実行結果:
💬 結果の読み方: 95% CI が ±1,656,653 ということは、 標本平均が 1,037,000 〜 4,350,000 のどこにあっても不思議でない。 つまり n=10 で「日本の県平均人口」を語ると 4 倍違う推定値が出る。 サンプリング設計の重要性が定量的に示される。
データ収集は「集める前にどう設計するか」が最終分析の品質を決める。 ここでは SSDSE-B-2026(独立行政法人統計センターが提供する都道府県別社会経済データ)を題材に、 散布図 / ヒストグラム / 多群箱ひげ図の 3 視点から「収集された統計データがどう見えるか」「集計単位や粒度を変えると何が変わるか」「収集設計のバイアスがどう表面化するか」を 17,000 文字級で徹底検証する。 これは座学の補強ではなく、 実際にデータ収集者の立場で「集計値だけを渡された後の分析者」が直面する典型的な解釈場面を再現する。
| 図 | 図ファイル | 使用変数 | 収集設計上の問い |
|---|---|---|---|
| 散布図 | figures/scatter_basic.png | 総人口 × 高齢人口 | サンプリング単位を「都道府県」にした時点で、 1 件の異常値(東京)が全体構造を支配しないか |
| ヒストグラム | figures/hist_basic.png | 総人口の分布 | 母集団 47 件・対数スケール未適用の素のヒストグラムで、 中心値・裾の重さ・代表値の選択は妥当か |
| 多群箱ひげ図 | figures/box_multigroup.png | 地域ブロック × 消費支出 | 地域別に層化収集した場合、 ブロック間分散とブロック内分散のどちらが大きいか(層化抽出設計の評価) |
SSDSE-B-2026 の都道府県単位データを散布図にすると、 多くの場合「東京・神奈川・大阪が右上に伸びるロング・テール構造」が出現する。 これは 収集単位の不均質性 が起こす典型現象で、 「市区町村」単位や「経済圏」単位に再集計すると景色が大きく変わる。 つまり収集データの解釈は「単位の選び方」と一体で考える必要がある。
このコードでやること: SSDSE-B-2026 を読み込み、 47 都道府県の総人口 (A1101) と高齢人口 (A1303, 65歳以上人口) で散布図を描く。 散布図そのものは figures/scatter_basic.png として既に保存済のため、 ここでは「再現スクリプト」と「読み取り結果」を提示する。
📥 入力データ (SSDSE-B-2026 の先頭抜粋、 A1303 は 65 歳以上人口):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import os os.makedirs('html/figures', exist_ok=True) # 保存先のフォルダを作っておく import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932') df = df[df['SSDSE-B-2026'] == 2023].rename(columns={'A1101': 'population', 'A1303': 'elderly'}) fig, ax = plt.subplots(figsize=(6, 4)) ax.scatter(df['population'], df['elderly'], alpha=0.7, edgecolor='#37474F') ax.set_xlabel('total population') ax.set_ylabel('elderly population (65+)') ax.set_title('SSDSE-B-2026: population vs elderly (n=47)') plt.tight_layout() plt.savefig('html/figures/scatter_basic.png', dpi=120) |
📤 実行結果(保存された画像から読める数値特徴):
💬 散布図から分かる「収集設計の課題」: r=0.991 という強い正の相関は一見「データ収集は成功」に見えるが、 実は東京・神奈川・大阪・愛知の 4 点が回帰直線を引っ張っている。 47 件サンプル中 4 件で結論が決まる構造は、 「サンプルサイズ」と「サンプルの代表性」は別物 という収集設計の鉄則を可視化している。 鳥取と東京を同じ「1 件のデータポイント」として扱うのは、 比較の単位として適切か再検討の余地がある。
47 都道府県の総人口を 8 ビンで描いたヒストグラムは、 強い右裾(東京方向)を持つ。 これは「収集された生データを単純平均すると、 ほとんどの県が平均以下」という直感に反する結果を生む。 平均と中央値の乖離は、 収集データを要約する際の 代表値選択 の重要性を示す。
このコードでやること: 総人口列を matplotlib.hist で 8 ビン分割し、 平均値・中央値・最頻ビンを比較する。
📥 入力データ: df['population'] (47 行の数値列、 上記散布図と同じソース)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import os os.makedirs('html/figures', exist_ok=True) # 保存先のフォルダを作っておく import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932') df = df[df['SSDSE-B-2026'] == 2023].rename(columns={'A1101': 'population'}) fig, ax = plt.subplots(figsize=(6, 4)) ax.hist(df['population'], bins=8, color='#42A5F5', edgecolor='#1565C0') ax.axvline(df['population'].mean(), color='#D32F2F', linestyle='--', label=f"mean={df['population'].mean():,.0f}") ax.axvline(df['population'].median(), color='#388E3C', linestyle=':', label=f"median={df['population'].median():,.0f}") ax.set_xlabel('total population') ax.set_ylabel('frequency (number of prefectures)') ax.legend() plt.tight_layout() plt.savefig('html/figures/hist_basic.png', dpi=120) |
📤 実行結果:
💬 ヒストグラムから分かる「収集データ要約の落とし穴」: 平均 265 万人を「典型的な県のサイズ」と説明すると、 35 件の県(全体の約 7 割)が「典型以下」と誤認される。 収集データを 1 数字で代表させる場合、 分布形状を確認してから「中央値が適切」「対数平均が適切」「最頻ビンの境界値が適切」のどれかを選ぶべき。 これは収集後の集計戦略に直結する。
| 分布形状 | 推奨代表値 | 収集時に追加すべきメタ情報 |
|---|---|---|
| 対称・正規型 | 算術平均 | 標準偏差・標本サイズ |
| 右裾長 (今回) | 中央値 + IQR | 四分位・最大値・歪度 |
| 左裾長 | 中央値 + IQR | 四分位・最小値・歪度 |
| 双峰 | 2 つの最頻値 | クラスタ ID・サブグループ定義 |
| 外れ値混入 | トリム平均 (5-10%) | 外れ値の出所・補正手順 |
47 都道府県を「北海道・東北 / 関東 / 中部 / 近畿 / 中国・四国 / 九州・沖縄」の 6 ブロックに分け、 1 世帯当たりの月額消費支出をブロック別に箱ひげ図で並べると、 ブロック間分散とブロック内分散 の比が一目で分かる。 これは層化抽出 (stratified sampling) を採用すべきかどうかの根拠となる。
このコードでやること: SSDSE-B の都道府県コードからブロック ID を作り、 ブロックごとの消費支出列を boxplot で並べる。 中央値・IQR・外れ値の位置をブロック間で比較する。
📥 入力データ: 地域コード + 消費支出(二人以上の世帯)列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import os os.makedirs('html/figures', exist_ok=True) # 保存先のフォルダを作っておく # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() df['年度'] = pd.to_numeric(df['年度'], errors='coerce') df = df[df['年度'] == df['年度'].max()] # SSDSE-B に「年収」は無い。実在するのは 1 世帯当たりの月額消費支出なので、それを使う df['expenditure'] = pd.to_numeric(df['消費支出(二人以上の世帯)'], errors='coerce') block_map = {1:'Hokkaido_Tohoku', 2:'Hokkaido_Tohoku', 3:'Hokkaido_Tohoku', 4:'Hokkaido_Tohoku', 5:'Hokkaido_Tohoku', 6:'Hokkaido_Tohoku', 7:'Hokkaido_Tohoku', 8:'Kanto', 9:'Kanto', 10:'Kanto', 11:'Kanto', 12:'Kanto', 13:'Kanto', 14:'Kanto', 15:'Chubu', 16:'Chubu', 17:'Chubu', 18:'Chubu', 19:'Chubu', 20:'Chubu', 21:'Chubu', 22:'Chubu', 23:'Chubu', 24:'Kinki', 25:'Kinki', 26:'Kinki', 27:'Kinki', 28:'Kinki', 29:'Kinki', 30:'Kinki', 31:'Chugoku_Shikoku', 32:'Chugoku_Shikoku', 33:'Chugoku_Shikoku', 34:'Chugoku_Shikoku', 35:'Chugoku_Shikoku', 36:'Chugoku_Shikoku', 37:'Chugoku_Shikoku', 38:'Chugoku_Shikoku', 39:'Chugoku_Shikoku', 40:'Kyushu_Okinawa', 41:'Kyushu_Okinawa', 42:'Kyushu_Okinawa', 43:'Kyushu_Okinawa', 44:'Kyushu_Okinawa', 45:'Kyushu_Okinawa', 46:'Kyushu_Okinawa', 47:'Kyushu_Okinawa'} # 地域コード 'R01000' の頭 2 桁が都道府県番号 df['pref_id'] = df['地域コード'].str.extract(r'R(\d{2})').astype(int) df['block'] = df['pref_id'].map(block_map) order = ['Hokkaido_Tohoku','Kanto','Chubu','Kinki','Chugoku_Shikoku','Kyushu_Okinawa'] data = [df.loc[df['block']==b, 'expenditure'].dropna().values for b in order] for _blk, _vals in zip(order, data): print(f'{_blk:<16} n={len(_vals):>2} median = {pd.Series(_vals).median():>9,.0f} 円/月') fig, ax = plt.subplots(figsize=(7, 4.2)) # matplotlib 3.9 以降、boxplot の labels= は tick_labels= ax.boxplot(data, tick_labels=order) ax.set_ylabel('消費支出(二人以上の世帯、円/月)') ax.tick_params(axis='x', rotation=20) plt.tight_layout() plt.savefig('html/figures/box_multigroup.png', dpi=120) |
📤 実行結果(ブロック別中央値):
💬 箱ひげ図から分かる「層化抽出設計の意義」: ブロック間で中央値が最大約 3.1 万円差 (Kanto 307,817 円 vs Kyushu_Okinawa 276,996 円)、 ブロック内 IQR は約 1.4-3.9 万円。 ブロック間の差がブロック内のばらつきと同程度以上あるため、 単純無作為抽出よりも 地域ブロックで層化したサンプリング の方が同じ標本サイズでも推定精度が上がる。 ANOVA の p=0.025 が層化の有効性を統計的に支持する。 なお SSDSE-B に「年収」は収録されていないので、 ここで比べているのは 1 世帯当たりの月額消費支出である (年収と桁が違う点に注意)。
| # | 原則 | SSDSE-B における具体例 |
|---|---|---|
| 1 | 収集単位 (unit of analysis) を最初に固定 | 都道府県 47 件 vs 市区町村 1,741 件で結論が変わる |
| 2 | 分布形状の事前想定とビン設計 | 総人口・高齢人口は右裾長 → 対数変換または中央値で要約 |
| 3 | 外れ値の出所と意味を記録 | 東京は「真の頂点」か「特異点」か明示する |
| 4 | 欠損値の理由をメタデータに残す | SSDSE-B は欠損ほぼ 0 だが、 民間調査は理由記録が必須 |
| 5 | 収集タイミングのラグを明記 | 家計・経済系指標 (L3221 等) は公表まで年単位のラグあり |
| 6 | 層化のための補助変数を同時収集 | 地域ブロック・人口規模・産業構造など |
| 7 | 再現可能性 (reproducibility) の確保 | 収集スクリプト・前処理コードを Git で共有 |
今、 47 都道府県ではなく 10 万世帯規模の家計調査 を新規に設計するとする。 SSDSE-B-2026 で見た 3 つの図 (散布図 / ヒストグラム / 箱ひげ図) を念頭に、 以下を決めなさい。
データ収集は「集める作業」ではなく「分析の前提を設計する作業」である。 図 1 (散布図) は 収集単位の不均質性 を、 図 2 (ヒストグラム) は 代表値選択の落とし穴 を、 図 3 (多群箱ひげ図) は 層化設計の根拠 をそれぞれ示した。 これら 3 視点を全て確認することで、 「集めたデータが分析可能か」を最終判定できる。 SSDSE-B-2026 という質の高い公的データですら、 散布図 1 枚で「東京がドライバ」と気づき、 ヒストグラム 1 枚で「平均は誤導的」と気づき、 箱ひげ図 1 枚で「ブロック差は無視できない」と気づける。 民間データではこの 3 倍の慎重さが必要である。
このページの R375 セクションは、 「データ収集」という抽象概念を SSDSE-B-2026 という具体的な実データ に紐づけて、 散布図・ヒストグラム・箱ひげ図の 3 視点から検証している。 抽象的な手順書だけを読んでも「自分が収集したデータが妥当か」は判定できない。 実データに当ててみて初めて、 「収集単位」「代表値選択」「層化設計」という 3 つの設計軸が立ち現れる。 ここで身につくのは 「収集者の視点」と「分析者の視点」を行き来する力 である。
A 市の総合計画室は、 市内 22 地区の人口動態を分析するため、 自治体のオープンデータ (住民基本台帳ベース) と SSDSE-B-2026 (都道府県集計) を統合しようとした。 ところが両者の 収集単位 が異なり、 単純結合では精度が出ない。 SSDSE-B-2026 は「県全体の総人口」、 自治体 OD は「地区別の年齢別人口」を持つ。 ここで必要な収集設計の追加は次の 3 点である。
結果として、 「素直に結合する」コードは 5 行で済むが、 「正しく結合する」ためのメタデータ列追加は 20 行近くになる。 これが 収集設計の見えないコスト である。
B さんは「全国の家賃相場」を可視化するため、 不動産ポータルサイトを 1 週間スクレイピングして 12 万件の物件データを集めた。 SSDSE-B-2026 と並べてみると、 ある地方都市だけ「平均家賃が県全体の倍」になっている。 原因を追ったところ、 そのポータルが地方では 「家賃の高い物件しか掲載していなかった」 ことが判明した。 これは 収集源バイアス の典型例で、 集計後の数値からは見抜けない。
収集段階で組み込むべき防衛策は以下の通り。
C 大学の研究室が「全国の 20-30 代の生活満足度」を調べるため、 Web アンケート 1 万件を回収した。 回答者の暮らし向き(世帯の支出水準)を SSDSE-B-2026 の都道府県平均と比べると、 回答者の方が 明らかに高所得側に偏っていた。 これは Web 調査では避けにくい 非回答バイアス (nonresponse bias) である。
対応として、 収集段階で「回答者の属性が母集団全体と類似しているか」を確認し、 必要なら IPW (inverse probability weighting) や層化補正で重みづけを行う。 これも「集めた後で何ができるか」ではなく「集める前に何を併せて集めておくか」の問題である。 たとえば 都道府県・性別・年齢階級 を必ず併せて取得しておけば、 SSDSE-B 等の母集団分布に合わせた重み補正が後から可能になる。
工場の生産ラインに 200 個の温度センサを設置し、 1 秒間隔で 1 ヶ月分のデータを収集する場合、 単純計算で 5 億行になる。 SSDSE-B-2026 のような「47 行・年次集計」の世界とは桁違いだが、 設計原則は同じである。
民間 EC の購買データと SSDSE-B-2026 を都道府県別に突合すると、 「EC 利用率が高い県は実は所得層も高い」「都市部の方が EC 比率が高いように見えるが、 単に物理店舗の選択肢が多いことの裏返しでもある」という重層的解釈が必要になる。 ここで重要な収集設計上の工夫は、 民間データ側に 「居住地と購入地を分ける」「ギフト購入を識別する」 といったメタ列を最初から仕込んでおくこと。 後から「東京の住所で買った商品が実は地方の親への贈り物だった」と気づいても遡及できない。
| 段階 | 必須メタデータ | 欠落時に起きる問題 |
|---|---|---|
| 設計 | 調査目的・母集団定義・標本設計 | 後から「何を代表しているのか」が分からない |
| 取得 | 取得日時・取得者・取得方法 | 再現性が失われる、 ソース消失で追跡不可 |
| 記録 | 記録形式・単位・コード体系 | 「単位は km か mile か」が判別不能 |
| 前処理 | 変換ルール・補完規則・除外条件 | 同じ生データから違う集計値が出てしまう |
| 共有 | ライセンス・利用範囲・連絡先 | 二次利用の可否で衝突 |
| 保管 | 保存期間・廃棄基準・アクセス権 | 個人情報の不適切な長期保存 |
| 図種 | 診断できる収集問題 | SSDSE-B での具体例 |
|---|---|---|
| 散布図 | 収集単位の不均質性、 外れ値、 共変関係の歪み | 東京が回帰直線を引っ張る |
| ヒストグラム | 分布形状、 代表値選択の妥当性、 ビン設計 | 右裾長で平均が誤導的 |
| 箱ひげ図 | 群間差、 層化設計の有効性、 外れ値の群依存 | 地域ブロック間で中央値 90 万円差 |
| 折れ線 | 時系列の連続性、 突然のレベル変化 | 2020 年のコロナ影響 |
| ヒートマップ | 欠損パターン、 多変量相関 | 地方の特定列だけ欠損 |
| QQ プロット | 分布仮定の妥当性 | 正規性検定の事前確認 |
8 点以上で実務水準、 10 点満点で査読論文水準。 6 点以下は「収集データの分析以前に、 収集設計のやり直しが必要」のサイン。
R375 セクションでは、 「データ収集」を SSDSE-B-2026 という実データ + 3 図 (散布図・ヒストグラム・多群箱ひげ図) を通じて検証した。 集めた数字を 1 つ提示するだけでは不十分で、 必ず分布・関係・群差の 3 軸で見て初めて「収集が成功したか」を判定できる。 これは座学では身につきにくく、 実データに触れて初めて体得できる感覚である。 SSDSE-B-2026 のような信頼度の高い公的統計でさえ 3 図検証が必要なら、 自前で集めたデータには 5-10 倍の慎重さ を払う必要がある。 収集 → 図示 → 診断 → 必要なら再収集、 というサイクルを回せることが、 本ページの最終到達点である。
SSDSE-B-2026 は約 130 列、 47 行 (都道府県) のワイドフォーマットで提供される。 列 ID は A1101 (総人口)、 A1303 (高齢人口=65歳以上人口)、 L3221 (消費支出) などのコード体系で、 ドキュメント (PDF) で「コード → 意味」を変換しないと中身が分からない。 これは 「データ単体では使えず、 コードブックと併せて初めて意味を持つ」 典型例で、 自前で収集する場合も 必ず列定義ドキュメントを同梱 する必要があることを示している。
SSDSE-B-2026 を「収集後の素データ」として扱った場合の典型ワークフローは次の通り。
pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='utf-8-sig') で BOM 付き UTF-8 を吸収。 1 行目は列日本語名なのでスキップ。rename で A1101 → population など解釈しやすい英名に変換。 元の列 ID は別途保存。df.dtypes で全列の型確認。 数値列に object が混じっていないか。len(df) が 47 か。 欠損行・重複行が無いか。df.isna().sum() で列別欠損数。 SSDSE-B は通常ほぼ 0 だが、 一部新規列は数件欠損あり。df.describe() で平均・標準偏差・四分位数。 単位が桁違いな列が混在しているので注意。hist でヒストグラム化。 対数変換の要否を判断。df.corr() で全列相関行列。 強相関ペア (r > 0.9) を発見。data/processed/SSDSE-B-2026_clean.csv として別ディレクトリに保存。| 収集形態 | 長所 | 短所 | SSDSE-B との関係 |
|---|---|---|---|
| 公的統計の二次利用 | 信頼性高・無料・全国カバー | 更新ラグ・集計単位固定 | SSDSE-B-2026 がこれに該当 |
| 独自アンケート | 知りたい変数を直接取得 | 非回答バイアス・コスト | SSDSE-B に無い質問項目を補完 |
| Web スクレイピング | 大量・低コスト | 収集源バイアス・法的リスク | SSDSE-B と突合して偏り確認 |
| センサ・IoT | 連続観測・高頻度 | 欠損・通信障害・容量 | SSDSE-B のような集計値には変換が必要 |
| API 提供データ | 機械処理向け・更新即時 | API 仕様変更で破綻 | SSDSE-B はファイル提供のみ |
| 実験・観察 | 因果推論可能 | コスト・倫理 | SSDSE-B は観察データの代表例 |
実務では「データを集める人」と「分析する人」が別であることが多い。 SSDSE-B-2026 の場合、 収集・公表は独立行政法人統計センター、 分析は各教育機関や企業が担う。 ここで起きやすい摩擦は、 分析者が「もう少しこの列が欲しかった」と気づいても、 収集者には伝わらない こと。 この摩擦を最小化するため、 収集計画の段階で 「想定分析シナリオ」を 3-5 つ書き出し、 それぞれに必要な列を逆算する アプローチが有効である。
たとえば SSDSE-B-2026 の場合、 「総人口と高齢人口の相関を見たい (散布図)」「人口分布の偏りを示したい (ヒストグラム)」「地域差を比較したい (箱ひげ図)」という 3 シナリオを想定すると、 必要な列は「総人口・高齢人口・地域ブロック ID・消費支出」の 4 つに絞れる。 もし収集計画でこの 4 列を最初から確保していれば、 後から「地域 ID を別途付与する手間」が発生しない。 これが 「集める前に分析を想像する」 収集設計の核心である。
SSDSE-B-2026 は 2024-2026 年公表値のスナップショットで、 5 年後にはやや古いデータとなる。 収集データには 暗黙の賞味期限 があり、 「分析時点で何年前のデータか」「その間に社会変化が起きていないか」を常に意識する必要がある。 とくにコロナ前後・大震災前後など、 構造変化を伴う時期は注意。 収集計画書には「データの有効期限・更新計画」を明記し、 古いデータをそのまま使う場合は「この分析は YYYY 年時点の状況を反映したもの」と但し書きを必ず添える。
R375 セクションを最後まで読んだ学習者は、 以下の力を獲得しているはず。
pd.read_csv で読み込み、 列名整理・型確認・件数確認まで自走できる。これらが揃って初めて、 「データ収集」を語る資格があると言える。 単に「集める」のではなく、 「集めた後の分析者が困らないように集める」 という他者視点を持てるかどうかが、 プロのデータ収集者と素人を分かつ最大のポイントである。
SSDSE-B-2026 は強力だが、 47 都道府県 × 約 130 列という粒度のため、 「市区町村単位の細部」「個人レベルの行動」「時系列の高頻度変動」「リアルタイム性」の 4 つは捉えられない。 これらを補完するには追加収集が必要で、 補完源と注意点は以下のように整理できる。
| SSDSE-B が捉えない側面 | 補完収集源 | 注意点 |
|---|---|---|
| 市区町村粒度 | e-Stat の市区町村別小地域統計、 自治体オープンデータ | 市町村合併の影響、 集計期間の不一致 |
| 個人レベル | 独自アンケート、 公開マイクロデータ (要申請) | 非回答バイアス、 個人情報保護 |
| 時系列高頻度 | POS データ、 SNS 投稿、 IoT センサ | 欠損理由の記録、 ノイズ除去 |
| リアルタイム | API ストリーム、 Web スクレイピング | 仕様変更耐性、 法的リスク |
| 因果推論 | RCT (実験)、 自然実験 | 倫理審査、 コスト |
SSDSE-B を 基盤 として、 上記の補完収集を組み合わせることで、 「マクロな構造 + ミクロな実態 + 因果の方向性」の三位一体を実現できる。 これが現代のデータサイエンスにおける収集設計の到達点である。
入門から上級まで、 すべての段階で SSDSE-B-2026 を「比較基準」として使い続けられる。 これが公的統計を学習基盤に置く最大の利点である。 SSDSE-B-2026 のような信頼できる基盤データを 1 つ深く知ることで、 他のデータを評価する物差しが自然と身につく。
Q1: SSDSE-B-2026 はどこで入手できるか?
A1: 独立行政法人統計センターの公式サイト (https://www.nstac.go.jp/use/literacy/ssdse/) から無料でダウンロード可能。 CSV 形式で提供され、 ライセンスは出典明示で自由利用可。
Q2: 散布図・ヒストグラム・箱ひげ図のうち、 どれを最初に描くべきか?
A2: 単変量ならヒストグラム、 二変量なら散布図、 群比較なら箱ひげ図。 ただし「最初の 1 枚」としては各変数のヒストグラムを必ず先に確認し、 分布形状を把握してから次に進むのが安全。
Q3: 47 件のサンプルサイズは統計分析に十分か?
A3: 「都道府県を母集団とみなす」なら 47 件は全数調査である。 「47 件から日本全体を推定」と捉えると標本数は少ない。 解析目的に応じて使い分ける。
Q4: 公的統計と民間データの突合で、 ライセンス上の問題はあるか?
A4: SSDSE-B-2026 は CC BY 相当で問題なし。 民間データ側のライセンスを必ず確認し、 突合結果の再配布可否を事前にクリアにしておく。
Q5: 収集計画書は何ページくらい必要か?
A5: 小規模なら A4 で 1-2 ページ、 大規模 (10 万件規模の調査) なら 10-30 ページ。 重要なのはページ数ではなく、 本付録の 10 項目テンプレートを全て埋められること。
Q6: SSDSE-B-2026 と SSDSE-A の違いは?
A6: SSDSE-B は都道府県別 47 行のワイド形式、 SSDSE-A は市区町村別 1,741 行 (合併等で変動) のワイド形式。 粒度が大きく異なる。 本ページは SSDSE-B を題材としているが、 市区町村単位の分析が必要なら SSDSE-A を併用する。
Q7: 列 ID 「A1101」「A1303」「L3221」などはどう調べるか?
A7: SSDSE-B-2026 の公式コードブック PDF に「アルファベット = 大分類 (A: 人口・世帯, B: 自然環境, L: 家計)」「数字 = 細目」が定義されている。 必ず手元に置いて参照する。
encoding を明示し、 BOM 付き UTF-8 で統一。drop_duplicates() + プライマリキー定義。これら 5 事例はすべて「収集後の分析」で発覚する失敗だが、 「収集時のチェック」で防げた ものばかり。 つまりデータ収集の品質保証は、 後追いより事前設計の方が圧倒的にコストが低い。 SSDSE-B-2026 がこうした失敗を起こさないのは、 統計センターが何十年も蓄積したノウハウを設計に組み込んでいるからである。 自前の収集でも同じレベルの品質保証を目指すのが目標である。
pandas で読み込み、 列名整理・型確認まで一気通貫で実施できるmatplotlib で描き分けられる上記 10 項目すべてに自信を持って「Yes」と言えるようになれば、 本ページ R375 セクションの学習目標は達成である。 まだ不安が残る項目があれば、 該当セクションをもう一度読み返し、 SSDSE-B-2026 を手元で動かして納得感を得てから次に進んでほしい。 データ収集は座学だけでは身につかない、 「手を動かしてこそ獲得できる現場感覚」 が本質である。
データ収集を担う者は、 単に「集めて渡す」のではなく、 「分析者と公開先の読者」まで責任が連鎖する ことを意識すべきである。 SSDSE-B-2026 の収集元である統計センターは、 全国の自治体・回答者から集めた個別データを匿名化・集計し、 教育機関に公開する。 この連鎖の中で 1 つでもメタデータが欠落すると、 最終的に読者が誤読する可能性が高まる。 だからこそ、 列定義 PDF・収集年・カバレッジ・更新履歴を必ず同梱し、 「収集者の判断」が分析者と読者にも追跡可能であることが、 公的統計が公的統計たる所以である。 自前の収集でも、 この姿勢を真似ることが信頼性確保の第一歩となる。 そして信頼性が確保されたデータだけが、 散布図・ヒストグラム・箱ひげ図といった視覚化を経て、 意思決定の根拠として使われる資格を得る。 R375 セクション全体を通じて伝えたいのは、 まさにこの 「責任ある収集」 の姿勢である。 SSDSE-B-2026 を学習基盤に置く理由はここにある。 収集の現場では、 集めた瞬間に「これで本当に分析者の問いに答えられるか」「公開時に読者を誤解させないか」を自問する習慣が、 何より大切である。 この自問を欠いた収集は、 たとえ大量のデータを生んでも、 後工程で必ずどこかが破綻する。 逆にこの自問を徹底すれば、 たとえ小規模でも価値ある収集データとなる。 そして自問の解像度を上げるための最良の教材が、 SSDSE-B-2026 のような公的統計を「読み解く側 / 集める側」の両視点で繰り返し触ることなのである。 本ページ R375 セクションは、 そのトレーニングの最初の一歩として設計されている。 SSDSE-B-2026 を題材に、 散布図 1 枚・ヒストグラム 1 枚・箱ひげ図 1 枚で「収集の品質」を判定する目を養うこと、 これが本セクションの究極の到達点である。
不等確率抽出 (大県は確率高、 小県は低) で総計を推定するときの王道、 HT 推定量です。
$$\hat{T}_{\text{HT}} = \sum_{i \in s} \frac{y_i}{\pi_i}$$
数式を言葉で読み解く: 「サンプル $i$ の観測値 $y_i$ を、 その単位が抽出される確率 $\pi_i$ で割って総和」。 「抽出されにくい単位は重く数える」という発想で、 不均等抽出のバイアスを補正。
SSDSE-B-2026 の文脈で言えば、 もし「人口に比例して抽出」と決めた場合、 東京 (1,408 万人) は確率高、 鳥取 (54 万人) は確率低。 集計時に各観測値を $1/\pi_i$ で重み付けすれば、 全国総計を不偏推定できる。
$$V(\hat{T}_{\text{HT}}) = \sum_{i} \frac{(1-\pi_i)}{\pi_i} y_i^2 + \sum_{i \neq j} \frac{\pi_{ij} - \pi_i \pi_j}{\pi_i \pi_j} y_i y_j$$
数式を言葉で読み解く: 第 1 項は各単位の個別分散、 第 2 項は単位間の共分散。 $\pi_i$ が小さい (めったに当たらない) 単位ほど分散寄与が大きいので、 「東京を必ず含める」「鳥取をほぼ含めない」のような極端な設計は分散爆発を招く。
47 都道府県を母集団として「人口の総和」を推定したい場合、 各抽出方式でどう結果が変わるかを実値で示します。 真値は SSDSE-B-2026 (2023 年) の総人口合計です。
| 抽出方式 | 設計 | 推定値の特性 |
|---|---|---|
| 悉皆 (SSDSE 実態) | 47 県すべて | 分散ゼロ、 真値そのもの |
| SRS (n=10) | 等確率で 10 県 | 不偏だが分散大 (東京の有無で結果激変) |
| 層化 (地方別) | 関東 3 件 + 関西 2 件 + 他地方各 1 件 | 分散減 |
| PPS (人口比例) | 大県ほど高確率 | HT 推定で不偏、 分散最小 |
| 系統抽出 | 9 県おき | 実装容易だが周期偏り注意 |
SSDSE-B-2026 は 47 件全部を収録した「悉皆データ」なので抽出は不要ですが、 これを母集団とみなすことで、 抽出方式の理論検証を電卓レベルで可能にします。
許容誤差 5%、 信頼水準 95%、 母比率 0.5 で必要サンプル n を計算する。
1 2 3 4 5 6 7 | import math z = 1.96 p = 0.5 e = 0.05 n = (z**2 * p * (1-p)) / e**2 print(f"n = {n:.2f}") print(f"切り上げ: {math.ceil(n)}") |
💬 手計算 (Step 2) 385 件と Python 出力が完全一致。
SSDSE-B-2026 のような公的統計データを Python で扱う際の基本パターン:
1 2 3 4 5 6 7 8 9 10 11 12 | import pandas as pd import numpy as np # データ読み込み df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1) print(df.shape) print(df.dtypes) print(df.describe()) # 「データ収集」の文脈で扱う場合の例: # 分野: データエンジニアリング # 関連手法は同カテゴリの他用語を参照してください。 |
具体的なコードは データエンジニアリング を参照してください。
分析結果を報告するときに含めるべき情報:
(1) e-Stat API から都道府県別人口を取得:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import requests import pandas as pd # e-Stat の API キー(無料登録) APP_ID = 'YOUR_APP_ID' # 人口推計の統計表 ID params = { 'appId': APP_ID, 'statsDataId': '0003448237', # 例: 都道府県別人口 'limit': 100 } res = requests.get('https://api.e-stat.go.jp/rest/3.0/app/json/getStatsData', params=params).json() # 整形して DataFrame に values = res['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE'] df = pd.DataFrame(values) print(df.head()) |
(2) SSDSE-B のCSVを取得(オフライン):
1 2 3 4 5 6 7 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1) print('取得行数:', len(df)) print('期間:', df['年度'].min(), '〜', df['年度'].max()) print('変数数:', df.shape[1]) print('欠損のある変数:', df.columns[df.isna().any()].tolist()) |
(3) サンプルサイズ計算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import math from scipy.stats import norm def sample_size_proportion(confidence=0.95, margin=0.03, p=0.5): z = norm.ppf(1 - (1 - confidence) / 2) return math.ceil(z**2 * p * (1 - p) / margin**2) # 95% 信頼、 ±3% 誤差 print(sample_size_proportion()) # 1068 # 有限母集団補正 def fpc(n, N): return math.ceil(n * N / (n + N - 1)) print(fpc(1068, 10000)) # 母集団1万人なら 906 で十分 |
(4) 倫理的な Web スクレイピング:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import requests import time from urllib.robotparser import RobotFileParser url = 'https://example.com' rp = RobotFileParser() rp.set_url(url + '/robots.txt') rp.read() if not rp.can_fetch('*', url): raise PermissionError('robots.txt で禁止') # レート制限を必ず守る for page in range(1, 11): res = requests.get(f'{url}?page={page}', headers={'User-Agent': 'research-bot v0.1 (mailto:me@example.com)'}) # ... パース処理 time.sleep(2.0) # 1 秒/req より遅く |
🎯 このコードでやること: SSDSE-B-2026 の全 47 都道府県の総人口合計 (真値) を計算する。
📥 入力: data/raw/SSDSE-B-2026.csv の A1101 (総人口)
1 2 3 4 5 6 7 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) true_total = df['A1101'].sum() print(f'真値 (47 県合計): {true_total:,} 人') print(f'平均: {df["A1101"].mean():,.0f} 人') print(f'標準偏差: {df["A1101"].std():,.0f} 人') |
📤 実行結果:
💬 結果の読み方: 2023 年の全国総人口は約 1.24 億人。 都道府県別の標準偏差 (280 万人) が平均値とほぼ同じ → ばらつきが極めて大きい。 SRS では分散が爆発しやすい構造。
🎯 このコードでやること: 47 都道府県から SRS で 10 件抽出 → 総人口推定 (47×平均) を 1000 回繰り返し、 分布を観察。
📥 入力: SSDSE-B-2026 の A1101 列 (47 件)
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) estimates = [] for trial in range(1000): sample = df.sample(n=10, random_state=trial) estimates.append(sample['A1101'].mean() * 47) import statistics print(f'SRS 平均推定値: {statistics.mean(estimates):,.0f}') print(f'SRS 推定の標準偏差: {statistics.stdev(estimates):,.0f}') print(f'真値: {df["A1101"].sum():,}') print(f'最大誤差: {max(abs(e - df["A1101"].sum()) for e in estimates):,.0f}') |
📤 実行結果:
💬 結果の読み方: SRS の平均推定値は真値 (1.24 億) に近いが、 標準偏差は 3,631 万 (真値の 29%!)。 最大誤差は 1.20 億で真値とほぼ同じオーダー。 東京 (1,409 万) が含まれるか否かで 4,000 万単位で結果が動く構造。
🎯 このコードでやること: 人口に比例した抽出確率で 10 件選び、 HT 推定で総人口を再構築する。
📥 入力: SSDSE-B-2026 の A1101 列 (47 件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) total = df['A1101'].sum() df['pi'] = df['A1101'] / total * 10 # 包含確率 (n=10) df['pi'] = df['pi'].clip(upper=1.0) # HT 推定の理論値検証 df['weighted'] = df['A1101'] / df['pi'] print(f"HT 推定 (理論期待値) = {df['weighted'].sum() * df['pi'].mean() / 47 :,.0f}") print(f"真値: {total:,}") print('PPS は分散をどれだけ抑えるか:') print(f" 最大 π: {df['pi'].max():.4f} (東京)") print(f" 最小 π: {df['pi'].min():.4f} (鳥取)") |
📤 実行結果:
💬 結果の読み方: PPS では東京は確率 1 (必ず含む)、 鳥取は 0.043 (希に含む)。 HT 推定値は不偏で、 SRS の 4,000 万分散と比較すると圧倒的に分散が小さい。 「重要な単位を確実に含める」のがビッグデータ時代のサンプリング思想。
🎯 このコードでやること: 公開 URL から CSV をダウンロードし、 pandas で読み込む典型例。 SSDSE-B-2026 は実際にこの方法で配布されている。
📥 入力: 公開 URL (例: https://www.nstac.go.jp/sys/.../SSDSE-B-2026.csv)
1 2 3 4 5 6 7 8 | import pandas as pd # 実際は URL を指定。 ここではローカルファイルで動作確認 url_or_path = 'data/raw/SSDSE-B-2026.csv' df = pd.read_csv(url_or_path, encoding='cp932', skiprows=[1]) print(f'ダウンロード成功: {df.shape}') print(f'最初の 3 行:') print(df.head(3)[['Code','Prefecture','A1101']]) |
📤 実行結果:
💬 結果の読み方: pandas は URL も直接読める。 SSDSE は CSV 形式で配布されているため、 ダウンロード → 即分析が 1 行で完結。 ファイルは encoding='cp932' (Windows 既定の日本語) を指定する必要あり。
🎯 このコードでやること: スクレイピングのテンプレート。 User-Agent 明示、 アクセス間隔、 robots.txt 尊重を含む。
📥 入力: 取得対象の URL (要許諾)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # 実行はしない参考コード (倫理的にライブで叩かない) import time import urllib.robotparser # robots.txt 尊重 rp = urllib.robotparser.RobotFileParser() rp.set_url('https://example.com/robots.txt') rp.read() allowed = rp.can_fetch('Mozilla/5.0', 'https://example.com/data') print(f'robots.txt 許可: {allowed}') # 適切な間隔とヘッダ import requests headers = {'User-Agent': 'ResearchBot/1.0 (contact@example.com)'} # response = requests.get('https://example.com/data', headers=headers, timeout=10) # time.sleep(2.0) # サーバ負荷配慮 print('スクレイピングは常に: 1) robots.txt 確認, 2) User-Agent 明示, 3) 間隔 1-3 秒以上, 4) サイト利用規約遵守') |
📤 実行結果:
💬 結果の読み方: スクレイピングは技術的に簡単だが、 サーバ負荷・利用規約・著作権を尊重しないと法的トラブル。 e-Stat や SSDSE のように公式に配布されている CSV を使うのが最善。
🎯 このコードでやること: SSDSE-B-2026 (社会指標) と SSDSE-C-2026 (生活時間) を「都道府県コード」で結合し、 異なる収集源を統合する。
📥 入力: SSDSE-B-2026.csv, SSDSE-C-2026.csv (両方 e-Stat 由来)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import pandas as pd # SSDSE-B は都道府県単位、SSDSE-C は市区町村単位。まず列数とキーの粒度を確かめる b = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=0) b = b[b['Code'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() b = b[b['SSDSE-B-2026'].astype(str) == '2023'] c = pd.read_csv('data/raw/SSDSE-C-2026.csv', encoding='cp932', header=0) c = c.rename(columns={'SSDSE-C-2026': 'Code'}) c = c[c['Code'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() c = c[c['Code'] != 'R00000'] # 全国計の行は落とす print(f'B 列数: {b.shape[1]}, C 列数: {c.shape[1]}') print('B のキー例:', b['Code'].head(3).tolist()) print('C のキー例:', c['Code'].head(3).tolist()) # そのまま結合すると 1 件も合わない(B は都道府県コード、C は市区町村コード) naive = pd.merge(b[['Code', 'Prefecture', 'A1101']], c[['Code', 'LA03']], on='Code') print(f'素朴に結合した件数: {len(naive)} 件 ← キーの粒度が違うので 0 件') # C の市区町村コードの頭 2 桁が都道府県番号。粒度を揃えてから結合する c['PrefCode'] = 'R' + c['Code'].str[1:3] + '000' c['LA03'] = pd.to_numeric(c['LA03'], errors='coerce') c_pref = c.groupby('PrefCode', as_index=False)['LA03'].mean() # LA03 = 世帯人員 merged = pd.merge(b[['Code', 'Prefecture', 'A1101']], c_pref, left_on='Code', right_on='PrefCode', validate='one_to_one') print(f'粒度を揃えてから結合: {merged.shape}') print(f'結合できたキー数: {len(merged)} / {len(b)}') print(merged.head()) |
📤 実行結果:
💬 結果の読み方: 異なる収集源 (社会指標 vs 生活時間) を共通キー (Code) で結合できる。 47 件すべて一致 → SSDSE は標準化された都道府県コードのおかげで結合容易。 民間データでは ID 体系不一致がリンケージの最大障害になる。
🎯 このコードでやること: 各都道府県の人口を母集団とし、 95% 信頼水準・許容誤差 5% で必要サンプルサイズを計算する。
📥 入力: SSDSE-B-2026 の A1101 (47 県の総人口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) z = 1.96 p = 0.5 E = 0.05 n_basic = z**2 * p * (1-p) / E**2 print(f'無限母集団仮定の n: {n_basic:.0f}') df['有限修正後 n'] = n_basic / (1 + (n_basic - 1) / df['A1101']) print('\n都道府県別必要サンプル:') print(df[['Prefecture','A1101','有限修正後 n']].head(5).to_string(index=False)) print('...') print(df[['Prefecture','A1101','有限修正後 n']].tail(3).to_string(index=False)) |
📤 実行結果:
💬 結果の読み方: どの都道府県でも約 384 人で十分。 人口 100 万人でも 1,400 万人でも必要サンプル数はほぼ同じ (383.8 vs 383.97)。 これが「ビッグデータ時代でも N=400 が魔法の数」と言われる理由。
「母集団 → 抽出設計 → 倫理審査 → 収集 → 品質管理 → メタデータ → 配布。 この 7 段階のいずれかを省略した時点で、 データの価値は半減する」。
🎯 このコードでやること: SSDSE-B-2026 のヘッダ 2 行 (英数字コード + 日本語ラベル) から列対応辞書を作る。 政府統計の「列名定義書」を機械的に生成。
📥 入力: SSDSE-B-2026.csv (1 行目: コード、 2 行目: 日本語ラベル)
1 2 3 4 5 6 7 8 9 10 11 12 | import pandas as pd # 2 行のヘッダを別々に読む codes = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', nrows=0) labels = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[0], nrows=0) # 対応辞書を作る meta = dict(zip(codes.columns, labels.columns)) print(f'列数: {len(meta)}') print('\n最初の 10 列の対応:') for c, j in list(meta.items())[:10]: print(f' {c:<10} → {j}') |
📤 実行結果:
💬 結果の読み方: 2 行ヘッダ構造から、 英コード ↔ 日本語ラベル対応を機械的に取得。 これがあれば「A1101 を `総人口` にリネーム」「ダッシュボードで日本語表示」が自動化できる。 メタデータが構造化データの価値を引き出す好例。
| KPI | 計算式 | SSDSE-B-2026 では |
|---|---|---|
| 回答率 | 回答 / 配布 | 悉皆 (100%) |
| 完了率 | 全項目回答 / 開始 | 100% |
| 欠損率 | NaN セル / 全セル | ≈ 0% |
| 重複率 | 重複 / 総件数 | 0% |
| エラー率 | 範囲外値 / 全値 | 0% |
| レイテンシ | 取得 → 配布の日数 | 調査年から 3 年 |
| 処理スループット | 件/秒 | 小規模 (47 件) |
| エンコーディング統一 | UTF-8 比率 | cp932 (Shift-JIS) |
| スキーマ準拠 | 合致行 / 全行 | 100% |
| メタデータ完備率 | 記述あり列 / 全列 | 100% (110/110) |
🎯 このコードでやること: SSDSE-B-2026 の品質 KPI (欠損率・重複率・スキーマ準拠率) を 1 度に算出。
📥 入力: SSDSE-B-2026.csv の全 47 行 × 110 列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) # 4 つの KPI を計算 missing_rate = df.isna().sum().sum() / df.size duplicate_rate = df.duplicated().sum() / len(df) schema_compliance = df['Code'].str.match(r'^R\d{5}$').sum() / len(df) metadata_coverage = df.columns.notna().sum() / len(df.columns) print(f'欠損率: {missing_rate:.4%}') print(f'重複率: {duplicate_rate:.4%}') print(f'スキーマ準拠率: {schema_compliance:.4%}') print(f'メタデータ完備率: {metadata_coverage:.4%}') |
📤 実行結果:
💬 結果の読み方: 欠損ゼロ、 重複ゼロ、 すべての Code が `R\d{5}` パターンに準拠、 全列に列名あり。 SSDSE-B-2026 はデータ収集 KPI で満点を取る理想的な構造化データ。 教育用に整っているのも納得。
データ収集は技術的な作業であると同時に、 倫理・法律の制約が強くかかる活動です。 SSDSE-B-2026 が安心して教育に使えるのは、 統計法 (e-Stat) の枠組みで匿名化と二次利用許諾が事前にクリアされているからです。
「何を知りたいか(課題)」を選び、 「どう集めるか(収集方法)」を切り替えると、 コスト・期間・データ量・品質(欠損率リスク/バイアスリスク)・リアルタイム性の 5+1 ゲージと、 課題との適合度判定がリアルタイムに更新されます。 さらに「設計ミス」のチェックを入れると、 収集段階の失敗が品質ゲージと適合度をどう悪化させるかを体感できます。
※ ゲージの数値は各方法の一般的性質を 0〜100 の相対目安で表した教材用スコアです(絶対値ではありません)。 サンプルサイズ計算のみ統計式 $n = z^2 p(1-p)/e^2$ による正確な計算値です。
比率推定・信頼水準 95%(z = 1.96)・母比率不明(p = 0.5)のとき、 許容誤差 e を動かすと必要標本数 $n = z^2 p(1-p)/e^2$ が変わります。
±3.0%誤差を半分にすると必要数は 4 倍($1/e^2$ の効果)。 全国世論調査の標本数 1,000〜2,000 件はこの式で説明できます。
シミュレータで課題を切り替えると、 同じ収集方法でも適合度が大きく変わることが分かります。 混雑分析ではセンサー・ログが◎でも、 県別人口動態では公的統計(悉皆)に遠く及ばず、 顧客満足度は行動ログでは測れずアンケートが必要になる。 つまり「どの方法が優れているか」という問いは無意味で、 「この問いに答えるにはどの母集団を、 どの粒度・頻度で観測すべきか」が先にあり、 方法はその従属変数です。 標本抽出の設計(誰を対象にするか)と収集手段の選択(どう取るか)は常にセットで考えます。
SSDSE-B-2026 はこの 7 段階を高度に洗練したベストプラクティス。 教育用にデータが綺麗に整っているのも、 この厳密なパイプラインの結果です。
データ収集は Plan と整備の間に位置し、 公的データ活用と直結する。
目的明確化 → 既存統計調査 → 補完収集 (調査/Web 取得) → ライセンス確認 → メタデータ整備の流れで、 後工程の妥当性を上流が担保する。
データ収集は一次/二次の選択、 標本設計、 バイアス制御の三段で進める。
網羅性なら公的統計、 リアルタイム性なら API/Web スクレイピング、 一次調査なら質問紙設計、 と「目的と更新頻度」で選ぶ。
本文では「どの経路で・どれだけ集めるか」(収集方法とサンプルサイズ)を扱いました。 ここでは姉妹ページ(標本抽出=誰を選ぶか、 選択バイアス=誰が漏れるか)と重ならないもう一つの設計軸、 観測単位(unit of observation)の選択を深掘りします。 SSDSE-B-2026 の 1 行は「人」ではなく「都道府県 × 年度」です。 この選択は収集が終わった後には変更できません ── 細かい単位(個人)で集めたデータは粗い単位(県)へ集計できますが、 県単位で集めたデータを個人単位に戻すことは原理的に不可能だからです(集計の非可逆性)。
アンケートなら回答者 1 人、 センサーログなら 1 秒 × 1 地点、 SSDSE-B なら 1 県 × 1 年度 ── データ収集とは、 実は「表の 1 行に世界の何を対応させるか」を先に確定させる行為です。 同じ「日本の高齢化を知りたい」という問いでも、 個人単位で集めれば「誰が高齢か」まで分析でき、 県単位で集めれば「どの県が高齢か」までしか分析できません。 収集コストは粗い単位ほど安く(SSDSE-B は 47 行 × 12 年で日本全体を覆う)、 分析の解像度は細かい単位ほど高い。 このトレードオフを問いに合わせて決めるのが、 収集方法の選択と並ぶもう一つの設計です。
SSDSE-B-2026 の 2023 年・47 都道府県で、 高齢化率(65歳以上人口 A1303 ÷ 総人口 A1101)を実際に計算すると:
| 計算方法 | 値(実測) | 意味 |
|---|---|---|
| 47 県の高齢化率を単純平均 | 31.59% | 「平均的な県」の高齢化率 |
| 全国集計(Σ65歳以上 ÷ Σ総人口) | 29.13% | 「平均的な日本人」から見た高齢化率 |
差は約 2.5 ポイント。 原因は、 単純平均では高齢化率最高の秋田県 39.06%(総人口 91.4 万人)と最低の東京都 22.75%(総人口 1,408.6 万人)が同じ 1 票を持つこと ── 人口が 15 倍違うのに、 です。 47 県悉皆で標本誤差ゼロのデータでも、 「県単位で収集された」という設計を忘れて人単位の結論(日本人の約 31.6% が高齢者、 は誤り)を語ると間違えます。 合計特殊出生率でも同様で、 47 県単純平均は 1.293 ですが東京都 0.99・沖縄県 1.60 と幅があり、 どちらの「平均」を報告すべきかは問いの単位で決まります。 さらに、 県レベルで見えた相関を個人に当てはめる生態学的誤謬(ecological fallacy)も、 根はこの観測単位の取り違えにあります(詳しくは 集計 を参照)。
※ 本節の数値はすべて SSDSE-B-2026(data/raw/SSDSE-B-2026.csv, cp932)から実際に計算した値です(2023 年断面および 2012〜2023 年合計)。