Kaggleに特化したChatGPTのカスタムインストラクションの紹介

# 用語説明
◆**ChatGPTのカスタムインストラクション**：ChatGPTに対して、あらかじめユーザー固有の前提条件や指示を組み込み、回答品質を向上させるための機能。

https://openai.com/index/custom-instructions-for-chatgpt/

ChatGPTのUIにおいて、右上のユーザーアイコンをクリックし、`ChatGPTをカスタマイズする`から設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/e59f37a0-6ab5-3763-2a39-cad320fe8eb9.png)

カスタム指示に、自分についての情報とChatGPTの回答方法を指定することができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/17ea7cff-b731-cea1-b841-b98a2ea3777d.png)


# はじめに
今年を振り返ると、Kaggle Masterになるためにあらゆる手を尽くした年でした。
その取り組みの一環として、**ChatGPTをKaggleに特化させるカスタムインストラクション**を設定しました。本記事では、Kaggle向けにカスタマイズしたChatGPTのカスタムインストラクションの例をご紹介いたします。Kaggle以外にも、任意のAI開発プロジェクトに有効です。


# Kaggleに特化したChatGPTのカスタムインストラクション
今回ご紹介するカスタムインストラクションは、私自身のコーディングスタイルを反映し、Kaggleでの作業効率を最大化することを目的としています。
- **コンペ概要・ベースライン情報を前提知識にする**：新しいチャットを開始する際でも、背景知識が事前に共有されているため、新しいチャットを立ち上げた直後でも、認識合わせが済んだ状態で開発に素早く着手できます。  
- **型ヒントを重視させる**：Python 3.10以降で加わった型ヒント（listやtupleなど）を優先し、コードを明確でメンテナンスしやすい状態にします。  
- **テストコード作成を推奨する**：pytestを活用したテストコードの生成を促し、モデル精度のみならずコード品質の向上も図ります。


## カスタムインストラクションの中身

### 「回答を向上させるために、自分について ChatGPT に知っておいてほしいことは何ですか？」

```
# 私についての情報
- 日本語のみを話します。
- 機械学習が専門のデータサイエンティスト
- 今目標としているのはKaggleの『■■■■』というコンペで優勝することです。
# コンペの概要
…（ここにコンペの詳細、ベースラインモデル、評価指標、使用モデル例などを記述します）…
```
「日本語のみを話します。」と明示している理由は、コンペ関連の英文資料などを参照する際に、英語につられてChatGPTが英語で回答することを防ぎたい意図です。
自分自身の情報については最低限共有します。機械学習が専門のデータサイエンティストということだけ記しました。
このカスタムインストラクションのメインの構成要素として、コンペ概要やベースラインなど、1500文字の制限範囲内で可能な限り情報を詰め込みます。自分が考えているアイデアも盛り込んでいきます。

### 「どのように ChatGPT に回答してほしいですか？」

```
- あなたは、Kaggleや機械学習についての全てを知っています。
- あなたは、型ヒントを必ず書きます。ListやTupleではなく、listやtupleを好みます。つまり、ユーザーのPythonのバージョンは3.10以降であることを知っています。
- あなたは、関数化、クラス化を好みます。
- あなたは、常にリファクタリングのことを考えています。
- あなたは、pytestでテストコードを書きます。
- あなたは、明瞭なDocstringを書きます。
- あなたは、コメントやDocstringを日本語で書きます。
- あなたは、コードには How、テストコードには What、コミットログには Why、コードコメントには Why notを必ず書きます。
```

ここでは、Kaggleや機械学習の専門知識を前提として、ChatGPTがコードを書き出す際のスタイルを詳細に指定しています。型ヒントを積極的に利用し、関数やクラス構造を重視することでコードの可読性と再利用性を高めます。また、常にリファクタリングを意識し、pytestによるテストコードを作成することで、コード品質の向上と将来的なメンテナンス性確保を狙います。さらに、Docstringやコメントは日本語で記述し、"How"・"What"・"Why"・"Why not"といったキーワードを入れることで、開発時やテスト時の意図や背景が明確になります。

この"How"・"What"・"Why"・"Why not"は、ソフトウェアテストの専門家であるt_wada氏による下記のツイートから着想を得ています：

https://x.com/t_wada/status/904916106153828352


これらのカスタムインストラクションを設定することで、ChatGPTはKaggleの問題背景を理解した上で、型ヒント、リファクタリング、テストコードといった開発上の品質要件にも柔軟に対応してくれます。その結果、新しいチャットを始めるときでも、スムーズに議論やコード修正を行うことができ、開発者体験は向上します。

# 実例
ここでは、ChatGPTのカスタムインストラクションを有効にした場合と無効にした場合で、同一の入力プロンプトに対する応答がどのように異なるかを比較します。

**入力プロンプト**

```
フィボナッチ数列の関数を書いてください
```


## カスタムインストラクションがOFFの場合のChatGPTの回答

以下は、カスタムインストラクションを設定せず、ChatGPTにフィボナッチ数列を求める関数の実装例を求めた場合の出力例です。ここでは、主に再帰的なアプローチや動的計画法を用いた実装例が示されています。

---


以下は、フィボナッチ数列を計算するPython関数の例です。これは再帰を使ったシンプルな方法です。

### 再帰を使ったフィボナッチ数列関数

```python
def fibonacci_recursive(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)

# 使用例
n = 10
print([fibonacci_recursive(i) for i in range(n)])
```

### 効率的な方法：動的計画法を使った実装
再帰を使う方法は直感的ですが、計算量が増えるため効率的ではありません。効率的な方法として、動的計画法を使った実装を以下に示します。

```python
def fibonacci_dp(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    
    fib = [0, 1]  # 最初の2つのフィボナッチ数
    for i in range(2, n + 1):
        fib.append(fib[i - 1] + fib[i - 2])
    return fib[-1]

# 使用例
n = 10
print([fibonacci_dp(i) for i in range(n)])
```

### メモ化を使った再帰的な実装
再帰の簡潔さを維持しつつ、効率化するにはメモ化を使用します。

```python
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci_memo(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci_memo(n - 1) + fibonacci_memo(n - 2)

# 使用例
n = 10
print([fibonacci_memo(i) for i in range(n)])
```

どの方法を選ぶかは、用途やデータサイズによります。効率を重視するなら、動的計画法やメモ化を使った方法が適しています。



## カスタムインストラクションがONの場合のChatGPTの回答

続いて、カスタムインストラクションを有効にした場合です。型ヒントを使用すること、Docstringやコメントを日本語で記述するといった指示がChatGPTに与えられています。その結果、以下のような洗練されたコードが得られます。

---


以下は、フィボナッチ数列を生成する関数です。この関数は、再帰を使わずに動的計画法を用いて効率的に計算します。

```python
def fibonacci(n: int) -> int:
    """
    指定したインデックス n のフィボナッチ数を計算します。

    Args:
        n (int): フィボナッチ数列のインデックス（0から始まる）。

    Returns:
        int: n 番目のフィボナッチ数。
    
    Raises:
        ValueError: n が負の整数の場合。
    """
    if n < 0:
        raise ValueError("nは0以上の整数である必要があります。")
    if n == 0:
        return 0
    if n == 1:
        return 1
    
    prev, curr = 0, 1
    for _ in range(2, n + 1):
        prev, curr = curr, prev + curr
    return curr

# 使用例
if __name__ == "__main__":
    print(f"フィボナッチ数列の10番目の値: {fibonacci(10)}")  # 出力: 55
```

### 解説
1. **動的計画法を使用**:
   - 計算済みの値を保存し、逐次的に計算することで効率を上げています。
2. **再帰を使用しない**:
   - 再帰を使うとスタックオーバーフローのリスクがありますが、このコードではそのリスクを回避しています。
3. **計算量**:
   - 時間計算量は \(O(n)\)、空間計算量は \(O(1)\) です。

他に、全てのフィボナッチ数列をリストとして生成したい場合も対応可能ですので、お気軽にお尋ねください。




# まとめ

今回ご紹介したカスタムインストラクションを用いることで、ChatGPTはKaggleのコンペ概要やベースライン情報を前提知識として保持し、コンペで有用なコードや戦略を即座に提示できるようになります。また、型ヒントやテストコード、明瞭なDocstringといった品質面での要求事項にも自動的に応えられるため、コードの信頼性や再利用性が大幅に向上します。
これにより、新たなチャットを開始する際に、いちいちコンペの文脈を説明したり、同じパターンのコード構造を再度提案する必要がなくなり、より高度な実験や分析に素早く着手できます。競争が激しいKaggleの世界では、こうした時間短縮や品質改善は、最終的なスコア向上や上位入賞への一歩につながる可能性があります。
カスタムインストラクションは本当に簡単に設定でき、大きな効果を上げる事ができます。ご自身のコーディングスタイルに合わせて、最強のカスタムインストラクションを見つけてください！

本記事は以上です。皆様の良いKaggleライフを応援しております。