🔹 フェーズ1:データ分析基礎(Python・可視化)【Week 1〜8】
🔹 フェーズ2:機械学習基礎と予測モデル構築【Week 9〜16】
🔹 フェーズ3:農業応用プロジェクト制作【Week 17〜24】
週 | 内容 | 実習・教材例 |
Week 1 | 農業データの概要・CSV操作 | センサーデータ(気温・湿度・CO₂)読み込み |
Week 2 | pandasによるデータ整形 | 欠損補完・日付処理・ユニット変換(℃→℉など) |
Week 3 | matplotlib / seabornで可視化① | 折れ線グラフ・散布図・ヒストグラム |
Week 4 | matplotlib / seabornで可視化② | 相関行列ヒートマップ・複数変数の比較可視化 |
Week 5 | データクリーニング演習 | 異常値除去、スケーリング(標準化・MinMax) |
Week 6 | GroupByと時系列集計 | 「1日ごと」「月ごと」などに集計し可視化 |
Week 7 | 実データ演習①:ビニールハウス温湿度 | 目標:快適環境の変動パターンを可視化 |
Week 8 | 小テスト & 発展課題 | 生育データ × 気象データのパターン分析 |
週 | 内容 | 実習・教材例 |
Week 9 | 教師あり学習の考え方(分類/回帰) | タスクの違いをグラフで視覚的に理解 |
Week 10 | 線形回帰と重回帰 | 施肥量と収量の関係予測モデル構築 |
Week 11 | ロジスティック回帰と分類タスク | 肥料種類・施肥時期による等級分類 |
Week 12 | 決定木・ランダムフォレスト | パラメータ変更による学習曲線比較 |
Week 13 | 勾配ブースティング(XGBoost) | 品質ランクの予測(等級A/B/C) |
Week 14 | モデル評価(RMSE・F1・混同行列など) | 検証・交差検証・オーバーフィッティング対策 |
Week 15 | 時系列予測(基本) | 温室内温度の未来予測(ARIMA) |
Week 16 | 時系列予測(応用) | 作物収量の月次予測(LSTMの導入紹介) |
週 | 内容 | プロジェクト例 |
Week 17 | 課題設定・テーマ決定 | 地元農家からニーズヒアリング(例:収量予測) |
Week 18 | データ収集と前処理 | 地方気象データ・作業記録データ・生育記録 |
Week 19〜21 | モデル構築と評価 | 精度・説明性のあるモデルを目指す |
Week 22 | 可視化ダッシュボード構築(Streamlit等) | 作業者向けに直感的な分析UIを構築 |
Week 23 | 発表準備・成果物まとめ | スライド・GitHub・プレゼンデモ準備 |
Week 24 | 成果発表会 | 地域関係者・農家・企業への発表会実施(ポスター or デモ) |
用途 | ツール・教材例 |
Python学習 | Google Colab + Jupyter Notebookベース教材(週単位で用意) |
可視化 | matplotlib, seaborn, plotly |
機械学習 | scikit-learn, XGBoost |
時系列 | statsmodels, Prophet, keras(LSTM) |
UI化 | Streamlit / Gradio |
データソース | 気象庁、アグリノート、農研機構オープンデータなど |
スキルカテゴリ | 到達レベル |
Python×分析 | pandas, NumPyで農業データ処理・可視化ができる |
モデル構築 | 回帰・分類モデルを適切に選択・構築できる |
精度評価 | RMSEやF1スコアで予測モデルの信頼性を評価できる |
応用設計 | 実データをもとに農業向けAIサービスを企画・試作できる |
📚 Week 1〜4:ノートブック教材(Jupyter/Colab用)
🧪 Week 1:農業データの取り扱い入門
タイトル : week01_intro_to_agri_data.ipynb
内容構成:
import pandas as pd
df = pd.read_csv("greenhouse_sensor_data.csv")
df.head()
データの型確認・変換(日時型など)
タイトル : week02_pandas_processing.ipynb
# Week 2: Pandasによるセンサーデータの基本処理
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
# 仮想センサーデータ作成
timestamps = [datetime(2025, 4, 1, hour=h) for h in range(24)]
data = {
'timestamp': timestamps,
'temperature': [25 + np.random.randn() for _ in range(24)],
'humidity': [60 + np.random.randn() * 5 for _ in range(24)],
'soil_moisture': [30 + np.random.randn() * 2 for _ in range(24)]
}
df = pd.DataFrame(data)
# 基本統計量
print("基本統計量:")
print(df.describe())
# 欠損値の導入と処理
df.loc[5, 'temperature'] = None
df.loc[10, 'soil_moisture'] = None
print("\n欠損データ処理:")
print("欠損数:\n", df.isnull().sum())
# 平均で補完
df_filled = df.fillna(df.mean(numeric_only=True))
# 外れ値の検出(Zスコアベース)
z_scores = (df_filled[['temperature', 'humidity', 'soil_moisture']] - df_filled[['temperature', 'humidity', 'soil_moisture']].mean()) / df_filled[['temperature', 'humidity', 'soil_moisture']].std()
outliers = (z_scores.abs() > 2)
print("\n外れ値の数:\n", outliers.sum())
# タイムスタンプをインデックスに
df_filled.set_index('timestamp', inplace=True)
# 移動平均
df_filled['temp_ma'] = df_filled['temperature'].rolling(window=3).mean()
# 表示
print("\n加工後のデータ:")
print(df_filled.head(10))
# CSVとして保存
df_filled.to_csv("cleaned_sensor_data.csv")
内容構成:
演習 :
タイトル : week03_visualization_basics.ipynb
# Week 3: センサーデータの可視化入門
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 前週で保存したデータを読み込む
df = pd.read_csv("cleaned_sensor_data.csv", parse_dates=["timestamp"])
df.set_index("timestamp", inplace=True)
# グラフの表示設定
plt.style.use("seaborn")
plt.rcParams["figure.figsize"] = (12, 6)
# 1. 温度と湿度の時系列グラフ
plt.plot(df.index, df["temperature"], label="Temperature (°C)", marker='o')
plt.plot(df.index, df["humidity"], label="Humidity (%)", marker='x')
plt.title("Temperature & Humidity over Time")
plt.xlabel("Time")
plt.ylabel("Values")
plt.legend()
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# 2. 土壌水分の棒グラフ
df["soil_moisture"].plot(kind="bar", title="Soil Moisture by Hour", color="green")
plt.ylabel("Soil Moisture (%)")
plt.tight_layout()
plt.show()
# 3. ペアプロットによる変数の相関視覚化
sns.pairplot(df[["temperature", "humidity", "soil_moisture"]])
plt.suptitle("Sensor Data Relationship", y=1.02)
plt.show()
# 4. 相関ヒートマップ
corr = df[["temperature", "humidity", "soil_moisture"]].corr()
sns.heatmap(corr, annot=True, cmap="coolwarm")
plt.title("Correlation Matrix")
plt.show()
タイトル : week04_correlation_and_heatmap.ipynb
# Week 4: 相関分析とヒートマップによる可視化
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# データ読み込み
df = pd.read_csv("cleaned_sensor_data.csv", parse_dates=["timestamp"])
df.set_index("timestamp", inplace=True)
# 相関係数の算出
corr_matrix = df[["temperature", "humidity", "soil_moisture"]].corr()
# 相関係数の表示
print("相関行列:")
print(corr_matrix)
# ヒートマップの作成
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
plt.title("Correlation Matrix of Sensor Data")
plt.show()
# 相関に関する補足テキスト
print("""
🔍 相関の読み解きポイント:
- temperature と humidity の相関が正なら、気温が上がると湿度も上がる傾向があります。
- 相関係数が -1〜1 に近いほど、強い関係性があります。
- 土壌水分が気温や湿度とどう関連するかを可視化し、管理戦略を考えましょう。
""")
タイトル : agri_project_template/
📁 ディレクトリ構成案
agri_project_template/
├── data/
│ ├── sensor_data.csv
│ ├── weather.csv
├── notebooks/
│ ├── 01_data_cleaning.ipynb
│ ├── 02_feature_engineering.ipynb
│ ├── 03_model_training.ipynb
│ ├── 04_evaluation.ipynb
│ └── 05_dashboard_streamlit.ipynb
├── README.md
├── requirements.txt
└── app/
└── dashboard.py
🔹 各ノートブックの概要
# 01_data_cleaning.ipynb:欠損処理、外れ値除去、型変換
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# データの読み込み
df = pd.read_csv("raw_agri_data.csv")
# --- データの基本確認 ---
print("📊 データの先頭:\n", df.head())
print("\n🧾 データ型:\n", df.dtypes)
print("\n📉 欠損状況:\n", df.isnull().sum())
# --- 型変換(文字列から日付型へ) ---
df['timestamp'] = pd.to_datetime(df['timestamp'])
# --- 欠損値の処理 ---
# 平均値で補完(数値列のみ)
df.fillna(df.mean(numeric_only=True), inplace=True)
# --- 外れ値検出・除去 ---
# Zスコアを使った外れ値除去
from scipy.stats import zscore
numeric_cols = ['temperature', 'humidity', 'soil_moisture']
z_scores = np.abs(zscore(df[numeric_cols]))
df_clean = df[(z_scores < 3).all(axis=1)]
# --- 確認 ---
print("\n✅ クレンジング後のデータ件数: ", len(df_clean))
print("🧽 外れ値除去前:", len(df), "→ 除去後:", len(df_clean))
# --- 結果の可視化(温度分布) ---
plt.hist(df_clean['temperature'], bins=20, color='orange', alpha=0.7)
plt.title("Temperature Distribution After Cleaning")
plt.xlabel("Temperature (°C)")
plt.ylabel("Frequency")
plt.grid(True)
plt.show()
# --- 保存 ---
df_clean.to_csv("cleaned_agri_data.csv", index=False)
# 02_feature_engineering.ipynb:特徴量エンジニアリング編
import pandas as pd
import numpy as np
# 前処理済みデータの読み込み
df = pd.read_csv("cleaned_agri_data.csv", parse_dates=["timestamp"])
# タイムスタンプをインデックスに
df.set_index("timestamp", inplace=True)
# --- 時間系の特徴量 ---
df['hour'] = df.index.hour
df['dayofweek'] = df.index.dayofweek
df['is_weekend'] = df['dayofweek'].apply(lambda x: 1 if x >= 5 else 0)
# --- 温度の変動(前時間との差分) ---
df['temp_diff'] = df['temperature'].diff().fillna(0)
# --- 湿度・土壌水分の移動平均(3時間) ---
df['humidity_ma3'] = df['humidity'].rolling(window=3, min_periods=1).mean()
df['soil_moisture_ma3'] = df['soil_moisture'].rolling(window=3, min_periods=1).mean()
# --- 湿度と土壌水分の比率(例:乾燥傾向) ---
df['moisture_to_humidity'] = df['soil_moisture'] / (df['humidity'] + 1e-5)
# --- 作物に関係しそうな合成特徴量例(例:蒸散指数っぽいもの) ---
df['env_index'] = (df['temperature'] * (100 - df['humidity'])) / 100
# --- 最終確認 ---
print("✅ 特徴量の一部:\n", df[[
'temperature', 'humidity', 'soil_moisture',
'hour', 'is_weekend', 'temp_diff',
'humidity_ma3', 'moisture_to_humidity', 'env_index'
]].head())
# --- 保存 ---
df.to_csv("engineered_agri_data.csv")
03_model_training.ipynb :回帰モデル or 分類モデルの訓練
# 03_model_training.ipynb:モデルの訓練(回帰または分類)
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import mean_squared_error, f1_score, classification_report
# データ読み込み
df = pd.read_csv("engineered_agri_data.csv", parse_dates=["timestamp"])
# 目的変数(例:soil_moistureの予測)
target_column = "soil_moisture"
# 特徴量として使用するカラムを定義
feature_cols = [
'temperature', 'humidity',
'hour', 'is_weekend', 'temp_diff',
'humidity_ma3', 'moisture_to_humidity', 'env_index'
]
# 特徴量と目的変数に分割
X = df[feature_cols]
y = df[target_column]
# データ分割(8:2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# --- 回帰モデルで学習(Random Forest) ---
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 予測
y_pred = model.predict(X_test)
# 評価(回帰)
rmse = mean
# 04_evaluation.ipynb:モデル評価(回帰 or 分類)と可視化
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import (
mean_squared_error, mean_absolute_error, r2_score,
classification_report, confusion_matrix, f1_score
)
# 予測結果と正解ラベルの読み込み
# ※前のノートブックから引き継いだ変数を使用する場合はスキップしてOK
# y_test, y_pred を使用
# --- 回帰モデル評価 ---
rmse = mean_squared_error(y_test, y_pred, squared=False)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"📏 RMSE: {rmse:.2f}")
print(f"📐 MAE: {mae:.2f}")
print(f"📈 R² Score: {r2:.2f}")
# ---
# 05_dashboard_streamlit.ipynb:Streamlitでダッシュボード可視化
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# タイトル
st.title("🌾 スマート農業ダッシュボード")
st.subheader("センサーデータと予測結果の可視化")
# データ読み込み
df = pd.read_csv("engineered_agri_data.csv", parse_dates=["timestamp"])
df.set_index("timestamp", inplace=True)
# 予測結果の読み込み(あれば)
try:
df['predicted_soil_moisture'] = pd.read_csv("predicted_soil_moisture.csv")['prediction']
except:
st.warning("💡 予測データが読み込まれていません。")
# サイドバー:日付選択
st.sidebar.header("📅 表示期間フィルター")
date_range = st.sidebar.date_input("期間を選択", [df.index.min(), df.index.max()])
if len(date_range) == 2:
df = df.loc[date_range[0]:date_range[1]]
# センサーデータの時系列表示
st.line_chart(df[['temperature', 'humidity', 'soil_moisture']])
# 予測結果と比較
if 'predicted_soil_moisture' in df.columns:
st.subheader("🔍 土壌水分の実測 vs 予測")