データから「真実」を掘り起こす技術
投稿者:Ryosuke Imai (SRE CTO)
基本統計と可視化で土台を固める
はじめに:データサイエンスの礎-なぜ最初の分析が最も重要なのか
データサイエンティストは、米国の企業口コミサービスで「最高の仕事」として長年君臨し、統計学修士号は「最も役立つ学位」のトップに挙げられています。
その理由は、AIや機械学習などの最先端技術を駆使し、ビジネス課題を解決する“データの取り扱いへの深い知見”への期待に他なりません。
しかし、真の価値は複雑なアルゴリズムを操る力だけではありません。
無機質なデータの海から、ビジネスの「本質的な原因」を発見し、意思決定を導く力こそが、データサイエンティストの真髄です。
この力の源泉となるのが
「記述統計」と「データ可視化」を駆使した探索的データ分析
です。
これは単なる分析の入口ではなく、推測統計・モデル構築・機械学習・AI開発など、すべての高度な分析の“土台” となる技術です。
データ分析のゴールは、単なるレポート作成ではありません。
データ ・ビジュアル・背景の文脈を組み合わせ、説得力ある物語を紡ぐ「データストーリーテリング」
にあります。
優れたデータストーリーは、信頼を生み、価値を創造し、組織を動かす力を持ちます。
本稿では、業界標準の分析プロセス「 CRISP-DM(クリスプディーエム)」1を羅針盤に、大量の構造化データをどのように“料理”し、マクロな集計からミクロな洞察へと掘り下げ、最終的に人を動かすストーリーへ昇華させるか、その実践的な手順を解説します。
生データとビジネス価値の間の曖昧な領域を航海し、確かな知見を届けることに意義があるからです。
第1章:分析者の羅針盤-CRISP-DMによる構造化アプローチ
データ分析の世界に足を踏み入れたとき、手元にあるデータを手当たり次第に触りたくなる衝動に駆られるかもしれません。
しかし、明確な計画なしに分析の海に飛び込むのは、羅針盤を持たずに航海に出るようなものです。
分析は非効率になり、ビジネスの目的から乖離し、誤った結論を導き出す危険性が高まります。
そこでひとつの指針となるのが、
「CRISP-DM(Cross-IndustryStandardProcessforDataMining)」
です。
これは、データマイニングプロジェクトを成功に導くために策定された、業界横断的な標準プロセスであり、データサイエンス全般に応用可能なフレームワークです。
CRISP-DMは、データ分析プロジェクトが場当たり的なものになるのを防ぎ、ビジネス成果に結びつくことを保証するための構造を提供します。
CRISP-DMは、以下の6つのフェーズで構成されています。
- ビジネスの理解(Business Understanding)
- どのようなビジネス課題を解決しようと しているのかを定義
- データの理解(Data Understanding)
- 分析に利用可能なデータは何か、その特性はどうかを把握
- データの準備(Data Preparation)
- 生データを分析に適した形式にクレンジングし、加工
- モデル作成(Modeling)
- 統計手法や機械学習アルゴリズムを適用
- 評価(Evaluation)
- 作成したモデルが、ビジネスの目的を達成できるかを評価
- 展開・共有(Deployment)
- 分析結果やモデルを実際の業務フローに組み込み、共有
(出典:Wikipedia,Cross-industrystandardprocessfordatamining)
このプロセスの最も重要な特徴は、その反復性にあります。
CRISP-DMは一方通行のウォーターフォールモデルではなく、サイクルを繰り返すことで、分析の精度とビジネス価値を高めていく、アジャイルなアプローチです。
例えば、「評価」フェーズでモデルの性能が不十分だと判明した場合、最初の「ビジネスの理解」フェーズまで戻って課題設定を再検討することもあります。このサイクルを繰り返すことで、分析は洗練されていきます。
この反復的な性質は、
初期の思い込みや確証バイアスから分析者を守るための、極めて重要な安全装置として機能します。
データ分析は単なる作業の実行ではなく、発見のプロセスです。最初の問い が最適であるとは限りません。データへの理解が深まるにつれて、より本質的な、より価値のある問いを発見することができるのです。CRISP-DMの柔軟な構造は、この発見のプロセスを体系的にサポートします。
本稿では、特に「データの理解」「データの準備」に焦点を当てます。これらの初期フェーズは、プロジェクト全体の時間の8割を占めるとも言われ、後続するすべての分析の成否を決定づける、まさにデータ分析の心臓部です。
第2章:ファーストコンタクト-ビジネスとデータの全体像を掴む(マクロ分析)
ビジネス課題を定義したら、次はいよいよデータそのものと向き合います。CRISP-DMの「データの理解」フェーズにあたるこの段階では、まず森全体を眺めるように、データの全体像(マクロな特徴)を把握することから始めます。
ここでは、架空の売上データを例に、具体的なコードと共にその手法を見ていきましょう。
最初の観察:マクロ集計と基本統計量
データ分析の現場では、Pythonのpandasライブラリが事実上の標準ツールとなっています。まずはこのライブラリを使ってデータを読み込み、最初の「偵察」を行います。
#pandasライブラリをpdという別名でインポート
import pandas as pd
#CSVファイルを読み込み、DataFrameオブジェクトとして変数dfに格納
df = pd.read_csv('sales_data.csv')
データが読み込めたら、まずは以下の基本的な関数を使い、データの素性を確認します。
df.head(): データの先頭5行を表示し、どのような列(カラム)があるのか、どのような値が入っているのかを概観します。df.shape: データの規模(行数と列数)を確認します。df.info(): 各列のデータ型(数値、文字列、日付など)と、欠損値(データがない項目)の数を確認します。これはデータ品質をチェックする最初のステップです。df.describe(): 数値データを持つすべての列について、個数、平均値、標準偏差、最小値、四分位数、最大値といった要約統計量を一覧で表示します。
::: warning 平均値の罠
df.describe()は非常に便利ですが、ここで表示される平均値(Mean)には注意が必要です。平均値は、データ全体の傾向を示す「代表値」の一つですが、常に最適な指標とは限りません。
:::
ここで、**中央値(Median)と最頻値(Mode)**の重要性を理解しましょう。
例えば、ある企業の売上データ(Revenue列)を考えてみましょう。ほとんどの取引が50万円前後である一方、数件だけ2億円の大型契約があったとします。この場合、平均売上は大型契約に大きく引っ張られ、例えば「平均200万円」といった、実態とはかけ離れた数値になってしまう可能性があります。
このような外れ値(極端に大きい、または小さい値)が存在する場合、より実態に近い「典型的な」値を示すのが中央値です。中央値は、データを小さい順に並べたときに、ちょうど真ん中に位置する値であり、外れ値の影響を受けにくいという大きな利点があります。年収や売上のように分布に偏り(歪み)があるデータでは、平均値と中央値を併記し、その差を確認することが、データの本質を誤解しないための重要な作法です。
Kaggleからサンプルを持ってきてもいいですね。
import kagglehub
# Download latest version
path = kagglehub.dataset_download("manovirat/groceries-sales-data")
print("Path to dataset files:", path)
# https://www.kaggle.com/datasets/manovirat/groceries-sales-data?resource=download
または、大量にサンプルデータを生成してみてください。
import pandas as pd
import numpy as np
import random
from datetime import date, timedelta
# --- 生成するデータのパラメータ設定 ---
NUM_ROWS = 500 # 生成す るデータ行数
START_DATE = date(2023, 1, 1)
END_DATE = date(2023, 12, 31)
REGIONS = ['東京', '大阪', '福岡', '名古屋', '札幌']
PRODUCTS = {
'ベーシックプラン': {'base_revenue': 10000, 'noise': 2000},
'スタンダードプラン': {'base_revenue': 50000, 'noise': 10000},
'プレミアムプラン': {'base_revenue': 200000, 'noise': 30000}
}
CUSTOMER_IDS = range(101, 301) # 200人の顧客を想定
# --- データ生成ロジック ---
data =
date_range_days = (END_DATE - START_DATE).days
for _ in range(NUM_ROWS):
# 日付をランダムに選択
random_date = START_DATE + timedelta(days=random.randint(0, date_range_days))
# 地域、製品、顧客をランダムに選択
region = random.choice(REGIONS)
product_name = random.choice(list(PRODUCTS.keys()))
customer_id = random.choice(CUSTOMER_IDS)
# 製品に応じて売上を生成(ベース価格 + 正規分布に従うノイズ)
product_info = PRODUCTS[product_name]
revenue = int(product_info['base_revenue'] + (np.random.randn() * product_info['noise']))
# 売上がマイナスにならないように0以上に調整
revenue = max(0, revenue)
data.append({
'Date': random_date,
'Region': region,
'Product_Category': product_name,
'Revenue': revenue,
'CustomerID': customer_id
})
# --- DataFrameの作成とCSVファイルへの保存 ---
df_large = pd.DataFrame(data)
# 日付順にソートして、より現実的なデータに見せる
df_large = df_large.sort_values(by='Date').reset_index(drop=True)
# CSVファイルとして保存
# encoding='utf-8-sig' を指定することでExcelで開いた際の文字化けを防ぎます
file_name = 'sales_data_large.csv'
df_large.to_csv(file_name, index=False, encoding='utf-8-sig')
print(f"'{file_name}'が正常に作成されました。{len(df_large)}行のデータが含まれています。")
print("\n生成されたデータの最初の5行:")
print(df_large.head())
百聞は一見に如かず:最初の可視化
要約統計量でデータの輪郭を掴んだら、次は視覚的にその姿を捉えます。
Pythonではmatplotlibと、その上でより美しく統計的なグラフを簡単に描けるように作られたseabornライブラリが広く使われています。
分布の可視化
まず、単一の変数がどのように分布しているかを見てみましょう。
-ヒストグラム(Histogram):連続的な値(例:顧客の年齢、商品の価格)がどの範囲にどれだけ集中しているかを示すグラフです。seabornのhistplotを使えば、データが正規分布(きれいな釣鐘型)に近いのか、左右どちらかに偏っているのか、あるいは山が二つある(バイモーダルな)分布なのかといった特徴を一目で把握できます。
importseabornassns
importmatplotlib.pyplotasplt
#seabornのヒストグラム機能で'Revenue'列の分布を可視化
sns.histplot(data=df,x='Revenue',bins=30)
plt.title('売上分布')
plt.show()
箱ひげ図(BoxPlot): 中央値、四分位範囲(データの中心50%が収まる範囲)、そして外れ値の候補をコンパクトに表現するグラフです。複数のカテゴリ(例:製品カテゴリ別)の分布を並べて比較する際に特に威力を発揮します。
この初期のデータ探索は、いわば健康診断のようなものです。df.info()でバイタルサインをチェックし、df.describe()で血液検査の数値を確認し、ヒストグラムや箱ひげ図というX線写真で異常の兆候を探します。ここで見つかる欠損値、奇妙な分布、極端な外れ値といった「異常」こそが、後のより深く、価値ある分析への出発点となるのです。
matplotlibやseabornでグラフを作成する際、デフォルト設定ではタイトルやラベルの日本語が文字化けすることがあります。これは分析者にとって一般的な悩みですが、japanize-matplotlibというライブラリを使えば簡単に解決できます。
#ライブラリが未インストールの場合はインストール
#!pipinstalljapanize-matplotlib
importjapanize_matplotlib#これをインポートするだけで日本語表示が有効になる