授業の概要#

Pythonはよく使われているオープンソースのプログラミング言語です。

Pythonは、簡単な構文、豊富なライブラリ、そして高い可読性という特徴を持ち、特に、科学計算とデータ分析のコミュニティの発展に伴う、Pythonはデータサイエンス、機械学習、深層学習などの領域において、最も重要な言語の一つと変わっていきました。

この授業は、Pythonの基礎から始め、計算社会科学研究ためのデータ操作・処理・分析用プログラムを書くための基本的な技術を習得することを目的とします。

授業の内容#

Python#

この授業は、Pythonの基礎から応用までカバーします。

  • Pythonのデータ型: タプル、リスト、辞書などデータ型の特徴と操作方法

  • Pythonの構文: 変数の宣言、演算子、制御構文(条件分岐、ループ)、関数の定義、クラスの定義、オブジェクト指向プログラミングの基本概念

  • Pythonの実践: ライブラリの使用

    • Pythonはデータ解析・機械学習のためのライブラリが充実しており、データ解析や機械学習の分野で最もよく使われている言語です。この授業は、その中に代表的かつ実用性の高いライブラリを紹介します。

NumPy#

NumPyは、プログラミング言語Pythonにおいて数値計算を効率的に行うための拡張モジュールです。

効率的な数値計算を行うための型付きの多次元配列(numpy.ndarray)のサポートをPythonに加えるとともに、それらを操作するための大規模な高水準の数学関数ライブラリを提供します。

  • 配列を作成するための関数は多く備えています

import numpy as np
a = np.zeros((2,2)) # すべて0の配列を作成
print(a)
[[0. 0.]
 [0. 0.]]
b = np.random.normal(
    loc   = 0,      # 平均
    scale = 1,      # 標準偏差
    size  = (2,2),# 出力配列のサイズ
) # 正規分布に従う乱数の配列を作成
print(b)
[[-1.02472513  1.27792111]
 [ 0.11120019  0.84785725]]
  • 行列の操作と演算を行うにはNumPyを使うと便利です

arr1 = np.arange(4).reshape((2, 2))
print(arr1)
[[0 1]
 [2 3]]
arr2 = np.arange(6).reshape((2, 3))
print(arr2)
[[0 1 2]
 [3 4 5]]
arr1.reshape((1, 4))
array([[0, 1, 2, 3]])
# 転置
arr1.T
array([[0, 2],
       [1, 3]])
# 逆行列
np.linalg.inv(arr1)
array([[-1.5,  0.5],
       [ 1. ,  0. ]])
# 内積
np.dot(arr1, arr2)
array([[ 3,  4,  5],
       [ 9, 14, 19]])

pandas#

pandasとは、データ解析を容易にする機能を提供するPythonのデータ解析ライブラリです。

Pandasの特徴は、データ操作のための高速で効率的なデータフレーム (DataFrame) という高いレベルのデータ構造データを提供しています。

csvやExcel、jsonなどのデータソースからデータを読み込んで操作することができます。そして、構造化されるデータ形式で、データの調整や変形など様々な処理が可能です。

import pandas as pd
data = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
data
---------------------------------------------------------------------------
SSLCertVerificationError                  Traceback (most recent call last)
File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py:1348, in AbstractHTTPHandler.do_open(self, http_class, req, **http_conn_args)
   1347 try:
-> 1348     h.request(req.get_method(), req.selector, req.data, headers,
   1349               encode_chunked=req.has_header('Transfer-encoding'))
   1350 except OSError as err: # timeout error

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:1286, in HTTPConnection.request(self, method, url, body, headers, encode_chunked)
   1285 """Send a complete request to the server."""
-> 1286 self._send_request(method, url, body, headers, encode_chunked)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:1332, in HTTPConnection._send_request(self, method, url, body, headers, encode_chunked)
   1331     body = _encode(body, 'body')
-> 1332 self.endheaders(body, encode_chunked=encode_chunked)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:1281, in HTTPConnection.endheaders(self, message_body, encode_chunked)
   1280     raise CannotSendHeader()
-> 1281 self._send_output(message_body, encode_chunked=encode_chunked)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:1041, in HTTPConnection._send_output(self, message_body, encode_chunked)
   1040 del self._buffer[:]
-> 1041 self.send(msg)
   1043 if message_body is not None:
   1044 
   1045     # create a consistent interface to message_body

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:979, in HTTPConnection.send(self, data)
    978 if self.auto_open:
--> 979     self.connect()
    980 else:

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:1458, in HTTPSConnection.connect(self)
   1456     server_hostname = self.host
-> 1458 self.sock = self._context.wrap_socket(self.sock,
   1459                                       server_hostname=server_hostname)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ssl.py:517, in SSLContext.wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)
    511 def wrap_socket(self, sock, server_side=False,
    512                 do_handshake_on_connect=True,
    513                 suppress_ragged_eofs=True,
    514                 server_hostname=None, session=None):
    515     # SSLSocket class handles server_hostname encoding before it calls
    516     # ctx._wrap_socket()
--> 517     return self.sslsocket_class._create(
    518         sock=sock,
    519         server_side=server_side,
    520         do_handshake_on_connect=do_handshake_on_connect,
    521         suppress_ragged_eofs=suppress_ragged_eofs,
    522         server_hostname=server_hostname,
    523         context=self,
    524         session=session
    525     )

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ssl.py:1108, in SSLSocket._create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)
   1107             raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
-> 1108         self.do_handshake()
   1109 except (OSError, ValueError):

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ssl.py:1379, in SSLSocket.do_handshake(self, block)
   1378         self.settimeout(None)
-> 1379     self._sslobj.do_handshake()
   1380 finally:

SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)

During handling of the above exception, another exception occurred:

URLError                                  Traceback (most recent call last)
Cell In[10], line 2
      1 import pandas as pd
----> 2 data = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
      3 data

File ~/Lecture/css_tohoku/.venv-jupyterbook1/lib/python3.11/site-packages/pandas/io/parsers/readers.py:873, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, skip_blank_lines, parse_dates, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, low_memory, memory_map, float_precision, storage_options, dtype_backend)
    861 kwds_defaults = _refine_defaults_read(
    862     dialect,
    863     delimiter,
   (...)    869     dtype_backend=dtype_backend,
    870 )
    871 kwds.update(kwds_defaults)
--> 873 return _read(filepath_or_buffer, kwds)

File ~/Lecture/css_tohoku/.venv-jupyterbook1/lib/python3.11/site-packages/pandas/io/parsers/readers.py:300, in _read(filepath_or_buffer, kwds)
    297 _validate_names(kwds.get("names", None))
    299 # Create the parser.
--> 300 parser = TextFileReader(filepath_or_buffer, **kwds)
    302 if chunksize or iterator:
    303     return parser

File ~/Lecture/css_tohoku/.venv-jupyterbook1/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1645, in TextFileReader.__init__(self, f, engine, **kwds)
   1642     self.options["has_index_names"] = kwds["has_index_names"]
   1644 self.handles: IOHandles | None = None
-> 1645 self._engine = self._make_engine(f, self.engine)

File ~/Lecture/css_tohoku/.venv-jupyterbook1/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1904, in TextFileReader._make_engine(self, f, engine)
   1902     if "b" not in mode:
   1903         mode += "b"
-> 1904 self.handles = get_handle(
   1905     f,
   1906     mode,
   1907     encoding=self.options.get("encoding", None),
   1908     compression=self.options.get("compression", None),
   1909     memory_map=self.options.get("memory_map", False),
   1910     is_text=is_text,
   1911     errors=self.options.get("encoding_errors", "strict"),
   1912     storage_options=self.options.get("storage_options", None),
   1913 )
   1914 assert self.handles is not None
   1915 f = self.handles.handle

File ~/Lecture/css_tohoku/.venv-jupyterbook1/lib/python3.11/site-packages/pandas/io/common.py:776, in get_handle(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)
    773     codecs.lookup_error(errors)
    775 # open URLs
--> 776 ioargs = _get_filepath_or_buffer(
    777     path_or_buf,
    778     encoding=encoding,
    779     compression=compression,
    780     mode=mode,
    781     storage_options=storage_options,
    782 )
    784 handle = ioargs.filepath_or_buffer
    785 handles: list[BaseBuffer]

File ~/Lecture/css_tohoku/.venv-jupyterbook1/lib/python3.11/site-packages/pandas/io/common.py:405, in _get_filepath_or_buffer(filepath_or_buffer, encoding, compression, mode, storage_options)
    403 # assuming storage_options is to be interpreted as headers
    404 req_info = urllib.request.Request(filepath_or_buffer, headers=storage_options)
--> 405 with urlopen(req_info) as req:
    406     content_encoding = req.headers.get("Content-Encoding", None)
    407     if content_encoding == "gzip":
    408         # Override compression based on Content-Encoding header

File ~/Lecture/css_tohoku/.venv-jupyterbook1/lib/python3.11/site-packages/pandas/io/common.py:282, in urlopen(*args, **kwargs)
    276 """
    277 Lazy-import wrapper for stdlib urlopen, as that imports a big chunk of
    278 the stdlib.
    279 """
    280 import urllib.request
--> 282 return urllib.request.urlopen(*args, **kwargs)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py:216, in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    214 else:
    215     opener = _opener
--> 216 return opener.open(url, data, timeout)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py:519, in OpenerDirector.open(self, fullurl, data, timeout)
    516     req = meth(req)
    518 sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
--> 519 response = self._open(req, data)
    521 # post-process response
    522 meth_name = protocol+"_response"

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py:536, in OpenerDirector._open(self, req, data)
    533     return result
    535 protocol = req.type
--> 536 result = self._call_chain(self.handle_open, protocol, protocol +
    537                           '_open', req)
    538 if result:
    539     return result

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py:496, in OpenerDirector._call_chain(self, chain, kind, meth_name, *args)
    494 for handler in handlers:
    495     func = getattr(handler, meth_name)
--> 496     result = func(*args)
    497     if result is not None:
    498         return result

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py:1391, in HTTPSHandler.https_open(self, req)
   1390 def https_open(self, req):
-> 1391     return self.do_open(http.client.HTTPSConnection, req,
   1392         context=self._context, check_hostname=self._check_hostname)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py:1351, in AbstractHTTPHandler.do_open(self, http_class, req, **http_conn_args)
   1348         h.request(req.get_method(), req.selector, req.data, headers,
   1349                   encode_chunked=req.has_header('Transfer-encoding'))
   1350     except OSError as err: # timeout error
-> 1351         raise URLError(err)
   1352     r = h.getresponse()
   1353 except:

URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)>
# 頻度を計算する
data["species"].value_counts()
species
setosa        50
versicolor    50
virginica     50
Name: count, dtype: int64
# 統計量を計算する
data["sepal_width"].describe()
count    150.000000
mean       3.057333
std        0.435866
min        2.000000
25%        2.800000
50%        3.000000
75%        3.300000
max        4.400000
Name: sepal_width, dtype: float64
# speciesごとに指標の平均を計算する
data.groupby("species").mean().reset_index()
species sepal_length sepal_width petal_length petal_width
0 setosa 5.006 3.428 1.462 0.246
1 versicolor 5.936 2.770 4.260 1.326
2 virginica 6.588 2.974 5.552 2.026
# データフレームの変形
data.melt(id_vars=["species"], 
        var_name="features", 
        value_name="values")
species features values
0 setosa sepal_length 5.1
1 setosa sepal_length 4.9
2 setosa sepal_length 4.7
3 setosa sepal_length 4.6
4 setosa sepal_length 5.0
... ... ... ...
595 virginica petal_width 2.3
596 virginica petal_width 1.9
597 virginica petal_width 2.0
598 virginica petal_width 2.3
599 virginica petal_width 1.8

600 rows × 3 columns

matplotlib#

matplotlibは、グラフ描画ライブラリでです。

オブジェクト指向のAPIを提供しており、様々な種類のグラフを描画する能力を持っています。

Pythonで使える可視化ためのライブライは他にもありますが、Matplotlibは最も広く使われているため、PandasやNumpyなどのライブライとうまく連携しやすくなっています。

import matplotlib.pyplot as plt
plt.rcParams['xtick.direction'] = "out"
plt.rcParams['ytick.direction'] = "in"

normal = np.random.normal(0, 1, 2000)
plt.hist(normal, bins=50, density=True, alpha=0.6, color='b')
plt.show()
../_images/516d0ac175faedfd4c9a8975f3d9c0cc91dd6d1e4593002368dc5d20c91844f7.png
for i in data["species"].unique():
    plt.scatter(data[data["species"]==i]["sepal_length"],
    data[data["species"]==i]["sepal_width"], label=i)
plt.rcParams['xtick.direction'] = "out"
plt.rcParams['ytick.direction'] = "in"
plt.legend()
<matplotlib.legend.Legend at 0x1373672f0>
../_images/96c083b19f09e49c71eca876d1c5b6db36a94e5691f1a3331c7cf54ea4aed801.png

scikit-learn#

scikit-learnは機械学習ライブラリです。

NumPyやSciPyといった科学計算ライブラリと組み合わせて使用することができ、また、PandasやMatplotlibといったライブラリとの互換性も高く、機械学習モデルの開発、評価、デプロイまでを網羅する幅広い機能を提供しています。

初心者にも扱いやすいAPIを提供しており、教師あり学習、教師なし学習に関するアルゴリズム(SVM、Random Forest、回帰、クラスタリングなど)の効率的な実装、交差検証、グリッドサーチ、チューニングや特徴量の選択など機械学習に関する操作もサポートされています。

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# データセットの読み込み
iris = load_iris()
X = iris.data
y = iris.target

# データセットの分割(学習用データとテスト用データ)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=3)

# ロジスティック回帰モデルのインスタンス化
logreg = LogisticRegression()

# 学習
logreg.fit(X_train, y_train)

# テストデータを用いた予測
y_pred = logreg.predict(X_test)

# 結果の表示
print("ロジスティック回帰モデルの予測の精度: {:.4f}".format(accuracy_score(y_test, y_pred)))
ロジスティック回帰モデルの予測の精度: 0.9600
from sklearn.svm import SVC
svm = SVC()

# SVMのインスタンス化
svm = SVC()

# 学習
svm.fit(X_train, y_train)

# テストデータを用いた予測
y_pred = svm.predict(X_test)

# 結果の表示
print("サポートベクターマシンの予測の精度: {:.4f}".format(accuracy_score(y_test, y_pred)))
サポートベクターマシンの予測の精度: 0.9600

学習の到達目標#

  • データ構造、制御構造、オブジェクト指向などプログラミング言語の基礎概念について学ぶとともに、ある程度自由にPythonを用いて計算やデータ処理を実装できるようになることを目指す

  • データ処理とデータ分析に必要なPythonライブラリの使い方を習得することを目指す

  • Python環境の構築、パッケージ管理、コード管理に関する知識を習得し、Pythonを用いて再生可能なデータ解析を行えるようにことを目指す

GitとGitHub#

Gitは「パージョン管理システム(Version Control System)」と呼ばれるものの一つです。

パージョン管理システムとは、一つのファイル、または複数のファイルの集合に対して、時間とともに加えられた変更を記録するシステムで、後から特定のバージョンを呼び出すことができるようにするためのものです。

ファイルの「パージョン(変更履歴)」を記録して、いつでも過去の状況に戻したり、過去の変更履歴を比較したり、またはどのタイミングで問題が起こっていたかを確認したり、様々なことができるプログラム開発やファイル管理を補助するシステムです。

GitHubなどのリモートリポジトリと組み合わせることで、クラウドでデータと進捗を管理したり、他のメンバーとコードと情報を共有したり、個人のプロジェクトだけでなく、共同開発するときも強力なツールとなります。

学習の到達目標#

  • Gitを用いてプロジェクトを管理するスキルを把握するを目指す

  • GitHubを用いて共同作業を進めるスキルを把握することを目指す

授業設計と成績評価#

  • 授業中実践的なプログラミング操作が多いので、必ずPCをご持参ください。

    • インターネットとの接続が必要される操作もありますので、PCのインターネット接続も事前に設定してください。

  • 成績評価の分配は以下の通りです

    • 出席 (\(30\%\)): 授業で学んだ知識とスキルの応用を問う課題

    • 授業後の課題 (\(70\%\)): 授業の理解度を確認するためのプログラミング課題

      • 基本的に毎回の授業後には課題が出ます

      • 個人差がありますが、平均的には30分程度要する課題を想定しています

      • 最後の課題は、授業から学んだ知識とスキルを問う課題になります

その他#

  • 授業の内容に関して不明点あるいはご要望があれば、随時メールでご連絡ください。また、プログラミングやソフトウェア操作の質問については、Google ClassroomまたはGitHub Issueでも受け付けます。

  • 授業のオフィスアワーは、できれば\(1\)日前アポイントを取ってくだい。

  • 本授業ではプログラミングの事前知識は不要ですが、マニュアルに従ったコンピュータの操作やエラーメッセージを検索を含む基本的な情報リテラシーは望まれます。

授業の資料#

この授業の資料は、Jupyter Notebook形式で作成されたソースファイルをJupyter Bookを用いて変換することで作成されたコンテンツになっている。

  • 授業の資料はこちらのリンクから閲覧できます。

  • .ipynb形式のソースファイルの管理と共有には、GitHubと呼ばれる環境を利用していて、ソースファイルはこちらからも閲覧できる。

  • Google Colaboratoryというサービスを利用してGoogleのクラウド環境上でJupyter Nootebookを編集・実行することができます (手持ちのPCの動作に不安がある方は、Google Colaboratoryを利用してください)。

Note

Google Colaboratory上でノートブックを開くには、ロケットの形をしたボタンにマウスオーバーして”Colab”から開く。

次回の授業までに#

  • 演習ための環境を事前に整備してください

    • GitHubアカウントを作ってください。

    • VSCodeをインストールしてください。

  • 授業中では以上の作業に関する説明が省略しますので、不明点があれば必ず次回の授業までに聞いてください。