Python のまとめ

要点】 このページは,Pythonの基礎から応用までの一連の知識と手続きについて詳述している.Pythonの起動やインストール方法についてWindowsとUbuntu の両方に対応して説明し,さらに複数バージョンの管理やパッケージ管理ツールpipの使い方も解説している.また,Pythonの隔離環境venvやAnaconda3,Google ColaboratoryといったPython環境の設定も詳しく記載している.さらに,Pythonプログラムの例として,グラフ描画や画像ファイルの操作,主成分分析やk-meansクラスタリングなどを紹介.そして,Python開発環境として,Jupyter Notebook,Jupyter Lab,Nteract,spyderなどのインストール方法と起動方法を解説.最後にPythonのプログラミング基礎,データ型,モジュールとライブラリ,クラス定義とオブジェクト生成,制御構造,関数定義等についても触れている.

目次

  1. Python プログラムの実行
    1. Windows での Python の起動
    2. Ubuntu での Python の起動
  2. Python のインストール
    1. Windows での Python のインストール
    2. Windows で Python のアンインストール
    3. Windows での複数の Python の同時インストール
    4. Ubuntu のシステム Python,Ubuntu での Python のインストール,pip と setuptools の更新
    5. Python の隔離された環境 venv
    6. Python の種々のバージョン
    7. Anaconda3
  3. Google Colaboratory

    Google Colaboratory はオンラインの Python 開発環境

    1. Google Colaboratory の主な機能
    2. Google Colaboratory で PYTHON 3 の新しいノートブックを新規作成
    3. Google Colaboratory でファイルのアップロードとダウンロード
    4. Google Colaboratory で TensorFlow,Keras のバージョン確認
    5. Google Colaboratory で NVIDIA CUDA のバージョン確認
    6. Google Colaboratory で GPU の確認
    7. Google Colaboratory を使用中であるかを判別する Python プログラム
    8. Google Colaboratory での画像表示
  4. Python プログラムの例と Google Colaboratory での実行結果
    1. 三角関数のプロット
    2. 折れ線グラフのプロット
    3. 散布図のプロット
    4. 画像ファイルの表示
    5. 画像ファイルのダウンロード,画像ファイル保存,表示
    6. 行列の積,主成分分析,SVD,k-Means クラスタリング
    7. 画像分類
    8. 空白などで区切られたテキストをリストに変換
  5. Python 関係のツール
    1. pip
    2. Python パッケージ・インデックス (PyPI)
    3. Google Colaboratory での pip の操作
    4. Windows での pip の操作
    5. Ubuntu での pip の操作
    6. pip と setuptools を最新版に更新
    7. pip のインストールを手動で行いたい場合
    8. Python の setup.py の実行
    9. Python の build_ext の実行
    10. 「Geospatial library wheels for Python on Windows」のページ

      https://github.com/cgohlke/geospatial-wheels

    11. 2to3
  6. Python 開発環境,Python コンソール(Jupyter ノートブック (Jupyter Notebook),Jupyter Lab,Nteract,spyder)
    1. Python,pip,Python 開発環境,Python コンソールのコマンドでの起動
    2. Windows での Python 開発環境として,Jupyter Qt ConsoleJupyter ノートブック (Jupyter Notebook)Jupyter LabNteract,spyder のインストール
    3. Ubuntu での Python 開発環境として,Jupyter Qt ConsoleJupyter ノートブック (Jupyter Notebook)Jupyter LabNteract,spyder のインストール
    4. Python コンソール
    5. Jupyter Qt Console
    6. Jupyter ノートブック (Jupyter Notebook)
    7. Jupyter Lab
    8. Nteract
    9. spyder
    10. PyCharm
  7. Python プログラミングの基礎
    1. オブジェクトの生成と削除,同値,同一性
    2. 単純値のデータ型
    3. オブジェクトのタイプ(クラス名)の取得
    4. 文字列の演算子
    5. pandas データフレーム
    6. numpy 全般
    7. 1次元の配列
    8. 2次元の配列
    9. 2次元の配列の種々の処理
    10. numpy の npz 形式(numpy.ndarray)ファイルの書き出しと読み込み
    11. 2次元配列データのCSV ファイル読み書き
    12. メッシュグリッド
    13. 配列の次元を増やす
    14. リスト
    15. Pythonのモジュール
    16. Pythonのライブラリ
    17. Matplotlib を用いたプロット
    18. Matplotlib を用いた種々のプロット
    19. TensorFlow
    20. Keras
    21. 制御構造(条件分岐,繰り返し)
    22. 式と変数
    23. 関数定義,関数オブジェクト
    24. 式の抽象化と関数
    25. 式の評価のタイミング
    26. クラス定義,オブジェクト生成,属性アクセス
    27. メソッド
    28. スーパークラスからの継承
    29. ファイルの選択
    30. 画像ファイルの表示,画像ファイルの画像のサイズの取得
    31. ply ファイルの表示
  8. Python プログラミングの応用
    1. 行列計算の基礎と実装
    2. 音声信号処理の基礎と実装

関連する外部ページ

サイト内の関連ページ

Python 関連

Python のインストール

各種オンラインサービス

関連項目Python のインストールAnaconda3 のインストール(winget を使用)(Windows 上)

Python

Pythonは,現在,人気の高いプログラミング言語の1つであり,読みやすく書きやすい文法と幅広い応用範囲を持つとされている.現在,様々な分野で使用され,豊富なライブラリがある.

Python 3.12 のインストール

インストール済みの場合は実行不要。

管理者権限でコマンドプロンプトを起動(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)し、以下を実行する。管理者権限は、wingetの--scope machineオプションでシステム全体にソフトウェアをインストールするために必要である。

REM Python をシステム領域にインストール
winget install --scope machine --id Python.Python.3.12 -e --silent
REM Python のパス設定
set "PYTHON_PATH=C:\Program Files\Python312"
set "PYTHON_SCRIPTS_PATH=C:\Program Files\Python312\Scripts"
echo "%PATH%" | find /i "%PYTHON_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_PATH%" /M >nul
echo "%PATH%" | find /i "%PYTHON_SCRIPTS_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_SCRIPTS_PATH%" /M >nul

関連する外部ページ

サイト内の関連ページ

関連項目Python

1. Pythonプログラムの実行

Pythonは人気の高いプログラミング言語の一つであり,読みやすく書きやすい文法と幅広い応用範囲を持つ.様々な分野で使用され,豊富なライブラリがある.

1. (1) Google Colaboratoryによるオンライン実行

Google ColaboratoryはオンラインのPython開発環境である.詳しくは,このページの別項目で説明している.

1. (2) WindowsでのPythonの起動

WindowsでのPythonのインストール: 別ページ »で説明

WindowsでPythonを起動する方法は以下のとおりである. Pythonのコマンドでの実行 コマンドプロンプトで以下のコマンドを実行する. ```bash python ```
Pythonコマンドでの起動画面
Windowsで複数のPythonをインストールしているときは,環境変数Pathで先頭のPythonが使用される. Pythonランチャーpyでのバージョン指定実行 Pythonランチャーを使用すると,バージョンを指定してPythonを実行できる. ```bash py - ```
Pythonランチャーでのバージョン指定実行
インストールされているPythonのバージョンは「py -0」で確認できる.
インストール済みPythonバージョンの確認
venvを使用する場合 venvを使うときは,activateコマンドを実行した後,「python」で起動する. その他の開発環境 Visual Studio CodeでのPythonの実行,Pythonのコンソール(Jupyter Qt Console),Jupyterノートブック(Jupyter Notebook),Python開発環境(Jupyter LabNteractSpyderPyCharmPyScripterなど)も利用できる.

1. (3) UbuntuでのPythonの起動

UbuntuでPythonを起動する方法は以下のとおりである. システムPythonを使用 UbuntuのシステムPythonのPythonバージョン3は,「python3」で起動する. ```bash python3 ``` pyenvを用いてインストールしたPython pyenvを用いてインストールしたPythonは,pyenvの設定の後,「python」で起動する. venvを使用する場合 venvを使うときは,activateコマンドを実行した後,「python」で起動する.

2. Pythonのインストール

2. (1) Python 3.12のインストール,pipとsetuptoolsの更新(Windows上)

Pythonの公式ページ: https://www.python.org/ Python開発環境,Pythonコンソール: 別項目で説明している.

インストールでの注意点

インストール時には以下の点に注意する. Python 64ビット版の使用 Python 64ビット版を使用すること. システム領域へのインストール Pythonをシステム領域にインストールすることを推奨する.Windowsでは,Pythonをユーザ領域(既定の設定)またはシステム領域にインストールできる.ユーザー名に日本語が含まれている場合,Pythonをユーザ領域にインストールすると問題が発生する可能性がある.システム領域にインストールすることで,ファイルパスに日本語が含まれることを避けることができる. TensorFlow 2.10.1の利用 TensorFlow 2.10.1は次のPythonのバージョンと互換性がある: Python 3.10,Python 3.9,Python 3.8,Python 3.7 この互換性情報は,https://pypi.org/project/tensorflow/2.10/#filesで確認できる.TensorFlow 2.10.1は,Python 3.6以前のバージョン,Python 3.11以降のバージョンではサポートされていない(2024年7月時点).最新の互換性情報は公式ドキュメントで確認すること. 複数バージョンの同時インストール Windowsでは,Pythonの3.6.A,3.7.B,3.8.C,3.9.D,3.10.Eのように,複数のバージョンのPythonを同時にインストールできる.詳しくは,別項目で説明している.

Python 3.10のインストール,pipとsetuptoolsの更新(Windows上)

WindowsでのPython 3.10のインストール手順は以下のとおりである. 1. TensorFlowのインストール予定がある場合には,次のページで必要なPythonのバージョンを確認する URL: https://pypi.org/project/tensorflow-gpu/#files 2. PythonのURLを開く URL: https://www.python.org 3. Windows版のPython 3.10をダウンロードする ページの上の方にある「Downloads」をクリックする.「Downloads」の下にメニューが出るので,その中の「Windows」をクリックする.
Pythonダウンロードページのメニュー
4. 「Stable Releases」から,Pythonのバージョンを選ぶ ここでは,Python 3.10系列の最新版を探して選ぶ.
Stable Releasesの一覧
以下,Python 3.10.9を選んだとして説明を続ける.他のバージョンでも手順はほぼ同じである.

TensorFlowを使う予定がある場合は,https://pypi.org/project/tensorflow-gpu/#filesで必要なPythonのバージョンを確認しておく.2024年5月時点では,TensorFlowバージョン2.10が動くのは,Python 3.10またはPython 3.9またはPython 3.8またはPython 3.7である(https://pypi.org/project/tensorflow/2.10/#files

5. ファイルの種類を選ぶ Windowsの64ビット版のインストーラをダウンロードしたいので,「Windows Installer (64-bit)」を選ぶ.
インストーラの種類選択
6. ダウンロードが始まる
ダウンロード中の画面
7. インストール時の設定を行う (1) いまダウンロードした.exeファイルを右クリックし,右クリックメニューで「管理者として実行」を選ぶ
管理者として実行の選択
(2) Pythonランチャーをインストールするために,「Use admin privileges when installing py.exe」をチェックする
Pythonランチャーのインストール設定

すでにPythonランチャーをインストール済みのときは,「Install launcher for all users (recommended)」がチェックできない場合がある.そのときは,チェックせずに進む

ランチャーがインストール済みの場合
(3) 「Add Python.exe to PATH」をチェックする
PATHへの追加設定
(4) 「Customize installation」をクリックする
カスタムインストールの選択
(5) オプションの機能(Optional Features)は,既定(デフォルト)のままでよい.「Next」をクリックする
オプション機能の選択画面
(6) 「Install Python 3.10 for all users」を選ぶ

ユーザ名が日本語のときのトラブルを防ぐため

全ユーザー向けインストールの選択
(7) Pythonのインストールディレクトリは,「C:\Program Files\Python310」のように自動設定されることを確認する
インストールディレクトリの確認
(8) 「Install」をクリックする
インストール開始ボタン
(9) インストールが始まる
インストール中の画面
(10) 「Disable path length limit」が表示される場合がある.クリックして,パス長の制限を解除する.表示されない場合は問題ない (11) インストールが終了したら,「Close」をクリックする
インストール完了画面
8. インストールのあと,Windowsのスタートメニューに「Python 3.10」が増えていることを確認する 9. システムの環境変数Pathの確認のため,新しくコマンドプロンプトを開き,次のコマンドを実行する pyとpipにパスが通っていることの確認である. ```bash where py where pip ``` where pyでは「C:\Windows\py.exe」が表示され,where pipでは「C:\Program Files\Python310\Scripts\pip.exe」が表示されることを確認する(「310」のところは使用するPythonのバージョンに読み替えること).
パスの確認結果

表示されないときは,システムの環境変数Pathに,C:\Program Files\Python310C:\Program Files\Python310\Scriptsが追加済みであることを確認する(「310」のところは使用するPythonのバージョンに読み替えること).無ければ追加し,再度コマンドプロンプトを開いて,再度「where py」,「where pip」を実行して確認する

それでもうまく行かない場合は,Pythonのアンインストールを行う.過去のアンインストールが不完全だった可能性がある

10. Windowsで,管理者権限コマンドプロンプトを起動する

Windowsでpipを実行するときは,コマンドプロンプト管理者として開き,それを使ってpipを実行する

コマンドプロンプトを管理者として実行: 別ページ »で説明

11. pipとsetuptoolsの更新を行う 次のコマンドを実行する. ```bash python -m pip install -U pip setuptools ```
pipとsetuptoolsの更新

Pythonに関しての情報取得

Pythonにトラブルがあった時に役に立つ情報取得の手順をまとめている. 1. Windowsのシステム環境変数Pathを確認する インストール時に,「Add Python ... to PATH」をチェックしたので,Pythonについての設定が自動で行われる.
システム環境変数Pathの確認
2. pythonのバージョンの確認を行う ```bash python --version ```
Pythonバージョンの確認
3. Pythonのビルドに用いられたコンパイラのバージョン番号の確認を行う ```bash python ``` 下の実行例では,バージョン番号として「1934」が表示されている.
コンパイラバージョンの確認
4. 次のPythonプログラムを実行し,バージョン番号を確認する 下の実行例では,バージョン番号として「14.3」が表示されている. ```python from distutils.msvc9compiler import * get_build_version() ```
ビルドバージョンの確認
5. exit()で終了する
Python終了
6. pipの動作確認を行う Pythonのパッケージも同時にインストールされることが分かる.エラーメッセージが出ないことを確認する. ```bash pip list ```
pipの動作確認

2. (2) WindowsでPythonのアンインストール

WindowsでPythonのアンインストールを行う手順は以下のとおりである. 1. まず,WindowsでPythonのアンインストール操作を行う 2. 次に,Python関係のファイルの削除を行う Windowsでは,コマンドプロンプトを管理者として実行し,次のコマンドを実行する. この操作は,必ずPythonをすべてアンインストールした後に行うこと.
Python関係ファイルの削除

次のコマンドは,rmdirを使用して,%APPDATA%\Pythonディレクトリを再帰的に削除する.次に,"C:\Program Files"ディレクトリに移動し,Python3で始まるディレクトリを検索し,見つかったディレクトリを再帰的に削除する

```bash rmdir /s /q %APPDATA%\Python cd "C:\Program Files" for /F %i in ('dir /ad /b /w Python3*') do rmdir /s /q %i ```

2. (3) Windowsでの複数のPythonの同時インストール

Windowsでは,Pythonの3.6.A,3.7.B,3.8.C,3.9.D,3.10.Eのように,複数のバージョンのPythonを同時にインストールできる. ただし,3.10.4と3.10.5の同時インストールはできない(3.Xのように,2桁目でバージョン番号が違うものを同時にインストールできる). そのときは,環境変数Pathの設定を常に意識すること.Pythonランチャーである「py」コマンドも利用すること. 複数のバージョンのPythonを同時にインストールしたとき,WindowsのPythonランチャーを用いて,インストールされているPythonのバージョンを調べたり,Pythonのバージョンを指定しての起動を行うことができる.Pythonのバージョンを指定してのpipvenvの実行を行うときにも便利である.

WindowsのPythonランチャーpy

Pythonランチャーは,Windowsで動くツールである.複数バージョンのPythonを同時にインストールしたときに便利である. Pythonランチャーは,WindowsでのPythonのインストール時に,同時にインストールできる. Pythonの起動 Pythonランチャーを使わない場合,Pythonは,環境変数Pathで先頭のPythonが使用される. WindowsのPythonランチャーを用いて,次のように使用するPythonのバージョンを指定できる.「py」はWindowsのPythonランチャーのコマンドである. - py -3.10 - py -3.9 - py -3.8 - py -3.7 - py -3.6
Pythonランチャーでのバージョン指定

「py -X」のように,バージョン指定の中の「-32」,「-64」を省略することもできる.そのときは,PythonバージョンXが実行されるが,PythonのバージョンX 32ビット版と64ビット版をインストールしている場合は,64ビット版の方が実行される

「py」のようにバージョン指定を省略したときは,インストールされているPythonの最新バージョンが実行される

インストールされているPythonバージョンの一覧表示 インストールされているPythonのバージョンは,Pythonランチャーを用いて,「py -0」(数字の「0」)で確認できる.
インストール済みPythonバージョンの一覧

「-3.7-64」,「-3.8-32」,「-3.8-64」が表示されたとする.この場合,これら3つのバージョンがインストール済みであり,「py -3.7-64」や「py -3.8-32」や「py -3.8-64」でpythonを使うことができる

2. (4) UbuntuのシステムPython,UbuntuでのPythonのインストール,pipとsetuptoolsの更新

UbuntuのシステムPython

Ubuntuをインストールすると,UbuntuのシステムPythonも同時にインストールされる. Ubuntuの場合はシステムPythonを用いる(その場合はインストールは不要)か,pyenvなどを用いて,システムPythonとは隔離した形でインストールする. UbuntuでシステムPythonを使用するときは,改めてPythonのインストールを行う必要はない. UbuntuのシステムPythonを用いるとき,python,pipは,次のコマンドで起動できる. - python3(UbuntuのシステムPython) - sudo pip3(UbuntuのシステムPythonのpip) 「python3」や「pip3」のように「3」を付ける. 次の実行により,「python」や「pip」で,「3」を付けなくても済むようになる. ```bash sudo apt -y install python-is-python3 ```

システムPythonを使っているときのpipとsetuptoolsの更新(Ubuntu上)

システムPythonを用いるときは,pip,setuptoolsの更新は次のコマンドで行う. ```bash sudo apt update sudo apt -y install python3-pip python3-setuptools ```

UbuntuでのPythonのインストール(pyenvを使用)

Ubuntuで,システムPython以外のPythonをインストールするにはpyenvの利用が便利である.pyenvは,Linux,MacOSで動くPythonバージョン管理のツールである.

Ubuntuをインストールすると,UbuntuのシステムPythonも同時にインストールされる.Ubuntuでは,システムPythonは,Ubuntuシステムの動作に関わっている.システムPythonをバージョンアップしたり,アンインストールを行ったりするのは良くない

pyenvのインストール Ubuntuでのpyenvのインストールは,次の手順で行う. pyenvのURL: https://github.com/pyenv/pyenv ```bash sudo apt -y update sudo apt -y install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev cd /tmp curl https://pyenv.run | bash echo 'export PYENV_ROOT="${HOME}/.pyenv"' >> ~/.bashrc echo 'if [ -d "${PYENV_ROOT}" ]; then' >> ~/.bashrc echo ' export PATH=${PYENV_ROOT}/bin:$PATH' >> ~/.bashrc echo ' eval "$(pyenv init -)"' >> ~/.bashrc echo ' eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc echo 'fi' >> ~/.bashrc exec $SHELL -l ``` pyenvの利用 pyenvを用いてインストール可能なPythonの一覧表示は,次で行う. ```bash pyenv install -l ``` pyenvを用いてのPythonのインストールは,次で行う. ```bash pyenv install <バージョン指定> ``` pyenvを用いてインストール済みのPythonの確認は,次で行う. ```bash pyenv version ``` pyenvを用いてのPythonの有効化は,次で行う. ```bash pyenv shell <バージョン指定> ``` pyenvのアンインストールは,次の手順で行う. ```bash rm -rf ~/.pyenv ```

pyenvについての詳細説明: 別ページ »で説明

2. (5) Pythonの隔離された環境

Pythonの隔離された環境

次のような場合は,Pythonの仮想環境が役に立つ.Pythonの仮想環境の利用には,Python 3.3以上で標準機能になったvenvが便利である.Python 3.3未満では,virtualenvが便利である.venvvirtualenvの利用により,Pythonの隔離された環境を複数共存させることができる. 複数のPython環境の使用 複数のPython環境を使用するとき,あるPythonでのパッケージの変更や更新などが,他のPythonに影響しないように隔離する. UbuntuのシステムPythonとは別のPython環境 Ubuntuでは,Pythonの多くのパッケージはaptの管理下にある(例えば「sudo apt -y install python3-numpy」のようなコマンドでインストールする). 「pipでインストールするPythonのパッケージ」と「aptでインストールするPythonのパッケージ」が混在し,管理が難しくなったり,動作が不安定になる可能性がある. このような場合,UbuntuのPythonとは隔離された,別のPythonの環境を作ると便利である.Pythonの仮想環境では,すべてのパッケージをpipで管理するようにできる.

venv

venvは,Pythonの仮想環境を作成する機能を提供するモジュールである.Pythonの仮想環境は隔離されており,特定のバージョンのPythonや,特定のバージョンやPythonパッケージを管理するのに役立つ. Pythonでは,さまざまなパッケージをインストールする.複数のバージョンのPythonを同時インストールすることもある.venvの利用により,次のメリットがある. - 簡単なコマンドで,「特定の1つのバージョンのPythonだけがインストールされたシステム」を仮想的に作ることができる - パッケージが違う複数のPython環境の共存

使用法の要点を以下に示す

Pythonの隔離された環境の新規作成 既定(デフォルト)では,Pythonの隔離された環境に,システムのsite packageは含まれない. Windows: ```bash python -m venv <ディレクトリ名> ``` (環境変数Pathで先頭のPythonが使用される) ```bash py -m venv <ディレクトリ名> ``` (PythonランチャーによるPythonのバージョン指定) Ubuntu: ```bash python3 -m venv <ディレクトリ名> ``` (システムPythonが使用される) Pythonの隔離された環境の有効化 Windows: ```bash <ディレクトリ名>\.venv\Scripts\activate.bat ``` Ubuntu: ```bash source <ディレクトリ名>/bin/activate ``` Pythonの隔離された環境の無効化 Windows: ```bash deactivate ``` Ubuntu: ```bash deactivate ```
venvはPython 3.3からPythonの標準機能になった. venvの公式の説明ページ: https://docs.python.org/ja/3/library/venv.html

Windowsで,Pythonの隔離された環境を扱う(venvを使用)

Windowsで,venvを用いて,新しいPythonの仮想環境の新規作成,有効化,無効化を行う. 1. 前もってPythonをインストールしておく.使用しているPythonのバージョンの確認は,次のコマンドで行うことができる ```bash python --version ``` 2. Pythonの仮想環境の作成と確認を行う ここでは,venvのためのディレクトリ名「%HOMEPATH%\.venv」を指定して,新しいPythonの仮想環境を生成する.

venvのためのディレクトリ名は何でもよいが,venvで使うことが分かるような分かりやすい名前がよい.記号や,日本語などの全角文字を含めないのがよい

「python -m venv」は,venvモジュールの実行である

```bash python -m venv %HOMEPATH%\.venv dir /w %HOMEPATH%\.venv ```
Pythonの仮想環境の作成
3. Pythonの隔離された環境の有効化を行う ```bash %HOMEPATH%\.venv\Scripts\activate.bat ```
Pythonの仮想環境の有効化
有効化後のプロンプト
4. パッケージの確認を行う

いま,venvを使用中かどうか,プロンプトの「(venv)」で分かる

```bash python -m pip list ```
パッケージの確認
5. 現在使用しているPythonの隔離された環境の使用中止(無効化)を行う ```bash deactivate ```
Pythonの仮想環境の無効化

WindowsのPythonランチャーでバージョン指定して,Pythonの隔離された環境を扱う(venvを使用)

Windowsで,venvを用いて,新しいPythonの仮想環境の新規作成,有効化,無効化を行う. Pythonの仮想環境の新規作成では,Pythonランチャーを用いて,Pythonのバージョンを選ぶ. 1. Pythonランチャーで,インストール済みのPythonのバージョンを確認する ```bash py -0 ```

このときの表示で,使いたいバージョンのPythonが無いときは,Pythonのインストールを行う

2. Pythonの仮想環境の新規作成と確認を行う ここでは,venvのためのディレクトリ名「%HOMEPATH%\.venv」を指定して,新しいPythonの仮想環境を生成する.

venvのためのディレクトリ名は何でもよいが,venvで使うことが分かるような分かりやすい名前がよい.記号や,日本語などの全角文字を含めないのがよい

「-3.10」は,使用したいPythonのバージョンの指定である. ```bash py -3.10 -m venv %HOMEPATH%\.venv dir /w %HOMEPATH%\.venv ``` 3. Pythonの隔離された環境の有効化を行う ```bash %HOMEPATH%\.venv\Scripts\activate.bat ``` 4. パッケージの確認を行う

いま,venvを使用中かどうか,プロンプトの「(venv)」で分かる

```bash python -m pip list ``` 5. pythonコマンド,pipコマンドでは,Pythonの仮想環境の新規作成のときにPythonランチャーで指定したPythonのバージョンのものが実行されるように設定されている.そのことを確認する ```bash python --version ``` 6. 現在使用しているPythonの隔離された環境の使用中止(無効化)を行う ```bash deactivate ```

UbuntuでPythonの隔離された環境を扱う(venvを使用)

venvを用いて,新しいPythonの仮想環境の新規作成,有効化,無効化を行う. 1. python3-venvのインストールを行う ```bash sudo apt update sudo apt -y install python3-venv ``` 2. 使用しているシステムPythonのバージョンの確認は,次のコマンドで行うことができる ```bash python3 --version ```
Pythonバージョンの確認
3. Pythonの仮想環境の作成を行う ここでは,venvのためのディレクトリ名「~/.venv」を指定して,新しいPythonの仮想環境を生成する.

venvのためのディレクトリ名は何でもよいが,venvで使うことが分かるような分かりやすい名前がよい.記号や,日本語などの全角文字を含めないのがよい

システムPythonと違うバージョンのPythonを使いたいときは,pyenvの利用が便利である.pyenvの詳細は,別ページ »で説明している

```bash python3 -m venv ~/.venv ls -la .venv ```
Pythonの仮想環境の作成
4. Pythonの隔離された環境の有効化を行う ```bash source ~/.venv/bin/activate ```
Pythonの仮想環境の有効化
5. パッケージの確認を行う

いま,venvを使用中かどうか,プロンプトの「(venv)」で分かる

```bash python -m pip list ```
パッケージの確認
6. 現在使用しているPythonの隔離された環境の使用中止(無効化)を行う ```bash deactivate ```
Pythonの仮想環境の無効化

virtualenv,virtualenv-wrapper

virtualenv,virtualenv-wrapperは,Pythonの仮想環境の作成ができるソフトウェアである.venvが対応していないようなPythonを使いたい場合には,virtualenv,virtualenv-wrapperが便利な場合がある. virtualenv-wrapperの使い方は次のとおりである. - mkvirtualenv : Python仮想環境の新規作成 - workon: Python仮想環境の一覧表示 - workon : Python仮想環境の有効化 - deactivate: いま有効化されているPython仮想環境の無効化 Windowsでvirtualenv,virtualenv wrapperをインストールする手順は以下のとおりである. ```bash python -m pip install -U pip setuptools python -m pip install -U setuptools python -m pip install -U virtualenv virtualenvwrapper-win ``` WindowsでPython 3のPythonの仮想環境を新規作成するときの操作例は以下のとおりである. ```bash mkvirtualenv py3 ``` WindowsでPython 3.6(旧バージョン)のPythonの仮想環境を新規作成するときの操作例は以下のとおりである. ```bash mkvirtualenv --python=%LOCALAPPDATA%\Programs\Python\Python36\python.exe py36 ``` WindowsでPython 2.7のPythonの仮想環境を新規作成するときの操作例は以下のとおりである. ```bash mkvirutalenv --python="C:\Python27\python.exe" py27 ``` PyCharmでvirtualenvのPython環境を使いたいときは,File → Settings → Project → Project InterpreterでPython環境内のpython.exeを指定した後,File → Settings → Console → Python Consoleでそのpython.exeを指定する.

2. (6) Pythonの種々のバージョン

Pythonの公式ページ: https://www.python.org/

2. (7) Anaconda3

Anaconda3

Anaconda3は、Anaconda Inc.社が提供しているPythonバージョン3のソフトウェアである。言語処理系、開発ツール、パッケージ管理ツールconda、さまざまなPythonパッケージから構成されている。さらに、アプリケーションとしてSpyder、conda、Anaconda Prompt、Jupyter Notebook、Anaconda Navigatorが含まれている。

  • Spyderは、Python開発環境である。
    Spyderの画面
  • condaは、Pythonのパッケージのインストール、各種ソフトウェアのインストール、新しいPython環境の作成等を行えるソフトウェアである。condaはAnaconda3の根幹となっている。
    condaの実行画面
  • Anaconda Promptは、コマンドラインインターフェイスである。
  • Jupyter Notebookは、対話型のプログラム実行ツールである。Webブラウザで動作する。Python以外にもJulia、Ruby、R、Lua、LuaJIT、Haskell、Scala、Go、JavaScript、Node.js、Bashなどに対応している。
    Jupyter Notebookの画面
  • Anaconda Navigatorは、アプリケーション管理ツールである。

関連する外部ページ

関連項目: Anaconda3のインストール(wingetを使用)(Windows上)

Anaconda3のインストール(wingetを使用)(Windows上)

  1. Windowsで、管理者権限コマンドプロンプトを起動する。
  2. 次のコマンドを実行する。このコマンドは、Anaconda3をインストールし、パスを通すものである。
    winget install --scope machine Anaconda.Anaconda3
    powershell -command "$oldpath = [System.Environment]::GetEnvironmentVariable(\"Path\", \"Machine\"); $oldpath += \";C:\ProgramData\Anaconda3;C:\ProgramData\Anaconda3\Scripts\"; [System.Environment]::SetEnvironmentVariable(\"Path\", $oldpath, \"Machine\")"
    
    Anaconda3インストールコマンドの実行
  3. Windowsのスタートメニューに「Anaconda3 (64-bit)」が追加され、その下に「Anaconda Navigator」、「Anaconda PowerShell Prompt」、「Anaconda Prompt」、「Jupyter Notebook」、「Reset Spyder Settings」、「Spyder」が表示される。
    Anaconda3のスタートメニュー項目

関連する外部ページ

サイト内の関連ページ

関連項目: Anaconda3

Anaconda3の使用上の注意点

Anaconda3でのパッケージ管理はpipではなくcondaを用いる。

Anaconda3のPythonのパスの設定

このサイトでは、システムの環境変数PATHの先頭部分に、次の5つが設定されているものとして説明している。

C:\ProgramData\Anaconda3
C:\ProgramData\Anaconda3\Library\mingw-w64\bin
C:\ProgramData\Anaconda3\Library\usr\bin
C:\ProgramData\Anaconda3\Library\bin
C:\ProgramData\Anaconda3\Scripts

Anaconda Prompt

Anaconda Promptは、Anaconda3に同封されたコマンドプロンプトのソフトウェアである。Windowsコマンドプロンプトとの違いは、conda関係の環境変数と、環境変数PYTHONIOENCODINGが自動設定されることである。

Anaconda Promptの起動画面

condaでPythonの隔離された環境

Pythonにはバージョンがある。Pythonには、さまざまなパッケージをインストールすることができる。condaの利用により、バージョンや搭載パッケージが異なる複数のPython環境を共存させることができる

Windowsでは、Anaconda3に同封のcondaが便利である。

conda create --name py39 python=3.9

WindowsでのPythonとAnaconda内のPythonの共存

Anaconda3に内蔵のPythonを使いたいときは、pyコマンドは使わない。パスを通すか、フルパスで指定するか、Anaconda Promptを使う。

すでにPythonをインストール済みの場合でも、Anaconda3両立できる

  • Anaconda3内のPythonは、孤立したPython環境である。
  • Anaconda3の利用では、Anaconda PromptSpyderが便利である(いずれもスタートメニューから起動できる)。
  • WindowsでPythonとAnaconda内のPythonが共存する場合、Anaconda3パスを通すのは推奨できない

Anaconda3ではpipを使わないこと。Anaconda3はpipの使用を想定していない。

WindowsのシステムのPythonについて、バージョンの異なるPythonを並列できる。バージョンの異なるPythonを使いたいだけのためにAnaconda3をインストールする必要はない。

conda

Anacondaは、condaを同封している。

3. Google Colaboratory

3. (1) Google Colaboratoryの主な機能

Google Colaboratoryの利用により、オンラインで、Webブラウザを用いて、次のことができる。

  • ノートブックの形式で、Pythonソースコードの編集や実行、実行結果の保存ができる。
  • 説明文の編集ができる。説明文には、リンク、添付ファイル、図を含めることができる。
  • 「!pip」、「%cd /content」などの、システム操作ができる。
  • 共有機能により、第三者がノートブックをダウンロードし、実行できる。編集もできる。

Google Colaboratoryは、オンラインで使用する。Google Colaboratoryの使用には、Googleアカウントの取得が必要である。

「Colaboratoryへようこそ」のページのURL

https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja

3. (2) Google Colaboratoryのプログラムを実行

  1. すべてのセルの実行を行うには、メニューで「ランタイム」、「すべてのセルを実行」と操作する。
    すべてのセルを実行のメニュー
  2. Googleアカウントでのログインが求められたときはログインする。
    Googleアカウントログイン画面
  3. 実行がうまく行かない場合には、次を行う。
    • Googleアカウントでログインしていないときは、ログインを行う。その後、再度、すべてのセルを実行する操作を行う。
    • すべてのアクティブなセッションを停止する。その後、再度、すべてのセルを実行する操作を行う。そのために、メニューの「ランタイム」、「セッションの管理」と操作する。アクティブなセッションの一覧が表示されるので、「終了」をクリックして、すべてのアクティブなセッションを終了する。

3. (3) Google ColaboratoryでPython 3の新しいノートブックを新規作成

Google ColaboratoryはオンラインのPython開発環境である。使用するにはGoogleアカウントが必要である。

  1. Google ColaboratoryのWebページを開く。

    https://colab.research.google.com

    Google Colaboratoryのトップページ
  2. ファイル」で、「ノートブックを新規作成」を選ぶ。
    ノートブックを新規作成のメニュー
  3. Googleアカウントでのログインが求められたときはログインする。
    Googleアカウントログイン画面
  4. コードセルの中にPythonプログラムを書き、「実行ボタン」をクリックする。
    コードセルの実行
  5. コードセルを追加したいときは、「挿入」で、「コードセル」をクリックする。
    コードセルの追加

3. (4) Google Colaboratoryでファイルのアップロードとダウンロード

ファイルのアップロード

ファイルのアップロードを行うには、次のコードを使用する。

from google.colab import files
uploaded = files.upload()
for fname in uploaded.keys():
  print(fname)

ディレクトリを新規作成し、そこにファイルをアップロードする場合は、次のコードを使用する。

from google.colab import files
import os
import shutil

udir = 'upload'
if os.path.isdir(udir):
  shutil.rmtree(udir)
os.mkdir(udir)
uploaded = files.upload()
for fname in uploaded.keys():
  print(fname)
ファイルのダウンロード
from google.colab import files
files.download('filename')

3. (5) Google ColaboratoryでTensorFlow、Kerasのバージョン確認

Google Colaboratoryのコードセルで、次のPythonプログラムを実行する。

import tensorflow as tf
print(tf.__version__)

import keras
print(keras.__version__)
TensorFlowとKerasのバージョン確認結果

3. (6) Google ColaboratoryでNVIDIA CUDAのバージョン確認

Google Colaboratoryのコードセルで、次のPythonプログラムを実行する。

!nvcc -V
NVIDIA CUDAのバージョン確認結果

3. (7) Google ColaboratoryでGPUの確認

!nvidia-smi --query-gpu=gpu_name,driver_version,memory.total --format=csv
GPUの確認結果

3. (8) Google Colaboratoryを使用中であるかを判別するPythonプログラム

try:
    from google.colab import drive
    USE_COLAB = True
except:
    USE_COLAB = False

Google Colaboratoryでの実行結果は次のとおりである。

Google Colaboratoryでの実行結果

Windowsコマンドプロンプトでの実行結果は次のとおりである。

Windowsコマンドプロンプトでの実行結果

3. (9) Google Colaboratoryでの画像表示

Google Colaboratoryのcv2_imshowを使用する方法である(Google Colaboratoryでのみ動作する)。

%cd /content
!curl -O http://images.cocodataset.org/val2017/000000439715.jpg

import cv2
from google.colab.patches import cv2_imshow
img  = cv2.imread("000000439715.jpg")
cv2_imshow(img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2_imshowによる画像表示

PILのImageを使用する方法である(IPython.displayのImageではない)。

%cd /content
!curl -O http://images.cocodataset.org/val2017/000000439715.jpg
from PIL import Image
Image.open('000000439715.jpg').show()

3. (10) Google Colaboratoryでの画像ファイルの表示

matplotlib.pyplotのimshowを使用する方法である。

見本1つめは次のとおりである。

%cd /content
!curl -O http://images.cocodataset.org/val2017/000000439715.jpg

import cv2
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

img  = cv2.imread("000000439715.jpg")
plt.style.use('default')
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
matplotlibによる画像表示(見本1)

見本2つめは次のとおりである。

%cd /content
!curl -O http://images.cocodataset.org/val2017/000000439715.jpg

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import os

os.environ["MPLBACKEND"] = "Agg"
fpath = '000000439715.jpg'
plt.imshow(mpimg.imread(fpath))
plt.axis('off')
plt.show()

3. (11) Google Colaboratoryでの動画像の表示

from IPython.display import HTML
from base64 import b64encode

def show_mp4(video_path, width=640, height=480):
    with open(video_path, "rb") as video_file:
        video_data = video_file.read()

    video_base64 = b64encode(video_data).decode()
    video_url = f"data:video/mp4;base64,{video_base64}"

    video_html = f"""
    <video width="{width}" height="{height}" autoplay loop controls>
        <source src="{video_url}">
    </video>
    """

    return HTML(video_html)

show_mp4("hoge.mp4")

3. (12) その他

Google ColaboratoryでのDetectron2のインストールは次のとおりである。

!python -m pip install pyyaml==5.1
import sys, os, distutils.core
!git clone --recursive https://github.com/facebookresearch/detectron2
dist = distutils.core.run_setup("./detectron2/setup.py")
!python -m pip install {' '.join([f"'{x}'" for x in dist.install_requires])}

!python -m pip install 'git+https://github.com/facebookresearch/detectron2.git'

4. Pythonプログラムの例とGoogle Colaboratoryでの実行結果

4. (1) 三角関数のプロット

import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
plt.style.use('ggplot')
x = np.linspace(0, 6, 100)
plt.style.use('default')
plt.plot(x, np.sin(x))
三角関数のプロット結果

4. (2) 折れ線グラフのプロット

import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
plt.style.use('ggplot')
x = [1, 2, 3, 4]
y = [3, 5, 2, 4]
plt.plot(x, y)
折れ線グラフのプロット結果

4. (3) 散布図のプロット

import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
plt.style.use('ggplot')
x = [1, 2, 3, 4]
y = [3, 5, 2, 4]
plt.scatter(x, y)
散布図のプロット結果

4. (4) 画像ファイルの表示

mmcvを使用する方法である。前準備としてmmcvのインストールが必要である。

import mmcv
mmcv.imshow('000000439715.jpg')

4. (5) 画像ファイルのダウンロード、画像ファイル保存、表示

from PIL import Image
import requests
from IPython.display import display

url = 'https://github.com/pytorch/hub/raw/master/images/dog.jpg'
response = requests.get(url)
img = Image.open(requests.get(url, stream=True).raw)
display(img)
img.save('dog.jpg')
画像ファイルの表示結果

4. (6) 行列の積、主成分分析、SVD、k-Meansクラスタリング

このプログラムは、NumPyとscikit-learnを使用して行列計算と機械学習タスクを実行し、その処理時間を測定している。具体的には、行列の積、主成分分析、特異値分解(SVD)、k-meansクラスタリングを行っている。

import time
import numpy
import numpy.linalg
import sklearn.decomposition
import sklearn.cluster
X = numpy.random.rand(2000, 2000)
Y = numpy.random.rand(2000, 2000)
a = time.time(); Z = numpy.dot(X, Y); print(time.time() - a)
pca = sklearn.decomposition.PCA(n_components = 2)
a = time.time(); pca.fit(X); X_pca = pca.transform(X); print(time.time() - a)
a = time.time(); U, S, V = numpy.linalg.svd(X); print(time.time() - a)
a = time.time();
kmeans_model = sklearn.cluster.KMeans(n_clusters=10, random_state=10).fit(X)
labels = kmeans_model.labels_
print(time.time() - a)
行列計算と機械学習タスクの実行結果

4. (7) ConvNeXt

ImageNetで学習済みのConvNeXtBaseモデルを用いた画像分類を行う。

  1. パソコン接続のカメラを使用するので準備しておく。
  2. 前準備としてPython用opencv-pythonのインストールを行う。
    python -m pip install -U opencv-python opencv-contrib-python
    
  3. Windowsで、コマンドプロンプトを実行する。
  4. エディタを起動する。
    cd /d c:%HOMEPATH%
    notepad convnext.py
    
  5. エディタで、次のプログラムを保存する。このプログラムは、TensorFlow、ConvNeXtBaseモデルを活用し、カメラから取得した画像をリアルタイムで画像分類する。プログラムでは、GPUの設定、モデルのロード、フレームの前処理、画像分類、結果と推論に要した時間を表示する。
    import tensorflow as tf
    from tensorflow.keras.applications import ConvNeXtBase
    import numpy as np
    import time
    import cv2
    
    def set_gpu_config():
        physical_devices = tf.config.list_physical_devices('GPU')
        if len(physical_devices) > 0:
            print("GPU available:", physical_devices)
            for device in physical_devices:
                tf.config.experimental.set_memory_growth(device, True)
        else:
            print("No GPU found. Running on CPU.")
    
    def preprocess_image(img):
        img = cv2.resize(img, (224, 224))
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = np.expand_dims(img, axis=0)
        img = tf.keras.applications.convnext.preprocess_input(img)
        return img
    
    def load_model():
        return ConvNeXtBase(weights='imagenet')
    
    def classify_camera_frames(model):
        cap = cv2.VideoCapture(0)
    
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break
    
            img = preprocess_image(frame)
    
            start_time = time.perf_counter()
            preds = model.predict(img)
            end_time = time.perf_counter()
            prediction_time = end_time - start_time
    
            top_pred_index = np.argmax(preds)
            class_label = tf.keras.applications.convnext.decode_predictions(preds, top=1)[0][0][1]
            confidence = preds[0][top_pred_index]
    
            cv2.putText(frame, f"Class: {class_label}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
            cv2.putText(frame, f"Confidence: {confidence:.4f}", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
            cv2.putText(frame, f"Time: {prediction_time:.4f} seconds", (10, 110), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
    
            cv2.imshow("Camera Classification", frame)
    
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
    
        cap.release()
        cv2.destroyAllWindows()
    
    def main():
        set_gpu_config()
        model = load_model()
        classify_camera_frames(model)
    
    if __name__ == '__main__':
        main()
    
    ConvNeXtプログラムの保存
  6. Pythonプログラムの実行を行う。

    Pythonプログラムの実行方法は次のとおりである。

    サイト内の関連ページ: Pythonのまとめ: 別ページ

    プログラムをconvnext.pyのようなファイル名で保存したので、「python convnext.py」のようなコマンドで実行する。

    python convnext.py
    
    ConvNeXtプログラムの実行
  7. 結果の確認を行う。終了はqキーである。
    ConvNeXtプログラムの実行結果

4. (8) 空白などで区切られたテキストをリストに変換

import re

def removeletters(s):
    return re.sub(r':|\||-', ' ', s)

def getdata(s):
    m = re.match(r'[0-9]+(b|B|k|K|m|M|g|G|t|T)*', s)
    if m:
        return m.group()
    else:
        return ''

s = 'system 07-09 15:00:03|  0   0 100   0   0:  0   0 100   0   0:  0   0 100   0   0:  0   0 100   0   0:  1   0  99   0   0:  0   0 100   0   0:  0   0 100   0   0:  0   0 100   0   0|   0    40k| 173   243 |0.03 0.05    0|1856M 14.1G 1553M 13.1G'
a = removeletters(s)
b = a.split()
print(list(map(getdata, b)))
テキストをリストに変換した結果

5. Python 関係のツール

5. (1) pip

pipはPythonのパッケージマネージャである。

Windows

  • pipの起動は「pip」または「python -m pip」である。
  • Windowsのユーザ名で日本語を使っているときは、コマンドプロンプトを管理者として実行してから、「pip」または「python -m pip」を実行する。
  • venvを使うときは、venvが定めるactivateを実行した後に「pip」または「python -m pip」を実行する。

Ubuntu

  • システムPythonを使っていて、隔離したPython環境を作らない(pyenv、venvなども使っていない)ときは、pipではなくて、aptでインストールする。
  • pyenvを使うときは、「pyenv shell <バージョン>」のあとに「pip」または「python -m pip」を実行する。
  • venvを使うときは、venvが定めるactivateを実行した後に「pip」または「python -m pip」を実行する。

5. (2) Python パッケージ・インデックス (PyPI)

パッケージの検索や調査を行うときに、次のURLを使う。

Python パッケージ・インデックス (PyPI) の URL: https://pypi.org/

5. (3) Google Colaboratory での pip の操作

Google Colaboratoryではpipを次のように操作する。頭に「!」を付ける

  • パッケージのインストール
    !pip3 install <パッケージ名>
    

    パッケージのバージョン指定を行うときは、パッケージ名(例えば「numpy」)の後に、「numpy==19.5」のように付ける。

  • インストール済みパッケージの一覧
    !pip3 list
    
  • アンインストール
    !pip3 uninstall <パッケージ名>
    
  • パッケージの情報
    !pip3 show <パッケージ名>
    

5. (4) Windows での pip の操作

Windowsではpipを次のように操作する。

  • Python のバージョン指定なし

    Windowsで複数のPythonをインストールしているときは、環境変数Pathで先頭のPythonが使用される。

    • パッケージのインストール
      pip install <パッケージ名>
      

      Windowsで、管理者の領域にPythonをインストールしている場合には、管理者の権限で実行する。

      パッケージのバージョン指定を行うときは、パッケージ名(例えば「numpy」)の後に、「numpy==19.5」のように付ける。

    • インストール済みパッケージの一覧
      pip list
      
    • アンインストール
      pip uninstall <パッケージ名>
      

      Windowsで、管理者の領域にPythonをインストールしている場合には、管理者の権限で実行する。

    • パッケージの情報
      pip show <パッケージ名>
      
  • WindowsのPython ランチャーでPythonのバージョン指定
    • パッケージのインストール
      py -3.10 -m pip install <パッケージ名> (Python 3.10 の pip を使う場合)
      

      Windowsで、管理者の領域にPythonをインストールしている場合には、管理者の権限で実行する。

      パッケージのバージョン指定を行うときは、パッケージ名(例えば「numpy」)の後に、「numpy==19.5」のように付ける。

    • インストール済みパッケージの一覧
      py -3.10 -m pip list (Python 3.10 の pip を使う場合)
      
    • アンインストール
      py -3.10 -m pip uninstall <パッケージ名> (Python 3.10 の pip を使う場合)
      

      Windowsで、管理者の領域にPythonをインストールしている場合には、管理者の権限で実行する。

    • パッケージの情報
      py -3.10 -m pip show <パッケージ名> (Python 3.10 の pip を使う場合)
      

venvを使うときは、venvが定めるactivateコマンドを実行した後、「python」で起動する。

5. (5) Ubuntu での pip の操作

UbuntuでシステムPythonを使う場合は、pipを次のように操作する。

  • パッケージのインストール
    sudo pip3 install <パッケージ名> (システムPythonを使う場合)
    

    Ubuntuでは、「sudo pip3 install」でパッケージをインストールする前に、「apt-cache search <キーワード>」でUbuntuのパッケージを検索し、Ubuntuパッケージが見つかった場合にはそちらを「apt install <UbuntuのパッケージA名>」でインストールする。

    パッケージのバージョン指定を行うときは、パッケージ名(例えば「numpy」)の後に、「numpy==19.5」のように付ける。

  • インストール済みパッケージの一覧
    pip3 list (システムPythonを使う場合)
    
  • アンインストール
    sudo pip3 uninstall <パッケージ名> (システムPythonを使う場合)
    
  • パッケージの情報
    pip3 show <パッケージ名> (システムPythonを使う場合)
    

pyenvを用いてインストールしたPythonは、pyenvの設定の後、「python」で起動する。

venvを使うときは、venvが定めるactivateコマンドを実行した後、「python」で起動する。

5. (6) pip と setuptools を最新版に更新

  • Windowsの場合

    Windowsでは、コマンドプロンプトを管理者として開き次のコマンドを実行する。

    python -m pip install -U pip setuptools
    
  • Ubuntuの場合
    sudo apt -y upgrade python3-pip python3-setuptools
    

5. (7) pip のインストールを手動で行いたい場合

Pythonをインストールするとpipがインストールされるので、ここに書いた操作は通常は必要ない。

  • Windowsでpypaを使ってpipの更新を行う操作
    cd /tmp
    curl -O https://bootstrap.pypa.io/get-pip.py
    python get-pip.py
    
  • 次のページから.whl形式ファイルをダウンロードしてpipでインストールする場合もある

    「Geospatial library wheels for Python on Windows」のページ: https://github.com/cgohlke/geospatial-wheels

5. (8) Python の setup.py の実行

次のような操作になる。「pip」のところは、Ubuntuでは必要に応じて「pip3」に読み替えること。

git clone https://github.com/openai/gym
cd gym
pip install -e .

必要に応じて、「pip install -e .」の代わりに、次のように操作する。

git clone https://github.com/openai/gym
cd gym
python setup.py build
python setup.py install

python setup ... にオプションを付けたいときは「--set CMAKE_PREFIX_PATH="c:\dlib"」のように付け加える。

Windowsでは、setup.pyの実行前に、次のようなコマンドを実行し、環境変数などを設定できる場合がある。

set MSVC_VERSION=16
set CMAKE_GENERATOR=Visual Studio 16 2019
set PREBUILD_COMMAND=vcvarsall.bat
set PREBUILD_COMMAND_ARGS=x64
# call "vcvarsall.bat" x64 -vcvars_ver=14.11

Pythonのsetup.pyを用いて、wheel形式のpipパッケージを作成したいとき。

python -m pip install wheel
python setup.py bdist_wheel

5. (9) Python の build_ext の実行

Pythonのpipコマンドで、pillowをソースコードからビルドしている例である。

python -m pip install pillow==6 --global-option="build_ext" --global-option="--disable-jpeg" --global-option="--disable-zlib"

pillowのソースコードをダウンロードし、ビルドしている例である。

cd c:\pytools
git clone https://github.com/python-pillow/Pillow
cd Pillow
python setup.py build_ext --disable-zlib --disable-jpeg install

5. (10) Geospatial library wheels for Python on Windows

「Geospatial library wheels for Python on Windows」のページ

https://github.com/cgohlke/geospatial-wheels

5. (11) 2to3

2to3は、Pythonバージョン2用のソースコードをPythonバージョン3用に変換するプログラムである。次のように実行する。

2to3 -w .

Windowsで2to3が動かないとき、環境変数PATHの設定により動くようになる。

システムの環境変数PATHに、「C:\Program Files\Python\Python310\Tools\scripts」を加える。「C:\Program Files\Python\Python310」は、実際にPythonをインストールしたディレクトリに読み替えること。

Windowsで次のようにフルパスを書いて実行してもよい。

python %LOCALAPPDATA%\Programs\Python\Python310\Tools\scripts\2to3.py -w .

6. Python 開発環境、Python コンソール(Jupyter Qt Console、Jupyter ノートブック (Jupyter Notebook)、Jupyter Lab、Nteract、spyder、PyCharm)

Pythonプログラムを動かして、結果をビジュアルに見たいときは、Pythonの開発環境やPythonコンソール(Jupyter Qt Console、Spyder、PyCharm、PyScripterなど)が便利である。

6. (1) Python、pip、Python 開発環境、Python コンソールのコマンドでの起動

Python、pip、Python開発環境の起動コマンドのまとめである。

Windowsの場合

Windowsで複数のPythonをインストールしているときは、環境変数Pathで先頭のPythonが使用される。

  • python: python
  • pip: python -m pip または pip
  • Jupyter Qt Console: jupyter qtconsole あるいは python -m jupyter qtconsole
  • Jupyter ノートブック (Jupyter Notebook): jupyter notebook
  • Jupyter Lab: jupyter lab あるいは python -m jupyter lab
  • Nteract: jupyter nteract あるいは python -m jupyter nteract
  • Spyder: spyder

WindowsのPythonランチャーでバージョン指定する場合

  • インストール済みPythonのバージョン一覧: py -0
  • python: py -3.10 (Python 3.10 を使う場合)
  • pip: py -3.10 -m pip (Python 3.10 の pip を使う場合)
  • Jupyter Qt Console: py -3.10 -m qtconsole (Python 3.10 を使う場合)
  • Jupyter ノートブック (Jupyter Notebook): py -3.10 -m notebook (Python 3.10 を使う場合)
  • Jupyter Lab: py -3.10 -m jupyterlab (Python 3.10 を使う場合)

Ubuntuの場合

  • python: python3
  • pip: sudo pip3
  • Jupyter Qt Console: jupyter qtconsole あるいは python -m jupyter qtconsole
  • Jupyter ノートブック (Jupyter Notebook): jupyter notebook
  • Jupyter Lab: jupyter lab あるいは python -m jupyter lab
  • Nteract: jupyter nteract あるいは python -m jupyter nteract
  • Spyder: spyder

6. (2) Windows での Python 開発環境として、Jupyter Qt Console、Jupyter ノートブック (Jupyter Notebook)、Jupyter Lab、Nteract、spyder のインストール

Pythonのバージョン指定なし

Windowsで複数のPythonをインストールしているときは、環境変数Pathで先頭のPythonが使用される。

  • Pythonコンソール(Jupyter Qt Console)、Jupyter ノートブック (Jupyter Notebook)、Jupyter Lab、Nteract、spyderのインストール

    Windowsでは、コマンドプロンプトを管理者として実行し、次のコマンドを実行する。

    python -m pip install -U pip setuptools requests notebook==6.5.7 jupyterlab jupyter jupyter-console jupytext PyQt5 nteract_on_jupyter spyder
    
    インストールコマンドの実行画面
  • WindowsでのPyCharmのインストールは、別ページで説明している。
  • WindowsでのPyScripterのインストールは、別ページで説明している。

WindowsのPythonランチャーでPythonのバージョン指定

使用するPythonのバージョンを指定する。Python 3.10 を使う場合は、コマンドプロンプトを管理者として開き次のコマンドを実行する。

py -3.10 -m pip install -U pip setuptools requests jupyterlab jupyter jupyter-console jupytext PyQt5 nteract_on_jupyter spyder

6. (3) Ubuntu での Python 開発環境として、Jupyter Qt Console、Jupyter ノートブック (Jupyter Notebook)、Jupyter Lab、Nteract、spyder のインストール

Ubuntuでインストールを行うには、次のコマンドを実行する。

# パッケージリストの情報を更新
sudo apt update
sudo apt -y install python-is-python3 python3-dev python-dev-is-python3 python3-pip python3-setuptools python3-venv build-essential
sudo pip3 uninstall -y ptyprocess sniffio terminado tornado jupyterlab jupyter jupyter-console jupytext nteract_on_jupyter spyder
sudo apt -y install jupyter jupyter-qtconsole spyder3
sudo apt -y install python3-ptyprocess python3-sniffio python3-terminado python3-tornado
sudo pip3 install -U jupyterlab jupyter jupyter-console jupytext nteract_on_jupyter

Ubuntuで複数のPythonバージョンを共存しているときは、pyenvを使う。次のようにバージョン指定する。

pyenv shell 3.8.3
python -m pip install jupyterlab jupyter jupyter-console jupytext

6. (4) Python コンソール

Pythonコンソールは、Pythonのシェルの画面のことである。プロンプトが出て、Pythonのプログラムを受け付ける。そして、その実行結果を表示する。

  • Jupyter Qt Console : Pythonコンソールの機能を持つ
  • Spyder: Pythonコンソールの機能を持つ(デフォルトで右下の画面がPythonコンソールになっている)
  • PyCharm: Pythonコンソールの機能を持つ
  • python

    Windowsでは、端末で「python」あるいは「py -3.10(Python 3.10 を使う場合)」を実行して起動する。

    Pythonコンソールの起動画面

Blender の Python コンソール

Blenderに内蔵されたPythonのコンソールである。Blender 3.0では次の手順で開くことができる。

画面として「Pythonコンソール」を選ぶ。

BlenderのPythonコンソール選択画面

6. (5) Jupyter Qt Console

Jupyter Qt ConsoleはPythonコンソールの機能を持ったソフトウェアである。インストールは、このページの別の項目で説明している。

Jupyter Qt Consoleの起動は、「jupyter qtconsole」または「py -3.10 -m qtconsole」(Python 3.10 を使う場合)である。

Jupyter Qt Consoleの起動画面
Jupyter Qt Consoleの実行画面

次のPythonプログラムを実行してみる。

次のプログラムは、NumPyとMatplotlibを使用して、0から6までの範囲のsin関数のグラフを描画する。warningsモジュールを使用してMatplotlibの警告表示を抑制し、Matplotlibでは、デフォルトのスタイルを使用する。

import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings

x = np.linspace(0, 6, 100)
plt.style.use('default')
plt.plot(x, np.sin(x))
グラフ描画の実行結果

6. (6) Jupyter ノートブック (Jupyter Notebook)

Jupyter ノートブックは、Pythonなどのプログラムのソースコード、実行結果などを1つのノートとして残す機能をもったノートブックである。インストールは、このページの別の項目で説明している。

Jupyter ノートブック (Jupyter Notebook)の起動は、「jupyter notebook」または「py -3.10 -m notebook」(Python 3.10 を使う場合)である。

Jupyter Notebookの起動画面
Jupyter Notebookの実行画面

6. (7) Jupyter Lab

Jupyter LabはPythonプログラム作成に関する種々の機能を持ったソフトウェアである。インストールは、このページの別の項目で説明している。

Jupyter Labの起動は、「jupyter lab」または「py -3.10 -m jupyterlab」(Python 3.10 を使う場合)である。

Jupyter Labの起動画面

pyenvを使うときは、次のようにバージョン指定する。

JupyterLabの起動は、「pyenv shell <バージョン>; jupyter lab」である。Jupyter Qt Consoleの起動は、「pyenv shell <バージョン>; jupyter qtconsole」である。

6. (8) Nteract

Nteractは、Pythonなどのプログラムのソースコード、実行結果などを1つのノートとして残す機能をもったノートブックである。インストールは、このページの別の項目で説明している。

Nteractの起動は、「jupyter nteract」である。

Nteractの起動画面
Nteractの実行画面

次のPythonプログラムを実行してみる。そのために「Start a new notebook」の下の「Python」をクリックし、次のプログラムを入れ実行する。

次のプログラムは、NumPyとMatplotlibを使用して、0から6までの範囲のsin関数のグラフを描画する。warningsモジュールを使用してMatplotlibの警告表示を抑制し、Matplotlibでは、デフォルトのスタイルを使用する。

import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings

x = np.linspace(0, 6, 100)
plt.style.use('default')
plt.plot(x, np.sin(x))
Nteractでのグラフ描画結果

Jupyter Notebookの保存設定

Jupyter Notebookで、保存のときに、.pyファイルと.ipynbファイルが保存されるように設定する。(この設定を行わないときは.ipynbファイルのみが保存される)

  1. 次のコマンドで、設定ファイルを生成する
    jupyter notebook --generate-config
    
  2. jupyter/jupyter_notebook_config.pyを編集し、末尾に、次を追加する

    c.NotebookApp.contents_manager_class = "jupytext.TextFileContentsManager"

6. (9) PyScripter

PyScripterはPythonプログラム作成に関する種々の機能を持ったソフトウェアである。

WindowsでのPyScripterのインストールは、別ページで説明している。

6. (10) spyder

Windowsで、Anaconda3をインストールしたときは、スタートメニューの「Anaconda3 (64-bit)」の下に「Spyder」があるので、これを使って実行するのが簡単である。

Ubuntuでは「spyder」で実行する。

spyderの右下の画面は、既定(デフォルト)で、Pythonコンソールになっている。

Spyderの実行画面

ラズベリーパイの場合は、次のコマンドでspyderをインストールすることができる。

sudo apt install python3-spyder
sudo apt install spyder3

6. (11) PyCharm

PyCharmはPythonプログラム作成に関する機能を持ったソフトウェアである。次の機能を持つ。

PyCharmでは、既定(デフォルト)でPythonの仮想環境が利用される。pipでPythonパッケージをインストールしたときなどで、システムのPythonを使いたいときは、別ページで説明する手順で設定する。

【PyCharm Community版の主な機能】

  • 日本語言語パックのプラグイン

    操作: Plugins、japaneseで検索、「Install」をクリック

  • Pythonコードインスペクション

    シンタックスハイライト、整形(コードフォーマッタ)、コード解析、修正候補の提示と実行(クイックフィックス)(Alt+Enterを使用)、コード補完など

  • 検索

    検索は、SHIFTを2回押す

  • ビジュアルなデバッガ

    ブレークポイント(マウスで指定可能)、変数値の表示など

    https://www.jetbrains.com/ja-jp/pycharm/features/tools.html#debugger

  • リファクタリング

    名前の変更、メソッドの抽出など(メニューで実行可能)

  • 型ヒント

    型ヒントは、Alt+Enterを使用

    https://www.jetbrains.com/help/pycharm/2016.3/type-hinting-in-pycharm.html

  • 単体テストでpy.testを使うように設定

    ファイル(File)、設定(Settings)、Python統合ツール(Python Integrated tools)、デフォルトのテストランナー(Default test runner)で、「pytest」を設定

Pythonプログラミングの基礎

7. (1) オブジェクトの生成と削除、同値、同一性

プログラミングでのオブジェクトは、コンピュータでの操作や処理の対象である。

キーワード: =del==is

  • 同値
    a = 123
    b = 123
    print(a == b)
    
    同値の比較結果を表示した画面
  • 同一性
    x = True
    y = None
    print(x is True)
    print(y is None)
    
    同一性の比較結果を表示した画面
  • オブジェクトの生成と削除

    最後の「print(c)」の実行ではエラーメッセージが出る。

    c = 123
    print(c)
    del c
    print(c)
    
    オブジェクト削除後のエラーメッセージを表示した画面

7. (2) 単純値のデータ型

  • キーワード: intfloatDecimalTrueFalseboolNonestrbyteslistrangetupledictset
    • int: 整数
    • float: 浮動小数点数
    • bool: ブール値
    • str: 文字列
    • bytes: バイト列
  • 辞書(dictionary)
    dic = {}
    dic.update( {"kaneko": 30} )
    print(dic)
    
    辞書の内容を表示した画面
  • 名前付きタプル(named tuple)
    import collections
    Point3d = collections.namedtuple('Point3d', 'x y z')
    p = Point3d(10, 20, 30)
    print(p)
    
    名前付きタプルの内容を表示した画面

7. (3) オブジェクトのタイプ

print( type(100) )
print( type(1.23) )
print( type(True) )
print( type(False) )
print( type("Hello") )
print( type([1, 2, 3]) )
dic = {}
dic.update( {"kaneko": 30} )
print( type(dic) )
import collections
Point3d = collections.namedtuple('Point3d', 'x y z')
p = Point3d(10, 20, 30)
print( type(p) )
import numpy as np
print( type(np.zeros(10)) )
各種オブジェクトのタイプを表示した画面

制御構造(条件分岐、繰り返し)

キーワード: ifelifelsewhilebreakfor

条件分岐

  • 条件分岐

    変数の値によって、実行の流れが変わる。

    age = 15
    if (age <= 12):
        print(500)
    else:
        print(1800)
    
    条件分岐の実行結果を表示した画面
  • 多分岐
    age = 15
    if age <= 12:
        print(500)
    elif age <= 15:
        print(1000)
    else:
        print(1800)
    
    多分岐の実行結果を表示した画面

繰り返し

  • whileによる繰り返し
    b = 8
    s = 0
    while s < 100:
        s = s + b
    
    print(s)
    
    while文による繰り返しの実行結果を表示した画面
  • forによる繰り返し
    for i in range(10):
        print(i)
    
    for文による繰り返しの実行結果を表示した画面
  • 月の日数

    月の日数についてのデータを作る。うるう年は考慮しない。

    import numpy as np
    days = np.array([0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31])
    print( days[7] )
    print( days[9] )
    
    月の日数を表示した画面
  • 物体の落下
    import numpy as np
    x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    for t in x:
        print( (9.8 / 2) * t * t )
    
    物体の落下距離を表示した画面
  • 10倍
    import numpy as np
    x = np.array([8, 6, 4, 2, 3])
    y = np.array([0, 0, 0, 0, 0])
    for i in range(0,5):
        y[i] = x[i] * 10
    
    print(x)
    print(y)
    
    配列の各要素を10倍にした結果を表示した画面
  • 「*」の表示を18回繰り返す
    import sys
    for i in range(18):
        sys.stdout.write("*")
    
    アスタリスクを18個並べて表示した画面

文字列の演算子

キーワード: +、in、%、split、join、replace、strip、match、sprintf

pandasデータフレーム

Pandasを用いたデータの扱い(CSVファイル読み込み、散布図、要約統計量、ヒストグラム)を示す。

説明のために、次のCSVファイルを使う。ファイル名はenquete.csvである。

アンケートデータのCSVファイルの内容

このCSVファイルのダウンロードは、Windowsでコマンドプロンプト管理者として開き、次のコマンドを実行する。

cd C:\
curl -O https://www.kkaneko.jp/sample/csv/enquete.csv

上のコマンドが実行できないときは、次のリンクからダウンロードする。ダウンロードしたファイルは、C:\の直下に置く。 https://www.kkaneko.jp/sample/csv/enquete.csv

CSVファイルの読み込み、確認

Pythonでグラフや図を表示する場合、Windowsでは、スタートメニューの「IDLE(Python ...)」、spyder3コマンド、PyCharmが便利である。

  1. アンケートデータの読み込み
    import pandas as pd
    import seaborn as sns
    
    x = pd.read_csv('C:/enquete.csv', encoding='SHIFT-JIS')
    
    CSVファイルを読み込んだ画面

    先頭行にデータ本体がある(先頭行が属性名でない)ときは、「pd.read_csv('hoge.csv', header=None)」のようにする。

  2. 読み込んだデータの表示
    print(x)
    
    読み込んだデータを表示した画面
  3. 読み込んだデータのうち、1列目と2列目の表示

    オブジェクトxには0列目と1列目と2列目がある。

    print(x.iloc[:,1])
    print(x.iloc[:,2])
    
    1列目と2列目を表示した画面
  4. 読み込んだデータについて、1列目と2列目の散布図

    plt.style.use('ggplot')」はグラフの書式の設定である。「ro」は赤い丸を意味する。

    %matplotlib inline
    import matplotlib.pyplot as plt
    import warnings
    warnings.filterwarnings('ignore')
    plt.style.use('ggplot')
    plt.plot(x.iloc[:,1], x.iloc[:,2], 'ro')
    plt.show()
    
    散布図を表示した画面
  5. 各列について、基本的な情報の表示
    • head: 先頭部分の表示
    • shape: サイズ
    • ndim: 次元数
    • columns: 属性名
    • info(): 各属性のデータ型
    print(x.head())
    print(x.info())
    print(x.shape)
    print(x.ndim)
    print(x.columns)
    
    データフレームの基本情報を表示した画面
  6. CSVファイルに書き出し
    x.to_csv('hoge.csv', header=True, index=False, encoding='SHIFT-JIS')
    

各属性の要約統計量

総数、平均、標準偏差、最小、四分位点、中央値、最大を表示する。

print(x.describe())
要約統計量を表示した画面

JSONファイルの書き出しと読み込み

import pandas as pd
x.to_json('hoge.json')
a = pd.read_json('hoge.json')

pandas.DataFrameのコンストラクタ

  • リストから
    import pandas as pd
    pd.DataFrame([1, 2, 3])
    
  • numpy.ndarrayから
    import numpy as np
    import pandas as pd
    pd.DataFrame( np.array([1,2,3]) )
    
    import numpy as np
    import pandas as pd
    pd.DataFrame( np.array([[1,2,3], [10,20,30], [100,200,300]]) )
    
  • 辞書から
    import pandas as pd
    pd.DataFrame( {'x' : [1, 2, 3], 'y' : [4, 5, 6]} )
    

ヒストグラムの表示

import matplotlib.pyplot as plt
plt.hist(x.iloc[:,1])
plt.show()

plt.hist(x.iloc[:,2])
plt.show()
1列目のヒストグラムを表示した画面
2列目のヒストグラムを表示した画面

2次元ヒストグラム

import matplotlib.pyplot as plt
plt.hist2d(x.iloc[:,1], x.iloc[:,2])
plt.show()
2次元ヒストグラムを表示した画面

numpy全般

次元数

numpyの1次元の配列の次元数1である(ndimで得る)。

1次元の配列の(<要素数>,)のように表示される(shapeで得る)。

import numpy as np
x = np.zeros(10)
print( x.ndim )
print( x.shape )
1次元配列の次元数と形を表示した画面

numpyの2次元の配列の次元数2である(ndimで得る)。

2次元の配列の(<要素数>,<要素数>)のように表示される(shapeで得る)。

import numpy as np
x = np.zeros((2, 3))
print( x.ndim )
print( x.shape )
2次元配列の次元数と形を表示した画面

データ型と、要素のデータ型

1次元の配列のデータ型はnumpy.ndarrayである(typeで得る)。

配列の要素のデータ型dtypeを使って表示する。「float64」は浮動小数点数である。

import numpy as np
x = np.zeros(10)
print( type( x ) )
print( x.dtype )
1次元配列のデータ型と要素のデータ型を表示した画面

2次元の配列のデータ型はnumpy.ndarrayである(typeで得る)。

配列の要素のデータ型dtypeを使って表示する。「float64」は浮動小数点数である。

import numpy as np
x = np.zeros((2, 3))
print( type( x ) )
print( x.dtype )
2次元配列のデータ型と要素のデータ型を表示した画面

1次元の配列

配列は、データの並びで、それぞれのデータに、0から始まる番号(添字)が付いている。

1次元の配列の生成

  • 0要素

    typeはオブジェクトのタイプの取得である。shapeは配列のサイズの取得である。

    import numpy as np
    x = np.zeros(10)
    print(x)
    print(type(x))
    print(x.shape)
    

    表示の「0.」は「0」を意味する。

    0要素の配列を表示した画面
  • 1要素
    import numpy as np
    x = np.ones(10)
    print(x)
    print(type(x))
    print(x.shape)
    

    表示の「1.」は「1」を意味する。

    1要素の配列を表示した画面
  • 乱数(正規分布、平均が0)
    import numpy as np
    x = np.random.randn(10)
    print(x)
    print(type(x))
    print(x.shape)
    
    乱数の配列を表示した画面
  • 要素指定
    import numpy as np
    x = np.array([3, 1, 2, 5, 4])
    print(x)
    print(type(x))
    print(x.shape)
    
    要素を指定した配列を表示した画面
  • arangeによる指定

    -5から開始して、2ずつ増やし、4まで

    import numpy as np
    x = np.arange(-5, 4, 2)
    print(x)
    print(type(x))
    print(x.shape)
    
    arangeで生成した配列を表示した画面
  • linspaceによる指定

    -2から、2まで、全部で、9個

    import numpy as np
    x = np.linspace(-2, 2, 9)
    print(x)
    print(type(x))
    print(x.shape)
    
    linspaceで生成した配列を表示した画面

合計

import numpy as np
x = np.array([8, 6, 4, 2, 3])
print(sum(x))
配列の合計を表示した画面

2次元の配列

import numpy as np
x = np.zeros((2, 3))
print(x)
print(type(x))
print(x.shape)

表示の「0.」は「0」を意味する。

2次元の0要素配列を表示した画面
import numpy as np
x = np.ones((2, 3))
print(x)
print(type(x))
print(x.shape)

表示の「1.」は「1」を意味する。

2次元の1要素配列を表示した画面
import numpy as np
x = np.random.randn(2,3)
print(x)
print(type(x))
print(x.shape)
2次元の乱数配列を表示した画面
  • 乱数(正規分布)
    import numpy as np
    x = np.random.randn(2,3)
    print(x)
    
    2次元の乱数配列を表示した画面

2次元の配列の処理

行列の積

時間計測も行う。

import numpy as np
import time

x = np.random.randn(5000, 5000)
y = np.random.randn(5000, 5000)

s = time.time()
z = np.dot(x, y)
print("%1.3f [sec.]" % float(time.time() - s))
行列の積の計算時間を表示した画面

CuPyを用いて行列の積を求める

時間計測も行う。

  • CPUを用いて、行列の積を求める
    !pip3 install cupy
    import numpy as np
    use_gpu=False
    if use_gpu:
        import cupy
        npcp = cupy
    else:
        npcp = np
    
    x = npcp.random.random((5000, 5000))
    y = npcp.random.random((5000, 5000))
    import datetime
    a = datetime.datetime.now()
    npcp.dot(x, y)
    print( (a - datetime.datetime.now()).microseconds )
    
    CPUを用いた行列の積の計算時間を表示した画面
  • GPUを用いて、行列の積を求める

    上のプログラムで、「use_gpu=False」を「use_gpu=True」に変更する。

    !pip3 install cupy
    import numpy as np
    use_gpu=True
    if use_gpu:
        import cupy
        npcp = cupy
    else:
        npcp = np
    
    x = npcp.random.random((5000, 5000))
    y = npcp.random.random((5000, 5000))
    import datetime
    a = datetime.datetime.now()
    npcp.dot(x, y)
    print( (a - datetime.datetime.now()).microseconds )
    

行列の積、主成分分析、SVD、k-means

次のプログラムは、NumPyとscikit-learnを使用して、行列計算とデータ分析を行う。

  1. 2000x2000の乱数行列XとYを生成し、それらの行列積を計算する。
  2. scikit-learnのPCAを使用して、Xの主成分分析を行い、2次元に次元削減する。
  3. NumPyのsvd関数を使用して、Xの特異値分解を行う。
  4. scikit-learnのKMeansを使用して、Xに対して10クラスタのk-meansクラスタリングを行う。

各操作の実行時間を測定し、結果を出力する。

import time
import numpy
import numpy.linalg
import sklearn.decomposition
import sklearn.cluster
X = numpy.random.rand(2000, 2000)
Y = numpy.random.rand(2000, 2000)
# 行列の積
a = time.time(); Z = numpy.dot(X, Y); print(time.time() - a)
# 主成分分析
pca = sklearn.decomposition.PCA(n_components = 2)
a = time.time(); pca.fit(X); X_pca = pca.transform(X); print(time.time() - a)
# SVD
a = time.time(); U, S, V = numpy.linalg.svd(X); print(time.time() - a)
# k-means
a = time.time();
kmeans_model = sklearn.cluster.KMeans(n_clusters=10, random_state=10).fit(X)
labels = kmeans_model.labels_
print(time.time() - a)

numpyのnpz形式ファイルの書き出しと読み込み

import numpy as np
np.savez('hoge.npz',a = np.array([1, 2, 3]), b = np.array([1, 2, 3]))
m = np.load('hoge.npz')
print( m['a'] )
print( m['b'] )

2次元配列データのCSVファイル読み書き

CSVファイルへの書き出しはpandasの機能で行う。次のプログラムを実行すると、ファイルXX.csvとYY.csvが作成される。

import numpy as np
import pandas as pd
X, Y = np.meshgrid( np.array([2, 3, 4]), np.array([10, 20]) )
XX = pd.DataFrame(X)
print(XX)
XX.to_csv("XX.csv", header=False, index=False)
YY = pd.DataFrame(Y)
print(YY)
YY.to_csv("YY.csv", header=False, index=False)

CSVファイルの読み込みもpandasの機能で行う。次のプログラムは、作成したファイルXX.csvを読み込む。

pd.read_csv("XX.csv", header=None)

同様に、ファイルYY.csvを読み込む。

pd.read_csv("YY.csv", header=None)

メッシュグリッド

メッシュグリッドは、3次元グラフの作成や繰り返し計算を行う際に使用する。

import numpy as np
X, Y = np.meshgrid( np.array([2, 3, 4]), np.array([10, 20]) )
print(X)
print(type(X))
print(X.shape)
print(Y)
print(type(Y))
print(Y.shape)

配列の次元を増やす

1次元配列を2次元配列に変換する。次のプログラムは、1次元配列xを2次元配列AとBに変換する。

import numpy as np
x = np.array([3, 1, 2, 5, 4])
A = x[:, np.newaxis]
B = x[np.newaxis, :]
print(A)
print(type(A))
print(A.shape)
print(B)
print(type(B))
print(B.shape)

リスト

Pythonのリストは、複数の要素を格納できるデータ構造である。

a = [1, 2, 3, 4]
print(a)
type(a)

Pythonのリストの添字は0から開始する。

a = [10, 20, 30]
print(a[1])
a[2] = 200
print(a)

Pythonのモジュール

Pythonのモジュールは、1つ以上の関数を集めて1つのファイルにまとめたものである。次のモジュールには関数taxが含まれている。

Pythonのモジュールは単体でも実行できるように作成できる。これはモジュールのテストを行う際に有用である(「if __name__ == "__main__"」から始まる部分が、単体実行を可能にする記述である)。

def tax(x):
    return x * 1.08

if __name__ == "__main__":
    print(tax(100))

このモジュールを他のプログラムでインポートして使用する場合は、モジュールを「hoge.py」のようなファイル名で保存する。その後、プログラムを次のように記述する。

import hoge
print(hoge.tax(10))

Pythonのライブラリ

Pythonには様々な機能を提供するライブラリが用意されている。

現在の日時

オペレーティングシステムのタイマーを利用して、現在の日時を取得できる。

import datetime
now = datetime.datetime.now()
print(now)

最大公約数

24と18の最大公約数を求める。

import math
print( math.gcd(24, 18) )

方程式を解く

方程式4x + 1 = 0を解く。

from scipy import optimize
def foo(x):
    return 4 * x + 1
print( optimize.fsolve(foo, 10) )

平方根

面積が7の正方形の一辺の長さを求める。

import math
print( math.sqrt(7) )

円の面積

半径3の円の面積を求める。円周率にはmath.piを使用する。

import math
print( 3 * 3 * math.pi )

三角形の面積

2辺の長さが4と6で、その間の角度が60度の三角形の面積を求める。

import math
print( (1/2) * 4 * 6 * math.sin(60 * math.pi / 180) )

IPython.displayを用いた画像表示

画像ファイルを読み込んで表示する。

from PIL import Image
from IPython.display import display

filename = '127.png'
img = Image.open(filename)
display(img)

Matplotlibを用いた散布図のプロット

matplotlibは、オープンソースのPythonプロットライブラリである。

  • リストx、yからの散布図の作成
    %matplotlib inline
    import matplotlib.pyplot as plt
    import warnings
    warnings.filterwarnings('ignore')
    import numpy as np
    x = [1, 2, 3, 4, 5]
    y = [2, 4, 1, 3, 5]
    plt.style.use('ggplot')
    plt.scatter(x, y)
    
  • pandasのDataFrameの2つの属性x、yからの散布図の作成
    import numpy as np
    import pandas as pd
    %matplotlib inline
    import matplotlib.pyplot as plt
    import warnings
    warnings.filterwarnings('ignore')
    a = pd.DataFrame( {'x' : [1, 2, 3, 4, 5], 'y' : [2, 4, 1, 3, 5]} )
    plt.style.use('ggplot')
    plt.plot(a['x'], a['y'], 'ro')
    plt.show()
    

3次元散布図

%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
import numpy as np
from mpl_toolkits.mplot3d import axes3d
plt.style.use('ggplot')
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 3, 5]
z = [1, 1, 2, 2, 3]
ax.scatter(x, y, z, c='b')

Matplotlibを用いた種々のプロット

OpenCV画像の表示

matplotlibを用いてOpenCVのカラー画像を表示する。

import cv2
import matplotlib.pyplot as plt
bgr = cv2.imread("126.png")
plt.style.use('default')
plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
plt.show()

matplotlibを用いてOpenCVの濃淡画像を表示する。

import cv2
import matplotlib.pyplot as plt
bgr = cv2.imread("126.png")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
plt.style.use('default')
plt.imshow(mono, cmap='gray')
plt.show()

Matplotlibでのサイズ調整

MatplotlibでOpenCV画像を表示すると、デフォルトでは小さく表示される場合がある。「plt.style.use('default')」を実行することで、表示サイズを大きくできる。

関数のプロット

matplotlibを用いたグラフ描画の例を示す。

import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
x = np.linspace(0, 6, 100)
plt.style.use('ggplot')
plt.plot(x, np.sin(x))

メッシュグリッドと関数の3次元プロット

%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
import numpy as np
from mpl_toolkits.mplot3d import axes3d
plt.style.use('ggplot')
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
X, Y = np.meshgrid( np.array([-2, -1, 0, 1, 2]), np.array([-3, -2, -1, 0, 1, 2, 3]) )
def f(x,y):
    return x * y
Z = f(X, Y)
ax.scatter(X, Y, Z, c='b')

x1、x2のソフトマックス関数の3次元プロット。

%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
import numpy as np
from mpl_toolkits.mplot3d import axes3d
plt.style.use('ggplot')
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
X1, X2 = np.meshgrid( np.array([-2, -1, 0, 1, 2]), np.array([-3, -2, -1, 0, 1, 2, 3]) )
def softmax(x):
    A = np.exp(x - np.max(x))
    return A / A.sum()
def f(x1, x2):
    return softmax( np.array([x1, x2]) )
Z = f(X1, X2)
ax.scatter(X1, X2, Z[0], c='b')
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.scatter(X1, X2, Z[1], c='b')

TensorFlow

TensorFlowは、Googleが開発した機械学習フレームワークである。Python、C/C++言語から利用可能で、CPU、GPU、TPU上で動作する。TensorFlowの特徴として「データフローグラフ」がある。これは、データの流れを表現するもので、グラフの節点は演算を、エッジはデータ(テンソル)の流れを表す。TensorFlowを使用することで、音声、画像、テキスト、ビデオなど多様なデータを扱う機械学習アプリケーションの開発が容易になる。

TensorFlowのプログラム例として、行列の足し算を示す。

import tensorflow as tf
import numpy as np
a = tf.constant( np.reshape([1, 1, 1, 1, 1, 1], (2, 3) ) )
b = tf.constant( np.reshape( [1, 2, 3, 4, 5, 6], (2, 3) ) )
c = tf.add(a, b)

print(c)

Keras

Kerasは、TensorFlowを用いてディープラーニング(深層学習)でのモデルの構築と訓練を簡単に行えるようにするソフトウェアである。

用語集

  • Kerasのモデルは、複数の層が組み合わさったものである。単純に層を積み重ねたもの(シーケンシャル)や、複雑な構成のもの(グラフ)がある。
  • Kerasの層には、活性化関数、層の重みの種類(カーネル、バイアスなど)を設定できる。
  • Kerasの層には、全結合、畳み込み(コンボリューション)などの種類がある。
  • 学習のために、オプティマイザの設定を行う。
  • Kerasのモデルの構成やオプティマイザの設定は保存できる。
  • 学習の結果は結合の重みになる。結合の重みも保存できる。

ニューラルネットワークのデモサイト: http://playground.tensorflow.org

手順

  1. パッケージのインポート
    from __future__ import absolute_import, division, print_function, unicode_literals
    
    import tensorflow as tf
    import tensorflow_datasets as tfds
    from tensorflow import keras
    
    import numpy as np
    %matplotlib inline
    import matplotlib.pyplot as plt
    import warnings
    warnings.filterwarnings('ignore')
    
    print(tf.__version__)
    
  2. 画像データセットMNISTの準備

    x_train: サイズ28×28の60000枚の濃淡画像

    y_train: 60000枚の濃淡画像それぞれの種類番号(0から9のどれか)

    x_test: サイズ28×28の10000枚の濃淡画像

    y_test: 10000枚の濃淡画像それぞれの種類番号(0から9のどれか)

    mnist, metadata = tfds.load(
        name="mnist", as_supervised=False, with_info=True, batch_size = -1)
    train, test = mnist['train'], mnist['test']
    print(metadata)
    
    x_train, y_train = train["image"].numpy().astype("float32") / 255.0, train["label"]
    x_test, y_test = test["image"].numpy().astype("float32") / 255.0, test["label"]
    
  3. 画像データセットMNISTの確認表示
    plt.style.use('default')
    plt.figure(figsize=(10,10))
    for i in range(25):
      plt.subplot(5,5,i+1)
      plt.xticks([])
      plt.yticks([])
      plt.grid(False)
      image, label = train["image"][i], train["label"][i]
      plt.imshow(image.numpy()[:, :, 0].astype(np.float32), cmap='gray')
      plt.xlabel(label.numpy())
    
    plt.show()
    
  4. 配列の形状と次元の確認

    配列の形: 60000×28×28

    次元: 3

    print( x_train.shape )
    print( x_train.ndim )
    
  5. ディープニューラルネットワークのモデルの作成

    2層のニューラルネットワークを作成する。1層目のユニット数は128、2層目のユニット数は10である。

    m = tf.keras.Sequential()
    m.add(tf.keras.layers.Flatten(input_shape=(28, 28, 1)))
    m.add(tf.keras.layers.Dense(units=128, activation='relu'))
    m.add(tf.keras.layers.Dropout(rate=0.2))
    m.add(tf.keras.layers.Dense(units=10, activation='softmax'))
    m.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    
  6. ニューラルネットワークの確認表示
    print(m.summary())
    
  7. ニューラルネットワークの学習を行う
    history = m.fit(x_train, y_train, epochs=50)
    
  8. 検証用データで検証する
    print( m.evaluate(x_test,  y_test, verbose=2) )
    

    訓練(学習)などで乱数が使われるため、実行ごとに結果が異なる場合がある。

  9. ニューラルネットワークを使ってみる

    テスト画像をニューラルネットワークに与えて予測させる。テスト画像は0から9の数字が書かれた画像である。

    predictions = m.predict(x_test)
    print(predictions[0])
    

    結果の見方: 0である確率、1である確率、2である確率、...、9である確率と、10個の数字が結果として得られる。先ほど作成したニューラルネットワークの2層目は10個のユニットがあった。各ユニットから1個の数字が得られている。

    訓練(学習)などで乱数が使われるため、実行ごとに結果が異なる場合がある。

  10. 正解表示

    テスト画像0番の正解を表示する。

    print(y_test[0])
    

式と変数

変数は、変化するデータのことである。「x = 100」のように書くとxの値が100に変化する。

の実行結果として値が得られる。式の中に変数名を書くことができる。

x = 100
y = 200
print(x + y)
print( (x + 10) * y)
teihen = 2.5
takasa = 5
print(teihen * takasa / 2)

関数定義と関数オブジェクト

関数定義はdefを用い、戻り値はreturnで指定する。

  • アッカーマン関数の定義
    def a(m, n):
        if m == 0:
            return n + 1
        elif n == 0:
            return a(m-1, 1)
        else:
            return a(m-1, a(m, n-1))
    
    print(a(3, 2))
    print(a(m = 3, n = 2))
    print(a(n = 2, m = 3))
    
  • 既定値(デフォルト値)
    def a(m, n = 1):
        if m == 0:
            return n + 1
        elif n == 0:
            return a(m-1, 1)
        else:
            return a(m-1, a(m, n-1))
    
    print(a(3, 1))
    print(a(3))
    print(a(m = 3))
    
  • 関数オブジェクト
    f = lambda x: x + 1
    print(f(100))
    

式の抽象化と関数

式の抽象化は、類似した複数の式を変数を使って1つにまとめることである。次の3つの式を考える。

print(100 * 1.08)
print(150 * 1.08)
print(400 * 1.08)

上の3つの式を抽象化すると「a * 1.08」のような式になる。

式「a * 1.08」を本体式とするような関数(関数名はfoo)の定義とその使用例を示す。関数の利用により、繰り返し同じことを書くことを防ぐことができ、ミスを減らすこともできる。プログラムの変更も簡単になる。

def foo(a):
    return a * 1.08
print(foo(100))
print(foo(150))
print(foo(400))

式の評価のタイミング

関数の中の式の評価では、最新の変数値が用いられる。

x = 30
def foo(a):
    return(a * x)
x = 300
print(foo(100))
x = 3000
print(foo(100))

クラス定義、オブジェクト生成、属性アクセス

  • メソッド: オブジェクトに属する操作や処理
  • クラス: 同一種類のオブジェクトの集まり
  • クラス定義: あるクラスが持つ属性とメソッドを定めること
  • 属性アクセス: 「.」+属性名で属性にアクセスする。メソッド内では、self +「.」で属性にアクセスする

クラス定義、オブジェクト生成、属性アクセスの例

クラス名: C

属性名: qty、weight、name

class C(object):
    def __init__(self, qty, weight, name):
        self.qty = qty
        self.weight = weight
        self.name = name

x = C(5, 170.51, 'apple')
y = C(3, 40.97, 'orange')
print(vars(x))
print(vars(y))
print(x.name)
print(y.name)

varsはオブジェクトの属性名と値を取得する。「x.name」、「y.name」は属性アクセスである。

getattrによる属性値の取得

クラス名: C

属性名: qty、weight、name

class C(object):
    def __init__(self, qty, weight, name):
        self.qty = qty
        self.weight = weight
        self.name = name

x = C(5, 170.51, 'apple')
y = C(3, 40.97, 'orange')
print(getattr(x, 'qty'))
print(getattr(y, 'weight'))

getattrはオブジェクトと属性名(文字列)を指定して値を取得する。

setattrによる属性の動的な追加

クラス名: C

属性名: qty、weight、name

class C(object):
    def __init__(self, qty, weight, name):
        self.qty = qty
        self.weight = weight
        self.name = name

x = C(5, 170.51, 'apple')
y = C(3, 40.97, 'orange')
setattr(x, 'color', 'red')
print(vars(x))
print(vars(y))

setattrでは、オブジェクトと属性名(文字列)と値を指定する。

コンストラクタでの既定値(デフォルト値)

既定値(デフォルト値)を設定している場合には、引数を省略できる。コンストラクタ以外のメソッドでも同様である。

クラス名: D

属性名: s_hour、s_minute、e_hour、e_minute

class D(object):
    def __init__(self, s_hour, s_minute):
        self.s_hour = s_hour
        self.s_minute = s_minute
        self.e_hour = None
        self.e_minute = None

z = D(15, 30)
z2 = D(16, 15)
print(vars(z))
print(vars(z2))

メソッド

メソッドの例

  • メソッドアクセス: 「.」+メソッド名でメソッドにアクセスする。メソッド内では、self +「.」で属性やメソッドにアクセスする
class C(object):
    def __init__(self, qty, weight, name):
        self.qty = qty
        self.weight = weight
        self.name = name
    def total(self):
        return self.qty * self.weight

x = C(5, 170.51, 'apple')
print(vars(x))
print(x.total())
help(x)

helpは、メソッドの説明を表示する。

setattrによるメソッドの追加

class C(object):
    def __init__(self, qty, weight, name):
        self.qty = qty
        self.weight = weight
        self.name = name
    def total(self):
        return self.qty * self.weight

x = C(5, 170.51, 'apple')
setattr(C, 'hoge', lambda self: int(self.weight))
print(x.hoge())
help(x)

スーパークラスからの継承

クラス名: C

属性名: qty、weight、name

クラス名: E

属性名: qty、weight、name、price

クラスEは、スーパークラスであるクラスCの属性とメソッドを継承する。

class C(object):
    def __init__(self, qty, weight, name):
        self.qty = qty
        self.weight = weight
        self.name = name
    def total(self):
        return self.qty * self.weight

class E(C):
    def __init__(self, qty, weight, name, price):
        super(E, self).__init__(qty, weight, name)
        self.price = price
    def payment(self):
        return self.qty * self.price

x2 = E(2, 875.34, 'melon', 500)
print(vars(x2))
print(x2.total())
print(x2.payment())

ファイルの選択

ファイルダイアログ(tkinterを使用)

次のPythonプログラムは、tkinterのfiledialogを使用し、ファイルを選択するためのダイアログを表示する。

import tkinter as tk
from tkinter import filedialog

root = tk.Tk()
root.withdraw()
fpath = filedialog.askopenfilename()
print("Selected file: ", fpath)

このプログラムを実行すると、ファイルダイアログが表示され、選択したファイルのパスが表示される。

ファイルダイアログの起動画面
ファイルダイアログでファイルを選択した画面

次のPythonプログラムは、tkinterのfiledialogを使用し、複数のファイルを選択するためのダイアログを表示する。

import tkinter as tk
from tkinter import filedialog

root = tk.Tk()
root.withdraw()
fpaths = filedialog.askopenfilenames()

for fpath in root.tk.splitlist(fpaths):
    print("Selected file: ", fpath)

ファイルを1つ選択(pysimpleguiを使用)

次のプログラムは、PNGファイルを1つ選び、myinput.pngというファイル名にコピーする。

「python -m pip install -U pysimplegui」でインストールを行っておく。

import PySimpleGUI as sg
import shutil
layout = [
          [sg.Text('png file', size=(8, 1)), sg.Input(), sg.FileBrowse()],
          [sg.Submit(), sg.Cancel()]]
window = sg.Window('PNG File Upload', layout)
event, values = window.read()
window.close()
shutil.copyfile(values[0], "myinput.png")

ファイルを複数選択(gooeyを使用)

次のプログラムは、ファイルを複数選択し、選択されたファイル名を表示する。

「python -m pip install -U gooey」でインストールを行っておく。

from gooey import Gooey, GooeyParser

@Gooey(required_cols=0)
def main():
    parser = GooeyParser(description='Process something.')

    parser.add_argument('-i', '--infiles', nargs='*', metavar='InFiles', help='Choose one file or more-than-on files!', widget="MultiFileChooser")
    parser.add_argument('-n', '--name', metavar='Name', help='Enter some text!')
    parser.add_argument('-f', '--foo', metavar='Flag 1', action='store_true', help='I turn things on and off')
    parser.add_argument('-b', '--bar', metavar='Flag 2', action='store_true', help='I turn things on and off')

    a = parser.parse_args()
    print(a.infiles)
    print(a.name)
    print(a.foo)
    print(a.bar)

if __name__ == '__main__':
    main()
gooeyによるファイル選択画面
gooeyで複数ファイルを選択した画面

画像ファイルの表示、画像ファイルのサイズの取得

PILのshowを使用して画像ファイルを表示する。

from PIL import Image
Image.open('1.png').show()

MatplotLibを使用して画像ファイルを表示する。

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img = mpimg.imread('1.png')
plt.imshow(img)
plt.show()

PILを使用して画像のサイズを取得する。

from PIL import Image

width, height = Image.open(image_path).size
print(width, height)

ply ファイルの表示

次のプログラムは,ファイルダイヤログにより ply ファイルを1つ選択ののち,表示を行うプログラムである.マウスの左クリックとマウス移動により回転できる.マウスホイールにより,前後移動する.

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from plyfile import PlyData, PlyElement

# PLYファイルを読み込む
import tkinter as tk
from tkinter import filedialog

root = tk.Tk()
root.withdraw()
fpath = filedialog.askopenfilename()

plydata = PlyData.read(fpath)
vertex_data = plydata['vertex'].data
face_data = plydata['face'].data

# 頂点と面をリストとして取得
vertices = [list(elem) for elem in vertex_data]
faces = [face[0] for face in face_data]

# PygameとOpenGLを初期化
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)
glTranslatef(0.0, 0.0, -5)

# マウス操作のための変数
rotation_enabled = False
rotation_start = (0, 0)
zoom = 0.0

# メインループ
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左クリック
                rotation_enabled = True
                rotation_start = pygame.mouse.get_pos()
            elif event.button == 4:  # ホイール回転(上方向)
                zoom = 1
            elif event.button == 5:  # ホイール回転(下方向)
                zoom = -1
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:  # 左クリック解除
                rotation_enabled = False
        elif event.type == pygame.MOUSEMOTION:
            if rotation_enabled:
                dx = event.pos[0] - rotation_start[0]
                dy = event.pos[1] - rotation_start[1]
                glRotatef(dx, 0, 1, 0)  # y軸周りに回転
                glRotatef(dy, 1, 0, 0)  # x軸周りに回転
                rotation_start = event.pos

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    # 視点の移動範囲を制限
    max_zoom = 5.0
    min_zoom = -5.0
    zoom = max(min_zoom, min(max_zoom, zoom))
    glTranslatef(0.0, 0.0, -zoom)
    zoom = 0

    glBegin(GL_TRIANGLES)
    for face in faces:
        for vertex_i in face:
            glVertex3fv(vertices[vertex_i][:3])
    glEnd()

    pygame.display.flip()
    pygame.time.wait(10)

行列計算の基礎と実装

行列計算の基礎と実装について,NumPyライブラリを中心に解説する.行列の積,LU分解,逆行列,行列式,畳み込みなどの基本的な行列演算について,説明とPythonによる実装例を示している.主成分分析(PCA)や因子分析などの応用的な統計解析手法についても,説明と実装例を示している.

行列計算の基礎と実装

Pythonの NumPyライブラリを使用することで,効率的な行列計算を実行できる.

1. 行列の積

NumPyでは@演算子またはnp.dot()関数を使用する.内部では高度に最適化されたBLAS(Basic Linear Algebra Subprograms:基本線形代数サブプログラム)が使用され,高速な演算が実現される.

import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = A @ B  # または C = np.dot(A, B)

2. LU分解

LU分解は行列Aを下三角行列(L)と上三角行列(U)の積に分解する数値計算手法である.実装では,数値安定性を高めるため,置換行列(P)も含めてA = PLUの形で分解される.

LU分解が連立方程式Ax = bを解くのに有用な理由は以下の通りである.

  • 分解は一度だけ実行すればよく,計算効率が高い
  • 異なるbに対する解を効率的に計算でき,繰り返し計算に適している
  • 行列の階数や行列式の計算が容易になり,行列の性質を解析できる

scipy.linalgモジュールのlu()関数を使用することで,LU分解を数値的に安定かつ効率的に計算できる.

3. 逆行列

逆行列A⁻¹は,元の行列との積が単位行列となる行列である.線形変換の逆変換を表現する重要な概念である.

逆行列は行列式が0でない場合(正則行列の場合)にのみ存在する.実用的な計算では,数値安定性を考慮して逆行列の直接計算を避けることが推奨される.

4. 行列式

行列式には以下の重要な用途がある.

  • 行列が正則であるかの判定(行列式が0でないとき正則)
  • 連立方程式が一意解を持つかの判定

5. 畳み込み

畳み込みは,信号処理や画像処理において基礎となる重要な演算である.特徴抽出やフィルタリングに広く活用される.

scipy.signal.convolve2d()関数のmodeパラメータには以下の選択肢があり,用途に応じて適切に選択する.

  • 'full':出力は入力よりも大きくなる(完全な畳み込み)
  • 'same':出力は入力と同じサイズ(中央部分を取り出す)
  • 'valid':カーネルが完全に重なる部分のみを計算
import numpy as np
from scipy import linalg
from scipy import signal

def matrix_operations_demo():
    """行列計算の基本操作"""
    # 1. 行列の積
    print("1. 行列の積の計算")
    A = np.array([[1, 2], [3, 4]])
    B = np.array([[5, 6], [7, 8]])
    C = A @ B  # または np.dot(A, B)
    print("行列A:\n", A)
    print("行列B:\n", B)
    print("A×B:\n", C)

    # 2. LU分解
    print("\n2. LU分解")
    # 3×3の行列を作成
    A = np.array([[2, -1, 1],
                  [4, 1, -1],
                  [1, 1, 1]])
    P, L, U = linalg.lu(A)
    print("元の行列A:\n", A)
    print("置換行列P:\n", P)
    print("下三角行列L:\n", L)
    print("上三角行列U:\n", U)
    # LU分解の検証
    print("P^T×L×U:\n", P.T @ (L @ U))
    print("元の行列との誤差:", np.max(np.abs(A - P.T @ (L @ U))))

    # LU分解を使用した連立方程式の解法
    b = np.array([1, 2, 3])
    x = linalg.lu_solve(linalg.lu_factor(A), b)
    print("連立方程式Ax = bの解:", x)
    print("残差 ||Ax - b||:", np.linalg.norm(A @ x - b))

    # 3. 逆行列
    print("\n3. 逆行列")
    A = np.array([[4, 7], [2, 6]])
    try:
        A_inv = np.linalg.inv(A)
        print("行列A:\n", A)
        print("逆行列:\n", A_inv)
        # 検証.A×A^(-1) = I
        print("A×A^(-1):\n", A @ A_inv)
        print("逆行列の精度:", np.max(np.abs(A @ A_inv - np.eye(2))))
    except np.linalg.LinAlgError:
        print("逆行列が存在しません")

    # 4. 行列式
    print("\n4. 行列式")
    det_A = np.linalg.det(A)
    print("行列A:\n", A)
    print("行列式:", det_A)

    # 5. 畳み込み積分
    print("\n5. 畳み込み積分")
    # 2D配列(画像を想定)
    image = np.array([[1, 2, 3, 4],
                      [5, 6, 7, 8],
                      [9, 10, 11, 12],
                      [13, 14, 15, 16]])
    # カーネル(エッジ検出フィルタ)
    kernel = np.array([[-1, -1, -1],
                      [-1,  8, -1],
                      [-1, -1, -1]])
    # 異なるモードでの畳み込み演算
    modes = ['full', 'same', 'valid']
    for mode in modes:
        conv_result = signal.convolve2d(image, kernel, mode=mode)
        print(f"\n畳み込み結果(mode='{mode}'):\n", conv_result)
        print(f"出力サイズ: {conv_result.shape}")

if __name__ == "__main__":
    matrix_operations_demo()

このコードを実行するには,次のコマンドで必要なライブラリをインストールする.

pip install numpy scipy

1. 主成分分析(PCA)

主成分分析は,データの分散が最大となる軸を算出し,効率的な次元削減を実現する統計的手法である.この手法は,高次元データの可視化や重要な特徴量の抽出において広く活用されている.

scikit-learn(機械学習ライブラリ)のPCAクラスを使用することで,データの標準化から主成分の抽出まで一貫して実行できる.explained_variance_ratio_属性により,各主成分の寄与率を定量的に評価できる.

import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

def pca_analysis():
    """主成分分析のデモンストレーション"""

    # サンプルデータの生成
    np.random.seed(42)
    n_samples = 1000
    n_features = 5

    # 相関のあるデータを生成
    cov = np.array([[1, .7, .5, .3, .1],
                    [.7, 1, .4, .2, .1],
                    [.5, .4, 1, .4, .2],
                    [.3, .2, .4, 1, .3],
                    [.1, .1, .2, .3, 1]])
    X = np.random.multivariate_normal(mean=np.zeros(n_features), cov=cov, size=n_samples)

    # データの標準化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # PCAの実行
    pca = PCA()
    X_pca = pca.fit_transform(X_scaled)

    # 結果の表示
    print("各主成分の寄与率:")
    for i, ratio in enumerate(pca.explained_variance_ratio_, 1):
        print(f"第{i}主成分: {ratio:.4f}")

    print("\n累積寄与率:")
    cumsum = np.cumsum(pca.explained_variance_ratio_)
    for i, ratio in enumerate(cumsum, 1):
        print(f"第{i}主成分まで: {ratio:.4f}")

    print("\n主成分負荷量:")
    for i, loadings in enumerate(pca.components_, 1):
        print(f"\n第{i}主成分:")
        for j, loading in enumerate(loadings):
            print(f"変数{j+1}: {loading:.4f}")

    # 可視化
    plt.figure(figsize=(10, 4))

    # スクリープロット
    plt.subplot(121)
    plt.plot(range(1, len(pca.explained_variance_ratio_) + 1),
             pca.explained_variance_ratio_, 'o-')
    plt.xlabel('主成分番号')
    plt.ylabel('寄与率')
    plt.title('スクリープロット')

    # 第1・第2主成分でのデータ分布
    plt.subplot(122)
    plt.scatter(X_pca[:, 0], X_pca[:, 1], alpha=0.5)
    plt.xlabel('第1主成分')
    plt.ylabel('第2主成分')
    plt.title('主成分空間でのデータ分布')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    pca_analysis()

2. 因子分析

因子分析は,観測変数の背後にある潜在的な共通因子を抽出する統計的手法である.心理学や社会科学の分野(例:質問紙調査データの解析)で広く活用されている.

scikit-learnのFactorAnalysisクラスでは,最尤法(さいゆうほう)による因子分析を実行できる.

import numpy as np
from sklearn.decomposition import FactorAnalysis
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

def factor_analysis():
    """因子分析のデモンストレーション"""

    # サンプルデータの生成(質問紙調査を想定)
    np.random.seed(42)
    n_samples = 500

    # 2つの潜在因子を仮定
    true_factors = np.random.normal(0, 1, (n_samples, 2))

    # 観測変数を生成(6つの質問項目を想定)
    loadings = np.array([[0.8, 0.2],
                        [0.7, 0.1],
                        [0.6, 0.3],
                        [0.2, 0.8],
                        [0.1, 0.7],
                        [0.3, 0.6]])

    X = true_factors @ loadings.T + np.random.normal(0, 0.1, (n_samples, 6))

    # データの標準化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # 因子分析の実行
    fa = FactorAnalysis(n_components=2, random_state=42)
    X_fa = fa.fit_transform(X_scaled)

    # 結果の表示
    print("因子負荷量:")
    for i, loadings in enumerate(fa.components_.T, 1):
        print(f"\n観測変数{i}:")
        for j, loading in enumerate(loadings, 1):
            print(f"因子{j}: {loading:.4f}")

    # 共通性の計算
    communalities = np.sum(fa.components_**2, axis=0)
    print("\n共通性:")
    for i, comm in enumerate(communalities, 1):
        print(f"観測変数{i}: {comm:.4f}")

    # 因子間相関の計算
    factor_corr = np.corrcoef(X_fa.T)
    print("\n因子間相関:")
    print(factor_corr)

    # 可視化
    plt.figure(figsize=(10, 4))

    # 因子負荷量のプロット
    plt.subplot(121)
    plt.scatter(fa.components_[0], fa.components_[1])
    for i, (x, y) in enumerate(zip(fa.components_[0], fa.components_[1]), 1):
        plt.annotate(f'Var{i}', (x, y))
    plt.xlabel('第1因子')
    plt.ylabel('第2因子')
    plt.title('因子負荷量プロット')
    plt.grid(True)

    # 因子得点の分布
    plt.subplot(122)
    plt.scatter(X_fa[:, 0], X_fa[:, 1], alpha=0.5)
    plt.xlabel('第1因子得点')
    plt.ylabel('第2因子得点')
    plt.title('因子得点の分布')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    factor_analysis()

3. 線形判別分析(LDA)

線形判別分析は,教師あり学習における次元削減手法である.クラス間の分散を最大化し,クラス内の分散を最小化する軸を見つけることで,特徴抽出を実現する.

2クラス問題では1つの判別軸,k個のクラスではk-1個の判別軸が得られる.


import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

def lda_analysis():
    """線形判別分析のデモンストレーション"""

    # サンプルデータの生成(3クラス)
    np.random.seed(42)
    n_samples = 300
    n_features = 4

    # 各クラスのデータを生成
    class1 = np.random.multivariate_normal(
        mean=[-2, -2, -2, -2],
        cov=np.eye(4),
        size=n_samples
    )
    class2 = np.random.multivariate_normal(
        mean=[0, 0, 0, 0],
        cov=np.eye(4),
        size=n_samples
    )
    class3 = np.random.multivariate_normal(
        mean=[2, 2, 2, 2],
        cov=np.eye(4),
        size=n_samples
    )

    # データの結合
    X = np.vstack([class1, class2, class3])
    y = np.hstack([np.zeros(n_samples),
                   np.ones(n_samples),
                   np.full(n_samples, 2)])

    # データの標準化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # LDAの実行
    lda = LinearDiscriminantAnalysis()
    X_lda = lda.fit_transform(X_scaled, y)

    # 結果の表示
    print("判別係数:")
    for i, coef in enumerate(lda.coef_, 1):
        print(f"\n判別関数{i}:")
        for j, c in enumerate(coef, 1):
            print(f"変数{j}: {c:.4f}")

    print("\nクラス間正答率:", lda.score(X_scaled, y))

    print("\n各判別関数の寄与率:")
    explained_ratios = lda.explained_variance_ratio_
    for i, ratio in enumerate(explained_ratios, 1):
        print(f"判別関数{i}: {ratio:.4f}")

    # 可視化
    plt.figure(figsize=(12, 4))

    # 第1・第2判別関数でのデータ分布
    plt.subplot(121)
    scatter = plt.scatter(X_lda[:, 0], X_lda[:, 1], c=y, cmap='viridis')
    plt.xlabel('第1判別関数')
    plt.ylabel('第2判別関数')
    plt.title('判別空間でのデータ分布')
    plt.colorbar(scatter)

    # 判別関数の寄与率
    plt.subplot(122)
    plt.bar(range(1, len(explained_ratios) + 1), explained_ratios)
    plt.xlabel('判別関数')
    plt.ylabel('寄与率')
    plt.title('判別関数の寄与率')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    lda_analysis()

4. クラスタリング

クラスタリングは,データを類似度に基づいてグループ化する教師なし学習手法である.代表的な手法として,k-means法と階層的クラスタリングがある.

k-means法は,クラスタ数を事前に指定する必要がある.階層的クラスタリングは,デンドログラムによりデータの階層構造を視覚的に把握できる.


import numpy as np
from sklearn.cluster import KMeans, AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt

def clustering_analysis():
    """クラスタリング分析のデモンストレーション"""

    # サンプルデータの生成(3つの自然なクラスタ)
    np.random.seed(42)
    n_samples_per_cluster = 100

    # クラスタ1: 左下のグループ
    cluster1 = np.random.normal(loc=[-2, -2], scale=0.3,
                               size=(n_samples_per_cluster, 2))

    # クラスタ2: 右下のグループ
    cluster2 = np.random.normal(loc=[2, -2], scale=0.3,
                               size=(n_samples_per_cluster, 2))

    # クラスタ3: 上部中央のグループ
    cluster3 = np.random.normal(loc=[0, 2], scale=0.3,
                               size=(n_samples_per_cluster, 2))

    # データの結合
    X = np.vstack([cluster1, cluster2, cluster3])

    # データの標準化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # k-meansクラスタリング
    kmeans = KMeans(n_clusters=3, random_state=42)
    kmeans_labels = kmeans.fit_predict(X_scaled)

    # 階層的クラスタリング
    hc = AgglomerativeClustering(n_clusters=3)
    hc_labels = hc.fit_predict(X_scaled)

    # 結果の表示
    print("K-means クラスタリング結果:")
    print("クラスタ中心:\n", scaler.inverse_transform(kmeans.cluster_centers_))
    print("各クラスタのサンプル数:", np.bincount(kmeans_labels))

    print("\n階層的クラスタリング結果:")
    print("各クラスタのサンプル数:", np.bincount(hc_labels))

    # 可視化
    plt.figure(figsize=(15, 5))

    # オリジナルデータ
    plt.subplot(131)
    X_orig = scaler.inverse_transform(X_scaled)
    plt.scatter(X_orig[:, 0], X_orig[:, 1], c='gray', alpha=0.5)
    plt.title('オリジナルデータ')
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')

    # k-meansの結果
    plt.subplot(132)
    scatter = plt.scatter(X_orig[:, 0], X_orig[:, 1],
                         c=kmeans_labels, cmap='viridis')
    centers = scaler.inverse_transform(kmeans.cluster_centers_)
    plt.scatter(centers[:, 0], centers[:, 1], c='red',
                marker='x', s=200, linewidths=3)
    plt.title('K-means クラスタリング結果')
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')
    plt.colorbar(scatter)

    # デンドログラム
    plt.subplot(133)
    linkage_matrix = linkage(X_scaled, method='ward')
    dendrogram(linkage_matrix)
    plt.title('階層的クラスタリング デンドログラム')
    plt.xlabel('サンプル番号')
    plt.ylabel('距離')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    clustering_analysis()


5. 特異値分解(SVD)

特異値分解は,行列を3つの行列(U,Σ,V^T)の積に分解する手法である.この分解により,データ圧縮や潜在的意味解析(LSA)などの分析が可能となる.

特異値の大きさは,各成分の重要度を示す指標である.小さい特異値を無視することで,データの次元削減が実現できる.


import numpy as np
import matplotlib.pyplot as plt

def svd_analysis():
    """特異値分解のデモンストレーション"""

    # サンプルデータの生成(ランク3の行列 + ノイズ)
    np.random.seed(42)
    n_rows, n_cols = 100, 50

    # ランク3の行列を生成
    U_true = np.random.normal(0, 1, (n_rows, 3))
    V_true = np.random.normal(0, 1, (n_cols, 3))
    singular_values_true = np.array([10, 5, 2])

    X = U_true @ np.diag(singular_values_true) @ V_true.T

    # ノイズを追加
    X_noisy = X + np.random.normal(0, 0.1, (n_rows, n_cols))

    # SVDの実行
    U, s, Vt = np.linalg.svd(X_noisy, full_matrices=False)

    # 結果の表示
    print("特異値:")
    for i, value in enumerate(s, 1):
        print(f"σ_{i}: {value:.4f}")

    # 低ランク近似の誤差を計算
    errors = []
    ranks = range(1, min(n_rows, n_cols) + 1)

    for r in ranks:
        # ランクrでの近似
        X_approx = U[:, :r] @ np.diag(s[:r]) @ Vt[:r, :]
        # フロベニウスノルムでの誤差
        error = np.linalg.norm(X_noisy - X_approx, 'fro')
        errors.append(error)

    # 可視化
    plt.figure(figsize=(12, 4))

    # 特異値のプロット
    plt.subplot(131)
    plt.plot(range(1, len(s) + 1), s, 'o-')
    plt.yscale('log')
    plt.xlabel('成分番号')
    plt.ylabel('特異値')
    plt.title('特異値のスケープロット')

    # 累積寄与率
    plt.subplot(132)
    cumulative_variance = np.cumsum(s**2) / np.sum(s**2)
    plt.plot(range(1, len(s) + 1), cumulative_variance, 'o-')
    plt.xlabel('成分数')
    plt.ylabel('累積寄与率')
    plt.title('累積寄与率')

    # 近似誤差
    plt.subplot(133)
    plt.plot(ranks, errors, 'o-')
    plt.xlabel('使用する特異値の数')
    plt.ylabel('近似誤差')
    plt.title('低ランク近似の誤差')

    plt.tight_layout()
    plt.show()

    # 画像の再構成例
    plt.figure(figsize=(15, 5))
    ranks_demo = [1, 5, 20]  # デモ用のランク

    plt.subplot(141)
    plt.imshow(X_noisy, cmap='coolwarm')
    plt.title('オリジナルデータ')
    plt.colorbar()

    for i, r in enumerate(ranks_demo, 1):
        X_approx = U[:, :r] @ np.diag(s[:r]) @ Vt[:r, :]
        plt.subplot(1, 4, i+1)
        plt.imshow(X_approx, cmap='coolwarm')
        plt.title(f'ランク{r}での近似')
        plt.colorbar()

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    svd_analysis()

6. QR分解

QR分解は,行列を直交行列Q(Q^T Q = I)と上三角行列Rの積に分解する手法である.この手法は,最小二乗法や固有値計算において重要な役割を持つ.

QR分解は,Gram-Schmidt直交化法を実装したものとして解釈できるという考え方がある.連立方程式の解法や固有値計算のQR法における基礎となる.

import numpy as np
import matplotlib.pyplot as plt
def qr_analysis():
    """QR分解のデモンストレーション"""
    # サンプルデータの生成
    np.random.seed(42)
    n_rows, n_cols = 5, 3  # 長方形行列
    A = np.random.randn(n_rows, n_cols)
    # QR分解の実行(numpyの実装)
    Q, R = np.linalg.qr(A)
    # Gram-Schmidt過程の実装(教育用)
    def gram_schmidt(A):
        m, n = A.shape
        Q = np.zeros((m, n))
        R = np.zeros((n, n))
        for j in range(n):
            v = A[:, j]
            for i in range(j):
                R[i, j] = Q[:, i].T @ A[:, j]
                v = v - R[i, j] * Q[:, i]
            R[j, j] = np.linalg.norm(v)
            Q[:, j] = v / R[j, j]
        return Q, R
    Q_gs, R_gs = gram_schmidt(A)
    # 結果の表示
    print("元の行列 A:")
    print(A)
    print("\nNumPyによるQR分解")
    print("Q行列(直交行列):")
    print(Q)
    print("\nR行列(上三角行列):")
    print(R)
    # 検証
    print("\n検証結果:")
    print("Q^T Q ≈ I:")
    print(np.round(Q.T @ Q, decimals=10))
    print("\nQR ≈ A(再構成誤差):")
    print(np.linalg.norm(A - Q @ R))
    # Gram-Schmidt実装との比較
    print("\nGram-Schmidt実装との差:")
    print("Q の差のノルム:", np.linalg.norm(abs(Q) - abs(Q_gs)))
    print("R の差のノルム:", np.linalg.norm(abs(R) - abs(R_gs)))
    # 可視化
    plt.figure(figsize=(15, 5))
    # 元の行列の可視化
    plt.subplot(131)
    plt.imshow(A, cmap='coolwarm')
    plt.title('元の行列 A')
    plt.colorbar()
    # Q行列の可視化
    plt.subplot(132)
    plt.imshow(Q, cmap='coolwarm')
    plt.title('直交行列 Q')
    plt.colorbar()
    # R行列の可視化
    plt.subplot(133)
    plt.imshow(R, cmap='coolwarm')
    plt.title('上三角行列 R')
    plt.colorbar()
    plt.tight_layout()
    plt.show()
    # Q の列ベクトルの直交性を示す散布図
    if n_cols >= 2:  # 2列以上ある場合のみ
        plt.figure(figsize=(6, 6))
        plt.scatter(Q[:, 0], Q[:, 1], c='b', label='Q の列1 vs 列2')
        # 原点から各ベクトルへの線を描画
        for i in range(2):
            plt.arrow(0, 0, Q[0, i], Q[1, i],
                     head_width=0.05, head_length=0.1,
                     fc='b', ec='b', alpha=0.5)
        plt.axis('equal')
        plt.grid(True)
        plt.title('Q の列ベクトルの直交性')
        plt.xlabel('第1列ベクトル')
        plt.ylabel('第2列ベクトル')
        plt.legend()
        plt.show()
def qr_applications():
    """QR分解の応用例:最小二乗法による線形回帰"""
    # サンプルデータの生成
    np.random.seed(42)
    n_samples = 100
    # 真の関係: y = 2x + 1 + ノイズ
    X = np.random.uniform(0, 10, n_samples)
    y = 2 * X + 1 + np.random.normal(0, 1, n_samples)
    # 設計行列の作成
    A = np.vstack([X, np.ones(n_samples)]).T
    # QR分解を使用した最小二乗法
    Q, R = np.linalg.qr(A)
    beta = np.linalg.solve(R, Q.T @ y)
    # 結果の表示
    print("\n最小二乗法の結果:")
    print(f"推定された傾き: {beta[0]:.4f}")
    print(f"推定された切片: {beta[1]:.4f}")
    # 結果の可視化
    plt.figure(figsize=(8, 6))
    plt.scatter(X, y, alpha=0.5, label='データ点')
    X_sort = np.sort(X)
    plt.plot(X_sort, beta[0] * X_sort + beta[1], 'r-',
             label='QR分解による回帰直線')
    plt.plot(X_sort, 2 * X_sort + 1, 'g--',
             label='真の関係')
    plt.xlabel('X')
    plt.ylabel('y')
    plt.title('QR分解を用いた線形回帰')
    plt.legend()
    plt.grid(True)
    plt.show()
if __name__ == "__main__":
    qr_analysis()
    qr_applications()
このコードでは,以下の機能を提供している:
  • NumPyによるQR分解の実行と,教育目的のGram-Schmidt過程の実装
  • 分解結果の視覚化と直交性の検証
  • QR分解の応用例として線形回帰問題の解法を実装

特に以下の点に注意が必要である:

  • 数値的安定性を確保するため,実装にはNumPyのQR分解を使用することが推奨される
  • 直交性の検証では,数値誤差を考慮して適切な閾値を設定する必要がある
  • 応用例では,QR分解を連立方程式の安定的な解法として活用している
コードを実行するには,以下のライブラリが必要である:
pip install numpy matplotlib

音声信号処理の基礎と実装

音声信号処理の基礎と実装について,Python のscipy,librosa,sounddeviceライブラリを用いた処理方法を示している.WAVファイルの入出力,スペクトログラム生成,基本周波数推定,フォルマント分析,環境音解析まで,説明とプロぐr舞うを示している.環境音解析については,スペクトル特徴量,時間領域特徴量,リズム特徴量などの複数の分析手法を提示している.

1. 音声ファイルの入出力

WAVファイルの読み込み,情報表示,書き出しを行う.scipyのwavfileモジュールやlibrosaを使用する.

サンプリング周波数やビット深度などの音声パラメータも合わせて行う.


import numpy as np
from scipy.io import wavfile
import librosa
import sounddevice as sd
import matplotlib.pyplot as plt

def audio_file_handling():
    """音声ファイルの入出力と情報表示のデモンストレーション"""

    # WAVファイルの読み込み(scipyを使用)
    def read_wav_scipy(filename):
        """scipyによるWAVファイル読み込み"""
        sampling_rate, data = wavfile.read(filename)
        print("=== Scipyでの読み込み結果 ===")
        print(f"サンプリング周波数: {sampling_rate} Hz")
        print(f"チャンネル数: {data.shape[1] if len(data.shape) > 1 else 1}")
        print(f"サンプル数: {len(data)}")
        print(f"時間長: {len(data)/sampling_rate:.2f} 秒")
        return sampling_rate, data

    # WAVファイルの読み込み(librosaを使用)
    def read_wav_librosa(filename):
        """librosaによるWAVファイル読み込み"""
        data, sampling_rate = librosa.load(filename, sr=None)
        print("\n=== Librosaでの読み込み結果 ===")
        print(f"サンプリング周波数: {sampling_rate} Hz")
        print(f"チャンネル数: {data.shape[1] if len(data.shape) > 1 else 1}")
        print(f"サンプル数: {len(data)}")
        print(f"時間長: {len(data)/sampling_rate:.2f} 秒")
        return sampling_rate, data

    # WAVファイルの書き出し
    def write_wav(filename, sampling_rate, data):
        """WAVファイルの書き出し"""
        normalized_data = np.clip(data, -1.0, 1.0)
        int_data = (normalized_data * 32767).astype(np.int16)
        wavfile.write(filename, sampling_rate, int_data)

    # 音声の再生
    def play_audio(data, sampling_rate):
        """音声データの再生"""
        sd.play(data, sampling_rate)
        sd.wait()  # 再生終了まで待機

    # テスト用の音声信号生成(1秒のサイン波)
    def generate_test_signal():
        """テスト用の音声信号生成"""
        duration = 1.0  # 1秒
        sampling_rate = 44100  # 44.1kHz
        t = np.linspace(0, duration, int(sampling_rate * duration))
        signal = 0.5 * np.sin(2 * np.pi * 440 * t)
        return sampling_rate, signal

    # メイン処理
    try:
        # テスト信号の生成と保存
        sampling_rate, test_signal = generate_test_signal()
        write_wav("test_signal.wav", sampling_rate, test_signal)

        # 保存した音声ファイルの読み込みと情報表示
        sr_scipy, data_scipy = read_wav_scipy("test_signal.wav")
        sr_librosa, data_librosa = read_wav_librosa("test_signal.wav")

        # 波形プロット
        plt.figure(figsize=(12, 4))
        time = np.arange(len(test_signal)) / sampling_rate
        plt.plot(time, test_signal)
        plt.xlabel('時間 [秒]')
        plt.ylabel('振幅')
        plt.title('テスト信号の波形')
        plt.grid(True)
        plt.show()

        # 音声の再生
        print("\n音声を再生します...")
        play_audio(test_signal, sampling_rate)

    except Exception as e:
        print(f"エラーが発生しました: {e}")

if __name__ == "__main__":
    audio_file_handling()

2. スペクトログラムの生成と表示

スペクトログラムは,音声信号の時間-周波数表現である.短時間フーリエ変換(STFT)を用いて算出する.

窓関数の選択やフレーム長,オーバーラップ率などのパラメータが結果のスペクトログラムに影響を与える.


import numpy as np
from scipy import signal
import librosa
import librosa.display
import matplotlib.pyplot as plt

def spectrogram_analysis():
    """スペクトログラム分析のデモンストレーション"""

    # テスト信号の生成(周波数が時間とともに変化する信号)
    def generate_chirp_signal():
        """チャープ信号の生成"""
        duration = 3.0  # 3秒
        sampling_rate = 44100  # 44.1kHz
        t = np.linspace(0, duration, int(sampling_rate * duration))
        # 周波数が100Hzから4000Hzまで指数的に変化
        chirp = signal.chirp(t, f0=100, f1=4000, t1=duration, method='exponential')
        return sampling_rate, chirp

    # STFTによるスペクトログラム計算(scipy使用)
    def calculate_spectrogram_scipy(audio_data, sampling_rate):
        """Scipyを使用したスペクトログラム計算"""
        nperseg = 2048  # フレーム長
        noverlap = nperseg // 2  # オーバーラップ

        frequencies, times, Sxx = signal.spectrogram(
            audio_data,
            fs=sampling_rate,
            window='hann',
            nperseg=nperseg,
            noverlap=noverlap,
            scaling='spectrum'
        )
        return frequencies, times, 10 * np.log10(Sxx + 1e-10)

    # STFTによるスペクトログラム計算(librosa使用)
    def calculate_spectrogram_librosa(audio_data, sampling_rate):
        """Librosaを使用したスペクトログラム計算"""
        n_fft = 2048  # FFTサイズ
        hop_length = n_fft // 2  # ホップ長

        D = librosa.stft(audio_data, n_fft=n_fft, hop_length=hop_length,
                        window='hann', center=True)
        S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
        return S_db

    # メイン処理
    sampling_rate, chirp = generate_chirp_signal()

    # Scipyによるスペクトログラム
    freqs, times, spec_scipy = calculate_spectrogram_scipy(chirp, sampling_rate)

    # Librosaによるスペクトログラム
    spec_librosa = calculate_spectrogram_librosa(chirp, sampling_rate)

    # 結果の可視化
    plt.figure(figsize=(15, 10))

    # 波形
    plt.subplot(3, 1, 1)
    time = np.arange(len(chirp)) / sampling_rate
    plt.plot(time, chirp)
    plt.xlabel('時間 [秒]')
    plt.ylabel('振幅')
    plt.title('チャープ信号の波形')
    plt.grid(True)

    # Scipyによるスペクトログラム
    plt.subplot(3, 1, 2)
    plt.pcolormesh(times, freqs, spec_scipy, shading='gouraud')
    plt.ylabel('周波数 [Hz]')
    plt.xlabel('時間 [秒]')
    plt.title('Scipyによるスペクトログラム')
    plt.colorbar(label='パワー [dB]')

    # Librosaによるスペクトログラム
    plt.subplot(3, 1, 3)
    librosa.display.specshow(spec_librosa, sr=sampling_rate, x_axis='time',
                           y_axis='hz', hop_length=1024)
    plt.ylabel('周波数 [Hz]')
    plt.xlabel('時間 [秒]')
    plt.title('Librosaによるスペクトログラム')
    plt.colorbar(label='振幅 [dB]')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    spectrogram_analysis()

3. 基本周波数(F0)推定

基本周波数は音声の高さを表す重要なパラメータである.自己相関法やケプストラム法など,様々な推定手法が存在する.

有声/無声の判定と,オクターブ誤りの処理が重要な課題である.


import numpy as np
import librosa
import matplotlib.pyplot as plt
from scipy.signal import correlate
from scipy.io import wavfile

def f0_estimation_demo():
    """基本周波数推定のデモンストレーション"""

    def generate_test_signal(f0=440, duration=1.0, sr=44100):
        """基本周波数を持つテスト信号の生成"""
        t = np.linspace(0, duration, int(sr * duration))
        # 基本波と倍音を含む信号
        signal = 0.5 * np.sin(2 * np.pi * f0 * t) + \
                0.25 * np.sin(2 * np.pi * 2 * f0 * t) + \
                0.125 * np.sin(2 * np.pi * 3 * f0 * t)
        return signal, sr

    def autocorrelation_f0(signal, sr, frame_length=2048, hop_length=512):
        """自己相関法によるF0推定"""
        f0_values = []
        times = []

        for i in range(0, len(signal) - frame_length, hop_length):
            frame = signal[i:i + frame_length]
            # 自己相関の計算
            corr = correlate(frame, frame, mode='full')
            corr = corr[len(corr)//2:]

            # 最初のピークを探す(直流成分を除く)
            peak_idx = np.argmax(corr[50:]) + 50
            if corr[peak_idx] > 0.1:  # 有声音の閾値
                f0 = sr / peak_idx
                if 50 <= f0 <= 2000:  # 有効なF0範囲
                    f0_values.append(f0)
                else:
                    f0_values.append(0)
            else:
                f0_values.append(0)

            times.append(i / sr)

        return np.array(f0_values), np.array(times)

    def librosa_f0(signal, sr):
        """librosaを使用したF0推定"""
        f0, voiced_flag, voiced_probs = librosa.pyin(
            signal,
            fmin=librosa.note_to_hz('C2'),
            fmax=librosa.note_to_hz('C7'),
            sr=sr
        )
        return f0, voiced_flag

    # テスト信号の生成と分析
    signal, sr = generate_test_signal(f0=440)

    # 自己相関法によるF0推定
    f0_autocorr, times_autocorr = autocorrelation_f0(signal, sr)

    # librosaによるF0推定
    f0_librosa, voiced_flag = librosa_f0(signal, sr)
    times_librosa = librosa.times_like(f0_librosa, sr=sr)

    # 結果の可視化
    plt.figure(figsize=(12, 8))

    # 波形
    plt.subplot(3, 1, 1)
    t = np.linspace(0, len(signal)/sr, len(signal))
    plt.plot(t, signal)
    plt.xlabel('時間 [秒]')
    plt.ylabel('振幅')
    plt.title('テスト信号の波形')
    plt.grid(True)

    # 自己相関法によるF0
    plt.subplot(3, 1, 2)
    plt.plot(times_autocorr, f0_autocorr, 'o-', label='推定F0')
    plt.axhline(y=440, color='r', linestyle='--', label='真のF0')
    plt.xlabel('時間 [秒]')
    plt.ylabel('周波数 [Hz]')
    plt.title('自己相関法によるF0推定結果')
    plt.legend()
    plt.grid(True)

    # librosaによるF0
    plt.subplot(3, 1, 3)
    plt.plot(times_librosa[voiced_flag], f0_librosa[voiced_flag],
             'o-', label='推定F0(有声区間)')
    plt.axhline(y=440, color='r', linestyle='--', label='真のF0')
    plt.xlabel('時間 [秒]')
    plt.ylabel('周波数 [Hz]')
    plt.title('PYIN(librosa)によるF0推定結果')
    plt.legend()
    plt.grid(True)

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    f0_estimation_demo()

4. フォルマント分析

フォルマントは,音声スペクトルの共鳴周波数であり,母音の特徴を表す重要なパラメータである.推定法としては,線形予測分析(LPC)がある.


import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

def formant_analysis():
    """フォルマント分析のデモンストレーション"""

    def generate_vowel(formants, duration=1.0, sr=16000):
        """フォルマントを持つ母音の生成"""
        t = np.linspace(0, duration, int(sr * duration))
        f0 = 130  # 基本周波数

        # 声帯波源(のこぎり波)
        source = signal.sawtooth(2 * np.pi * f0 * t)

        # フォルマントフィルタの作成
        vowel = np.zeros_like(t)
        for formant in formants:
            bw = formant * 0.1  # バンド幅
            w0 = 2 * np.pi * formant / sr
            r = np.exp(-np.pi * bw / sr)

            # 共鳴フィルタ
            a = [1, -2*r*np.cos(w0), r**2]
            b = [1]
            vowel += signal.lfilter(b, a, source)

        return vowel / np.max(np.abs(vowel)), sr

    def estimate_formants(signal, sr, order=12):
        """LPCによるフォルマント推定"""
        # LPC係数の計算
        a = librosa.lpc(signal, order=order)

        # 根を求める
        roots = np.roots(a)
        roots = roots[np.imag(roots) >= 0]  # 正の虚部を持つ根のみ

        # 角周波数から周波数へ変換
        angles = np.arctan2(np.imag(roots), np.real(roots))
        freqs = angles * (sr / (2 * np.pi))

        # バンド幅の計算
        bandwidth = -1/2 * (sr/(2*np.pi)) * np.log(np.abs(roots))

        # 周波数でソート
        sorted_idx = np.argsort(freqs)
        freqs = freqs[sorted_idx]
        bandwidth = bandwidth[sorted_idx]

        return freqs, bandwidth

    # 母音/a/のフォルマント
    formants_a = [730, 1090, 2440]
    # 母音/i/のフォルマント
    formants_i = [270, 2290, 3010]

    # 母音の生成
    vowel_a, sr = generate_vowel(formants_a)
    vowel_i, _ = generate_vowel(formants_i)

    # フォルマント推定
    freqs_a, bw_a = estimate_formants(vowel_a, sr)
    freqs_i, bw_i = estimate_formants(vowel_i, sr)

    # 結果の可視化
    plt.figure(figsize=(15, 10))

    # 母音/a/の波形とスペクトル
    plt.subplot(2, 2, 1)
    plt.plot(vowel_a)
    plt.title('母音/a/の波形')
    plt.xlabel('サンプル')
    plt.ylabel('振幅')

    plt.subplot(2, 2, 2)
    freq, spec = signal.welch(vowel_a, sr, nperseg=2048)
    plt.plot(freq, 10 * np.log10(spec))
    plt.vlines(freqs_a[:3], plt.ylim()[0], plt.ylim()[1],
              colors='r', linestyles='--', label='推定フォルマント')
    plt.vlines(formants_a, plt.ylim()[0], plt.ylim()[1],
              colors='g', linestyles=':', label='真のフォルマント')
    plt.title('母音/a/のスペクトル')
    plt.xlabel('周波数 [Hz]')
    plt.ylabel('パワー [dB]')
    plt.legend()

    # 母音/i/の波形とスペクトル
    plt.subplot(2, 2, 3)
    plt.plot(vowel_i)
    plt.title('母音/i/の波形')
    plt.xlabel('サンプル')
    plt.ylabel('振幅')

    plt.subplot(2, 2, 4)
    freq, spec = signal.welch(vowel_i, sr, nperseg=2048)
    plt.plot(freq, 10 * np.log10(spec))
    plt.vlines(freqs_i[:3], plt.ylim()[0], plt.ylim()[1],
              colors='r', linestyles='--', label='推定フォルマント')
    plt.vlines(formants_i, plt.ylim()[0], plt.ylim()[1],
              colors='g', linestyles=':', label='真のフォルマント')
    plt.title('母音/i/のスペクトル')
    plt.xlabel('周波数 [Hz]')
    plt.ylabel('パワー [dB]')
    plt.legend()

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    formant_analysis()

5. 環境音の解析

環境音の解析では,時間-周波数表現に加えて,音響的特徴量の抽出が重要である.特に,以下の特徴量が有用である.

環境音は非定常な性質を持つため,統計的な特徴量や変動パターンの分析が重要である.

import numpy as np
import librosa
import librosa.display
import scipy.stats
from scipy.signal import welch
import matplotlib.pyplot as plt
import warnings

def environmental_sound_analysis():
    """環境音の解析デモンストレーション"""

    def compute_spectral_features(y, sr, n_fft=2048, hop_length=512):
        """スペクトル特徴量の計算(エラー処理追加)"""
        # 無音区間の検出
        if np.all(y == 0):
            return {
                'centroid': np.zeros(1),
                'bandwidth': np.zeros(1),
                'rolloff': np.zeros(1),
                'flatness': np.zeros(1)
            }

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            # スペクトル重心
            spectral_centroid = librosa.feature.spectral_centroid(
                y=y, sr=sr, n_fft=n_fft, hop_length=hop_length
            )[0]

            # スペクトル帯域幅
            spectral_bandwidth = librosa.feature.spectral_bandwidth(
                y=y, sr=sr, n_fft=n_fft, hop_length=hop_length
            )[0]

            # スペクトルロールオフ
            spectral_rolloff = librosa.feature.spectral_rolloff(
                y=y, sr=sr, n_fft=n_fft, hop_length=hop_length
            )[0]

            # スペクトル平坦度
            spectral_flatness = librosa.feature.spectral_flatness(
                y=y, n_fft=n_fft, hop_length=hop_length
            )[0]

        return {
            'centroid': spectral_centroid,
            'bandwidth': spectral_bandwidth,
            'rolloff': spectral_rolloff,
            'flatness': spectral_flatness
        }

    def compute_temporal_features(y, sr, frame_length=2048, hop_length=512):
        """時間領域特徴量の計算(エラー処理追加)"""
        # 無音区間の検出
        if np.all(y == 0):
            return {
                'rms': np.zeros(1),
                'zcr': np.zeros(1),
                'crest_factor': 0,
                'kurtosis': 0
            }

        # RMSエネルギー
        rms = librosa.feature.rms(
            y=y, frame_length=frame_length, hop_length=hop_length
        )[0]

        # ゼロ交差率
        zero_crossing_rate = librosa.feature.zero_crossing_rate(
            y=y, frame_length=frame_length, hop_length=hop_length
        )[0]

        # 波形の統計量(ゼロ割り防止)
        rms_val = np.sqrt(np.mean(y**2)) + 1e-10
        crest_factor = np.max(np.abs(y)) / rms_val
        kurtosis = scipy.stats.kurtosis(y, fisher=True)

        return {
            'rms': rms,
            'zcr': zero_crossing_rate,
            'crest_factor': crest_factor,
            'kurtosis': kurtosis
        }

    def compute_rhythm_features(y, sr):
        """リズム特徴量の計算"""
        # テンポグラム
        onset_env = librosa.onset.onset_strength(y=y, sr=sr)
        tempogram = librosa.feature.tempogram(
            onset_envelope=onset_env,
            sr=sr
        )

        # オンセット検出
        onset_frames = librosa.onset.onset_detect(
            onset_envelope=onset_env,
            sr=sr
        )

        return {
            'tempogram': tempogram,
            'onset_frames': onset_frames
        }

    def analyze_noise_color(y, sr):
        """ノイズの色分析(パワースペクトル密度の傾き)"""
        freqs, psd = welch(y, sr, nperseg=2048)
        # 対数変換
        log_freqs = np.log10(freqs[1:])  # 0Hzを除外
        log_psd = np.log10(psd[1:])
        # 線形回帰で傾きを計算
        slope, _, _, _, _ = scipy.stats.linregress(log_freqs, log_psd)
        return slope, freqs[1:], psd[1:]

    # テスト信号として雨音をシミュレート
def simulate_rain(duration=5.0, sr=44100):
        """より現実的な雨音のシミュレーション"""
        t = np.linspace(0, duration, int(sr * duration))
        rain = np.zeros_like(t)

        # 雨滴の種類(大小)を考慮
        drop_types = {
            'small': {
                'freq_range': (2000, 4000),
                'duration_range': (0.01, 0.03),
                'amplitude_range': (0.1, 0.3)
            },
            'medium': {
                'freq_range': (1000, 2000),
                'duration_range': (0.03, 0.06),
                'amplitude_range': (0.3, 0.6)
            },
            'large': {
                'freq_range': (500, 1000),
                'duration_range': (0.06, 0.1),
                'amplitude_range': (0.6, 1.0)
            }
        }

        # 各種類の雨滴を生成
        for drop_type, params in drop_types.items():
            # 雨滴の数(ポアソン分布に従う)
            n_drops = np.random.poisson(duration *
                     (100 if drop_type == 'small' else
                      50 if drop_type == 'medium' else 20))

            for _ in range(n_drops):
                # 雨滴の時刻
                t_drop = np.random.random() * duration
                idx = int(t_drop * sr)

                # 雨滴のパラメータ
                freq = np.random.uniform(*params['freq_range'])
                drop_duration = np.random.uniform(*params['duration_range'])
                amplitude = np.random.uniform(*params['amplitude_range'])

                # 雨滴の波形生成
                n_samples = int(drop_duration * sr)
                if idx + n_samples >= len(rain):
                    continue

                # 減衰正弦波として雨滴を生成
                t_drop = np.arange(n_samples) / sr
                envelope = np.exp(-t_drop * 30)  # 指数減衰
                drop = amplitude * envelope * np.sin(2 * np.pi * freq * t_drop)

                # ランダムなフィルタリングで音色を変化
                drop = scipy.signal.lfilter(
                    [1], [1, -0.99], drop
                )

                rain[idx:idx+n_samples] += drop

        # クリッピングを防ぎつつ正規化
        rain = rain / (np.max(np.abs(rain)) + 1e-10)

        return rain, sr

    # 解析の実行
    y, sr = simulate_rain()

    # 各種特徴量の計算
    spectral_features = compute_spectral_features(y, sr)
    temporal_features = compute_temporal_features(y, sr)
    rhythm_features = compute_rhythm_features(y, sr)
    noise_slope, freqs_psd, psd = analyze_noise_color(y, sr)

    # 結果の可視化
    plt.figure(figsize=(15, 10))

    # 波形
    plt.subplot(3, 2, 1)
    plt.plot(np.linspace(0, len(y)/sr, len(y)), y)
    plt.title('雨音波形')
    plt.xlabel('時間 [秒]')
    plt.ylabel('振幅')

    # スペクトログラム
    plt.subplot(3, 2, 2)
    D = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)
    librosa.display.specshow(D, sr=sr, x_axis='time', y_axis='log')
    plt.colorbar(format='%+2.0f dB')
    plt.title('スペクトログラム'
    # スペクトル特徴量の時間変化
    plt.subplot(3, 2, 3)
    times = np.linspace(0, len(y)/sr, len(spectral_features['centroid']))
    plt.plot(times, librosa.amplitude_to_db(spectral_features['flatness']),
             label='平坦度')
    plt.plot(times, spectral_features['centroid']/sr, label='重心')
    plt.legend()
    plt.title('スペクトル特徴量の時間変化')
    plt.xlabel('時間 [秒]')

    # パワースペクトル密度(ノイズの色分析)
    plt.subplot(3, 2, 4)
    plt.loglog(freqs_psd, psd)
    plt.title(f'パワースペクトル密度 (傾き: {noise_slope:.2f})')
    plt.xlabel('周波数 [Hz]')
    plt.ylabel('PSD')

    # テンポグラム
    plt.subplot(3, 2, 5)
    librosa.display.specshow(rhythm_features['tempogram'],
                           sr=sr, x_axis='time')
    plt.title('テンポグラム')
    plt.xlabel('時間 [秒]')
    plt.ylabel('テンポ [BPM]')

    # エネルギーとゼロ交差率
    plt.subplot(3, 2, 6)
    times_rms = np.linspace(0, len(y)/sr, len(temporal_features['rms']))
    plt.plot(times_rms, temporal_features['rms'], label='RMS')
    plt.plot(times_rms, temporal_features['zcr'], label='ZCR')
    plt.legend()
    plt.title('時間領域特徴量')
    plt.xlabel('時間 [秒]')

    plt.tight_layout()
    plt.show()

    # 統計値の表示
    print(f"クレストファクター: {temporal_features['crest_factor']:.2f}")
    print(f"尖度: {temporal_features['kurtosis']:.2f}")
    print(f"ノイズの色(スペクトル傾き): {noise_slope:.2f}")

if __name__ == "__main__":
    environmental_sound_analysis()

このコードは環境音分析の主要である以下の特徴量を計算している:
  • スペクトル特徴量(重心,帯域幅,ロールオフ,平坦度)
  • 時間領域特徴量(RMS,ゼロ交差率,クレストファクター,尖度)
  • リズム特徴量(テンポグラム,オンセット検出)
  • ノイズの色分析(パワースペクトル密度の傾き)

特に以下の点が重要である:

  • 非定常性の定量化
  • 時間-周波数表現の適切な選択
  • 統計的特徴量の組み合わせ