第8章 8-7 / データエンジニアリング

プログラミングの基礎

このページで学ぶこと

ここからは「データエンジニアリング力」の中でも、実際に手を動かしてプログラムを組む力について学びます。データサイエンティストは統計や機械学習の理論だけでなく、設計書をもとにデータ処理プログラムを実装する力も求められます。このページでは、変数とデータ型、条件分岐・繰り返しとフローチャート、オブジェクト指向の基本、テストの考え方、そして計算量への意識という5つの土台を扱います。

プログラミング未経験の方でも読み進められるよう、専門用語には脚注をつけ、コード例は数行程度に絞っています。丸暗記ではなく「何のための仕組みか」をイメージできることを目指しましょう。

1. 変数とデータ型 ― 値を入れておく「箱」

プログラムの中で扱う数値や文字列を一時的に保存しておく入れ物のことを変数と呼びます。買い物カゴのように、必要な値を出し入れするためのラベル付きの箱をイメージするとわかりやすいでしょう。そして、その箱にどんな種類の値が入るかを示すのがデータ型です。代表的なデータ型には、整数型(int)、小数点を含む数値型(float)、文字列型(string)、真偽値型(boolean、true/falseのみ)などがあります。

重要なのは、プログラム言語や実行環境によって、同じ「整数」を扱う変数でも確保するメモリサイズや自動型変換の仕様が異なるという点です。たとえば、ある言語では整数型が4バイトのメモリを確保する一方、別の言語ではもっと柔軟にサイズが決まることがあります。また「1」という文字列と「1」という数値を足し算しようとしたときに、自動的に型を変換してくれる言語もあれば、エラーになる言語もあります。この違いを理解しないままプログラムを設計すると、意図しない誤動作(バグ)につながります。

age = 20          # 整数型(int)
height = 165.4    # 小数型(float)
name = "田中"      # 文字列型(string)
is_member = True  # 真偽値型(boolean)
EXAMPLE
  • ECサイトの「在庫数」は整数型、「価格」は小数を含む数値型で扱う
  • アンケートの「はい/いいえ」の回答は真偽値型で持たせると、集計処理が書きやすい
  • 電話番号は数値ではなく文字列型で保存する(先頭の「0」が消えるのを防ぐため)
POINT

「数字に見えるから数値型」と決めつけないことが大切です。郵便番号や電話番号のように、計算に使わない数字は文字列型として扱うのが実務での定石です。

さえちゃん
さえ

変数は「ラベル付きの箱」、データ型は「箱に入れていいものの種類」って考えるとイメージしやすいよ。同じ言語でも型のルールが違うことがあるから、最初は戸惑うかも!

2. 制御構文とフローチャート ― 分岐と繰り返し

プログラムの処理の流れを決めるのが制御構文です。代表的なものに、条件によって処理を分ける分岐(if文)と、同じ処理を繰り返す繰り返し(for文・while文)があります。設計書に基づいてデータ処理プログラムを実装するときは、まずこの分岐や繰り返しを含んだフローチャート※1を作成し、処理の流れを整理してからコードに落とし込むのが基本の手順です。

for customer in customers:
    if customer.age >= 20:
        print("成人向け案内を送付")
    else:
        print("案内対象外")

このコードは「顧客リストを1件ずつ繰り返し確認し(for)、20歳以上なら案内を送り、そうでなければ何もしない(if / else)」という処理です。フローチャートに描く場合は、ひし形(条件分岐)と長方形(処理)、矢印(処理の流れ)を組み合わせて表現します。文章で処理を説明するよりも、図にしたほうが誰が見ても同じ理解に到達しやすく、設計レビューの場でも役立ちます。

EXAMPLE ― 分岐と繰り返しの使い分け
  • 「会員ランクによって割引率を変える」→ 分岐(if文)
  • 「1000件の注文データを1件ずつチェックする」→ 繰り返し(for文)
  • 「在庫がなくなるまで発注を繰り返す」→ 条件付きの繰り返し(while文)
POINT

小規模な構造化データ(CSV、RDBなど)を扱うデータ処理を実装する際は、いきなりコードを書き始めるのではなく、フローチャートで分岐・繰り返しの流れを可視化してから実装に入ると、手戻りが少なくなります。

3. オブジェクト指向の基本 ― 「継承」という考え方

プログラムの規模が大きくなると、似たような処理をあちこちに書き散らすのではなく、部品として整理したくなります。その代表的な考え方がオブジェクト指向※2です。オブジェクト指向では、データとその操作方法をひとまとめにした設計図を「クラス」と呼びます。

特に押さえておきたいのが継承※3という概念です。継承とは、既存のクラス(スーパークラス・親クラス)が持つ性質(プロパティ)や機能(メソッド)を、新しいクラス(サブクラス・子クラス)がそのまま受け継ぐ仕組みのことです。共通の部分は親クラスにまとめておき、個別の違いだけを子クラスで追加・上書きすることで、同じコードを何度も書く無駄を減らせます。

class Animal:            # スーパークラス(親クラス)
    def cry(self):
        return "..."

class Dog(Animal):       # サブクラス(子クラス)。Animalを継承
    def cry(self):
        return "ワン!"
EXAMPLE
  • 「社員」クラスを親クラスにして、「正社員」「契約社員」を子クラスとして作り、給与計算だけ子クラスごとに変える
  • 「商品」クラスを親にして、「食品」「家電」を子クラスにし、それぞれ異なる税率計算メソッドを持たせる
さえちゃん
さえ

継承は「親の特徴を子どもが受け継ぐ」ってイメージでOK! 共通部分は親クラスにまとめて、違うところだけ子クラスで書き足すから、コードがすっきりするんだよ。

4. テストの考え方 ― ホワイトボックスとブラックボックス

プログラムを実装したら、正しく動くかを確認するテストが欠かせません。テストには大きく2つのアプローチがあります。ホワイトボックステスト※4は、プログラムの内部構造(処理の分岐やロジック)を把握したうえで、すべての分岐が正しく通るかを確認するテストです。一方ブラックボックステスト※5は、内部の作りは気にせず、「この入力を与えたら、この出力が返ってくるはずだ」という仕様の観点だけでテストケースを作成する方法です。

観点 ホワイトボックステスト ブラックボックステスト
見る対象 プログラムの内部ロジック・分岐 入力と出力の対応(仕様)
目的 すべての分岐・処理経路を網羅する 仕様どおりに動くかを確認する
身近な例え 料理のレシピの手順すべてを確認する できあがった料理の味だけを確認する
EXAMPLE
  • 割引計算プログラムで、if文のすべての分岐(会員/非会員、20%引き/10%引きなど)を通すテストケースを作る → ホワイトボックス
  • 「注文金額1万円を入れたら、正しい合計金額が返ってくるか」を入出力だけで確認する → ブラックボックス
POINT

ホワイトボックステストとブラックボックステストは対立する概念ではなく、組み合わせて使うものです。内部の分岐漏れがないかはホワイトボックスで、仕様どおりの結果になるかはブラックボックスで確認します。

5. 計算負荷の高いロジックに気づく ― 二重ループへの注意

プログラムが「正しく動く」ことと「速く動く」ことは別の問題です。特に注意したいのが、入れ子の繰り返し処理(二重ループ)※6です。繰り返しの中に、さらに繰り返しを書くと、データ件数が増えたときに処理時間が急激に増加することがあります。

# 二重ループの例(顧客どうしの総当たり比較)
for a in customers:        # 1000件
    for b in customers:     # さらに1000件
        compare(a, b)       # 合計100万回の処理

顧客が1,000人いる場合、この二重ループは1,000 × 1,000 = 100万回もの比較処理を行うことになります。顧客が10倍の1万人になれば、比較回数は1億回に膨れ上がります。このように、データ件数の増加に対して処理時間が急激に増える箇所を特定し、「そもそも総当たりで比較する必要があるのか」「あらかじめ絞り込んでから比較できないか」といったアルゴリズムの改善策を検討する視点が、実務でもDS検定でも重要です。

EXAMPLE ― 改善の発想
  • 全顧客どうしを総当たりで比較する前に、都道府県で絞り込んでから比較件数を減らす
  • 同じ計算を繰り返し呼び出している箇所を見つけ、一度計算した結果を保存して使い回す
  • 大量データの処理は、繰り返し処理よりも表計算ソフトやSQLの集計機能に任せられないか検討する
さえちゃん
さえ

「動くから良し」で終わらせずに、「件数が増えても大丈夫か」を考えるクセをつけると、実務で頼られるようになるよ。二重ループは特に要注意ポイント!

まとめ

このページでは、プログラミングの基礎となる5つの考え方を見てきました。最後に振り返っておきましょう。

  1. 変数とデータ型 ― 値を入れる箱と、その中身のルール。言語ごとにメモリサイズや自動型変換の仕様が異なることに注意する
  2. 制御構文とフローチャート ― 分岐(if)と繰り返し(for/while)を、設計段階で図にして整理する
  3. オブジェクト指向の継承 ― 親クラスの性質・機能を子クラスが受け継ぎ、共通処理をまとめる
  4. ホワイトボックス/ブラックボックステスト ― 内部ロジックの網羅と、仕様どおりの動作確認を組み合わせる
  5. 計算負荷への意識 ― 二重ループなど処理が重くなりやすい箇所を特定し、改善策を検討する

次のレッスンでは、これらの基礎の上に立って、データ分析に特化したプログラミングとSQLの基本を扱います。実際にデータを取り出し、加工していく実務的な内容に進んでいきましょう。

脚注 ─ 用語解説
  1. フローチャート … 処理の流れを、長方形(処理)やひし形(条件分岐)、矢印(流れ)などの図記号で表した図。プログラムを書く前に処理手順を整理するために使う。
  2. オブジェクト指向 … データ(プロパティ)とその操作方法(メソッド)をひとまとめにした「クラス」という設計図をもとにプログラムを組み立てる考え方。
  3. 継承 … あるクラス(スーパークラス・親クラス)が持つプロパティやメソッドを、別のクラス(サブクラス・子クラス)がそのまま受け継ぐ仕組み。共通処理の重複を減らせる。
  4. ホワイトボックステスト … プログラムの内部構造(分岐やロジック)を把握したうえで、すべての処理経路が正しく動くかを確認するテスト手法。
  5. ブラックボックステスト … プログラムの内部構造を気にせず、入力に対して仕様どおりの出力が返るかどうかだけを確認するテスト手法。
  6. 入れ子の繰り返し処理(二重ループ) … 繰り返し処理(ループ)の中に、さらに別の繰り返し処理を組み込んだ構造のこと。データ件数が増えると処理回数が掛け算的に増え、処理時間が急激に長くなりやすい。