データサイエンス演習
【概要】本資料は、Pythonを用いたICTシステム演習のための教材集である。データサイエンスの基礎から主成分分析、相関分析、統計的検定までを段階的に学習できる構成となっている。
教材の利用条件: クリエイティブコモンズ 表示-非営利-継承 4.0 国際ライセンス(CC BY-NC-SA 4.0)に基づき、著作者表示・非営利目的・同一ライセンスでの再配布を条件として自由に利用可能である。
pd-1. データサイエンス、散布図、平均、分布
Pythonを用いたデータの可視化と基本統計量の算出、データから知見を導くための基礎技術の習得
【学習内容の構成】
- データサイエンス:データから正しい知見や結論を導くための学問
- 散布図:時間変化や2つの量の関係を視覚的に把握するグラフ
- 平均:データ集合の代表値としての算出方法と注意点
- ヒストグラム:区間ごとのデータ分布と密度の把握
意義:研究レポート作成やデータ活用の実力向上
Irisデータセットは4つの特徴量を持つ。各列の対応は以下のとおりである。 Irisデータセット(アヤメ属3種の花被片サイズ計測データ、150件)を読み込み、配列の形状を確認する。 Irisデータセットの列構成は、0列:外花被片の長さ、1列:外花被片の幅、2列:内花被片の長さ、3列:内花被片の幅である。yには花の種類(0, 1, 2)が格納されている。 散布図を用いてIrisデータセットの2つの特徴量の関係を視覚化する。 x[:, 0]は配列xの全行の0列目を取得する記法である。散布図は、時間変化や2つの量の関係を把握するために用いる。 散布図に花の種類を色で表現し、種類ごとの分布の違いを把握する。 c=yで色を設定する。yには0, 1, 2の値が入っており、各値に異なる色が自動的に割り当てられる。 複数の系列を持つデータに対して、散布図と折れ線グラフを描画する。 plt.plotの第3引数で描画スタイルを指定する。'o'は点のみ、'o-'は点と線を描画する。label引数で指定した文字列がplt.legend()によって凡例として表示される。折れ線グラフを描画する場合は'o'を'o-'に変更する。 NumPyを用いて平均(データの合計をデータの個数で割ったもの)を算出する。 平均はデータ集合の代表値として用いられることがある。ただし、データの分布によっては平均が役に立たないこともある。 ヒストグラム(区間ごとにデータを数え上げたグラフ)を描画し、データの分布の全体傾向を把握する。 bins=5は区間の数を5に設定することを意味する。ヒストグラムから、密度が高い領域や山の数といった全体傾向を読み取ることができる。演習パート(クリックして展開)
Irisデータセットの列構成
列番号
特徴量名
日本語名
0
sepal length (cm)
外花被片の長さ
1
sepal width (cm)
外花被片の幅
2
petal length (cm)
内花被片の長さ
3
petal width (cm)
内花被片の幅
演習1:Irisデータセットのロード
目的
手順
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target
print(x)
print(y)ヒント
演習2:Irisデータセットの散布図描画
目的
手順
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()ヒント
演習3:Irisデータセットの散布図(色付き)
目的
手順
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()ヒント
演習4:複数列データの散布図・折れ線描画
目的
手順
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()ヒント
演習5:平均の算出
目的
手順
import numpy as np
y1 = [10, 40, 30, 40]
y2 = [5, 10, 5, 20]
print(np.mean(y1))
print(np.mean(y2))ヒント
演習6:ヒストグラムの描画
目的
手順
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()ヒント
pd-2. 主成分分析、次元削減
YouTube動画:https://youtu.be/NBfphF5v8ag
主成分分析による次元削減の原理と実装、外れ値検出への応用
【学習内容の構成】
- 次元削減の基礎:データの次元の定義、削減の効果(可視化、ノイズ除去、計算効率化)、各種手法の概要
- 主成分分析の原理:分散最大化による主軸の決定、上位主軸への投影による次元削減
- 実践演習:Irisデータセットを用いた主成分分析の実行、スケーリングの重要性
- 外れ値検出:主成分分析を利用した外れ値の識別、ロバスト主成分分析
意義:多次元データの可視化と分析、データ品質の評価手法の習得
データの次元(dimension)とは、データの表現に必要な最小の情報の数である。例えば、3次元空間の点は(x, y, z)の3つの値で表現されるため次元数は3となる。
次元削減(dimensionality reduction)とは、データの本質的な情報を保ちながら次元数を減らす処理である。次元削減には以下の効果がある。
主成分分析(PCA)は次元削減の代表的な手法であり、データの分散(ばらつき)が最大となる方向に主軸(principal axis)を見つけ、上位の主軸へ投影することで次元削減を行う。
NumPyでランダムデータを生成し、matplotlibで散布図を作成する。主成分分析の準備として、データの分布を視覚的に把握する。
scikit-learnのPCAクラスを使用して主成分分析を実行し、主軸の方向と分散を確認する。主軸がデータの分散を最大化する方向を向くことを視覚的に理解する。
Irisデータセットは4つの特徴量を持つ。各列の対応は以下のとおりである。
scikit-learnからIrisデータセットを読み込み、データ構造を確認する。
Irisデータセットの4次元データから0列目と1列目を取り出し、散布図を作成する。属性選択による単純な次元削減を体験する。
Irisデータセットの4次元データを主成分分析で2次元に削減し、散布図で可視化する。演習4の結果と比較する。
外れ値(outlier)とは、他の値と比べて異常に離れた値である。外れ値はデータ分析の結果に悪影響を与えるため、適切に検出して対処する必要がある。主成分分析を利用した外れ値検出では、データを主成分空間に投影し、他のデータ点から大きく離れた点を外れ値として特定する。
PyODライブラリを使用してIrisデータセットから外れ値を検出し、可視化する。
演習パート(クリックして展開)
背景知識
演習1:ランダムデータの散布図
目的
手順
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()
ヒント
plt.axis('equal')はx軸とy軸のスケールを揃える設定であるnp.random.normal(0, 1, 100)は平均0、標準偏差1の正規分布から100個のデータを生成する
演習2:ランダムデータの主成分分析
目的
手順
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()
ヒント
explained_varianceの値が大きいほど、その主軸がデータの特徴をよく捉えているplt.quiverは原点から指定した方向へ矢印を描画する関数であるIrisデータセットの列構成
列番号
特徴量名
日本語名
0
sepal length (cm)
外花被片の長さ
1
sepal width (cm)
外花被片の幅
2
petal length (cm)
内花被片の長さ
3
petal width (cm)
内花被片の幅
演習3:Irisデータセットのロード
目的
手順
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.dataは特徴量データ(150×4の配列)を返すiris.targetはラベル(0=setosa, 1=versicolor, 2=virginica)を返す
演習4:Irisデータセットの0,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()
ヒント
x[:, 0]は配列xの全行の0列目を取得するスライシング記法であるiris.feature_namesで各列の特徴量名を取得できる
演習5:主成分分析による2次元への次元削減
目的
手順
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()
ヒント
StandardScalerはデータを平均0、標準偏差1に標準化する。異なる尺度の特徴量を揃えるために重要であるn_components=2で次元削減後の次元数を指定する背景知識
演習6:主成分分析を利用した外れ値の検出
目的
手順
!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()
contaminationパラメータの値を変更して、外れ値の検出数がどのように変化するか観察するヒント
!pip install pyodはPyOD(Python Outlier Detection)ライブラリをインストールするコマンドであるcontamination=0.1は「データ全体の約10%が外れ値である」という仮定を設定している。この値は分析対象のデータの性質に応じて調整するpca.labels_は各データ点が正常値(0)か外れ値(1)かを示すラベルである
pd-3. 相関、相関係数、t 検定
YouTube動画:https://youtu.be/jgzWT8ODhJY
2変数間の関連性を数値化する相関係数,2つの標本の平均値の差が統計的に有意かを判断するt検定
【学習内容の構成】
- 相関と相関係数:2変数間の関連性を−1から1の範囲で数値化し,正の相関・負の相関・相関なしを判断
- 母集団と標本:調査対象全体(母集団)から一部を選ぶサンプリングと,標本サイズの重要性
- t検定とp値:2つの標本の平均値の差が偶然によるものか,統計的に有意かを判断する手法
意義:データ間の関係性分析や統計的仮説検定の実践力
Irisデータセットは4つの特徴量を持つ。各列の対応は以下のとおりである。 Irisデータセットの特定の列を用いて散布図を作成し、相関係数を算出することで、変数間の関係性を視覚的・数値的に把握する方法を学ぶ。 相関係数(correlation coefficient)とは、2つの変数間の関連性の強さを示す数値である。値の範囲は-1から1までであり、1に近いほど正の相関(一方が増えると他方も増える傾向)、-1に近いほど負の相関(一方が増えると他方は減る傾向)、0に近いほど相関がないことを示す。 自分で用意した2つのデータセットに対してt検定を実施し、p値を算出・解釈する方法を学ぶ。 t検定(t-test)とは、2つの標本(sample)の平均値が統計的に有意に異なるかどうかを判断するための統計手法である。p値(p-value)は、2つの標本の差が偶然によるものである確率を示す。p値が小さいほど、差が偶然ではなく有意である可能性が高い。 p値の解釈をより深く理解するために、以下の2パターンを試すこと。 2つのパターンでp値がどのように変化するかを確認し、p値と平均値の差の関係について考察すること。演習パート(クリックして展開)
Irisデータセットの列構成
列番号
特徴量名
日本語名
0
sepal length (cm)
外花被片の長さ
1
sepal width (cm)
外花被片の幅
2
petal length (cm)
内花被片の長さ
3
petal width (cm)
内花被片の幅
演習1: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
plt.scatter(x[:, 0], x[:, 2])
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[2])
plt.title('Iris dataset')
plt.show()
np.corrcoef(x[:, 0], x[:, 2])
ヒント
演習2:t検定によるp値の算出
目的
前提知識
手順
from scipy import stats
sample1 = [自分で考えた5個以上の数値をカンマ区切りで入力]
sample2 = [自分で考えた5個以上の数値をカンマ区切りで入力]
t, p = stats.ttest_ind(sample1, sample2)
print(p)
追加課題:p値の変化を確認する
sample1 = [90, 92, 88, 95, 91]
sample2 = [60, 58, 62, 55, 59]
t, p = stats.ttest_ind(sample1, sample2)
print(p)
sample1 = [80, 82, 78, 85, 81]
sample2 = [79, 83, 77, 84, 80]
t, p = stats.ttest_ind(sample1, sample2)
print(p)
ヒント
pd-4. 標本の平均、母平均
スライド資料: [PDF], [パワーポイント]
NumPy ライブラリの mean 関数を使用して、データの平均(データの合計をデータの個数で割った値)を算出する方法を習得する。 np.mean() は引数として渡されたリストや配列の算術平均を返す。y1 の場合、(10 + 40 + 30 + 40) ÷ 4 = 30 となる。 NumPy ライブラリの var 関数を使用して、データの不偏分散(母分散の推定に使用される統計量)を算出する方法を習得する。 np.var() で ddof=1 を指定すると、分母が n-1 となり不偏分散が算出される。ddof は「delta degrees of freedom(自由度の減少分)」を意味する。ddof=0(デフォルト)では標本分散、ddof=1 では不偏分散となる。 正規分布(平均と分散だけで頻度分布を定める分布)に従うランダムデータを生成し、その平均と不偏分散を算出する。また、ヒストグラムを表示してデータの分布を視覚的に確認する。 np.random.normal(loc, scale, size) は正規分布に従う乱数を生成する。loc は平均、scale は標準偏差(分散の平方根)、size はデータ数を指定する。標本数が多い場合、不偏分散の値は母分散の値に近づく(大数の法則)。 母集団(調査や研究の対象となる全体の集団)からサンプリング(一部を選ぶこと)を行い、標本(サンプリングで選ばれたもの)を得る方法を習得する。 np.random.choice(a, size) は配列 a からランダムに size 個の要素を選択する。選ばれた標本によって値が異なり、平均なども異なってくる。 サンプリングを複数回繰り返し、標本ごとに値が異なることを確認する。 for ループを使用して同じサンプリング処理を繰り返している。range(10) により 10 回の繰り返しとなる。 サンプリングを繰り返して標本の平均と不偏分散を算出し、標本数(n)の違いによる推定精度の変化を理解する。母平均(母集団の平均)の推定において、標本数が大きいほど精度が向上することを確認する。 母集団が正規分布であるとき、標本平均の分布も正規分布となり、その分散は「母分散 ÷ n」となる。したがって、n が大きいほど標本平均のばらつきは小さくなり、母平均の推定精度が向上する。標本の平均から母平均を推定する際は、必ず誤差が発生することを認識し、論文などに細かすぎる値を書かないよう注意する。演習パート(クリックして展開)
演習1:平均の算出
目的
手順
コード
import numpy as np
y1 = [10, 40, 30, 40]
y2 = [5, 10, 5, 20]
print(np.mean(y1))
print(np.mean(y2))
ヒント
演習2:不偏分散の算出
目的
手順
コード
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))
ヒント
演習3:正規分布に従うランダムデータの生成と分析
目的
手順
コード(データ生成と統計量算出)
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()
ヒント
演習4:サンプリング
目的
手順
コード
import numpy as np
y1 = np.random.normal(100, np.sqrt(20), 1000000)
n = 5
s = np.random.choice(y1, n)
print(s)
ヒント
演習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(s)
ヒント
演習6:標本の平均と不偏分散の算出(標本数による精度比較)
目的
手順
コード(標本数 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))
ヒント