データサイエンス演習

【概要】本資料は、Pythonを用いたICTシステム演習のための教材集である。データサイエンスの基礎から主成分分析、相関分析、統計的検定までを段階的に学習できる構成となっている。

教材の利用条件: クリエイティブコモンズ 表示-非営利-継承 4.0 国際ライセンス(CC BY-NC-SA 4.0)に基づき、著作者表示・非営利目的・同一ライセンスでの再配布を条件として自由に利用可能である。

pd-1. データサイエンス、散布図、平均、分布

スライド資料: [PDF], [パワーポイント]

Pythonを用いたデータの可視化と基本統計量の算出、データから知見を導くための基礎技術の習得

【学習内容の構成】

  1. データサイエンス:データから正しい知見や結論を導くための学問
  2. 散布図:時間変化や2つの量の関係を視覚的に把握するグラフ
  3. 平均:データ集合の代表値としての算出方法と注意点
  4. ヒストグラム:区間ごとのデータ分布と密度の把握

意義:研究レポート作成やデータ活用の実力向上

演習パート(クリックして展開)

Irisデータセットの列構成

Irisデータセットは4つの特徴量を持つ。各列の対応は以下のとおりである。

列番号 特徴量名 日本語名
0 sepal length (cm) 外花被片の長さ
1 sepal width (cm) 外花被片の幅
2 petal length (cm) 内花被片の長さ
3 petal width (cm) 内花被片の幅

演習1:Irisデータセットのロード

目的

Irisデータセット(アヤメ属3種の花被片サイズ計測データ、150件)を読み込み、配列の形状を確認する。

手順

  1. Google Colaboratoryで新しいノートブックを作成する
  2. 以下のコードを実行する
  3. 出力結果を確認し、xが2次元配列(150行4列)、yが1次元配列(150要素)であることを確認する
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target
print(x)
print(y)

ヒント

Irisデータセットの列構成は、0列:外花被片の長さ、1列:外花被片の幅、2列:内花被片の長さ、3列:内花被片の幅である。yには花の種類(0, 1, 2)が格納されている。

演習2:Irisデータセットの散布図描画

目的

散布図を用いてIrisデータセットの2つの特徴量の関係を視覚化する。

手順

  1. 必要なライブラリをインポートする
  2. Irisデータセットをロードする
  3. plt.scatterを用いて散布図を描画する
  4. 軸ラベルとタイトルを設定する
  5. グラフを表示する
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target
# グラフ
plt.scatter(x[:, 0], x[:, 1])
# ラベル
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.title('Iris データセット')
# 表示
plt.show()

ヒント

x[:, 0]は配列xの全行の0列目を取得する記法である。散布図は、時間変化や2つの量の関係を把握するために用いる。

演習3:Irisデータセットの散布図(色付き)

目的

散布図に花の種類を色で表現し、種類ごとの分布の違いを把握する。

手順

  1. 演習2のコードを基に、plt.scatterの引数にc=yを追加する
  2. グラフを表示し、色によって花の種類が区別されていることを確認する
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target
# グラフ
plt.scatter(x[:, 0], x[:, 1], c=y)
# ラベル
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.title('Iris データセット')
# 表示
plt.show()

ヒント

c=yで色を設定する。yには0, 1, 2の値が入っており、各値に異なる色が自動的に割り当てられる。

演習4:複数列データの散布図・折れ線描画

目的

複数の系列を持つデータに対して、散布図と折れ線グラフを描画する。

手順

  1. Pythonリストとしてデータを準備する
  2. plt.plotを用いてグラフを描画する('o'で散布図、'o-'で折れ線)
  3. 凡例を追加して系列を区別できるようにする
import matplotlib.pyplot as plt

x = [1985, 1990, 1995, 2000, 2005, 2010]
y1 = [1432, 1222, 1187, 1191, 1063, 1071]
y2 = [752, 820, 922, 962, 1084, 1197]
# グラフ(散布図の場合)
plt.plot(x, y1, 'o', label='出生数')
plt.plot(x, y2, 'o', label='死亡数')
# ラベル
plt.xlabel('年次')
plt.ylabel('数(単位:1000人)')
plt.title('出生数と死亡数')
# 凡例
plt.legend()
# 表示
plt.show()

ヒント

plt.plotの第3引数で描画スタイルを指定する。'o'は点のみ、'o-'は点と線を描画する。label引数で指定した文字列がplt.legend()によって凡例として表示される。折れ線グラフを描画する場合は'o'を'o-'に変更する。

演習5:平均の算出

目的

NumPyを用いて平均(データの合計をデータの個数で割ったもの)を算出する。

手順

  1. NumPyライブラリをインポートする
  2. Pythonリストとしてデータを準備する
  3. np.mean関数を用いて平均を算出する
import numpy as np

y1 = [10, 40, 30, 40]
y2 = [5, 10, 5, 20]
print(np.mean(y1))
print(np.mean(y2))

ヒント

平均はデータ集合の代表値として用いられることがある。ただし、データの分布によっては平均が役に立たないこともある。

演習6:ヒストグラムの描画

目的

ヒストグラム(区間ごとにデータを数え上げたグラフ)を描画し、データの分布の全体傾向を把握する。

手順

  1. 必要なライブラリをインポートする
  2. Irisデータセットをロードする
  3. plt.histを用いてヒストグラムを描画する
  4. bins引数で区間の数を設定する
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target
# グラフ
plt.hist(x[:, 0], bins=5)
# ラベル
plt.title(iris.feature_names[0])
# 表示
plt.show()

ヒント

bins=5は区間の数を5に設定することを意味する。ヒストグラムから、密度が高い領域や山の数といった全体傾向を読み取ることができる。

pd-2. 主成分分析、次元削減

スライド資料: [PDF], [パワーポイント]

YouTube動画:https://youtu.be/NBfphF5v8ag

主成分分析による次元削減の原理と実装、外れ値検出への応用

【学習内容の構成】

  1. 次元削減の基礎:データの次元の定義、削減の効果(可視化、ノイズ除去、計算効率化)、各種手法の概要
  2. 主成分分析の原理:分散最大化による主軸の決定、上位主軸への投影による次元削減
  3. 実践演習:Irisデータセットを用いた主成分分析の実行、スケーリングの重要性
  4. 外れ値検出:主成分分析を利用した外れ値の識別、ロバスト主成分分析

意義:多次元データの可視化と分析、データ品質の評価手法の習得

演習パート(クリックして展開)

背景知識

データの次元(dimension)とは、データの表現に必要な最小の情報の数である。例えば、3次元空間の点は(x, y, z)の3つの値で表現されるため次元数は3となる。

次元削減(dimensionality reduction)とは、データの本質的な情報を保ちながら次元数を減らす処理である。次元削減には以下の効果がある。

主成分分析(PCA)は次元削減の代表的な手法であり、データの分散(ばらつき)が最大となる方向に主軸(principal axis)を見つけ、上位の主軸へ投影することで次元削減を行う。

演習1:ランダムデータの散布図

目的

NumPyでランダムデータを生成し、matplotlibで散布図を作成する。主成分分析の準備として、データの分布を視覚的に把握する。

手順

  1. Google Colaboratoryで新しいノートブックを開く
  2. 以下のコードを実行する
import numpy as np
import matplotlib.pyplot as plt

x = np.random.normal(0, 1, 100)
y = 3 * x + np.random.normal(0, 1, 100)

# グラフとラベル
plt.axis('equal')
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.title('random data')
plt.show()
  1. 散布図が表示されることを確認する
  2. コードを複数回実行し、毎回異なるデータが生成されることを確認する

ヒント


演習2:ランダムデータの主成分分析

目的

scikit-learnのPCAクラスを使用して主成分分析を実行し、主軸の方向と分散を確認する。主軸がデータの分散を最大化する方向を向くことを視覚的に理解する。

手順

  1. 以下のコードを実行する
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

# ランダムデータ
x = np.random.normal(0, 1, 100)
y = 3 * x + np.random.normal(0, 1, 100)
data = np.column_stack((x, y))

# 主成分分析
pca = PCA(n_components=2)
pca.fit(data)
components = pca.components_
explained_variance = pca.explained_variance_

print(f'Principal components:\n{components}')
print(f'Explained variance: {explained_variance}')

plt.axis('equal')
plt.scatter(x, y)
plt.quiver(0, 0, components[0, 0], components[0, 1], color='r')
plt.quiver(0, 0, components[1, 0], components[1, 1], color='b')
plt.title('PCA')
plt.show()
  1. 出力される主成分(Principal components)と分散(Explained variance)の値を確認する
  2. 散布図上に表示される赤い矢印(1番目の主軸)と青い矢印(2番目の主軸)の方向を確認する

ヒント

Irisデータセットの列構成

Irisデータセットは4つの特徴量を持つ。各列の対応は以下のとおりである。

列番号 特徴量名 日本語名
0 sepal length (cm) 外花被片の長さ
1 sepal width (cm) 外花被片の幅
2 petal length (cm) 内花被片の長さ
3 petal width (cm) 内花被片の幅

演習3:Irisデータセットのロード

目的

scikit-learnからIrisデータセットを読み込み、データ構造を確認する。

手順

  1. 以下のコードを入力して実行する
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

iris = load_iris()
x = iris.data
y = iris.target

print(x)
print(y)
  1. 出力されるxの形状(150行4列の2次元配列)を確認する
  2. 出力されるyの値(0, 1, 2のいずれかで、アヤメの種類を表す)を確認する

ヒント


演習4:Irisデータセットの0,1列目の可視化

目的

Irisデータセットの4次元データから0列目と1列目を取り出し、散布図を作成する。属性選択による単純な次元削減を体験する。

手順

  1. 以下のコードを実行する
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

iris = load_iris()
x = iris.data
y = iris.target

# グラフ
plt.scatter(x[:, 0], x[:, 1])

# ラベル
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.title('Iris dataset')

# 表示
plt.show()
  1. 散布図が表示されることを確認する
  2. x軸とy軸のラベルが特徴量名になっていることを確認する

ヒント


演習5:主成分分析による2次元への次元削減

目的

Irisデータセットの4次元データを主成分分析で2次元に削減し、散布図で可視化する。演習4の結果と比較する。

手順

  1. 以下のコードを実行する
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler

# Iris データセットをロード
iris = load_iris()
data = iris.data
y = iris.target

# 平均0、標準偏差1にスケーリング
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# 主成分分析.2次元に次元削減
pca = PCA(n_components=2)
data_pca = pca.fit_transform(data_scaled)

# 散布図
plt.scatter(data_pca[:, 0], data_pca[:, 1])
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('PCA of IRIS dataset')
plt.show()
  1. 散布図が表示されることを確認する
  2. 演習4の結果と比較し、データの分布の違いを観察する

ヒント

背景知識

外れ値(outlier)とは、他の値と比べて異常に離れた値である。外れ値はデータ分析の結果に悪影響を与えるため、適切に検出して対処する必要がある。主成分分析を利用した外れ値検出では、データを主成分空間に投影し、他のデータ点から大きく離れた点を外れ値として特定する。

演習6:主成分分析を利用した外れ値の検出

目的

PyODライブラリを使用してIrisデータセットから外れ値を検出し、可視化する。

手順

  1. 以下のコードを Google Colaboratory のコードセルに入力して実行する。あるいは「pip install pyod」を実行の後、残りの部分のコードを実行する
!pip install pyod

import numpy as np
import matplotlib.pyplot as plt
from pyod.models.pca import PCA as PCA_pyod
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler

# Iris データセットをロード
iris = load_iris()
data = iris.data
y = iris.target

# 平均0、標準偏差1にスケーリング
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# 主成分分析.2次元に次元削減
pca = PCA_pyod(n_components=2, contamination=0.1)
pca.fit(data_scaled)

y_train_pred = pca.labels_  # binary labels (0: inliers, 1: outliers)
y_train_scores = pca.decision_scores_  # raw outlier scores

outlier_mask = y_train_pred != 0  # True for outliers
inlier_mask = np.logical_not(outlier_mask)  # True for inliers

data_pca_manual = np.dot(data_scaled, pca.components_.T)

plt.scatter(data_pca_manual[inlier_mask, 0], data_pca_manual[inlier_mask, 1], color='b', label='Inliers')
plt.scatter(data_pca_manual[outlier_mask, 0], data_pca_manual[outlier_mask, 1], color='r', label='Outliers')
plt.legend()
plt.title('Robust PCA of IRIS dataset')
plt.show()
  1. 散布図で青い点(正常値)と赤い点(外れ値)が区別されていることを確認する
  2. contaminationパラメータの値を変更して、外れ値の検出数がどのように変化するか観察する

ヒント

pd-3. 相関、相関係数、t 検定

スライド資料: [PDF], [パワーポイント]

YouTube動画:https://youtu.be/jgzWT8ODhJY

2変数間の関連性を数値化する相関係数,2つの標本の平均値の差が統計的に有意かを判断するt検定

【学習内容の構成】

  1. 相関と相関係数:2変数間の関連性を−1から1の範囲で数値化し,正の相関・負の相関・相関なしを判断
  2. 母集団と標本:調査対象全体(母集団)から一部を選ぶサンプリングと,標本サイズの重要性
  3. t検定とp値:2つの標本の平均値の差が偶然によるものか,統計的に有意かを判断する手法

意義:データ間の関係性分析や統計的仮説検定の実践力

演習パート(クリックして展開)

Irisデータセットの列構成

Irisデータセットは4つの特徴量を持つ。各列の対応は以下のとおりである。

列番号 特徴量名 日本語名
0 sepal length (cm) 外花被片の長さ
1 sepal width (cm) 外花被片の幅
2 petal length (cm) 内花被片の長さ
3 petal width (cm) 内花被片の幅

演習1:Irisデータセットの散布図作成と相関係数の算出

目的

Irisデータセットの特定の列を用いて散布図を作成し、相関係数を算出することで、変数間の関係性を視覚的・数値的に把握する方法を学ぶ。

前提知識

相関係数(correlation coefficient)とは、2つの変数間の関連性の強さを示す数値である。値の範囲は-1から1までであり、1に近いほど正の相関(一方が増えると他方も増える傾向)、-1に近いほど負の相関(一方が増えると他方は減る傾向)、0に近いほど相関がないことを示す。

手順

  1. Google Colaboratoryで新しいノートブックを開く
  2. 以下のコードを実行し、必要なライブラリをインポートしてIrisデータセットをロードする
    import matplotlib.pyplot as plt
    import numpy as np
    from sklearn.datasets import load_iris
    iris = load_iris()
    x = iris.data
    y = iris.target
    
  3. Irisデータセットの0列目と2列目を使用して散布図を作成する。以下のコードを実行する
    plt.scatter(x[:, 0], x[:, 2])
    plt.xlabel(iris.feature_names[0])
    plt.ylabel(iris.feature_names[2])
    plt.title('Iris dataset')
    plt.show()
    
  4. 0列目と2列目の相関係数を算出する。以下のコードを実行する
    np.corrcoef(x[:, 0], x[:, 2])
    
  5. 算出された相関係数行列を確認し、右上または左下の値を読み取る。この値が相関係数である
  6. 散布図の形状と相関係数の値から、2つの変数間にどのような関係があるか考察する

ヒント

演習2:t検定によるp値の算出

目的

自分で用意した2つのデータセットに対してt検定を実施し、p値を算出・解釈する方法を学ぶ。

前提知識

t検定(t-test)とは、2つの標本(sample)の平均値が統計的に有意に異なるかどうかを判断するための統計手法である。p値(p-value)は、2つの標本の差が偶然によるものである確率を示す。p値が小さいほど、差が偶然ではなく有意である可能性が高い。

手順

  1. サイズが5以上の数値データを2個準備する。以下は例である。自分でデータを考えて設定すること
    from scipy import stats
    sample1 = [自分で考えた5個以上の数値をカンマ区切りで入力]
    sample2 = [自分で考えた5個以上の数値をカンマ区切りで入力]
    
  2. t検定を実施し、p値を算出する
    t, p = stats.ttest_ind(sample1, sample2)
    print(p)
    
  3. 算出されたp値を記録する
  4. p値の大きさから、2つのデータの差が統計的に有意かどうかを考察する

追加課題:p値の変化を確認する

p値の解釈をより深く理解するために、以下の2パターンを試すこと。

  1. p値が小さくなる例:2つのデータの平均値が大きく異なるようにデータを設定する
    sample1 = [90, 92, 88, 95, 91]
    sample2 = [60, 58, 62, 55, 59]
    t, p = stats.ttest_ind(sample1, sample2)
    print(p)
    
  2. p値が大きくなる例:2つのデータの平均値が近くなるようにデータを設定する
    sample1 = [80, 82, 78, 85, 81]
    sample2 = [79, 83, 77, 84, 80]
    t, p = stats.ttest_ind(sample1, sample2)
    print(p)
    

2つのパターンでp値がどのように変化するかを確認し、p値と平均値の差の関係について考察すること。

ヒント

pd-4. 標本の平均、母平均

スライド資料: [PDF], [パワーポイント]

演習パート(クリックして展開)

演習1:平均の算出

目的

NumPy ライブラリの mean 関数を使用して、データの平均(データの合計をデータの個数で割った値)を算出する方法を習得する。

手順

  1. コードを実行し、出力結果を確認する。
  2. y1 の平均が 30.0、y2 の平均が 10.0 となることを手計算でも確認する。

コード

import numpy as np

y1 = [10, 40, 30, 40]
y2 = [5, 10, 5, 20]
print(np.mean(y1))
print(np.mean(y2))

ヒント

np.mean() は引数として渡されたリストや配列の算術平均を返す。y1 の場合、(10 + 40 + 30 + 40) ÷ 4 = 30 となる。

演習2:不偏分散の算出

目的

NumPy ライブラリの var 関数を使用して、データの不偏分散(母分散の推定に使用される統計量)を算出する方法を習得する。

手順

  1. コードを実行し、出力結果を確認する。
  2. ddof=1 を指定することで不偏分散が算出されることを理解する。

コード

import numpy as np

y1 = [10, 40, 30, 40]
y2 = [5, 10, 5, 20]
print(np.var(y1, ddof=1))
print(np.var(y2, ddof=1))

ヒント

np.var() で ddof=1 を指定すると、分母が n-1 となり不偏分散が算出される。ddof は「delta degrees of freedom(自由度の減少分)」を意味する。ddof=0(デフォルト)では標本分散、ddof=1 では不偏分散となる。

演習3:正規分布に従うランダムデータの生成と分析

目的

正規分布(平均と分散だけで頻度分布を定める分布)に従うランダムデータを生成し、その平均と不偏分散を算出する。また、ヒストグラムを表示してデータの分布を視覚的に確認する。

手順

  1. 以下のコード(データ生成と統計量算出)を実行する。
  2. 出力された平均と不偏分散が、設定した値(平均100、分散20)に近いことを確認する。
  3. 次のコード(ヒストグラム表示)を実行する。
  4. ヒストグラムの形状が正規分布の釣鐘型になっていることを確認する。

コード(データ生成と統計量算出)

import numpy as np

y1 = np.random.normal(100, np.sqrt(20), 1000000)
print(np.mean(y1))
print(np.var(y1, ddof=1))

コード(ヒストグラム表示)

import numpy as np
import matplotlib.pyplot as plt

y1 = np.random.normal(100, np.sqrt(20), 1000000)
plt.hist(y1)
plt.show()

ヒント

np.random.normal(loc, scale, size) は正規分布に従う乱数を生成する。loc は平均、scale は標準偏差(分散の平方根)、size はデータ数を指定する。標本数が多い場合、不偏分散の値は母分散の値に近づく(大数の法則)。

演習4:サンプリング

目的

母集団(調査や研究の対象となる全体の集団)からサンプリング(一部を選ぶこと)を行い、標本(サンプリングで選ばれたもの)を得る方法を習得する。

手順

  1. コードを実行し、5個の標本が出力されることを確認する。
  2. 複数回実行して、毎回異なる標本が得られることを確認する。

コード

import numpy as np

y1 = np.random.normal(100, np.sqrt(20), 1000000)
n = 5
s = np.random.choice(y1, n)
print(s)

ヒント

np.random.choice(a, size) は配列 a からランダムに size 個の要素を選択する。選ばれた標本によって値が異なり、平均なども異なってくる。

演習5:サンプリングの繰り返し

目的

サンプリングを複数回繰り返し、標本ごとに値が異なることを確認する。

手順

  1. コードを実行し、10組の標本が出力されることを確認する。
  2. 各標本の値が異なることを観察する。

コード

import numpy as np

y1 = np.random.normal(100, np.sqrt(20), 1000000)
n = 5
for i in range(10):
    s = np.random.choice(y1, n)
    print(s)

ヒント

for ループを使用して同じサンプリング処理を繰り返している。range(10) により 10 回の繰り返しとなる。

演習6:標本の平均と不偏分散の算出(標本数による精度比較)

目的

サンプリングを繰り返して標本の平均と不偏分散を算出し、標本数(n)の違いによる推定精度の変化を理解する。母平均(母集団の平均)の推定において、標本数が大きいほど精度が向上することを確認する。

手順

  1. 以下のコード(標本数 n=5)を実行する。
  2. 出力された平均と不偏分散の値を記録する。
  3. 次のコード(標本数 n=50)を実行する。
  4. 標本数 5 の結果と標本数 50 の結果を比較する。
  5. どちらが母集団の真の値(平均100、分散20)に近いか考察する。

コード(標本数 n=5)

import numpy as np

y1 = np.random.normal(100, np.sqrt(20), 1000000)
n = 5
for i in range(10):
    s = np.random.choice(y1, n)
    print(np.mean(s), np.var(s, ddof=1))

コード(標本数 n=50)

import numpy as np

y1 = np.random.normal(100, np.sqrt(20), 1000000)
n = 50
for i in range(10):
    s = np.random.choice(y1, n)
    print(np.mean(s), np.var(s, ddof=1))

ヒント

母集団が正規分布であるとき、標本平均の分布も正規分布となり、その分散は「母分散 ÷ n」となる。したがって、n が大きいほど標本平均のばらつきは小さくなり、母平均の推定精度が向上する。標本の平均から母平均を推定する際は、必ず誤差が発生することを認識し、論文などに細かすぎる値を書かないよう注意する。