データ前処理入門|欠損値補完と特徴量エンジニアリング

目次

初案件で大失敗した、あのデータ前処理の話

2023年の夏、私は人生で初めてデータ分析の副業案件を受注した。クライアントは地方の小売チェーン。売上データを分析して、来月の売上を予測してほしいという依頼だった。報酬は20万円。

「これは簡単だろう」

そう思ってた。Pythonは使い慣れてるし、機械学習の基礎も勉強してた。Kaggleでもそこそこのスコアを出せてた。

でも現実は甘くなかった。

クライアントから送られてきたExcelファイルを開いた瞬間、背筋が凍った。データがめちゃくちゃだった。

売上金額の列に「#N/A」が並んでる。日付の列が空白だらけ。商品コードが途中で変わってる。店舗名の表記が統一されてない(「渋谷店」「SHIBUYA店」「shibuya」が混在)。

深夜、PCの画面を見て頭を抱える30代男性エンジニアの線画イラスト

「こんなの聞いてない…」

Kaggleのデータは綺麗に整形されてた。でも実務のデータは、こんなに汚いのか。予測モデルを作る前に、データの掃除だけで3日かかった。しかも、最初のアプローチが間違ってて、途中でやり直し。納期ギリギリで何とか納品したけど、精度はイマイチ。

あの時、データ前処理の重要性を痛感した。

機械学習の教科書には載ってない。でも実務では、作業時間の8割がデータ前処理。予測モデルの精度も、データの質で決まる。綺麗なデータで作った普通のモデルは、汚いデータで作った高度なモデルに勝つ。

あれから2年。今は月30万円以上の副業収入がある。データ前処理のスキルが、案件獲得の決め手になってる。「データが汚くても大丈夫です」って言えるだけで、クライアントの反応が全然違う。

この記事では、データ前処理の中でも特に重要な「欠損値補完」と「特徴量エンジニアリング」について、実務で使える技術を解説する。教科書的な説明じゃなく、私が実際に案件で使ってる方法を共有していく。

プログラミング学習してる人、データサイエンスで副業したい人、機械学習を勉強中の人。この記事を読めば、実務レベルのデータ前処理ができるようになる。Kaggleで学んだ知識を、リアルな案件で使えるようになる。

なぜデータ前処理が副業案件で重要なのか

実務のデータは9割が汚い

Kaggleやチュートリアルのデータは、誰かが綺麗に整形してくれてる。欠損値は少ないし、データ型も統一されてるし、外れ値も処理済み。

でも実務は違う。

クライアントから送られてくるデータは:

  • 複数のExcelシートに分散してる
  • 日付のフォーマットが統一されてない
  • 数値の列に文字列が混ざってる
  • 欠損値が30%以上ある
  • 重複データがある
  • 外れ値だらけ
  • カラム名が日本語で長い

これが現実。

私がこれまで受けた案件50件のうち、最初からクリーンなデータだったのは2件だけ。残りは全部、データクリーニングが必要だった。

あるクライアントのデータは、売上金額に「¥1,234」って文字列で入ってた。カンマと円マークを削除して数値に変換する処理が必要だった。別のクライアントは、日付が「2023年1月1日」と「2023/01/01」と「20230101」の3種類で混在してた。

データ前処理ができる人は希少価値が高い

データサイエンスを学んでる人の多くは、機械学習のアルゴリズムに興味がある。深層学習とか、最新の手法とか。

でも実務で一番価値があるのは、汚いデータを綺麗にできるスキル。

クライアントが本当に困ってるのは:

  • 「データはあるけど、分析できる形になってない」
  • 「欠損値が多すぎて、どう扱えばいいかわからない」
  • 「予測精度が低い。データの問題かもしれない」

こういう課題。

データ前処理ができる人は、クライアントの「困った」を解決できる。だから、案件が取りやすいし、単価も高い。

私の場合、提案文に「データクリーニング・前処理も対応可能です」って一文を入れるだけで、採用率が2倍になった。他の提案者は「機械学習できます」って書いてるけど、クライアントが欲しいのはそこじゃない。

前処理の質が予測精度を決める

機械学習の教科書には、こう書いてある。

「データの質が予測精度の8割を決める」

これ、本当。

私の経験でも:

  • データ前処理に時間をかけた案件:予測精度90%以上
  • 前処理を適当にやった案件:予測精度70%前後

予測精度が20%違うと、クライアントの評価も全然違う。リピート率も変わる。

あるEC企業の案件で、売上予測モデルを作った。最初は精度75%で、クライアントの反応は「まあまあですね」って感じだった。

でも、特徴量エンジニアリングを丁寧にやり直したら、精度が88%に上がった。クライアントは大喜び。「すごい!」って。継続案件になって、月15万円の定期収入になった。

カフェで嬉しそうにクライアントとオンライン打ち合わせする40代男性の線画イラスト

差は、データ前処理の質。予測アルゴリズムは変えてない。

副業で最も需要がある「地味なスキル」

機械学習の華やかな部分(ディープラーニングとか)は、みんなが勉強してる。でも地味な部分(データ前処理とか)は、みんな避けがち。

だから、チャンス。

クラウドワークスで「データクリーニング」で検索すると、300件以上の案件が出てくる。しかも競合が少ない。みんな「機械学習」の案件に群がってるから。

単価も悪くない:

  • 簡単なデータクリーニング:3~5万円
  • データ統合・前処理:5~10万円
  • 前処理+予測モデル:15~30万円

最初の1件は、データクリーニングだけの案件でもいい。実績を作って、次に繋げる。

私の初案件も、実はデータクリーニングがメインだった。予測モデルはオマケ。でも報酬は20万円。時給換算で6,000円くらい。

欠損値補完の基礎:実務で使える5つの手法

欠損値(missing value)は、データ分析で必ず遭遇する問題。どう扱うかで、結果が大きく変わる。

欠損値の種類を理解する

欠損値には3種類ある。扱い方が全然違うから、まず見極める。

MCAR(完全にランダムな欠損)

  • 欠損がランダムに発生してる
  • 他の変数との関係がない
  • 例:アンケートで一部の人が回答を飛ばした

MAR(ランダムな欠損)

  • 欠損が他の変数と関係してる
  • でも欠損値そのものとは無関係
  • 例:高齢者ほど所得の記入を避ける傾向

MNAR(ランダムでない欠損)

  • 欠損が欠損値そのものと関係してる
  • 一番厄介
  • 例:所得が高い人ほど所得を記入しない

実務では、MARとMNARが多い。でも正直、現場で完璧に見極めるのは難しい。だから、複数の手法を試して、結果を比較する。

手法1:削除(最もシンプル、でも要注意)

欠損値がある行や列を、丸ごと削除する。

import pandas as pd
import numpy as np

# サンプルデータ
df = pd.DataFrame({
    '売上': [100, 200, np.nan, 400, 500],
    '広告費': [10, 20, 30, np.nan, 50],
    '来客数': [50, 60, 70, 80, 90]
})

# 欠損値がある行を削除
df_clean = df.dropna()
print(df_clean)

使うべき場面:

  • 欠損値が全体の5%未満
  • データ量が十分にある(1万行以上)
  • 欠損がランダム(MCAR)

避けるべき場面:

  • 欠損値が30%以上
  • データ量が少ない(1000行未満)
  • 欠損に偏りがある(MAR、MNAR)

実務での失敗談:あるプロジェクトで、欠損値がある行を全部削除したら、データが5000行から800行に減った。予測精度がガタ落ち。やり直しになった。

削除は最後の手段。他の方法を試してから。

手法2:平均値・中央値で補完(基本中の基本)

欠損値を、その列の平均値や中央値で埋める。

# 平均値で補完
df['売上'].fillna(df['売上'].mean(), inplace=True)

# 中央値で補完(外れ値に強い)
df['広告費'].fillna(df['広告費'].median(), inplace=True)

# カテゴリカル変数は最頻値で補完
df['店舗'].fillna(df['店舗'].mode()[0], inplace=True)

使うべき場面:

  • 欠損値が10~30%
  • データ分布が正規分布に近い
  • 外れ値が少ない

注意点:
平均値は外れ値に弱い。売上データに「10億円」みたいな外れ値があると、平均値が歪む。そういう時は中央値を使う。

実務での使い方:
私は、まず分布を確認する。ヒストグラムを描いて、外れ値がないかチェック。外れ値があれば中央値、なければ平均値。

import matplotlib.pyplot as plt

# 分布を確認
df['売上'].hist(bins=30)
plt.show()

# 外れ値を確認
Q1 = df['売上'].quantile(0.25)
Q3 = df['売上'].quantile(0.75)
IQR = Q3 - Q1
outliers = ((df['売上'] < Q1 - 1.5 * IQR) | (df['売上'] > Q3 + 1.5 * IQR))
print(f'外れ値の数: {outliers.sum()}')

手法3:前後の値で補完(時系列データに有効)

時系列データ(日付順に並んでるデータ)の欠損値は、前後の値を使って補完できる。

# 前の値で補完(Forward Fill)
df['売上'].fillna(method='ffill', inplace=True)

# 次の値で補完(Backward Fill)
df['売上'].fillna(method='bfill', inplace=True)

# 線形補間(前後の値から推測)
df['売上'].interpolate(method='linear', inplace=True)

使うべき場面:

  • 時系列データ
  • センサーデータ
  • 連続的な変化が期待される

実務での例:
ある案件で、店舗の日次売上データを分析した。たまに売上が記録されてない日がある。休業日ではなく、単に記録ミス。

こういう場合、前後の値から補間する。

# 日付でソート
df = df.sort_values('日付')

# 線形補間
df['売上'] = df['売上'].interpolate(method='linear')

月曜100万、火曜欠損、水曜120万なら、火曜は110万で補完される。

自宅のデスクでデータを確認しながらコードを書く20代女性の線画イラスト

手法4:予測モデルで補完(高度だけど効果的)

欠損値を、他の変数から予測して補完する。

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split

# 欠損値がない行を訓練データに
train_df = df[df['売上'].notna()]
test_df = df[df['売上'].isna()]

# 特徴量とターゲット
X_train = train_df[['広告費', '来客数']]
y_train = train_df['売上']
X_test = test_df[['広告費', '来客数']]

# モデル訓練
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# 欠損値を予測
y_pred = model.predict(X_test)

# 補完
df.loc[df['売上'].isna(), '売上'] = y_pred

使うべき場面:

  • 欠損値が多い(30%以上)
  • 他の変数との相関が強い
  • データ量が十分にある

注意点:
計算コストが高い。データが少ないと過学習のリスク。

実務での使い方:
ある顧客分析の案件で、年収の欠損値が40%あった。削除したらデータが激減。平均値で埋めたら予測精度が低い。

で、年齢・職業・居住地から年収を予測するモデルを作って補完した。結果、予測精度が15%向上。クライアントも満足。

手法5:欠損フラグを立てる(意外と重要)

欠損値を補完するだけじゃなく、「欠損していた」という情報も保持する。

# 欠損フラグを追加
df['売上_欠損フラグ'] = df['売上'].isna().astype(int)

# その後で補完
df['売上'].fillna(df['売上'].mean(), inplace=True)

なぜ重要か?
欠損していること自体が、重要な情報の場合がある。

例:

  • 所得の欠損 → 低所得者かもしれない
  • 購買履歴の欠損 → 新規顧客かもしれない

実務での例:
あるECサイトの顧客分析で、「最終購入日」が欠損してる顧客がいた。これは「一度も購入したことがない」という意味。欠損フラグを立てたら、離脱予測の精度が10%上がった。

実務で使う判断基準

欠損値の割合で判断する:

欠損率推奨手法
0~5%削除
5~20%平均値/中央値補完
20~40%予測モデル補完 + 欠損フラグ
40%以上列ごと削除を検討 or 予測モデル

ただし、これは目安。データの性質やビジネス要件で変わる。

私のやり方:

  1. まず欠損率を確認
  2. 複数の手法を試す
  3. 予測精度を比較
  4. 一番良い方法を採用
# 欠損率を確認
missing_rate = df.isnull().sum() / len(df) * 100
print(missing_rate)

# 複数の手法で補完したデータを作成
df_mean = df.copy()
df_mean['売上'].fillna(df['売上'].mean(), inplace=True)

df_median = df.copy()
df_median['売上'].fillna(df['売上'].median(), inplace=True)

df_model = df.copy()
# ... (予測モデルで補完)

# それぞれで予測精度を比較
# 一番良い方法を採用

特徴量エンジニアリング:予測精度を上げる実践テクニック

特徴量エンジニアリング(Feature Engineering)は、生データから予測に有効な特徴量を作り出す技術。機械学習の精度を決める最重要スキル。

Kaggleの上位者は、特徴量エンジニアリングに膨大な時間をかけてる。アルゴリズムはほぼ同じでも、特徴量で差がつく。

特徴量とは何か(初心者向け解説)

特徴量(feature)は、予測モデルに入力するデータの項目。

例:顧客の購買予測

  • 元のデータ:年齢、性別、会員登録日、最終購入日
  • 作成する特徴量:会員歴(登録日から現在まで)、前回購入からの日数

生データをそのまま使うより、加工した方が予測精度が上がる。

テクニック1:時系列データから特徴量を抽出

日付データは、そのままだと使いにくい。分解して特徴量を作る。

import pandas as pd

# 日付データ
df = pd.DataFrame({
    '購入日': ['2023-01-15', '2023-02-20', '2023-03-10'],
    '売上': [10000, 15000, 12000]
})

df['購入日'] = pd.to_datetime(df['購入日'])

# 年月日を分解
df['年'] = df['購入日'].dt.year
df['月'] = df['購入日'].dt.month
df['日'] = df['購入日'].dt.day
df['曜日'] = df['購入日'].dt.dayofweek  # 0=月曜, 6=日曜

# 四半期
df['四半期'] = df['購入日'].dt.quarter

# 月の週番号
df['月の週'] = (df['購入日'].dt.day - 1) // 7 + 1

# 週末フラグ
df['週末フラグ'] = (df['曜日'] >= 5).astype(int)

print(df)

実務での例:
小売店の売上予測案件で、日付を分解したら精度が20%上がった。なぜか?

  • 曜日効果:土日は売上が高い
  • 月末効果:給料日後は売上が高い
  • 季節効果:12月は売上が高い

日付をそのまま使っても、モデルはこれらのパターンを学習しにくい。分解すると学習しやすくなる。

テクニック2:カテゴリカル変数のエンコーディング

カテゴリカル変数(「東京」「大阪」みたいな文字列)は、数値に変換する必要がある。

Label Encoding(ラベルエンコーディング)

from sklearn.preprocessing import LabelEncoder

df = pd.DataFrame({
    '店舗': ['渋谷', '新宿', '池袋', '渋谷'],
    '売上': [100, 200, 150, 180]
})

le = LabelEncoder()
df['店舗_encoded'] = le.fit_transform(df['店舗'])

print(df)
# 渋谷=0, 新宿=1, 池袋=2 みたいに変換される

One-Hot Encoding(ワンホットエンコーディング)

# One-Hot Encoding
df_onehot = pd.get_dummies(df, columns=['店舗'], prefix='店舗')

print(df_onehot)
# 店舗_渋谷, 店舗_新宿, 店舗_池袋 の列が作られる
# 該当する列だけ1、他は0

どっちを使うか?

  • カテゴリに順序がある(小・中・大 など)→ Label Encoding
  • カテゴリに順序がない(地名、色 など)→ One-Hot Encoding

実務での失敗談:
ある案件で、都道府県をLabel Encodingしちゃった。「東京=0」「大阪=1」みたいに。でもこれだと、モデルが「大阪は東京より大きい」って勘違いする。

One-Hot Encodingにしたら、精度が改善した。

コワーキングスペースでコードのエラーと格闘する30代男性の線画イラスト

テクニック3:数値データの変換(スケーリング)

数値データの範囲がバラバラだと、モデルの学習がうまくいかない。

例:

  • 年齢:20~80(範囲60)
  • 所得:200~2000万円(範囲1800万)

所得の影響が過大評価される。

標準化(Standardization)

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

df[['年齢', '所得']] = scaler.fit_transform(df[['年齢', '所得']])

# 平均0、標準偏差1に変換される

正規化(Normalization)

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()

df[['年齢', '所得']] = scaler.fit_transform(df[['年齢', '所得']])

# 0~1の範囲に変換される

どっちを使うか?

  • 標準化:データが正規分布に近い時
  • 正規化:データの範囲を揃えたい時

実務では、両方試して比較する。

テクニック4:交互作用項の作成

2つの変数を掛け合わせた特徴量を作る。単独では見えない関係性が見える。

# 広告費と来客数の交互作用
df['広告費×来客数'] = df['広告費'] * df['来客数']

# 年齢と所得の交互作用
df['年齢×所得'] = df['年齢'] * df['所得']

実務での例:
住宅価格の予測案件で、「面積」と「駅からの距離」を掛け合わせた。

  • 面積が広い+駅近 → 超高価格
  • 面積が広い+駅遠 → 普通の価格

単独の変数だけでは捉えにくい関係性を、交互作用項で表現できた。精度が12%向上。

テクニック5:集約特徴量の作成

グループごとに統計量を計算して、特徴量を作る。

# 顧客ごとの購買統計
customer_stats = df.groupby('顧客ID').agg({
    '購入金額': ['mean', 'sum', 'std', 'max', 'min'],
    '購入回数': 'count'
}).reset_index()

# 列名を整理
customer_stats.columns = ['顧客ID', '平均購入金額', '合計購入金額', 
                          '購入金額の標準偏差', '最大購入金額', 
                          '最小購入金額', '購入回数']

# 元のデータに結合
df = df.merge(customer_stats, on='顧客ID', how='left')

実務での例:
ECサイトの顧客分析で、「過去の購買履歴から統計量を作成」した。

  • 平均購入金額:この顧客の平均的な購買力
  • 購入金額の標準偏差:購買パターンの安定性
  • 最終購入からの日数:離脱リスク

これらの特徴量を作ったら、離脱予測の精度が25%向上。

テクニック6:外れ値の処理

外れ値は、予測精度を下げる原因。でも、単純に削除するのは危険。

# IQR法で外れ値を検出
Q1 = df['売上'].quantile(0.25)
Q3 = df['売上'].quantile(0.75)
IQR = Q3 - Q1

# 外れ値を上下限でクリップ
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

df['売上_clipped'] = df['売上'].clip(lower=lower_bound, upper=upper_bound)

外れ値を削除すべきか、残すべきか?

判断基準:

  • データ入力ミス → 削除
  • 本当に異常値(商品の単価が100万円とか)→ 削除
  • ビジネス的に意味がある(大口顧客の購入)→ 残す

実務での失敗談:
ある案件で、売上が1000万円以上のデータを「外れ値」として削除した。でも、それは大口法人顧客だった。クライアントに「なんでこの顧客のデータがないの?」って言われて、やり直し。

外れ値を削除する前に、必ずクライアントに確認する。

実務で使う特徴量エンジニアリングのワークフロー

私が案件でやってる手順:

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, LabelEncoder

# 1. データ読み込み
df = pd.read_csv('sales_data.csv')

# 2. 日付データを分解
df['日付'] = pd.to_datetime(df['日付'])
df['年'] = df['日付'].dt.year
df['月'] = df['日付'].dt.month
df['曜日'] = df['日付'].dt.dayofweek
df['週末フラグ'] = (df['曜日'] >= 5).astype(int)

# 3. カテゴリカル変数をエンコード
le = LabelEncoder()
df['店舗_encoded'] = le.fit_transform(df['店舗'])

# 4. 集約特徴量を作成
店舗別統計 = df.groupby('店舗')['売上'].agg(['mean', 'std']).reset_index()
店舗別統計.columns = ['店舗', '店舗平均売上', '店舗売上の標準偏差']
df = df.merge(店舗別統計, on='店舗')

# 5. 交互作用項を作成
df['広告費×来客数'] = df['広告費'] * df['来客数']

# 6. スケーリング
scaler = StandardScaler()
df[['広告費', '来客数']] = scaler.fit_transform(df[['広告費', '来客数']])

# 7. 不要な列を削除
df = df.drop(['日付', '店舗'], axis=1)

print(df.head())

実践アドバイス:よくある失敗と対策

失敗1:データリーク(Data Leakage)

何が起きるか:
訓練データに、テストデータの情報が漏れる。精度が異常に高くなるけど、実運用では全く使えない。

例:

# ダメな例
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
df[['売上']] = scaler.fit_transform(df[['売上']])  # 全データで標準化

X_train, X_test, y_train, y_test = train_test_split(df, ...)

訓練データとテストデータを分ける前に、全データで標準化しちゃってる。テストデータの情報が訓練に漏れてる。

正しいやり方:

# 正しい例
X_train, X_test, y_train, y_test = train_test_split(df, ...)

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)  # 訓練データで学習
X_test = scaler.transform(X_test)  # テストデータに適用

実務での失敗談:
ある案件で、データリークに気づかず納品した。クライアントが実運用したら、精度が半分以下に落ちた。「話が違う」ってクレーム。信頼を失いかけた。

訓練とテストのデータ分割は、前処理の最初にやる。これは鉄則。

深夜、クライアントからのメールを見て焦る表情の40代男性の線画イラスト

失敗2:過度な特徴量エンジニアリング

特徴量を作りすぎると、過学習(overfitting)する。訓練データでは精度が高いけど、新しいデータでは精度が低い。

目安:

  • データ数が1000行 → 特徴量は10~20個
  • データ数が10000行 → 特徴量は30~50個

特徴量の数は、データ数の1/50~1/100くらいが安全。

対策:
特徴量の重要度を確認して、不要な特徴量を削除する。

from sklearn.ensemble import RandomForestRegressor

model = RandomForestRegressor()
model.fit(X_train, y_train)

# 特徴量の重要度
importance = pd.DataFrame({
    '特徴量': X_train.columns,
    '重要度': model.feature_importances_
}).sort_values('重要度', ascending=False)

print(importance)

# 重要度が低い特徴量を削除
threshold = 0.01
important_features = importance[importance['重要度'] > threshold]['特徴量']
X_train = X_train[important_features]
X_test = X_test[important_features]

失敗3:ドメイン知識を無視した特徴量

統計的には良さそうでも、ビジネス的に意味がない特徴量を作ってしまう。

実務での例:
ある小売店の売上予測で、「前日の売上」を特徴量に入れた。精度は高かった。

でも、クライアントから「前日の売上がわからないと予測できないの?それじゃ意味ないよ」って言われた。

当日の朝に売上を予測したいのに、前日の売上を使ってたら、予測のタイミングが合わない。

対策:
クライアントに、いつ何を予測したいのか、詳しくヒアリングする。

  • 予測するタイミング:いつ?
  • 予測する期間:何日後?
  • 利用可能なデータ:予測時点で何がわかってる?

これを確認してから、特徴量を作る。

失敗4:欠損値補完の方法を統一しすぎる

全ての列に同じ方法(例:平均値補完)を使うと、データの特性を無視してしまう。

列ごとに、最適な方法を選ぶ。

# 列ごとに欠損値補完の方法を変える
補完方法 = {
    '売上': '平均値',
    '来客数': '中央値',
    '天気': '最頻値',
    '気温': '線形補間'
}

for col, method in 補完方法.items():
    if method == '平均値':
        df[col].fillna(df[col].mean(), inplace=True)
    elif method == '中央値':
        df[col].fillna(df[col].median(), inplace=True)
    elif method == '最頻値':
        df[col].fillna(df[col].mode()[0], inplace=True)
    elif method == '線形補間':
        df[col].interpolate(method='linear', inplace=True)

失敗5:前処理のコードが再利用できない

案件ごとに、毎回ゼロからコードを書いてると、時間がかかる。

対策:
前処理のテンプレートを作って、再利用する。

def preprocess_data(df, config):
    """
    データ前処理の共通関数

    Parameters:
    df: pandas DataFrame
    config: dict, 前処理の設定

    Returns:
    df: 前処理済みDataFrame
    """
    # 日付データの分解
    if 'date_columns' in config:
        for col in config['date_columns']:
            df[col] = pd.to_datetime(df[col])
            df[f'{col}_year'] = df[col].dt.year
            df[f'{col}_month'] = df[col].dt.month
            df[f'{col}_dayofweek'] = df[col].dt.dayofweek

    # 欠損値補完
    if 'missing_value_strategy' in config:
        for col, strategy in config['missing_value_strategy'].items():
            if strategy == 'mean':
                df[col].fillna(df[col].mean(), inplace=True)
            elif strategy == 'median':
                df[col].fillna(df[col].median(), inplace=True)

    # カテゴリカル変数のエンコーディング
    if 'categorical_columns' in config:
        for col in config['categorical_columns']:
            le = LabelEncoder()
            df[f'{col}_encoded'] = le.fit_transform(df[col])

    return df

# 使い方
config = {
    'date_columns': ['購入日'],
    'missing_value_strategy': {'売上': 'mean', '来客数': 'median'},
    'categorical_columns': ['店舗']
}

df = preprocess_data(df, config)

私はこういう関数を、案件ごとにブラッシュアップしてる。今では、前処理が30分で終わる。

よくある質問(FAQ)

Q1: データ前処理の勉強、どこから始めればいい?

おすすめの順番:

  1. Pandasの基礎(公式ドキュメント、Kaggle Learn)
  2. 欠損値の扱い方(上で紹介した5つの手法)
  3. 特徴量エンジニアリング(Kaggleのコンペで実践)

Kaggleは、データ前処理の宝庫。上位者のNotebookを読むと、めちゃくちゃ勉強になる。

Q2: どれくらいで実務レベルになる?

人による。でも目安:

  • Pythonの基礎がある人:1~2ヶ月
  • プログラミング初心者:3~4ヶ月

毎日1~2時間学習すれば、3ヶ月で簡単な案件は取れる。

私の場合、Pandasは仕事で使ってたから、データ前処理の学習は1ヶ月くらいだった。

Q3: 案件でデータ前処理が難しすぎたらどうする?

正直に言う。「この部分は難しいので、調べて対応します」って。

無理して引き受けて、できませんでしたは最悪。

でも、「できる範囲」を提示すれば、クライアントは理解してくれる。

実務での経験:
あるクライアントから「画像データの前処理もお願いしたい」って言われた。でも私、画像はやったことない。

「画像は専門外なので、テキストデータの前処理に専念させてください」って言った。クライアントは「わかりました」って。無理しなくて良かった。

Q4: 特徴量エンジニアリング、どこまでやればいい?

予測精度が頭打ちになるまで。

私のやり方:

  1. まず基本的な特徴量で予測(ベースライン)
  2. 特徴量を追加して予測精度を確認
  3. 精度が上がらなくなったら終了

精度が1%上がるごとに、特徴量の追加が難しくなる。どこかで見切りをつける。

クライアントとの契約で「精度〇〇%を目指す」って決めてあれば、それを目標にする。

Q5: データ前処理って、案件でどれくらい時間かかる?

データの状態による。

  • クリーンなデータ:1~2時間
  • 普通のデータ:5~10時間
  • 汚いデータ:20時間以上

初めての案件は、予想の2~3倍かかる。余裕を持ってスケジュールを立てる。

私の初案件は、データクリーニングだけで3日かかった。今は、同じ作業が半日で終わる。慣れると早くなる。

Q6: ドメイン知識がない業界の案件、受けていい?

受けていい。ただし、クライアントに確認しながら進める。

データ分析の技術は汎用的。業界が変わっても、基本は同じ。

でも、特徴量エンジニアリングでは、ドメイン知識が必要。わからないことは、クライアントに聞く。

「この変数は、ビジネス的にどういう意味ですか?」
「この数値が高いと、何が起きますか?」

こういう質問をすると、クライアントも「ちゃんと考えてくれてる」って思ってくれる。

自宅でクライアントとビデオ会議しながらメモを取る20代女性の線画イラスト

Q7: データ前処理の本、おすすめは?

実務で使える本:

  • 「前処理大全」(本橋智光)
  • 「Kaggleで勝つデータ分析の技術」(門脇大輔ほか)
  • 「Pythonではじめる機械学習」(Andreas C. Müller)

この3冊を読めば、実務レベルのデータ前処理ができる。

私は「前処理大全」を何度も読み返してる。案件で困ったら、この本を開く。

まとめ:データ前処理は地味だけど、最も価値があるスキル

ここまで読んでくれてありがとう。データ前処理の重要性、理解してもらえたと思う。

最後に、重要なポイントをまとめる。

データ前処理が重要な理由

  • 実務のデータは9割が汚い
  • 前処理の質が予測精度を決める
  • 前処理ができる人は希少価値が高い
  • 副業案件で最も需要がある「地味なスキル」

欠損値補完の5つの手法

  1. 削除(欠損値が少ない時)
  2. 平均値・中央値補完(基本)
  3. 前後の値で補完(時系列データ)
  4. 予測モデルで補完(欠損値が多い時)
  5. 欠損フラグを立てる(欠損自体が情報)

特徴量エンジニアリングのテクニック

  1. 時系列データから特徴量を抽出
  2. カテゴリカル変数のエンコーディング
  3. 数値データのスケーリング
  4. 交互作用項の作成
  5. 集約特徴量の作成
  6. 外れ値の処理

実務でよくある失敗

  • データリーク
  • 過度な特徴量エンジニアリング
  • ドメイン知識の無視
  • 欠損値補完の方法を統一しすぎる
  • 前処理のコードが再利用できない

データ前処理は、機械学習の華やかな部分じゃない。地味。でも、実務で最も価値がある。

私が月30万円稼げてるのも、データ前処理のスキルがあるから。クライアントが困ってる「汚いデータ」を綺麗にできる。それが、副業での差別化ポイント。

もしあなたが、データサイエンスで副業したいなら。機械学習のアルゴリズムを勉強するより、データ前処理を極めた方がいい。需要がある。単価も高い。案件も取りやすい。

まずは、Kaggleで練習する。上位者のNotebookを読んで、真似する。

そして、簡単な案件に提案してみる。「データクリーニング・前処理も対応可能です」って一文を入れる。これだけで、採用率が変わる。

データ前処理は、地味だけど最も価値があるスキル。これを極めれば、副業で安定して稼げる。

それじゃ、頑張って!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いたエンジニア

渡辺 一誠のアバター 渡辺 一誠 バックエンドスペシャリスト

バックエンドに長く携わるスペシャリストで、高負荷環境での最適化が得意。論理的かつストイックだが仲間へのサポートは手厚い。クラシック音楽が好きで、集中したい時はよく流している。確かな技術でプロジェクトを支える存在。

目次