ChatGPT3 vs ChatGPT4(実用性が激増してる件について)


# ChatGPT4、大きな改善2点
触ってみてすぐに気づいたのがこちら。
①プログラミング能力の向上
②記憶の向上

この2点、IT業界にかなり関わりが深くなると思う。
①は言わずもがな。しかしより本質的かもしれないのは②。

そして、①②の組み合わせで起こる実用性の向上がかなり凄い気がしている。
「どちらか」ではダメで、「どちらも」起こったことでChatGTP3よりも大幅に実用度が上がったと思う。

## ①「プログラミング能力の向上」の検証
### 指示
>pandasとpolars、基本的な処理を5つくらい書いてみて。時間の計測関数も用意して、出来るだけ短く簡潔にまとめて。コメントは最小限にして。

上記をGPT3と４にそれぞれ投げてみて、返ってきた結果を下に記載。
3の方は、プログラムを2つに分けてきた(めんどいェ・・・)。

#### GPT3
```gpt3_pandas.py
import pandas as pd
import numpy as np
import time

# データフレームの作成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']},
                   index=[0, 1, 2, 3])

df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']},
                   index=[4, 5, 6, 7])

# 1. データフレームのマージ
start_time = time.time()
merged_df = pd.merge(df1, df2, how='outer', on='A')
print("--- %s seconds ---" % (time.time() - start_time))
print(merged_df)

# 2. データフレームのグループ化
start_time = time.time()
grouped_df = df1.groupby(['A']).sum()
print("--- %s seconds ---" % (time.time() - start_time))
print(grouped_df)

# 3. 条件に合う行の抽出
start_time = time.time()
filtered_df = df1[df1['B'] == 'B1']
print("--- %s seconds ---" % (time.time() - start_time))
print(filtered_df)

# 4. 新しい列の追加
start_time = time.time()
df1['E'] = np.nan
print("--- %s seconds ---" % (time.time() - start_time))
print(df1)

# 5. データフレームの並び替え
start_time = time.time()
sorted_df = df1.sort_values(by=['B'], ascending=False)
print("--- %s seconds ---" % (time.time() - start_time))
print(sorted_df)
```
```gpt3_polars.py
import polars as pl
import time

# データフレームの作成
df1 = pl.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})

df2 = pl.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7
```

ちなみに3の方は、ここで止まったので「続けて」と書いたら
> 申し訳ありませんが、質問内容が不明確です。もう少し具体的なご質問をいただけますか？

と返されたわけですが・・・。


#### GPT4
```gpt4.py
import pandas as pd
import polars as pl
import time

def measure_time(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.5f} seconds")
        return result
    return wrapper

# データの作成
@measure_time
def create_data(library):
    if library == "pandas":
        df = pd.DataFrame({"A": range(1000), "B": range(1000, 2000)})
    elif library == "polars":
        df = pl.DataFrame({"A": range(1000), "B": range(1000, 2000)})
    return df

# 列の追加
@measure_time
def add_column(df, library):
    if library == "pandas":
        df["C"] = df["A"] * 2
    elif library == "polars":
        df = df.with_columns([(df["A"] * 2).alias("C")])
    return df

# 列の削除
@measure_time
def drop_column(df, library):
    if library == "pandas":
        df = df.drop(columns=["B"])
    elif library == "polars":
        df = df.drop("B")
    return df

# フィルタリング
@measure_time
def filter_rows(df, library):
    if library == "pandas":
        df = df[df["A"] > 500]
    elif library == "polars":
        df = df.filter(pl.col("A") > 500)
    return df

# グループ化と集約
@measure_time
def group_and_aggregate(df, library):
    if library == "pandas":
        df = df.groupby("A").sum()
    elif library == "polars":
        df = df.groupby("A").agg(pl.sum("C"))
    return df

libraries = ["pandas", "polars"]

for lib in libraries:
    print(f"\n{lib.upper()}")
    df = create_data(lib)
    df = add_column(df, lib)
    df = drop_column(df, lib)
    df = filter_rows(df, lib)
    df = group_and_aggregate(df, lib)

```
### 感想
●ChatGPT3
・冗長。「出来るだけ短く簡潔に」って書いてるのだが・・・。
・「続けて」で続けてくれない。ポンコツ。
・pandas覚えたての初心者がチュートリアルに沿って一生懸命進めてる感。
・適当なcsv用意してないとそもそも動かん。その説明も一切なし。

●　ChatGPT4
・ネスト関数使ってきやがったぞコイツ。
・デコレータも使いよる。
・改善の余地はあるが、3よりかなり良い。中級者は名乗って良い。
・「時間の計測関数も用意して、出来るだけ短く簡潔にまとめて。コメントは最小限にして」←この辺、ちゃんと意識している感じが素敵。


## ②「記憶の向上」の検証
記憶力が上がると何が嬉しいか？
複数の文章やコードを読み込ませて、即座に呼び出したり、タスク１と２をつなげて加工できる可能性がある。

プログラムと絡めて書くと、300行のソースファイルが10ファイルあるとする。
どこかにバグがあるらしいがどこにあるかわからない。
こういう時に、記憶する力を持っていてくれたら、ファイル１、ファイル２、ファイル３・・・と記憶させていって「おかしい箇所あった？」って聞けばすぐに見つけられるんじゃないかと思った。

#### GPT3
GPT3で試した時は結構悔しい思いをした。
新しいタスクを記憶させると古い記憶がなくなる？　のか、ごっちゃになってきたり、一部漏れが出てくる。
こちらは「全て記憶している」という前提で確認をしていると、件数がしばしば抜け落ちたりして「あ、こいつ信用できんわ」となった(非常に残念)。

やりとりを全部載せると冗長になるので、要点だけ。
例えば以下のようなタスクをいくつか記憶させる。

>タスク１として記憶して。
・お風呂を沸かす
・チョコレートを食べる
・山田太郎くんに電話をする

これを複数用意して、タスク２、タスク３、タスク４とかって登録していく。
「全部で何件登録したっけ？」と聞くと、12件登録したはずなのに「11件です」とかって返ってきたり、しばしばタスク内容を改竄される。

また、タスクと全然違う内容について質問して、またタスクについて聞くと既に忘れてて、「タスクとは何でしょうか？」みたいに返ってきたこともあって本当にがっかりした。

この類の処理は「99％正しい」くらいじゃないと使い物にならないので、諦めた。

#### GPT4
触った範囲内で言えば飛躍的な向上を見せてくれている。
ついにやりたいことができるかも！？

上記同様、タスクを1~4まで登録して件数を聞くと「12件」と返してきた。

また、タスク２の中に
>・パスタを買ってくる

タスク３の中に
>・パスタを食べる

が入っていたので、「パスタはどうするんだっけ？」と聞いてみたら、
>これまでに登録されたタスクに関連するパスタについての情報は以下の通りです。
>タスク2: パスタを買ってくる
>タスク3: パスタを食べる
>まず、タスク2でパスタを買ってきて、その後タスク3でパスタを食べる予定です。

と返してきた。時系列までちゃんと答えやがるぞ。

また、「全部のタスクの中で似た作業はどれ？全部グループ化して。」と聞いたら正しくまとめてきた。
こんな感じ。どのタスクにあった項目かも添えられている。

>グループ化:
>食べ物関連:
>タスク1: チョコレートを食べる
>タスク2: パスタを買ってくる
>タスク3: パスタを食べる

>電話関連:
>タスク1: 山田太郎くんに電話をする
>タスク2: 22時くらいに、花子ちゃんから電話がくるかも？

>メンテナンス関連:
>タスク2: 自転車のメンテナンス
>タスク3: 自動車のメンテナンス

>その他:
>タスク1: お風呂を沸かす
>タスク2: 21時からチェンソーマン
>タスク3: たくさん寝る
>タスク3: スクワット100回

これなら、もう少し高度なことが出来るのではと思ってちょっと無茶振りしてみた。

# ③プログラムを記憶させて、応用コードを書かせてみる
①②を通して実用段階に入ったと感じたので、より実践的な内容を投げてみることにした。

#### GPT4
まず、適当な関数を3つ記憶させた。
記憶のさせ方は「記憶して　[コード貼り付け]」で記憶してくれる。

適当な関数3つ。
```tekitou1.py
from datetime import datetime, timedelta

def subtract_days(start_date, days):
    end_date = start_date - timedelta(days=days)
    return end_date.strftime('%Y-%m-%d')

```

```tekitou2.py
import random

def random_string(length, characters):
    return ''.join(random.choice(characters) for _ in range(length))
```

```tekitou3.py
import random

def get_max_min(nums, n):
    """ランダムな整数値からなるリストをn個生成し、最大値と最小値を返す関数"""
    data = [[random.randint(0, 1000) for _ in range(nums)] for _ in range(n)]
    max_val = max(map(max, data))
    min_val = min(map(min, data))
    return max_val, min_val
```

さて、ここまで準備してから以下の無茶振り指示。
>今記憶した3つの関数を使って、50行程度でなんでも良いからプログラムを書いて。
for文、if文、デコレータ、クラス定義を行って。あとtensorflowも使用して。
記憶した関数はそれぞれ、import文で呼び出して使用して。

以下が返ってきたコード。

```mutyaburi.py
import tensorflow as tf
from tensorflow import keras

class MyModel:
    def __init__(self):
        self.subtract_days = subtract_days
        self.random_string = random_string
        self.get_max_min = get_max_min
    
    @staticmethod
    def preprocess_data(data):
        return data / 255.0
    
    def train(self, data):
        processed_data = self.preprocess_data(data)
        model = keras.Sequential([
            keras.layers.Dense(128, activation='relu'),
            keras.layers.Dense(10, activation='softmax')
        ])
        model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
        model.fit(processed_data, epochs=5)

data = tf.keras.datasets.mnist.load_data()
(x_train, y_train), (x_test, y_test) = data

model = MyModel()

max_val, min_val = model.get_max_min(5, 2)
print(f"Max: {max_val}, Min: {min_val}")

if max_val > 500:
    print("Max value is greater than 500")

random_str = model.random_string(5, "abcdefghijklmnopqrstuvwxyz")
print(f"Generated random string: {random_str}")

new_date = model.subtract_days(datetime.today(), 7)
print(f"Date 7 days ago: {new_date}")

model.train(x_train)
```

これを実行してみると・・・

エラー！

しかし、
・3つの関数を使用している
・40程度で書いてきた(GPT3はしばしば50行と指定しても5行くらいで返してくる)
・if文を使っている(forは抜けていた・・・)
・tensorflowは使用している
と、「こちらの指示に応えようとしてくれる感」は結構ある。
(関数、import文での使用は怠っているが)

### エラー修正
エラーを吐いたときは「エラー出たよ　[エラー全文貼り付け]」で修正したコードを返してくる。

それを3回ほど繰り返した結果、動くコードが出てきた。
この修正能力がGPT３より格段に高い気がする。
GPT3は「何回繰り返してもエラーが解消されない」という印象だったが、GPT４は数回の修正で動くようには持っていってくれる感じ。

```kansei.py
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.optimizers import Adam
from datetime import datetime, timedelta
import random

def subtract_days(start_date, days):
    end_date = start_date - timedelta(days=days)
    return end_date.strftime('%Y-%m-%d')

def random_string(length, characters):
    return ''.join(random.choice(characters) for _ in range(length))

def get_max_min(nums, n):
    """ランダムな整数値からなるリストをn個生成し、最大値と最小値を返す関数"""
    data = [[random.randint(0, 1000) for _ in range(nums)] for _ in range(n)]
    max_val = max(map(max, data))
    min_val = min(map(min, data))
    return max_val, min_val

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

x_train = x_train.reshape(-1, 28, 28, 1) / 255.0
x_test = x_test.reshape(-1, 28, 28, 1) / 255.0
y_train_onehot = tf.keras.utils.to_categorical(y_train, num_classes=10)
y_test_onehot = tf.keras.utils.to_categorical(y_test, num_classes=10)

model = Sequential([
    Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)),
    MaxPooling2D(pool_size=(2, 2)),
    Conv2D(64, kernel_size=(3, 3), activation='relu'),
    MaxPooling2D(pool_size=(2, 2)),
    Flatten(),
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')
])

model.compile(optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train, y_train_onehot, batch_size=32, epochs=5, validation_data=(x_test, y_test_onehot))

random_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
rand_str = random_string(10, random_chars)
print(f"Random string: {rand_str}")

today_date = datetime.now().date()
new_date = subtract_days(today_date, 7)
print(f"Date 7 days ago: {new_date}")

max_val, min_val = get_max_min(10, 5)
print(f"Max value: {max_val}, Min value: {min_val}")
```

# まとめ
GPT３が「非常に面白い玩具」だったのに対して、GPT４は「明らかに使える道具」になってきた。イメージとしては「自分専用のドラえもん」が出てきた感じ。
必要なコード、文章をバンバン投げ込んで記憶させて、コード１と２の比較とか、複数のファイルをつないでおかしい点を探し出したり、その説明書を書かせたり・・・。もう、無限に応用パターンが出てくる気がする。

GPT３の価値を１０とすると、4は１００くらいあると思いますマジで。
GPT３は「この閾値を越えないとほとんど成果なし」っていうギリギリちょっと下くらいだった。面白いんだけどね。
新人が10人いても仕事が何も捗らないみたいな感じ。

GPT4になってそのラインを超えてきた。これは事務作業全般の革命になるんでないかな。