🐱

ChatGPTを使って野良猫の保護活動をする場合

に公開

2月から5月は、野良猫がもっとも繁殖しやすい時期です。
ある日ふと庭先からMeow Meowという鳴き声が聞こえ、気づけば子猫が産み落とされていた──そんな経験をした人もいるかもしれません。(実は、私自身もそうでした)

私も当初は野良猫に関する知識はほとんどなかったのでGGってみたところ、次のような情報に辿り着きました。

  • 野良の子猫の生存率は非常に低く、自然界では生後1ヶ月の子猫の50%が死亡するというデータもある。
  • 親猫の育児放棄、事故、病気などで親が不在の場合、ほぼ確実に死亡する

そのため、野良猫や地域猫を保護している団体は以下のようなことを推奨しているようです。

  1. 子猫を見つけたら、まず親猫の存在を確認する
  2. 親猫が見当たらない場合は、一時保護し、里親を探す or 自分で飼う
  3. 難しい場合は、地域の保護団体へ相談する
    (参考: 野良の子猫を見つけたらどうすればよい?保護方法・やるべきことを解説をもとに編集)

(※保護行動の是非や自然淘汰に関する議論は、ここでは一旦横に置きます)

私は現時点で実際に保護活動をしているわけではありませんが、もし将来的にそうしたことを行うなら、ChatGPTのようなAIをどのように活用できるのか? という観点から、いくつかのプロンプト例を交えてアイデアをまとめてみます。

想定シーン

  • 時期:5月頃
  • 場所:東京テレポート〜青海エリア周辺

alt text
東京テレポート〜青海エリア周辺の航空写真。今回はこの辺りに捨て子猫の場所を推定してみる。

プロンプト例

1. 推定ロジックの生成

子猫が産み落とされる可能性がある場所を、ロジカルに、根拠に基づいて推定してほしい。

alt text

2. 子猫スポットを推定

この航空写真の上に、出現確率の高い場所を重ね合わせてプロットせよ
(航空写真を添付)

ChatGPTが生成したコード
# Load the second satellite map image
image_path_2 = "/mnt/data/318c0598-f646-4d66-a495-70f8ab136caa.png"
img2 = Image.open(image_path_2)
draw2 = ImageDraw.Draw(img2)

# Estimate likely kitten appearance spots (manually selected based on terrain features)
likely_spots_2 = [
    (380, 250),  # Park area on left with trees and isolation
    (580, 480),  # Circular plaza with surrounding trees - partial shelter
    (720, 300),  # Near fenced lots / construction - low human interference
    (1040, 420), # Back side of parking lot area, near edge of urban zone
    (900, 580),  # Rear of warehouse/industrial area - quiet
]

# Draw red pins
for spot in likely_spots_2:
    x, y = spot
    radius = 10
    draw2.ellipse((x - radius, y - radius, x + radius, y + radius), fill='red', outline='black')

# Display the result
plt.figure(figsize=(12, 8))
plt.imshow(img2)
plt.axis('off')
plt.title("Likely Kitten Appearance Spots (Pins Only)")
plt.show()

alt text

3. 確率分布等高線を重ねて可視化

確率分布等高線を重ねて可視化して

ChatGPTが生成したコード
# Re-define the likely spots for second image since they are lost between executions
likely_spots_2 = [
    (380, 250),  # Park area on left with trees and isolation
    (580, 480),  # Circular plaza with surrounding trees - partial shelter
    (720, 300),  # Near fenced lots / construction - low human interference
    (1040, 420), # Back side of parking lot area, near edge of urban zone
    (900, 580),  # Rear of warehouse/industrial area - quiet
]

# Create a new probability map for the second image
prob_map2 = np.zeros((height2, width2))

# Add Gaussian distributions around each likely spot
for x, y in likely_spots_2:
    xv, yv = np.meshgrid(np.arange(width2), np.arange(height2))
    gaussian = np.exp(-((xv - x)**2 + (yv - y)**2) / (2 * 80**2))  # 80px std dev
    prob_map2 += gaussian

# Normalize the map
prob_map2 = prob_map2 / np.max(prob_map2)

# Plot the image with contour overlay
plt.figure(figsize=(12, 8))
plt.imshow(img2)
plt.contour(prob_map2, levels=10, linewidths=1.5, cmap='hot', alpha=0.7)
plt.axis('off')
plt.title("Kitten Appearance Probability Contour Overlay (2nd Area)")
plt.show()

alt text

4. 巡回ルートを計算、可視化

最も効率的な巡回ルートを画像に重ね合わせる形で可視化して。この問題はすべての地点を1度のみ通過すればよいため、巡回セールスマン問題として解ける。

ChatGPTが生成したコード
# Re-import necessary modules after environment reset
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial.distance import pdist, squareform
from itertools import permutations

# Reload the image
image_path_2 = "/mnt/data/318c0598-f646-4d66-a495-70f8ab136caa.png"
img2 = Image.open(image_path_2)

# Re-define the likely kitten locations
likely_spots_2 = [
    (380, 250),
    (580, 480),
    (720, 300),
    (1040, 420),
    (900, 580),
]

# Recalculate distance matrix and TSP solution
coords = np.array(likely_spots_2)
dist_matrix = squareform(pdist(coords))

# Solve TSP via brute force (since number of points is small)
best_order = None
min_distance = float("inf")
for order in permutations(range(len(coords))):
    dist = sum(dist_matrix[order[i], order[i + 1]] for i in range(len(order) - 1))
    if dist < min_distance:
        min_distance = dist
        best_order = order

# Generate probability heatmap for contour overlay
width2, height2 = img2.size
prob_map2 = np.zeros((height2, width2))
for x, y in likely_spots_2:
    xv, yv = np.meshgrid(np.arange(width2), np.arange(height2))
    gaussian = np.exp(-((xv - x)**2 + (yv - y)**2) / (2 * 80**2))
    prob_map2 += gaussian
prob_map2 = prob_map2 / np.max(prob_map2)

# Plot the result with route
plt.figure(figsize=(12, 8))
plt.imshow(img2)
plt.contour(prob_map2, levels=10, linewidths=1.5, cmap='hot', alpha=0.7)

# Draw the optimized path
for i in range(len(best_order) - 1):
    start = coords[best_order[i]]
    end = coords[best_order[i + 1]]
    plt.plot([start[0], end[0]], [start[1], end[1]], color='blue', linewidth=2, marker='o')
    plt.annotate('', xy=end, xytext=start, arrowprops=dict(arrowstyle="->", color='blue', lw=1.5))

# Number the points
for i, idx in enumerate(best_order):
    x, y = coords[idx]
    plt.text(x + 5, y - 10, f'{i+1}', color='white', fontsize=12, weight='bold')

plt.axis('off')
plt.title("Optimized Patrol Route (TSP) for Kitten Search")
plt.show()

alt text

ポイントが減っているが、最後の手直しは人間がすれば吉。

まとめ

ChatGPTを活用すれば、野良猫の保護活動においても「出現確率の推定」や「巡回ルートの最適化」といった分析作業を簡単に実現できます。

とくにBeta機能だったode Interpreter(現: Pythonモード)がGAされれたため、画像上での可視化や地理データの扱いもスムーズに行えるようになりました。

ChatGPTのようなサービスが一般化したことで我々パンピーの情報の探索コストや推論の敷居は大きく下がりましたが、その推論を実際の行動に移すステップ──今回で言えば実際に見に行き、保護し、対応するような行動──の価値は相対的に高まっているように思います。

今回はアイディアの共有兼思考実験が目的だったのでこの辺で終わりにします。

以上です。

Discussion