♎

Pythonで性格診断アプリ!?

に公開
2025/08/01

🧠 【プログラミング初心者向け】Python Streamlit x 機械学習で作る性格診断AI

機械学習の代表的なタスクであるテキスト分類に挑戦してみませんか?今回は、Python で scikit-learn を使って、キーワードから性格を診断するAIアプリを作成します。TF-IDFとランダムフォレストを使った本格的な機械学習アプリを、初心者でも理解できるように詳しく解説していきます。
読み進めていくと、コード量が多く感じるかもしれませんが、可読性工場目的で改行を多用しているためですので!

機械学習、テキスト処理、分類問題まで含む本格的なAIアプリを、ステップバイステップで学んでいきましょう。

🌟 この記事を読めば...

機械学習とテキスト分類の使い方を学べます 🎯

この記事では、単なる診断アプリを作るだけでなく、機械学習の基本であるテキスト分類と自然言語処理を徹底的に学べます。例えば:

  • テキストデータの前処理とベクトル化
  • TF-IDFによる特徴量抽出
  • ランダムフォレストによる分類
  • モデルの学習と評価
  • 予測確率の可視化

今この時点では❓❓だとしても!
記事を読み終えたときには、自分で占いアプリだって作れちゃいます!!

💡 そもそも機械学習って❓

**機械学習(Machine Learning)**は、データからパターンを学習して予測や分類を行うAI技術です。

  • 大量のデータから自動的にルールを学習
  • 新しいデータに対して予測や分類を実行
    🎯 今回の例:
  • AIが「キーワードの組み合わせ」から性格タイプを自動学習

📁 フォルダとファイルの作成

1. フォルダ構造

character-judge-project/
├── character_judge.py
└── requirements.txt

2. 必要なライブラリをインストール

まず、requirements.txtファイルに以下を書きます:

streamlit>=1.28.0
pandas>=2.0.0
scikit-learn>=1.3.0
plotly>=5.15.0
numpy>=1.24.0

これで、プロジェクトの準備が整いました!

⚡ 性格診断AIを作ってみよう

さっそく、character_judge.py にコードを書いていきましょう!

1️⃣📱 アプリの基本設定とライブラリのインポート

まずは、アプリの基本設定と必要なライブラリのインポートから始めます。

# 必要なライブラリをインポート
import streamlit as st  # Webアプリ作成用
import pandas as pd     # データ処理用
import plotly.graph_objects as go  # インタラクティブグラフ用
from sklearn.feature_extraction.text import TfidfVectorizer  # TF-IDFベクトル化用
from sklearn.ensemble import RandomForestClassifier  # 機械学習モデル
from sklearn.model_selection import train_test_split  # データ分割用
from sklearn.metrics import accuracy_score  # 精度評価用
import random  # ランダム生成用

# ===== ページ設定 =====
st.set_page_config(
    page_title="性格診断AI",  # ブラウザのタブに表示されるタイトル
    page_icon="🧠",          # ブラウザのタブに表示されるアイコン
    layout="wide",           # レイアウトをワイドに設定
)

# ===== タイトルとヘッダー =====
st.title("🧠 性格診断AI")  # メインタイトル
st.markdown("---")  # 区切り線

# 赤表記で注意書き
st.error("""
⚠️ **重要なお知らせ**
- この診断はネタです🧪
""")

cursor のターミナルで以下のコマンドを実行して画面表示を確認しましょう!

python -m streamlit run character_judge.py

2️⃣🤖 データセットとモデルの準備

今回、性格診断AIには4つの性格タイプと豊富なキーワードデータを使います。
定義やデータセットの中身が多いので折りたたんでいます。
sample_dataの中身はコピペしちゃいましょう!
黄色文字の部分は自身でアレンジOK!!

データセット
# ===== 性格タイプの定義 =====
# 機械学習モデルで使用する正式な性格タイプ名と、表示用の名前
types = {
    "外向的": "パリピ予備軍",
    "内向的": "家でゴロゴロ族",
    "論理的": "データオタク",
    "感情的": "涙腺ゆるゆる系"
}

# ===== 学習データセットの準備 =====
@st.cache_data  # キャッシュデコレータ:データセットを一度だけ作成する
def create_sample_data():
    # 各性格タイプに対して、特徴的なキーワードとその性格タイプのラベルを定義
    sample_data = [
        # パリピ予備軍の学習データ
        ["楽しい!", "外向的"],
        ["みんなでワイワイ", "外向的"],
        ["パーティー最高", "外向的"],
        ["友達とおしゃべり", "外向的"],
        ["新しいことに挑戦", "外向的"],
        ["人前で話すのが好き", "外向的"],
        ["旅行に行きたい", "外向的"],
        ["カフェでお茶", "外向的"],
        ["インスタ映え", "外向的"],
        ["みんなでカラオケ", "外向的"],
        ["ワイワイ騒ぐ", "外向的"],
        ["みんなで集まる", "外向的"],
        ["新しい友達", "外向的"],
        ["おしゃべり好き", "外向的"],
        ["アクティブ", "外向的"],
        ["人と会う", "外向的"],
        ["イベント参加", "外向的"],
        ["みんなで食事", "外向的"],
        ["お祭り好き", "外向的"],
        ["人前で発表", "外向的"],
        
        # 家でゴロゴロ族の学習データ
        ["静かな時間が好き", "内向的"],
        ["一人で読書", "内向的"],
        ["家でゆっくり", "内向的"],
        ["深く考える", "内向的"],
        ["小さなグループ", "内向的"],
        ["計画を立てる", "内向的"],
        ["集中して作業", "内向的"],
        ["落ち着いた場所", "内向的"],
        ["Netflix見放題", "内向的"],
        ["宅配ピザ", "内向的"],
        ["一人の時間", "内向的"],
        ["静かな場所", "内向的"],
        ["家で過ごす", "内向的"],
        ["本を読む", "内向的"],
        ["考え事", "内向的"],
        ["少人数", "内向的"],
        ["計画的", "内向的"],
        ["集中作業", "内向的"],
        ["リラックス", "内向的"],
        ["動画視聴", "内向的"],
        ["家で食事", "内向的"],
        
        # データオタクの学習データ
        ["データを見る", "論理的"],
        ["効率を重視", "論理的"],
        ["分析する", "論理的"],
        ["事実を確認", "論理的"],
        ["システム化", "論理的"],
        ["客観的に判断", "論理的"],
        ["構造化する", "論理的"],
        ["論理的に考える", "論理的"],
        ["エクセル大好き", "論理的"],
        ["グラフ作成", "論理的"],
        ["データ分析", "論理的"],
        ["効率化", "論理的"],
        ["統計", "論理的"],
        ["事実重視", "論理的"],
        ["システム設計", "論理的"],
        ["客観的", "論理的"],
        ["構造化", "論理的"],
        ["論理的思考", "論理的"],
        ["表計算", "論理的"],
        ["チャート作成", "論理的"],
        
        # 涙腺ゆるゆる系の学習データ
        ["直感を信じる", "感情的"],
        ["気持ちを大切に", "感情的"],
        ["共感する", "感情的"],
        ["創造的", "感情的"],
        ["芸術が好き", "感情的"],
        ["人の気持ちを考える", "感情的"],
        ["自由に表現", "感情的"],
        ["心の声を聞く", "感情的"],
        ["映画で泣く", "感情的"],
        ["動物動画", "感情的"],
        ["直感重視", "感情的"],
        ["感情豊か", "感情的"],
        ["共感力", "感情的"],
        ["クリエイティブ", "感情的"],
        ["アート", "感情的"],
        ["人の気持ち", "感情的"],
        ["自由表現", "感情的"],
        ["心の声", "感情的"],
        ["感動", "感情的"],
        ["動物好き", "感情的"]
    ]
    # pandasのDataFrameに変換して返す
    # columns=['テキスト', '性格タイプ']:テキストデータとその性格タイプのラベル
    df = pd.DataFrame(sample_data, columns=['テキスト', '性格タイプ'])
    return df
# ===== モデル関連の関数 =====
@st.cache_resource  # キャッシュデコレータ:モデルを一度だけ作成する
def create_model():
    # 機械学習モデルの作成・学習・評価を行う関数
    with st.spinner("🤖 AI先生が勉強中..."):  # スピナー:処理中の表示
        # データセットの準備
        df = create_sample_data()  # 学習用データセットを取得

        # TfidfVectorizer:テキストデータを数値ベクトルに変換
        # max_features=200:最大200個の特徴量(単語)を使用
        # min_df=1:最低1回出現した単語を特徴量として使用
        # max_df=0.9:90%以上の文書に出現する単語は除外(一般的すぎる単語を除外)
        vectorizer = TfidfVectorizer(max_features=200, min_df=1, max_df=0.9)
        X = vectorizer.fit_transform(df['テキスト'])  # テキストをベクトル化
        y = df['性格タイプ']  # 正解ラベル(性格タイプ)
        
        # train_test_split:データを学習用とテスト用に分割
        # test_size=0.2:20%をテストデータとして使用
        # random_state=42:再現性のための乱数シード
        # stratify=y:各性格タイプの比率を保持したまま分割
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
        
        # RandomForestClassifier:ランダムフォレスト分類器
        # n_estimators=200:200個の決定木を作成
        # max_depth=10:各決定木の最大深さを10に制限(過学習防止)
        # random_state=42:再現性のための乱数シード
        # class_weight='balanced':クラス不均衡対策(各性格タイプのサンプル数が異なる場合の対策)
        model = RandomForestClassifier(n_estimators=200, max_depth=10, random_state=42, class_weight='balanced')
        model.fit(X_train, y_train)  # モデルに学習データを学習させる
        
        # モデルの性能評価
        y_pred = model.predict(X_test)  # テストデータで予測
        accuracy = accuracy_score(y_test, y_pred)  # 正解率(モデルの性能評価)を計算
        
        st.success(f"🎉 診断AIの準備完了!(的中率: {accuracy:.1%}") # モデルの性能評価結果を小数点1桁で表示
        
        # 学習済みモデルとベクトル化器を辞書形式で返す
        return {'model': model, 'vectorizer': vectorizer}

# st.session_state:ページを更新してもデータを保持するStreamlitの機能
# モデルを一度だけ読み込むための条件分岐
if 'character_model' not in st.session_state:
    st.session_state.character_model = create_model() #モデルを読み込む

📝 モデル管理・キャッシュの詳細説明:

  • @st.cache_data でデータセットの再作成を防止し、アプリの高速化・安定化を実現します。
  • @st.cache_resource でモデルの再学習・再読み込みを防止し、アプリの高速化・安定化を実現します。
  • st.session_state でページリロード時もモデルを保持し、無駄な再計算を防ぎます。

📝 TF-IDFベクトルを分解して解説:

TF-IDF(Term Frequency-Inverse Document Frequency)は、テキストデータを数値ベクトルに変換する手法です。

🔍 TF-IDFの基本概念:

  1. TF(Term Frequency):文書内での単語の出現頻度

    • その単語が文書内で何回出現するかを数える
  2. IDF(Inverse Document Frequency):文書全体での単語の希少性

    • その単語が何個の文書に出現するかを逆数で表す
  3. TF-IDF値:TF × IDF

    • 文書内で頻繁に出現し、かつ全体で珍しい単語ほど高い値
    • 特徴的な単語を自動的に抽出

📝 TF-IDFベクトル化の詳細説明:

🔍 ベクトル化の流れ:

  1. 学習データのベクトル化:
# 入力テキスト例
["楽しい!", "みんなでワイワイ", "データを見る", "静かな時間が好き"]

# TF-IDFベクトル化後(概念的な例)
楽しい!     → [0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...]
みんなでワイワイ → [0.0, 0.7, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, ...]
データを見る   → [0.0, 0.0, 0.0, 0.9, 0.0, 0.0, 0.0, 0.0, ...]
静かな時間が好き → [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.7, ...]
  1. ユーザー入力のベクトル化:
# ユーザーが選択したキーワード
selected_keywords = ["楽しい", "データ", "分析"]

# selected_keywordsはリストなので、スペースで結合
input_text = " ".join(selected_keywords)
➡️input_text = "楽しい データ 分析"

# TF-IDFベクトル化
text_vector = vectorizer.transform([input_text])
# 結果:[0.6, 0.0, 0.0, 0.8, 0.7, 0.0, 0.0, 0.0, ...]

🎯 ベクトルの意味:

  • 各要素➡️特定の単語のTF-IDF値
  • 値が高い➡️その単語が文書内で重要
  • 値が0➡️その単語が文書内に存在しない

❓ なぜスパース行列を使うのか

スパース行列は、大部分の要素が0(ゼロ)である行列のことです。

📊 メモリ効率の比較:

通常の行列(密行列):

  • 6個のテキスト × 10個の単語 = 60個の要素
  • 各要素が8バイト = 480バイト

スパース行列:

  • 各テキストに含まれる単語は平均3-5個
  • 6個のテキスト × 10個の単語 = 実際に保存されるのは12個の要素
  • 各要素が8バイト = 96バイト

約5倍のメモリ節約!

🎯 今回の例:

# 通常の行列
楽しい! → [0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...] (200個の要素)

# スパース行列
楽しい! → (0, 0.8)  # 位置0に値0.8がある
みんなでワイワイ → (1, 0.7), (2, 0.6)  # 位置1に0.7、位置2に0.6がある
データを見る → (3, 0.9)  # 位置3に値0.9がある

⚡ 計算速度の向上:

  • 0の要素は計算をスキップ
  • 非ゼロ要素のみ計算
  • 処理時間が大幅に短縮

ここまでお話しましたが、以下で自動的にスパース行列を生成するので、開発時に特に意識する必要はありません!

X = vectorizer.fit_transform(df['テキスト'])

内部で何が行われているか頭の片隅に是非!

これでモデルの準備が出来上がりました!!
あと少しです!!

3️⃣🎭 性格タイプとコメントの定義

各性格タイプに対応するコメントと運勢メッセージを定義します。
コメントやメッセージが多いので折りたたんでいます。
内容は好きなようにアレンジしましょう!
ただし、変数名はcomments,daily_fortuneのままで!
黄色文字の部分は自身でアレンジOK!!
カッコの書き方や、内容は以下をクリックして参考にしてください!

性格タイプとコメント
# ===== 各性格タイプに対して、ランダムで表示されるコメント =====
comments = {
    "外向的": [
        "あなたはパーティーの主役になりがち!でも家に帰ると疲れて寝落ち確定。",
        "友達の友達も即友達になるタイプ。LINEグループの数がヤバい。",
        "居酒屋で知らない人とも仲良くなっちゃう。翌日名前忘れてる。"
    ],
    "内向的": [
        "「今度みんなで遊ぼう」→(心の声:家がいい...)",
        "コンビニで店員さんと目を合わせるのが苦手。セルフレジ愛用者。",
        "Netflix見ながらベッドでゴロゴロが最高の贅沢。外出は体力勝負。"
    ],
    "論理的": [
        "あなたはExcelマスター!感情よりもデータを信じるタイプ。",
        "効率重視すぎて、恋愛も数値で考えがち。",
        "ランキング大好き。何でもグラフにしたくなる病気持ち。"
    ],
    "感情的": [
        "あなたは映画で泣きがち!ティッシュ消費量が半端ない。",
        "芸術系が好きで、インスタの写真がエモい。",
        "「なんか良い」「雰囲気が好き」が決め台詞。理由は聞かないで。"
    ]
}

# ===== 各性格タイプに対して、ランダムで表示される今日の運勢メッセージ =====
daily_fortune = {
    "外向的": [
        "今日は新しい友達ができる予感!でも財布の紐は緩めすぎ注意。",
        "パーティーのお誘いが3件以上!体力配分を考えよう。",
        "今日は一人の時間も大切に。家でまったりも悪くない。"
    ],
    "内向的": [
        "読みかけの本を読み終えるチャンス!集中力MAX。",
        "外出の誘いがあっても断る勇気を。自分の時間を大切に。",
        "今日は意外と人と話したくなるかも。たまには外に出てみて。"
    ],
    "論理的": [
        "データ分析がはかどる日。新しい発見がありそう。",
        "効率化のアイデアが浮かぶ予感。周りに提案してみよう。",
        "エクセルの新機能を覚えるのに最適な日。スキルアップのチャンス。"
    ],
    "感情的": [
        "今日は直感が冴える日。ピンときたら行動してみよう。",
        "アート系のものに触れると運気UP。美術館や映画館へGO。",
        "クリエイティブな作業がはかどる予感。何か作ってみて。"
    ]
}

📝 コメント・運勢システムの詳細説明:

  • random.choice() で各性格タイプに対応するコメントからランダムに選択。
  • ユーザーが何度診断しても異なるコメントが表示され、楽しさを演出します。

4️⃣🔮 診断機能セクション

ユーザーがキーワードを選択して診断できる機能を実装します。

# ===== 診断機能セクション =====
st.markdown("---")  # 区切り線
st.header("🔮 性格診断")  # 診断セクションのヘッダー

# ===== 各性格タイプに対応するキーワードの定義 =====
# ユーザーが選択できるキーワードと、機械学習モデルの学習データを対応させる
keywords_by_type = {
    "外向的": ["楽しい", "みんなで", "パーティー", "友達", "新しい", "旅行", "カフェ", "カラオケ", "ワイワイ", "おしゃべり", "アクティブ", "イベント", "お祭り", "人前"],
    "内向的": ["静か", "一人", "読書", "家", "深く", "計画", "集中", "落ち着く", "Netflix", "宅配", "リラックス", "動画", "少人数", "考え事"],
    "論理的": ["データ", "効率", "分析", "事実", "システム", "客観的", "構造", "論理的", "エクセル", "グラフ", "統計", "表計算", "チャート", "設計"],
    "感情的": ["直感", "気持ち", "共感", "創造的", "芸術", "映画", "動物", "自由", "心", "表現", "感動", "アート", "クリエイティブ", "感情豊か"]
}

# ===== 各性格タイプのキーワードを1つのリストにまとめる =====
all_keywords = []
for keywords in keywords_by_type.values():
    all_keywords.extend(keywords)

st.subheader("📝 キーワード選択")

# ===== st.multiselect:複数のオプションを選択できるドロップダウンメニュー =====
selected_keywords = st.multiselect(
    "あなたに当てはまるキーワードを選択してください(複数選択可)",  # ラベル
    options=all_keywords,  # 選択肢のリスト
    help="複数のキーワードを選択すると、より正確な診断ができます"  # ?にカーソルを合わせると表示される
)

実際にキーワードを選択してみましょう!

📝 キーワード選択の詳細説明:

  • st.multiselect() で複数のキーワードを選択可能。
  • 各性格タイプに対応するキーワードを事前に定義し、ユーザーが直感的に選択できるようにしています。

5️⃣🔍 予測機能の実装

AIによる性格診断機能を実装します。

# ===== 診断実行ボタンを作成 =====
if st.button("🔮 性格を暴く!", type="primary"):
    # ボタンが押された場合、以下の処理
    if selected_keywords: # キーワードが選択されている場合
        # 選択されたキーワードをスペースで結合してテキストを作成
        input_text = " ".join(selected_keywords)
        
        # ===== 学習済みモデルの取得 =====
        model_data = st.session_state.character_model  # セッション状態からモデルを取得
        vectorizer = model_data['vectorizer']  # TF-IDFベクトル化器
        model = model_data['model']  # 学習済みランダムフォレストモデル
        
        # ===== vectorizer.transform:入力テキストを学習済みベクトル化器でベクトル化 =====
        text_vector = vectorizer.transform([input_text])
        
        # ===== 予測実行 =====
        with st.spinner("🤔 AI先生が分析中..."):  # スピナー:処理中の表示
            # model.predict:最も可能性の高い性格タイプを予測
            predicted_type = model.predict(text_vector)[0]
            # model.predict_proba:各性格タイプの確率を取得
            prediction_proba = model.predict_proba(text_vector)[0]
            # model.classes_:学習済みモデルのクラス名(性格タイプ)を取得
            type_names = model.classes_

            st.subheader("🎉 診断結果発表!")  # 結果セクションのヘッダー
            
            # ===== types.get:正式な性格タイプ名を表示用の名前に変換 =====
            your_character = types.get(predicted_type, predicted_type)
            st.success(f"**あなたは**: **{your_character}** です!")
            
            # ===== random.choice:該当する性格タイプのコメントからランダムに選択 =====
            comment = random.choice(comments.get(predicted_type, ["面白い人ですね!"]))
            st.info(f"💬 **AI先生からのコメント**: {comment}")
            
            # ===== 今日の運勢の表示 =====
            # random.choice:該当する性格タイプの運勢からランダムに選択
            fortune = random.choice(daily_fortune.get(predicted_type, daily_fortune['外向的']))
            st.info(f"🌟 **今日の運勢**: {fortune}")

診断を実行してみましょう!

📝 予測機能の詳細説明:

  • model.predict() 最も可能性の高い性格タイプを出力。
  • model.predict_proba() で各性格タイプの確率を取得。

6️⃣🔍 確率の表示

確率の表示機能を実装します。

            col1, col2 = st.columns(2)  # 画面を2つのカラムに分割
            with col1: # 左のカラム
                st.subheader("📊 性格タイプ別の確率")
                proba_data = []
                for i, type_name in enumerate(type_names):
                    # 正式な性格タイプ名を表示用の名前に変換
                    display_type_name = types.get(type_name, type_name)
                    # 確率をパーセント形式で追加。小数点1桁で表示
                    proba_data.append([display_type_name, f"{prediction_proba[i]*100:.1f}%"])
                
                # ===== pandasのDataFrameでテーブル表示 =====
                proba_df = pd.DataFrame(proba_data, columns=['性格タイプ', '確率'])
                st.dataframe(proba_df, use_container_width=True)
                
            with col2: # 右のカラム
                # ===== 確率を棒グラフで表示 =====
                # 正式な性格タイプ名を表示用の名前に変換
                display_type_names = [types.get(t, t) for t in type_names]
                # Plotlyで棒グラフを作成
                fig = go.Figure(data=[
                    go.Bar(
                        x=display_type_names,  # x軸:性格タイプ名
                        y=prediction_proba,  # y軸:予測確率
                        # 予測された性格タイプは赤、それ以外は薄い青で表示
                        marker_color=['red' if t == predicted_type else 'lightblue' for t in type_names],
                        text=[f"{p*100:.1f}%" for p in prediction_proba],  # 棒グラフ上に確率を表示
                        textposition='auto',  # テキストの位置を自動調整
                    )
                ])
                
                # ===== グラフのレイアウト設定 =====
                fig.update_layout(
                    title="🎭 あなたの性格内訳",  # グラフのタイトル
                    xaxis_title="性格タイプ",      # x軸のタイトル
                    yaxis_title="確率",            # y軸のタイトル
                    showlegend=False,              # 凡例を非表示
                    height=300                     # グラフの高さ
                )
                # Plotlyの図をStreamlitに表示
                st.plotly_chart(fig, use_container_width=True)
    
    else:
        # ===== キーワード未選択時の警告 =====
        st.warning("⚠️ キーワードを選択してください!")

再度診断を実行して、表とグラフの表示を確認しましょう!

📝 enumerate()の詳細説明:

for i, type_name in enumerate(type_names):

🔍 enumerate()とは:

  • リストの要素とインデックス(番号)を同時に取得する関数
  • i = インデックス(0, 1, 2, 3...)
  • type_name = リストの要素

📊 具体例:

type_names = ["外向的", "内向的"]

for i, type_name in enumerate(type_names):
    print(f"インデックス{i}: {type_name}")

# 出力結果:
# インデックス0: 外向的
# インデックス1: 内向的

📝 proba_data.append()の詳細説明:

proba_data.append([display_type_name, f"{prediction_proba[i]*100:.1f}%"])

🔍 分解して理解:

  1. proba_data.append(): リストに新しい要素を追加
  2. [display_type_name, f"{prediction_proba[i]*100:.1f}%"]: 2つの要素を持つリスト
    • display_type_name: 性格タイプ名("パリピ予備軍"など)
    • f"{prediction_proba[i]*100:.1f}%": 確率をパーセント形式に変換(小数点第1位まで)

📊 確率の変換例:

prediction_proba = [0.45, 0.25]  # 確率

# 変換後
f"{prediction_proba[0]*100:.1f}%"  # "45.0%"
f"{prediction_proba[1]*100:.1f}%"  # "25.0%"

📝 marker_colorの詳細説明:

marker_color=['red' if t == predicted_type else 'lightblue' for t in type_names]

これは「リスト内包表記(List Comprehension)」という書き方です。

分解して理解しましょう!:

1. 基本的な構造:

marker_color = [色 for t in type_names]

2. 条件分岐を追加:

marker_color = ['red' if t == predicted_type else 'lightblue' for t in type_names]

3. 同じ処理をfor文で書くと:

marker_color = []
for t in type_names:
    if t == predicted_type:
        marker_color.append('red')
    else:
        marker_color.append('lightblue')

🎉 完成!

おめでとうございます!

今回出来上がった画面はこちらです 👇

実際に様々なキーワードを選択して診断を試してみましょう!!

🎯 まとめ:性格診断AIで学んだこと

今回作成した性格診断AIは、以下のような多くの重要な概念が含まれています:

  • テキスト処理 - TF-IDFを使ったテキストのベクトル化
  • 機械学習 - ランダムフォレストを使った分類モデル構築
  • データ前処理 - テキストデータの前処理と特徴量抽出
  • リアルタイム予測 - キーワード選択と同時の予測実行
  • 可視化 - Plotlyを使った美しいグラフ表示

今回の性格診断AIの特徴:

  • TF-IDFベクトル化 - テキストデータを数値ベクトルに変換
  • ランダムフォレスト分類 - 複数の決定木による高精度分類
  • キーワード選択 - 直感的なキーワード選択による診断
  • 予測確率表示 - 各性格タイプの確率を詳細表示
  • 視覚的フィードバック - テーブルとグラフでの結果表示

🚀 次のステップ

今回学んだ機械学習を応用して、以下のような機能を追加してみましょう:

  1. データ拡張 - より多くのキーワードと学習データの追加
  2. モデル改善 - より高度なアルゴリズム(SVM、ニューラルネットワーク)の活用
  3. 特徴量エンジニアリング - より洗練された特徴量の作成
  4. リアルタイム学習 - ユーザーのフィードバックで継続学習
  5. 多言語対応 - 英語や他の言語での診断機能

機械学習は、このように少しずつ機能を追加していくことで、どんどん面白くなります!今回学んだTF-IDFとランダムフォレストは、AI開発の基本中の基本なので、しっかりと理解しておきましょう!


🎓 プログラミング学習におすすめ

プログラミング未経験の方には CyTech(サイテック) がおすすめです!

CyTech は、未経験から IT エンジニアを目指す人向けのオンライン学習プラットフォームで、基礎から実務レベルのスキルを最短 10 ヶ月で習得できるカリキュラムを提供しています。
HTML/CSS/JavaScript/PHP/SQL/Git などのプログラミング言語に加え、デザイン、英語なども学べる総合的なプラットフォームです。
今後随時学習できるプログラミング言語増加予定!
エンジニア学習にお困りの方はまずは CyTech 無料カウンセリングでお悩み解消!

Discussion