【Python】正規化とは?初心者向けにわかりやすく具体例つきで解説
はじめに
Pythonを使って開発をする上で、正規化という言葉を耳にすることがあります。
正規化はデータを扱うときや文字列を処理するときなど、さまざまなシーンで登場します。
例えば数値データをスケーリングする場合や、文字列の表記ゆれを統一したい場合に役立ちます。
しかし、正規化と聞くと「なんとなく難しそう」と感じる方もいるのではないでしょうか。
そこで本記事では、Pythonを使った正規化の実践方法を初心者向けにわかりやすく解説していきます。
実務ではデータ分析やWebアプリケーションの文字列処理など、多彩な場面でこの手法を使いますので、その使い方を具体例とともに紹介していきます。
この記事を読むとわかること
- 正規化の考え方
- Pythonでの文字列の正規化 (Unicode関連)
- Pythonでの数値データの正規化
- 正規化の実務での活用イメージ
ここまで読んでいただくと、「なぜ正規化が必要なのか」「どのようにコードを書けばよいのか」という疑問が解消されるはずです。
Pythonにおける正規化とは
正規化には複数の意味があります。
一例として、文字コードを一定の形式に変換することを指す場合や、数値データを一定の範囲に揃える操作を指す場合があります。
これらを総称して**“正規化”**と呼ぶのが一般的です。
実務においては、以下のような場面が挙げられます。
- テキストデータの表記揺れや文字化けを防ぐ
- 乱雑な数値データをスケーリングして機械学習モデルに入力する
- データベース設計で重複データを排除する
ここでは特に、Pythonで扱う文字列データと数値データの正規化に焦点を当てていきます。
テキストデータの正規化
テキストの正規化とは、文字や文字列の形式を統一することを指します。
日本語であれば「カタカナを全角・半角のどちらかに統一する」といった用途が代表的かもしれません。
英語圏でもアクセント記号付きの文字を通常のアルファベットに置き換えるなど、国際化対応の場面でも使用します。
Unicode正規化が必要となるケース
Pythonで文字列を扱うときは、内部的にUnicodeが使われています。
しかしUnicode文字には複数の表現パターンがあるため、同じ文字なのにシステムによって微妙にコード値が異なる場合があります。
例えば「é」という文字は、ひとつのコードポイントとして定義されているものと、e + アクセント記号という2文字の組み合わせで表現されるものの2種類があります。
こうした差を吸収しないと、文字列が同じであるにもかかわらず比較すると不一致と判定されてしまうことがあります。
これを避けるために、Unicodeを正規化という手順で統一的に扱えるようにしておくと便利です。
unicodedataを使った正規化の例
Pythonには標準ライブラリであるunicodedataが用意されています。
このライブラリの normalize()
関数を使うことで、簡単にUnicodeの形式を統一できます。
import unicodedata text1 = "é" # 合成済み文字(U+00E9) text2 = "e\u0301" # 分解文字(e + アクセント記号) print(text1 == text2) # Falseになる場合がある # 正規化(NFC:完全に合成された形式に揃える) normalized_text1 = unicodedata.normalize("NFC", text1) normalized_text2 = unicodedata.normalize("NFC", text2) print(normalized_text1 == normalized_text2) # Trueになる
このコードでは、同じ見た目の文字列をNFC形式に正規化しています。
もしNFD形式(分解済み)のほうが都合が良い場面であれば、 "NFD"
を指定して統一するのも可能です。
用途に合わせて使い分ける点がポイントです。
実務の現場でも、ユーザー入力フォームなどで入力された文字を同一の形式にそろえることで、表記のゆれを防ぐケースがあります。
例えば検索機能を実装するとき、ユーザーが入力したキーワードを正規化してからデータベースと比較するといった方法が挙げられます。
文字列の正規化を行うと、アクセント記号や濁点などの表現が変化する場合があります。
ユーザーに入力内容を正確に保持してほしい場合は、正規化せずに生データを扱うケースもあるため、運用方針をあらかじめ決めておくと良いでしょう。
数値データの正規化
一方、数値の正規化は特にデータ分析や機械学習の分野で重要です。
データの値が大きくばらついていると、特定の要素だけが機械学習モデルに強く影響を与えるかもしれません。
そこでスケーリングや標準化などの方法で数値のスケールを整え、計算を安定させるのが一般的です。
scikit-learnを使った数値の正規化
Pythonの機械学習ライブラリであるscikit-learnには、数値データを簡単に正規化するためのツールが用意されています。
代表的なものは以下の2つです。
- MinMaxScaler:各特徴量を0〜1の範囲に収める
- StandardScaler:平均0、標準偏差1に変換する
具体的には、以下のようなコード例で利用します。
from sklearn.preprocessing import MinMaxScaler, StandardScaler import numpy as np data = np.array([[100, 0.5], [200, 0.1], [300, 0.9], [400, 0.3]]) # MinMaxScaler min_max_scaler = MinMaxScaler() scaled_data_minmax = min_max_scaler.fit_transform(data) print("Min-Max正規化:", scaled_data_minmax) # StandardScaler standard_scaler = StandardScaler() scaled_data_std = standard_scaler.fit_transform(data) print("標準化:", scaled_data_std)
このスクリプトでは、2つの特徴量を持つデータに対して、Min-Maxスケーリングと標準化を行っています。
Min-Maxスケーリングでは、各列の最小値が0になり最大値が1になります。
標準化では、すべての列で平均が0、標準偏差が1に正規化されます。
実務では、データの傾向やアルゴリズムに応じてどちらの手法が適しているかを選びます。
例えば外れ値の影響を大きく受けにくいモデルの場合はMin-Maxスケーリング、正規分布を仮定しているモデルなら標準化といった使い分けを考えることもあります。
pandasでのスケーリング
もしデータをpandasのDataFrameで管理しているなら、同じく MinMaxScaler
や StandardScaler
が使えます。
ただし、適用前にDataFrameを values
などでNumPy配列に変換するか、あるいは同じライブラリ内で流れるように処理することが多いです。
以下はイメージコードです。
import pandas as pd from sklearn.preprocessing import MinMaxScaler df = pd.DataFrame({ "col1": [100, 200, 300, 400], "col2": [0.5, 0.1, 0.9, 0.3] }) scaler = MinMaxScaler() scaled_values = scaler.fit_transform(df[["col1", "col2"]]) df_scaled = pd.DataFrame(scaled_values, columns=["col1", "col2"]) print(df_scaled)
元のDataFrameのデータをNumPy配列に変換し、スケーラーで変換してから新たなDataFrameを作成する流れです。
こうした数値正規化は、データを扱うすべての人にとって基本的なテクニックと言えます。
データベース設計における正規化
少し話題を広げると、正規化はデータベースの設計でも出てきます。
この場合、重複データを削減し、保守性や整合性を高めるための手法を指します。
第1正規形(1NF)、第2正規形(2NF)、第3正規形(3NF)などの段階に分かれており、テーブル構造を整えていくことが一般的です。
例えば以下のようなシンプルなテーブル構成で考えます。
- 商品情報を持つテーブル
- 顧客情報を持つテーブル
- 注文情報を持つテーブル
テーブル同士を紐付けるときに、同じ情報を繰り返し記述せずに参照キーを使う設計を進めるのが正規化の基本です。
Pythonプログラムでデータベースにアクセスする際も、きちんと正規化された構造を前提とすると、整合性の取れたデータ処理が可能になります。
Pythonを使ったSQLとの連携
SQLiteやPostgreSQL、MySQLなどのデータベースにアクセスするときは、Pythonの標準ライブラリや外部ライブラリを使って操作します。
以下はSQLiteの例です。
import sqlite3 connection = sqlite3.connect("example.db") cursor = connection.cursor() # テーブルを作成 cursor.execute(""" CREATE TABLE IF NOT EXISTS products ( id INTEGER PRIMARY KEY, name TEXT, price REAL ) """) # データの挿入 cursor.execute("INSERT INTO products (name, price) VALUES (?, ?)", ("Pen", 100.0)) cursor.execute("INSERT INTO products (name, price) VALUES (?, ?)", ("Notebook", 200.0)) # データの取得 cursor.execute("SELECT * FROM products") rows = cursor.fetchall() for row in rows: print(row) connection.commit() connection.close()
このようにPythonからSQLを発行してデータを読み書きする際は、テーブル設計(正規化)の度合いがシステムのメンテナンス性にも影響します。
このため、必要な情報をきちんと整理したテーブル構成になっていることが重要です。
データベース設計の正規化は、テーブルを細かく分割しすぎると逆にパフォーマンスに影響を与える場合もあります。
実際の業務では最適なバランスを考慮した上で正規化を進めることが多いです。
まとめ
Pythonでは、文字列データや数値データなどの異なる領域で正規化という概念が使われることがあります。
文字列の表記を統一したり、数値データをスケーリングしたりすることで、システム全体の動作をスムーズにする役割を果たします。
テキストの正規化では、unicodedata.normalize()
を活用して文字列を統一的に扱うことができます。
数値データの正規化では、scikit-learnの MinMaxScaler
や StandardScaler
を使ってスケールを調整できるのが大きなメリットです。
また、データベースの正規化ではテーブル構造の重複や矛盾を防ぎ、保守性や拡張性の高いシステムに仕上げることが目標です。
実務では、これらの正規化を場面に応じて正しく適用するのがポイントです。
「なぜ正規化が必要なのか」を理解しつつ、具体的なコードや設計をイメージしながら進めれば、扱うデータが増えても混乱することなく管理できるようになるでしょう。