線型多項分類器

from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

clf = LogisticRegression(multi_class='multinomial', solver='lbfgs', max_iter=200)
clf.fit(X, y)

print(clf.predict(X[:5]))

$ python3 linear_classifier.py
/home/vagrant/.local/lib/python3.10/site-packages/sklearn/linear_model/_logistic.py:1272: FutureWarning: ‘multi_class’ was deprecated in version 1.5 and will be removed in 1.7. From then on, it will always use ‘multinomial’. Leave it to its default value to avoid this warning.
warnings.warn(
[0 0 0 0 0]

HeyGenのようにアバターが回答する仕組み

テキストベースのチャットbotとは異なり、複数の技術が組み合わさっている。

### アバターが回答する仕組み(HeyGenのようなシステム)
1. 音声合成(Text-to-Speech, TTS)… Google Cloud Text-to-Speech, Amazon Polly
ユーザのテキスト入力を音声に変換する技術

2. 顔の動きや表情の生成
アバターの顔の動きや表情を生成するために、以下の技術が使用される
– 3Dモデリングとアニメーション: アバターの3Dモデルを作成し、表情や動きをアニメーションで表現 Unity, Unreal Engine
– フェイシャルキャプチャ: ユーザの表情をリアルタイムでキャプチャし、それをアバターに反映させる

3. 音声とアニメーションの同期
生成した音声とアニメーションを再生

### gTTSによる簡単な音声合成(Text-to-Speech, TTS)
$ pip3 install gTTS

from gtts import gTTS
import os

text = "こんにちは、私はAIアバターです!"

tts = gTTS(text=text, lang='ja')

tts.save("output.mp3")
# os.system("start output.mp3")  # For Windows

### 口パク同期処理
$ pip install gTTS pygame pydub numpy
gTTS -> 音声生成
pygame -> 口パクの可視化(簡易アバター表示)
pydub -> 音声の振幅解析
numpy -> 音声データ処理

from gtts import gTTS
from pydub import AudioSegment
import numpy as np
import pygame
import os

# --- 1. 音声生成 ---
text = "こんにちは、私はAIアバターです!"
tts = gTTS(text=text, lang='ja')
tts.save("output.mp3")

# mp3 → wav に変換(pydubで扱いやすくするため)
sound = AudioSegment.from_mp3("output.mp3")
sound.export("output.wav", format="wav")

# --- 2. 音声データを読み込む ---
audio = AudioSegment.from_wav("output.wav")
samples = np.array(audio.get_array_of_samples())
# モノラルに変換(ステレオの場合)
if audio.channels == 2:
    samples = samples.reshape((-1, 2))
    samples = samples.mean(axis=1)
# 振幅を正規化
samples = samples / np.max(np.abs(samples))

# --- 3. Pygameで口パク表示 ---
pygame.init()
screen = pygame.display.set_mode((400, 400))
pygame.display.set_caption("口パクアバター")

# 音声再生開始
os.system("start output.wav")  # macOS: afplay output.wav / Linux: aplay output.wav

clock = pygame.time.Clock()
running = True
idx = 0
sample_rate = audio.frame_rate
fps = 30  # 1秒あたりのフレーム数
samples_per_frame = int(sample_rate / fps)

while running and idx < len(samples):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
    # 現フレームの振幅を計算
    frame = samples[idx:idx+samples_per_frame]
    amplitude = np.abs(frame).mean()
    
    # 口の高さを振幅に応じて変化
    mouth_height = int(50 + amplitude * 200)
    
    # 背景
    screen.fill((255, 255, 255))
    # 顔(円)
    pygame.draw.circle(screen, (255, 224, 189), (200, 200), 100)
    # 口(長方形)
    pygame.draw.rect(screen, (150, 0, 0), (150, 250, 100, mouth_height))
    
    pygame.display.flip()
    
    idx += samples_per_frame
    clock.tick(fps)

pygame.quit()

### フロント(X-code, AndroidStudio)とバックエンド(Python)の切り分け
##### バックエンドで担当する処理
1. ユーザー入力の受け取り
アプリから送られてくるテキストメッセージを受信
例: /chat エンドポイントで JSON 受け取り

2. AI応答生成
ChatGPT APIなどを呼び出して返信テキストを生成
例: “こんにちは!今日はどんなことを話しましょうか?”

3. 音声生成(Text-to-Speech, TTS)
生成したテキストを音声データに変換
gTTS, OpenAI TTS, Coqui TTS など
出力形式は MP3/WAV など

4. 音声解析(口パク用振幅解析)
音声データを読み込んでフレームごとの振幅を算出
numpy や pydub で RMS / 平均振幅を計算
口パクアニメーションの高さや動きの指標として返す

5. バックエンドからクライアントへの送信

{
  "text": "こんにちは!",
  "audio_url": "https://server/output.wav",
  "lip_sync": [0.1, 0.2, 0.3, ...]  # フレームごとの振幅データ
}

##### クライアント(Android / iOS)で担当する処理
1. ユーザー入力の送信
テキストをバックエンドに送る
HTTP POST / WebSocket

2. 受信したデータの処理
テキスト表示
音声データの再生
Android: MediaPlayer / ExoPlayer
iOS: AVAudioPlayer
口パクデータの再生(振幅に応じてアバターの口を動かす)

3. 口パクアニメーション
受信した lip_sync 配列をフレーム単位で参照
Unity / SceneKit / SpriteKit などでアバターの口の高さや形を変化させる

バックエンドは「音声と口パクデータの生成」まで
実際の描画や音声再生はアプリ側で行う

なるほど、この仕組みは凄い!

chatバックエンド側(Python (Flask + PostgreSQL + OpenAI))の作り込み1

chat() の中で  
認証チェックを追加  
DBにユーザーの入力を保存  
OpenAI API や HuggingFace API を呼んで応答を生成  
生成した応答をDBに保存して返却

### step.0 テーブル作成

CREATE TABLE chat_messages (
    id SERIAL PRIMARY KEY,
    user_id VARCHAR(50) NOT NULL,
    message TEXT NOT NULL,
    reply TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

### step.1 パッケージインストール
$ install flask psycopg2-binary openai

### step.2 Python (Flask + PostgreSQL + OpenAI)

from flask import Flask, request, Response
import json
import psycopg2
import os
from openai import OpenAI

app = Flask(__name__)

DB_CONFIG = {
    "dbname": os.getenv("DB_NAME"),
    "user": os.getenv("DB_USER"),
    "password": os.getenv("DB_PASSWORD"),
    "host": os.getenv("DB_HOST", "localhost"),
    "port": os.getenv("DB_PORT", 5432)
}


def get_db_connection():
    try:
        conn = psycopg2.connect(**DB_CONFIG)
        return conn
    except Exception as e:
        print(f"Database connection error: {e}")
        return None

@app.route("/chat", methods=["POST"])
def chat():
    try:
        data = request.get_json()

        user_id = data.get("user_id")
        message = data.get("message")

        if not user_id or not message:
            return Response(json.dumps({"error": "user_id and message are required"}), status=400, content_type="application/json; charset=utf-8")

        conn = get_db_connection()
        cur = conn.cursor()

        cur.execute(
            "INSERT INTO chat_messages (user_id, message) VALUES (%s, %s) RETURNING id;",
            (user_id, message)
        )
        chat_id = cur.fetchone()[0]

        client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
        completion = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages = [
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": message}
            ]
        )
        api_reply = completion.choices[0].message.content

        cur.execute(
            "UPDATE chat_messages SET reply = %s WHERE id = %s;",
            (api_reply, chat_id)
        )
        conn.commit()
        cur.close()
        conn.close()
        

        response_json = json.dumps({"reply": api_reply}, ensure_ascii=False)
        return Response(response_json, content_type="application/json; charset=utf-8")

    except Exception as e:
        error_json = json.dumps({"error": str(e)}, ensure_ascii=False)
        return Response(error_json, status=400, content_type="application/json; charset=utf-8")


if __name__ == "__main__":
    app.run(debug=True)

$ curl -X POST http://127.0.0.1:5000/chat -H “Content-Type: application/json” -d ‘{“user_id”: “12345”, “message”: “おはよう!”}’
{“reply”: “おはようございます!元気ですか?何かお手伝いできることがありますか?”}

おおお

ChatGPT-4oとGPT5の違い

ChatGTP-4oがマルチモーダルAI実用化であったのに対し、ChatGPT5はは「思考するAI」「動けるAI」へ進化

#### ChatGPT-4o
– モデル構造 : テキスト・音声・画像を統合した「マルチモーダルモデル」
– モデルの選択 : 手動選択(GPT-4o, o3など)
– 応答速度(音声) : 平均320ms, 自然な会話速度
– 記憶機能(メモリ) : 一部記憶あり
– 外部連携機能 : なし

#### ChatGPT-5
– モデル構造 : 複数の思考エンジンを自動で切り替える「統合システム+動的推論」
– モデルの選択 : 自動判定(Base/Thinking/Proにルーティング)
– 応答速度(音声) : 音声は4oベース、今後統合予定
– 記憶機能(メモリ) : 永続メモリ。過去の会話やユーザの好みを保持
– 外部連携機能 : Gmail、カレンダー、Drive等と直接連携可能

プロンプトの内容や難易度を自動解析し、最適な推論モデル(高速応答/深層思考)を選択
AIの性格を選べる

ソフトウェア開発、数学、多言語コード編集、マルチモーダル理解などあらゆる指標で賢くなった
プランはFree, Plus, Pro, Enterpriseなどあり

思考の質が自動最適化され、過去を覚える

Pythonで入力中の続きのコード生成AIをAPIで試す

フィボナッチ関数について、途中まで書いていて、その続きのコードをレスポンスとして返します。
ソースコードをapiに私、”complete this code”と指示を出しています。

from openai import OpenAI

client = OpenAI(api_key="sk-hoge****")

partial_code = """
def fibonacci(n):
    \"\"\"n番目までのフィボナッチ数列を返す関数.\"\"\"
    sequence = [0, 1]
"""

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "You are an expert Python programmer. Complete the given code without explanations, only code."},
        {"role": "user", "content": f"Complete this Python code:\n\n{partial_code}"}
    ],
    temperature=0.2,
)

print(response.choices[0].message.content)

$ python3 codegen_input.py
“`python
if n <= 0: return [] elif n == 1: return [0] elif n == 2: return sequence for i in range(2, n): next_value = sequence[-1] + sequence[-2] sequence.append(next_value) return sequence ``` Github Copilotではコメントからコード生成はグレーアウトされたコードで即時表示している。 これは特定の実行ボタンなどを押下しなくても表示しているので、Ajaxなど非同期で実行していると思われる。 入力中の続きのコード生成も同様 コメントを書き終えた時や、コードを打ち終えた時などにトリガーが発動される。

Pythonでコード型の生成AIをAPIで試す

from openai import OpenAI

client = OpenAI(api_key="sk-hoge****")

prompt = """
# Pythonで、与えられた文字列を逆順にして返す関数を作ってください
"""

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "You are a helpful assistant that writes clean Python code.."},
        {"role": "user", "content": prompt}
    ],
    temperature=0.2,
)

print(response.choices[0].message.content)

$ python3 codegen.py
もちろんです!以下は、与えられた文字列を逆順にして返すPythonの関数です。

“`python
def reverse_string(s):
return s[::-1]

# 使用例
input_string = “こんにちは”
reversed_string = reverse_string(input_string)
print(reversed_string) # 出力: はこんに
“`

この関数 `reverse_string` は、スライスを使って文字列を逆順にしています。`s[::-1]` は、文字列 `s` の全ての文字を逆順に取得します。

model, message, tempratureを指定してリクエストしていることがわかります。
なるほど

AI生成ツールの比較

1. Copilot Chat: Microsoft(+openAI) コーディング補助
2. Claude: Anthropic 長文補助
3. Gemini: Google 汎用AI・検索統合
4. Cursor: AI搭載のIDE、コーディングに特化
5. Devin: AIソフトウェアエンジニア, 自律型のコード開発

GeminiはChatGTPに比べてレスポンスの文章量が少ない印象。ChatGTPの方が丁寧で参考になりそう。
Devinは色々触って試してみたい。

Definition of Scripts

Definition of Scripts
A causally coherent set of events.

1. Each event sets off, or causes, the next event.
2. The causal connections between events make sense.
3. The parts are actions or scenes in the world.

Restaurant Script
Script: restaurant
track: formal dining
props: tables, menu, check, money, F = food, P = place
roles: S = customer, W = waiter, C = cook, M = cashier, O = owner
entry: S is hungry, S has money
result: S has less money, O has more money, S is not hungry, S is pleased
scenes: