Google Colaboratoryを用いたAI入門

【概要】本稿は、Google Colaboratoryを使用した機械学習の入門である。ブラウザから利用可能なColabの基本操作、CNNによる画像分類、LSTMによる感情分析および時系列予測、データ可視化について、実践的なコード例とともに解説する。

【前提知識】Pythonの基本文法を理解していることを前提とする。

【目次】

  1. Google Colaboratory
  2. 基本概念と用語
  3. 画像分類プロジェクト
  4. 自然言語処理による感情分析プロジェクト
  5. 時系列データ予測システムの構築
  6. データの可視化と分析プロジェクト
  7. 学習結果の共通評価方法

Google Colaboratory

Google Colaboratoryの基本情報

Google Colaboratory(以下、Colab)は、ブラウザ上でPythonコードを実行できるGoogleの無料サービスである。GPUを無料で利用でき、環境構築なしで機械学習を始められる点が利点である。

「Colaboratoryへようこそ」のページのURLは、https://colab.research.google.com/?hl=ja である。

事前インストール済みライブラリ

NumPy、Pandas、Matplotlib、TensorFlow、PyTorchなど、科学計算や機械学習に必要なライブラリが事前にインストールされている。そのため、import文を記述するだけで利用できる。

追加ライブラリのインストール

事前にインストールされていないライブラリは!pipコマンドでインストールできる。ただし、インストールしたライブラリはセッション終了後に消去されるため、次回セッションで再インストールが必要となる。

選択基準

基本概念と用語

本セクションでは、以降のプロジェクトで使用する機械学習の基本用語を解説する。初めて機械学習に触れる場合は、このセクションを一読してからプロジェクトに進むことを推奨する。

機械学習の基本概念

正規化(normalization)は、データの値を0から1の範囲に変換する処理である。特徴量ごとに値の範囲が異なると特定の特徴量が学習に過大な影響を与えるため、同一の範囲に揃えることで学習の安定化と高速化に寄与する。

エポック(epoch)は、全訓練データを1回学習することを指す。エポック数が多すぎると過学習、少なすぎると学習不足になる。

バッチサイズ(batch size)は、一度に処理するデータの数である。バッチサイズが大きいと学習が安定するがメモリを多く使用し、小さいと学習が不安定になるが汎化性能が向上する傾向がある。

汎化性能(generalization)は、学習に使用していない未知のデータに対する予測精度である。汎化性能が高いモデルは、新しいデータに対しても正確な予測ができる。

過学習(overfitting)は、訓練データに過度に適合し、未知のデータに対する予測精度が低下する現象である。訓練精度は高いが検証精度が低い場合、過学習が疑われる。

検証データ(validation data)は、学習の進捗確認に使用するデータであり、訓練には使用しない。過学習の早期発見に役立つ。

ドロップアウト(dropout)は、学習時にニューロンの一部を無作為に無効化し、過学習を防ぐ手法である。特定のニューロンへの依存を減らすことで、モデルの汎化性能を高める。

ニューラルネットワークの種類

CNN(畳み込みニューラルネットワーク、Convolutional Neural Network)は、画像の特徴を段階的に学習するモデルである。畳み込み層で画像から特徴を抽出し、プーリング層で情報を圧縮しながら、エッジや形などの局所的な特徴から物体全体の認識へと進む。画像内の位置によらず特徴を抽出でき、画像認識タスクで高い性能を発揮する。

LSTM(長短期記憶、Long Short-Term Memory)は、時系列データや文章の流れを理解できるモデルである。従来のRNN(再帰型ニューラルネットワーク、Recurrent Neural Network)では、長い系列を処理する際に過去の情報が失われる勾配消失問題が発生する。勾配消失問題とは、学習時に誤差の勾配が層を遡るにつれて小さくなり、初期の層が学習できなくなる現象である。LSTMはゲート機構によりこの問題を解決し、長期的な依存関係を学習できる。

データ処理用語

ワンホットエンコーディング(one-hot encoding)は、カテゴリ変数を数値に変換する手法である。例えば、「犬」「猫」「鳥」を[1,0,0]、[0,1,0]、[0,0,1]のような形式に変換する。機械学習モデルは数値のみを扱えるため、この変換が必要となる。

パディング(padding)は、文章の長さを揃えるため、短い文章に特別な値(通常は0)を追加する処理である。LSTMは固定長の入力を必要とするため、この処理を行う。

埋め込み層(embedding layer)は、単語を数値ベクトルに変換する層である。意味が近い単語は近いベクトルを持つように学習される。

評価指標

シグモイド関数(sigmoid function)は、任意の入力値を0から1の範囲に変換する関数である。出力を確率として解釈できるため、二値分類で使用される。

RMSE(平均平方根誤差、Root Mean Squared Error)は、予測精度を表す指標である。予測値と実際の値の差を二乗して平均し、その平方根を取る。二乗により大きな誤差が強調され、平方根により単位が元データと揃う。値が小さいほど精度が高い。

画像分類プロジェクト

概要

このセクションでは、CNNを用いた画像分類の実装方法を学ぶ。完了後、画像データの前処理、CNNモデルの構築、学習結果の評価ができるようになる。

画像分類とは、コンピュータが画像を見てその内容を自動的に分類する技術である。人間が写真を見て「これは犬」「これは車」と判断するように、コンピュータにも同様の判断を行わせる。

CIFAR-10データセットは、10種類の物体(飛行機、車、鳥、猫、鹿、犬、カエル、馬、船、トラック)の32×32ピクセルの画像が60,000枚含まれている。低解像度のため計算が軽く教育用途に適しているが、実用では高解像度の画像を扱う点に留意する。

実装例

以下のコードは、CIFAR-10データセットを用いてCNNによる画像分類を行う。コードは「環境設定」「データ準備」「モデル構築」「学習」「評価」の順に構成されている。

# CIFAR-10データセットを使用したCNN画像分類システム

# --- 環境設定 ---
# 日本語フォントのインストール(グラフの日本語表示に必要)
!apt-get -qq install -y fonts-ipafont-gothic
!pip install -q japanize-matplotlib
import japanize_matplotlib
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

# 再現性のための乱数シード設定
SEED, EPOCHS, BATCH_SIZE, NUM_CLASSES = 42, 5, 32, 10
CLASS_NAMES = ['飛行機', '自動車', '鳥', '猫', '鹿', '犬', 'カエル', '馬', '船', 'トラック']
np.random.seed(SEED)
tf.random.set_seed(SEED)

# --- データ準備 ---
# データの読み込みと正規化(0-255の値を0-1に変換)
(x_train_full, y_train_full), (x_test, y_test) = keras.datasets.cifar10.load_data()
x_train_full, x_test = x_train_full.astype('float32') / 255.0, x_test.astype('float32') / 255.0
# ラベルをワンホットエンコーディングに変換
y_train_full = keras.utils.to_categorical(y_train_full, NUM_CLASSES)
y_test = keras.utils.to_categorical(y_test, NUM_CLASSES)

# 訓練データと検証データの分割(80%:20%)
val_size = int(len(x_train_full) * 0.2)
x_train, x_val = x_train_full[:-val_size], x_train_full[-val_size:]
y_train, y_val = y_train_full[:-val_size], y_train_full[-val_size:]

# --- モデル構築 ---
# CNNモデルの定義
model = keras.Sequential([
    # 畳み込み層:画像から特徴を抽出
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
    # プーリング層:特徴マップのサイズを縮小
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    # 全結合層への変換
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    # 出力層:10クラスの確率を出力
    layers.Dense(NUM_CLASSES, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# --- 学習 ---
history = model.fit(x_train, y_train, epochs=EPOCHS, batch_size=BATCH_SIZE,
                    validation_data=(x_val, y_val), verbose=1)

# --- 評価 ---
# 予測結果の可視化
predictions = model.predict(x_test[:5])
plt.figure(figsize=(15, 3))
for i in range(5):
    plt.subplot(1, 5, i+1)
    plt.imshow(x_test[i])
    plt.title(f'予測: {CLASS_NAMES[np.argmax(predictions[i])]}\n実際: {CLASS_NAMES[np.argmax(y_test[i])]}')
    plt.axis('off')
plt.tight_layout()
plt.show()

# 学習履歴の可視化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
ax1.plot(history.history['accuracy'], label='訓練精度')
ax1.plot(history.history['val_accuracy'], label='検証精度')
ax1.set_title('モデル精度')
ax1.set_xlabel('エポック')
ax1.set_ylabel('精度')
ax1.legend()
ax2.plot(history.history['loss'], label='訓練損失')
ax2.plot(history.history['val_loss'], label='検証損失')
ax2.set_title('モデル損失')
ax2.set_xlabel('エポック')
ax2.set_ylabel('損失')
ax2.legend()
plt.tight_layout()
plt.show()

# 最終評価
test_accuracy = model.evaluate(x_test, y_test, verbose=0)[1]
print(f"テスト精度: {test_accuracy:.4f}")
print(f"解釈: 1.0に近いほど予測精度が高く、0.7以上であれば良好とされる")

実行結果の読み方

テスト精度は0.0から1.0の範囲で表示され、1.0に近いほど予測精度が高い。0.7以上であれば良好、0.5未満は学習失敗の可能性がある。

予測結果表示では、5枚の画像について予測ラベルと実際のラベルが表示され、一致していれば予測が成功している。

学習履歴グラフでは、訓練精度と検証精度が近い値で上昇していれば正常な学習である。検証精度が訓練精度より大幅に低い場合は過学習の可能性がある。損失については、両者が減少傾向であれば学習が進行しており、検証損失が上昇に転じた場合は過学習の兆候である。

自然言語処理による感情分析プロジェクト

概要

このセクションでは、LSTMを用いたテキストの感情分析を学ぶ。完了後、テキストデータの前処理、LSTMモデルの構築、感情の二値分類ができるようになる。

感情分析とは、テキストデータから感情の極性(ポジティブまたはネガティブ)を自動判定する技術であり、映画レビューやSNSの投稿などの分析に使用される。

IMDbデータセットは、映画レビューサイトのデータで「好評価」「低評価」に明確に分類されており、感情分析の学習に適している。50,000件のレビューからなり、訓練用25,000件、テスト用25,000件に分けられている。英語テキストであるため、日本語への直接適用はできない点に留意する。

自然言語処理の特殊概念

単語インデックスは、各単語に割り当てられた固有の番号であり、コンピュータが文字を数値として扱うために用いる。例えば、「the」=1、「movie」=2のように変換される。

実装例

以下のコードは、IMDbデータセットを用いてLSTMによる感情分析を行う。コードは「環境設定」「データ準備」「モデル構築」「学習」「評価」の順に構成されている。

# IMDbレビューデータを使用したLSTM感情分析システム

# --- 環境設定 ---
!apt-get -qq install -y fonts-ipafont-gothic
!pip install -q japanize-matplotlib
import japanize_matplotlib
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.preprocessing.sequence import pad_sequences
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

SEED, EPOCHS, BATCH_SIZE = 42, 5, 32
# MAX_WORDS: 使用する単語数の上限
# MAX_LENGTH: 入力文の最大長(これより長い文は切り詰められる)
MAX_WORDS, MAX_LENGTH, EMBEDDING_DIM, LSTM_UNITS, DROPOUT_RATE = 10000, 250, 128, 64, 0.5
np.random.seed(SEED)
tf.random.set_seed(SEED)

# --- データ準備 ---
# データの読み込み(単語は既にインデックスに変換済み)
(x_train_full, y_train_full), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=MAX_WORDS)
# パディング:文章の長さを揃える(短い文章は0で埋める)
x_train_full, x_test = pad_sequences(x_train_full, maxlen=MAX_LENGTH), pad_sequences(x_test, maxlen=MAX_LENGTH)

# 訓練データと検証データの分割
val_size = int(len(x_train_full) * 0.2)
x_train, x_val = x_train_full[:-val_size], x_train_full[-val_size:]
y_train, y_val = y_train_full[:-val_size], y_train_full[-val_size:]

print(f"訓練データサイズ: {len(x_train)}")
print(f"検証データサイズ: {len(x_val)}")
print(f"テストデータサイズ: {len(x_test)}")

# --- モデル構築 ---
model = keras.Sequential([
    # 埋め込み層:単語インデックスを密なベクトルに変換
    layers.Embedding(MAX_WORDS, EMBEDDING_DIM),
    # LSTM層:系列データの特徴を学習
    layers.LSTM(LSTM_UNITS, dropout=DROPOUT_RATE, recurrent_dropout=DROPOUT_RATE),
    # 出力層:ポジティブ/ネガティブの確率を出力
    layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# --- 学習 ---
history = model.fit(x_train, y_train, epochs=EPOCHS, batch_size=BATCH_SIZE,
                    validation_data=(x_val, y_val), verbose=1)

# --- 評価 ---
predictions = model.predict(x_test[:5])
print("\n予測結果:")
for i in range(5):
    prob = predictions[i][0]
    sentiment = "ポジティブ" if prob > 0.5 else "ネガティブ"
    actual = "ポジティブ" if y_test[i] == 1 else "ネガティブ"
    print(f"レビュー {i+1}: 予測={sentiment} (予測確率: {prob:.3f}), 実際={actual}")

# レビュー例の復元表示(インデックスを単語に戻す)
reverse_word_index = {v: k for k, v in keras.datasets.imdb.get_word_index().items()}
print(f"\nレビュー例:\n{' '.join([reverse_word_index.get(i-3, '?') for i in x_test[0]])}")

# 学習履歴の可視化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
ax1.plot(history.history['accuracy'], label='訓練精度')
ax1.plot(history.history['val_accuracy'], label='検証精度')
ax1.set_title('モデル精度')
ax1.set_xlabel('エポック')
ax1.set_ylabel('精度')
ax1.legend()
ax2.plot(history.history['loss'], label='訓練損失')
ax2.plot(history.history['val_loss'], label='検証損失')
ax2.set_title('モデル損失')
ax2.set_xlabel('エポック')
ax2.set_ylabel('損失')
ax2.legend()
plt.tight_layout()
plt.show()

# 最終評価
test_accuracy = model.evaluate(x_test, y_test, verbose=0)[1]
print(f"\nテスト精度: {test_accuracy:.4f}")
print(f"解釈: 0.8以上であれば実用的な感情分析性能とされる")

実行結果の読み方

予測結果では、予測ラベル(ポジティブまたはネガティブ)と実際のラベルが比較表示される。予測確率は0.0から1.0の範囲で表示され、1.0に近いほどポジティブ、0.0に近いほどネガティブと予測していることを示す。0.5に近い場合は判断が曖昧である。

テスト精度は全体的な予測精度であり、感情分析では0.8以上で実用的とされる。0.6未満の場合は学習パラメータの見直しが必要である。

学習履歴グラフは画像分類と同様に解釈する。自然言語処理では学習に時間がかかるため、エポック数を増やすことで精度が向上する場合がある。

時系列データ予測システムの構築

概要

このセクションでは、LSTMを用いた時系列データの予測を学ぶ。完了後、時系列データの前処理、予測モデルの構築、予測精度の評価ができるようになる。

時系列予測とは、時間とともに変化するデータから未来の値を予測する技術であり、株価、売上、気温などの予測に使用される。

本例では実際の株価データを使用して予測を行う。ただし、株価は経済情勢や企業業績など多くの要因に影響されるため、このモデルだけで実際の投資判断を行うべきではない。

時系列分析の特殊概念

時系列データは、時間順に並んだデータである。過去のパターンから未来を予測する際に用いる。

逆正規化は、正規化されたデータを元の範囲に戻す処理である。予測結果を実際の価格に戻して解釈するために必要となる。

シーケンス化は、過去の一定期間のデータから未来の値を予測するため、データを時系列の組み合わせに変換する処理である。例えば、過去60日分のデータから61日目を予測する形式に変換する。期間が短すぎると情報が不足し、長すぎると計算負荷が増大する。

実装例

以下のコードは、Yahoo Financeから取得した株価データを用いてLSTMによる価格予測を行う。コードは「環境設定」「データ取得」「前処理」「モデル構築」「学習」「評価」の順に構成されている。

# 株価データを使用したLSTM時系列予測システム

# --- 環境設定 ---
!apt-get -qq install -y fonts-ipafont-gothic
!pip install -q japanize-matplotlib yfinance
import japanize_matplotlib
import yfinance as yf
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
import warnings
warnings.filterwarnings('ignore')

SEED, EPOCHS, BATCH_SIZE = 42, 10, 32
# TICKER_SYMBOL: 株式銘柄コード(AAPL=Apple)
# SEQUENCE_LENGTH: 予測に使用する過去のデータ数
TICKER_SYMBOL, PERIOD, SEQUENCE_LENGTH = "AAPL", "2y", 60
TRAIN_RATIO, VAL_RATIO = 0.7, 0.15
np.random.seed(SEED)
tf.random.set_seed(SEED)

# --- データ取得 ---
df = yf.Ticker(TICKER_SYMBOL).history(period=PERIOD)
data = df['Close'].values.reshape(-1, 1)
print(f"データサイズ: {len(data)}")
print(df.head())

# --- 前処理 ---
# 正規化:値を0-1の範囲に変換(学習の安定化のため)
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(data)

# シーケンス化:過去60日のデータから翌日を予測する形式に変換
X = np.array([scaled_data[i:i+SEQUENCE_LENGTH, 0] for i in range(len(scaled_data)-SEQUENCE_LENGTH)])
y = np.array([scaled_data[i+SEQUENCE_LENGTH, 0] for i in range(len(scaled_data)-SEQUENCE_LENGTH)])

# 訓練・検証・テストデータの分割
train_size = int(len(X) * TRAIN_RATIO)
val_size = int(len(X) * VAL_RATIO)
X_train = X[:train_size].reshape(-1, SEQUENCE_LENGTH, 1)
X_val = X[train_size:train_size+val_size].reshape(-1, SEQUENCE_LENGTH, 1)
X_test = X[train_size+val_size:].reshape(-1, SEQUENCE_LENGTH, 1)
y_train, y_val, y_test = y[:train_size], y[train_size:train_size+val_size], y[train_size+val_size:]

# --- モデル構築 ---
model = keras.Sequential([
    # 2層のLSTM(return_sequences=Trueで次のLSTM層に系列を渡す)
    layers.LSTM(50, return_sequences=True, input_shape=(SEQUENCE_LENGTH, 1)),
    layers.LSTM(50, return_sequences=False),
    layers.Dense(25),
    layers.Dense(1)
])
model.compile(optimizer='adam', loss='mean_squared_error')

# --- 学習 ---
history = model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS,
                    validation_data=(X_val, y_val), verbose=1)

# --- 評価 ---
# 予測の実行と逆正規化(実際の価格に戻す)
train_pred = scaler.inverse_transform(model.predict(X_train))
test_pred = scaler.inverse_transform(model.predict(X_test))
y_train_actual = scaler.inverse_transform(y_train.reshape(-1, 1))
y_test_actual = scaler.inverse_transform(y_test.reshape(-1, 1))

# 結果の可視化
train_plot, test_plot = np.full_like(scaled_data, np.nan), np.full_like(scaled_data, np.nan)
train_plot[SEQUENCE_LENGTH:SEQUENCE_LENGTH+len(train_pred)] = train_pred
test_start = SEQUENCE_LENGTH + train_size + val_size
test_plot[test_start:test_start+len(test_pred)] = test_pred

plt.figure(figsize=(15, 6))
plt.plot(scaler.inverse_transform(scaled_data), label='実際の価格', linewidth=2)
plt.plot(train_plot, label='訓練予測', alpha=0.7)
plt.plot(test_plot, label='テスト予測', alpha=0.7)
plt.title('株価予測結果')
plt.xlabel('日数')
plt.ylabel('価格')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 精度の計算
train_rmse = np.sqrt(mean_squared_error(y_train_actual, train_pred))
test_rmse = np.sqrt(mean_squared_error(y_test_actual, test_pred))
print(f'訓練RMSE: {train_rmse:.2f}')
print(f'テストRMSE: {test_rmse:.2f}')
print(f'解釈: RMSE値が小さいほど予測精度が高く、テストRMSEが訓練RMSEより大きいのは正常である')

# 学習履歴の表示
plt.figure(figsize=(8, 4))
plt.plot(history.history['loss'], label='訓練損失')
plt.plot(history.history['val_loss'], label='検証損失')
plt.title('モデル損失')
plt.xlabel('エポック')
plt.ylabel('損失')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

実行結果の読み方

データサイズでは取得したデータの件数が表示され、データ例として先頭5件の株価情報が表示される。

RMSE値について、訓練RMSEは訓練データに対する予測誤差、テストRMSEはテストデータに対する予測誤差である。値が小さいほど予測精度が高い。テストRMSEが訓練RMSEより大きくなるのは正常であり、2倍以上の場合は過学習の可能性がある。

時系列予測グラフでは、実際の価格は元の時系列データ、訓練予測は訓練期間での予測結果、テスト予測は未知データでの予測結果を示す。実際の値との乖離が小さいほど予測性能が高い。

学習損失グラフでは、訓練損失と検証損失が共に減少していれば正常な学習であり、検証損失が上昇に転じた場合は学習停止のタイミングである。

データの可視化と分析プロジェクト

概要

このセクションでは、データの可視化と統計分析の基本を学ぶ。完了後、データの基本統計量の算出、各種グラフの作成、相関分析ができるようになる。

データ分析とは、データに含まれる傾向やパターンを発見し、有用な情報を抽出する技術である。

Irisデータセットは、アヤメの花の測定データであり、統計学や機械学習の教材として広く使用されている。データが整理されており欠損値がないため、データ分析の基本手法を学ぶのに適しているが、実際のデータはより複雑であることに留意する。

データ分析の特殊概念

基本統計量は、平均、標準偏差、最大値、最小値などデータの基本的な特徴を表す数値である。

ヒストグラムは、データの分布を表示するグラフである。横軸に値の範囲、縦軸に頻度を取り、データがどの範囲に集中しているかを確認できる。

散布図は、2つの変数の関係を点で表示するグラフである。点の配置から変数間の関係を視覚的に把握できる。

箱ひげ図(box plot)は、データの分布を四分位数で表示するグラフである。四分位数とは、データを小さい順に並べて4等分した位置の値であり、第1四分位数(25%点)、中央値(50%点)、第3四分位数(75%点)からなる。

相関係数は、2つの変数間の線形関係の強さを-1から1の値で表す指標である。1に近いほど正の相関(一方が増えると他方も増える)、-1に近いほど負の相関(一方が増えると他方は減る)、0に近いほど関係が弱いことを示す。ただし、線形関係のみを測定するため、非線形の関係は検出できない。

ヒートマップは、数値データを色の濃淡で表現したグラフであり、複数の変数間の関係を一覧できる。

実装例

以下のコードは、Irisデータセットを用いて統計分析と可視化を行う。コードは「環境設定」「データ読み込み」「基本情報表示」「可視化」「相関分析」の順に構成されている。

# Irisデータセットの統計分析・可視化システム

# --- 環境設定 ---
!apt-get -qq install -y fonts-ipafont-gothic
!pip install -q japanize-matplotlib seaborn
import japanize_matplotlib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_iris
from IPython.display import Javascript, display
import warnings
warnings.filterwarnings('ignore')

# Colabの出力表示領域を拡大
display(Javascript('google.colab.output.setIframeHeight(0, true, {maxHeight: 5000})'))
np.random.seed(42)

# --- データ読み込み ---
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = iris.target_names[iris.target]

# --- 基本情報表示 ---
print("=== データセット基本情報 ===")
print(f"データサイズ: {df.shape}")
print(f"欠損値: {df.isnull().sum().sum()}")
print(f"数値特徴量: {len(df.select_dtypes(include=[np.number]).columns)}")
print(f"カテゴリ特徴量: {len(df.select_dtypes(include=['object']).columns)}")
print("\nデータ例:")
print(df.head())
print("\n基本統計量:")
print(df.describe())

# --- 可視化 ---
fig, axes = plt.subplots(3, 2, figsize=(15, 18))

# ヒストグラム:データの分布を確認
axes[0, 0].set_title('がく片の長さ分布')
for species in df['species'].unique():
    axes[0, 0].hist(df[df['species'] == species]['sepal length (cm)'], alpha=0.7, label=species, bins=15)
axes[0, 0].set_xlabel('長さ (cm)')
axes[0, 0].set_ylabel('頻度')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)

# 散布図:2変数間の関係を確認
axes[0, 1].set_title('がく片の長さ vs 幅')
for species in df['species'].unique():
    subset = df[df['species'] == species]
    axes[0, 1].scatter(subset['sepal length (cm)'], subset['sepal width (cm)'], label=species, alpha=0.7, s=60)
axes[0, 1].set_xlabel('がく片の長さ (cm)')
axes[0, 1].set_ylabel('がく片の幅 (cm)')
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)

# 箱ひげ図:グループ間の分布を比較
axes[1, 0].set_title('種別の花弁長さ比較')
df.boxplot(column='petal length (cm)', by='species', ax=axes[1, 0])
axes[1, 0].set_xlabel('種')
axes[1, 0].set_ylabel('花弁の長さ (cm)')
axes[1, 0].grid(True, alpha=0.3)

# ヒートマップ:変数間の相関を一覧表示
axes[1, 1].set_title('特徴量間の相関')
sns.heatmap(df.select_dtypes(include=[np.number]).corr(), annot=True, cmap='coolwarm', center=0, ax=axes[1, 1], fmt='.3f')

# 散布図(花弁)
axes[2, 0].set_title('花弁の長さ vs 幅')
for species in df['species'].unique():
    subset = df[df['species'] == species]
    axes[2, 0].scatter(subset['petal length (cm)'], subset['petal width (cm)'], label=species, alpha=0.7, s=60)
axes[2, 0].set_xlabel('花弁の長さ (cm)')
axes[2, 0].set_ylabel('花弁の幅 (cm)')
axes[2, 0].legend()
axes[2, 0].grid(True, alpha=0.3)

# バイオリンプロット:分布の形状を詳細に表示
axes[2, 1].set_title('特徴量分布の比較')
sns.violinplot(data=df.melt(id_vars=['species'], var_name='feature', value_name='value'), x='species', y='value', ax=axes[2, 1])
axes[2, 1].set_xlabel('種')
axes[2, 1].set_ylabel('測定値')
axes[2, 1].tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.show()

# --- 相関分析 ---
corr_matrix = df.select_dtypes(include=[np.number]).corr()
upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))
max_corr = upper.abs().max().max()
max_corr_idx = upper.abs().stack().idxmax()

print("\n=== 分析結果サマリー ===")
print(f"最大相関係数: {max_corr:.3f}")
print(f"最大相関ペア: {max_corr_idx[0]} - {max_corr_idx[1]}")
print("\n種別統計:")
for species in df['species'].unique():
    print(f"{species}: {len(df[df['species'] == species])}件")
print("\n相関解釈:")
print("- 相関係数の絶対値が0.7以上: 強い相関")
print("- 相関係数の絶対値が0.3-0.7: 中程度の相関")
print("- 相関係数の絶対値が0.3未満: 弱い相関")

実行結果の読み方

基本統計量は平均、標準偏差、最大値、最小値などデータの基本的な特徴であり、外れ値の有無や分布の偏りを確認できる。

相関係数は-1.0から1.0の範囲で、絶対値が0.7以上であれば強い相関があり、0に近い場合は関係性が弱い。

グラフの読み方として、ヒストグラムでは各特徴量の分布形状を確認し正規分布に近いか偏りがあるかを判断する。散布図では2つの特徴量間の関係を視覚的に確認し、点が直線状に並んでいれば相関があることを示す。箱ひげ図ではグループ間の特徴量の違いを比較し、箱の位置や大きさから分布の差を読み取る。ヒートマップでは色の濃淡で相関の強さを表示し、赤は正の相関、青は負の相関を示す。

学習結果の共通評価方法

本セクションでは、機械学習モデルの評価方法をまとめる。各プロジェクトで得られた結果を解釈する際の参考とする。

精度評価の共通指標

訓練精度と検証精度の関係について、両者が近い値で上昇している場合は正常な学習である。検証精度が訓練精度より大幅に低い場合は過学習の可能性があり、検証精度が上昇しない場合は学習パラメータの調整が必要である。

損失値の推移について、訓練損失と検証損失が共に減少している場合は正常な学習進行である。検証損失が上昇に転じた場合は過学習の兆候であり学習停止のタイミングである。損失が減少しない場合はパラメータの再調整が必要である。

各タスクの性能基準

画像分類(CIFAR-10)では、テスト精度0.7以上で良好、0.5未満は学習失敗の可能性がある。

感情分析(IMDb)では、テスト精度0.8以上で実用的、0.6未満は学習パラメータの見直しが必要である。

時系列予測(株価)では、テストRMSEが訓練RMSEの2倍未満であれば正常、2倍以上は過学習の可能性がある。

うまくいかない場合の対処

精度が向上しない場合は、エポック数の増加、バッチサイズの調整、モデル構造の変更(層の追加・削除)を試す。過学習が発生する場合は、ドロップアウト率の増加、訓練データの増加、エポック数の削減を検討する。