統計分析のPython 実現ガイド
【概要】Pandas、SciPy、Matplotlibを用いた統計分析のPython実装ガイドである。記述統計量、ヒストグラム、箱ひげ図、クロス集計表、t検定、一元配置分散分析、正規性検定の7つの統計手法を解説し、各手法のPythonコードと実行結果を示す。
【目次】
【サイト内のPython関連主要ページ】
- Windows AI支援Python開発環境構築ガイド: 別ページ »で説明
- AIエディタ Windsurf の活用: 別ページ »で説明
- AIエディタCursorガイド: 別ページ »で説明
- Google Colaboratory: 別ページ »で説明
- Python(Google Colaboratoryを含む)のまとめ: 別ページ »で説明
- 機械学習の Python 実現ガイド: 別ページ »で説明
- 行列計算の Python 実現ガイド: 別ページ »で説明
- 統計分析のPython での実現ガイド: 別ページ »で説明
- 音声信号処理の Python 実現ガイド: 別ページ »で説明
- カラー画像処理の Python 実現ガイド: 別ページ »で説明
- Python 言語によるとても簡単なアドベンチャーゲーム(変数,式,if,while,関数,print,time.sleep, def, global を使用): 別ページ »で説明
- Pythonプログラミング講座:基礎から応用まで(授業資料,全15回): 別ページ »で説明
- Pythonプログラミングの例と実践ガイド: 別ページ »で説明
【外部リソース】
- Pythonの公式サイト: https://www.python.org
- 東京大学の「Pythonプログラミング入門」: https://utokyo-ipp.github.io/IPP_textbook.pdf
- ITmedia社の「Pythonチートシート」の記事: https://atmarkit.itmedia.co.jp/ait/articles/2004/20/news015.html
統計手法
本ガイドでは、以下の統計手法を扱う。
- 記述統計量
- ヒストグラム
- クロス集計表
- 検定
記述統計量
記述統計量は、データセットの特徴を数値的に要約する統計指標である。
- 平均値: データの中心傾向を示す
- 標準偏差: データのばらつきを示す
- 中央値: 順序付けられたデータの中央の値
- 四分位数: データを4等分する境界値
- 最大値・最小値: データの範囲を示す
- 分散: 標準偏差の二乗
- 歪度: 分布の非対称性を示す
- 尖度: 分布の尖り具合を示す
用語リスト
- 平均値: データの総和をデータ数で除した値である。外れ値の影響を受けやすい。
- 標準偏差: 平均値からの平均的な距離を表す。値が大きいほどばらつきが大きい。
- 中央値: 順序付けられたデータの中央に位置する値である。外れ値の影響を受けにくい。
- 四分位数: データを4等分する境界値であり、第1四分位数、中央値、第3四分位数から構成される。
- 分散: 各データ点と平均値の差の二乗平均である。標準偏差の二乗値に等しい。
- 歪度: 分布の非対称性を示す。正規分布では0となる。
- 尖度: 分布の尖り具合を示す。SciPyのstats.kurtosis()は超過尖度を返し、正規分布で0となる。
- ヒストグラム: データの範囲を区間分割し、各区間の頻度を棒グラフで表示する。
- クロス集計表: 2つの変数の組み合わせごとの度数を表形式で示す。
- t検定: 2群の平均値の差の統計的有意性を評価する検定手法である。
- Welchのt検定: 等分散を仮定しないt検定である。
- 一元配置分散分析: 3群以上の平均値の差を同時に検定する手法である。
- Shapiro-Wilk検定: データの正規性を評価する検定手法である。
- p値: 帰無仮説が真である場合に観測データが得られる確率である。一般に5%未満を統計的有意とする。
- pandas: データ分析のためのPythonライブラリである。describeメソッドにより主要な統計量を算出できる。
- データフレーム: 行と列で構成される2次元のデータ構造である。pandasの中核機能として提供される。
- 外れ値: データセット内で他のデータから著しく離れた値である。
統計処理の比較
| 処理内容 | SPSS言語 | Rシステム | Python (pandas/scipy) |
|---|---|---|---|
| 記述統計量 | describe、skew、kurt descriptive |
summary、sd、skewness、kurtosis |
df.describe()、stats.skew()、stats.kurtosis() |
| 頻度表 | hist、frequencies |
table |
value_counts() |
| クロス集計表 | crosstab、crosstabs |
table |
pd.crosstab() |
| 集約 | aggregate |
aggregate |
groupby().agg() |
| Welchのt検定 | ttest_ind |
t.test |
stats.ttest_ind() |
| 一元配置分散分析 | f_oneway |
oneway.test |
stats.f_oneway() |
| Wilcoxon検定 | mannwhitneyu |
wilcox.test |
stats.mannwhitneyu() |
Pythonプログラム例
以下のプログラム例では、次のデータセットを使用する。
| 科目 | 受講者 | 得点 |
|---|---|---|
| 国語 | A | 90 |
| 国語 | B | 80 |
| 算数 | A | 95 |
| 算数 | B | 90 |
| 理科 | A | 80 |
Pythonのインストールと必要なPythonライブラリのインストール(Windows上)
- Pythonのインストール
注:既にPython(バージョン3.12を推奨)がインストール済みの場合は、この手順は不要である。
winget(Windowsパッケージマネージャー)を使用してインストールを行う。
- Windowsで、コマンドプロンプトを管理者権限で起動する(手順: Windowsキーまたはスタートメニュー、「cmd」と入力、右クリックメニューなどで「管理者として実行」を選択)。
- winget(Windowsパッケージマネージャー)が利用可能か確認する。
winget --version
- Pythonのインストール(下のコマンドによりPython 3.12がインストールされる)。
reg add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f REM Python をシステム領域にインストール winget install --scope machine --id Python.Python.3.12 -e --silent REM Python のパス set "INSTALL_PATH=C:\Program Files\Python312" echo "%PATH%" | find /i "%INSTALL_PATH%" >nul if errorlevel 1 setx PATH "%PATH%;%INSTALL_PATH%" /M >nul echo "%PATH%" | find /i "%INSTALL_PATH%\Scripts" >nul if errorlevel 1 setx PATH "%PATH%;%INSTALL_PATH%\Scripts" /M >nul
- 必要なPythonライブラリのインストール
【関連する外部ページ】
【サイト内の関連ページ】
基本的なデータ構造とデータフレームの作成
辞書からデータフレームを作成し、データ型を指定する。
import pandas as pd
# データの作成
data = {
'科目': ['国語', '国語', '算数', '算数', '理科'],
'受講者': ['A', 'B', 'A', 'B', 'A'],
'得点': [90, 80, 95, 90, 80]
}
# データフレームの作成
df = pd.DataFrame(data)
# データ型の指定
df = df.astype({
'科目': 'category',
'受講者': 'category',
'得点': 'int32'
})
print("基本データ:")
print(df)
個別の統計量計算
各統計量を個別に算出する。標本標準偏差の計算にはddof=1を指定する。
import pandas as pd
from scipy import stats
# データの作成
data = {
'科目': ['国語', '国語', '算数', '算数', '理科'],
'受講者': ['A', 'B', 'A', 'B', 'A'],
'得点': [90, 80, 95, 90, 80]
}
# データフレームの作成
df = pd.DataFrame(data)
df = df.astype({
'科目': 'category',
'受講者': 'category',
'得点': 'int32'
})
scores = df['得点']
print("基本統計量:")
print(f"平均値: {scores.mean():.1f}")
print(f"標準偏差: {scores.std(ddof=1):.1f}")
print(f"中央値: {scores.median():.1f}")
print(f"最大値: {scores.max()}")
print(f"最小値: {scores.min()}")
print(f"第1四分位数: {scores.quantile(0.25):.1f}")
print(f"第3四分位数: {scores.quantile(0.75):.1f}")
print(f"歪度: {stats.skew(scores):.3f}")
print(f"尖度: {stats.kurtosis(scores):.3f}")
総合的な統計分析
describe()メソッドにより基本統計量を一括算出する。groupby()との組み合わせでカテゴリ別の統計量も算出できる。
import pandas as pd
# データの作成
data = {
'科目': ['国語', '国語', '算数', '算数', '理科'],
'受講者': ['A', 'B', 'A', 'B', 'A'],
'得点': [90, 80, 95, 90, 80]
}
df = pd.DataFrame(data)
df = df.astype({
'科目': 'category',
'受講者': 'category',
'得点': 'int32'
})
print("総合的な統計量:")
print(df['得点'].describe())
print("\n科目別の統計量:")
print(df.groupby('科目')['得点'].describe())
データの可視化
箱ひげ図とヒストグラムによりデータ分布を可視化する。
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
import platform
if platform.system() == 'Windows':
plt.rcParams['font.family'] = 'Meiryo'
data = {
'科目': ['国語', '国語', '算数', '算数', '理科'],
'受講者': ['A', 'B', 'A', 'B', 'A'],
'得点': [90, 80, 95, 90, 80]
}
df = pd.DataFrame(data)
df = df.astype({
'科目': 'category',
'受講者': 'category',
'得点': 'int32'
})
# 箱ひげ図
plt.figure(figsize=(10, 6))
df.boxplot(column='得点', by='科目')
plt.suptitle('')
plt.title('科目別得点分布', pad=15)
plt.ylabel('得点')
plt.grid(True)
plt.savefig('score_distribution.png', bbox_inches='tight')
plt.show()
plt.close()
# ヒストグラム
plt.figure(figsize=(10, 6))
plt.hist(df['得点'], bins=range(0, 101, 10), edgecolor='black')
plt.title('得点分布のヒストグラム')
plt.xlabel('得点')
plt.ylabel('頻度')
plt.grid(True)
plt.savefig('score_histogram.png', bbox_inches='tight')
plt.show()
plt.close()
クロス集計表
pd.crosstab()により2変数間の度数を集計する。
import pandas as pd
data = {
'グループ1': ['a', 'b', 'c', 'a', 'b'],
'グループ2': ['d', 'd', 'e', 'e', 'e']
}
df = pd.DataFrame(data)
cross_table = pd.crosstab(df['グループ1'], df['グループ2'])
print(cross_table)
# 合計付き
cross_table_with_margins = pd.crosstab(df['グループ1'], df['グループ2'], margins=True)
print("\n合計付きのクロス集計表:")
print(cross_table_with_margins)
t検定
Welchのt検定により2群の平均値の差を検定する。equal_var=Falseで等分散を仮定しない。
import numpy as np
from scipy import stats
np.random.seed(42)
group1 = np.random.normal(0, 1, 100)
group2 = np.random.normal(0.5, 1, 100)
t_stat, p_value = stats.ttest_ind(group1, group2, equal_var=False)
print(f"t値: {t_stat:.3f}")
print(f"p値: {p_value:.3f}")
一元配置分散分析
stats.f_oneway()により3群以上の平均値の差を検定する。
from scipy import stats
group_a = [3.42, 3.84, 3.96, 3.76]
group_b = [3.17, 3.63, 3.47, 3.44, 3.39]
group_c = [3.64, 3.72, 3.91]
f_stat, p_value = stats.f_oneway(group_a, group_b, group_c)
print(f"F値: {f_stat:.3f}")
print(f"p値: {p_value:.3f}")
正規性の検定
Shapiro-Wilk検定によりデータの正規性を評価する。
from scipy import stats
import numpy as np
np.random.seed(42)
data = np.random.normal(0, 1, 100)
stat, p_value = stats.shapiro(data)
print(f"検定統計量: {stat:.3f}")
print(f"p値: {p_value:.3f}")