{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "abd76d41-772c-47d6-beb1-44a1e21aa6cf", "metadata": {}, "outputs": [], "source": [ "import json\n", "import pandas as pd\n", "from openai import OpenAI\n", "from dotenv import dotenv_values\n", "from pycaret.clustering import predict_model, load_model" ] }, { "cell_type": "code", "execution_count": 2, "id": "514496ba-4001-473d-b799-5d17dcc06073", "metadata": {}, "outputs": [], "source": [ "env = dotenv_values(\".env\")\n", "\n", "openai_client = OpenAI(api_key=env[\"OPENAI_API_KEY\"])" ] }, { "cell_type": "markdown", "id": "9bc409bd-218f-4ad9-8469-06dbba741e1a", "metadata": {}, "source": [ "### Ładujemy dane" ] }, { "cell_type": "code", "execution_count": 3, "id": "260d3be5-23b9-4bc9-853f-4541a631fef0", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ageedu_levelfav_animalsfav_placegender
0<18PodstawoweBrak ulubionychNaNKobieta
125-34ŚredniePsyNad wodąMężczyzna
245-54WyższePsyW lesieMężczyzna
335-44ŚrednieKotyW górachMężczyzna
435-44WyższePsyNad wodąMężczyzna
\n", "
" ], "text/plain": [ " age edu_level fav_animals fav_place gender\n", "0 <18 Podstawowe Brak ulubionych NaN Kobieta\n", "1 25-34 Średnie Psy Nad wodą Mężczyzna\n", "2 45-54 Wyższe Psy W lesie Mężczyzna\n", "3 35-44 Średnie Koty W górach Mężczyzna\n", "4 35-44 Wyższe Psy Nad wodą Mężczyzna" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('welcome_survey_simple_v2.csv', sep=';')\n", "df.head()" ] }, { "cell_type": "markdown", "id": "1978c6cd-5298-4e7b-b3d3-99b0fa158e34", "metadata": {}, "source": [ "### Ładujemy wytrenowany model v2" ] }, { "cell_type": "code", "execution_count": 5, "id": "3a948bea-141b-4a37-84c5-28038b0b4039", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Transformation Pipeline and Model Successfully Loaded\n" ] } ], "source": [ "kmeans_pipeline = load_model('welcome_survey_clustering_pipeline_v2')" ] }, { "cell_type": "markdown", "id": "9a42b293-f408-40d3-b339-1a13b0c3ebbb", "metadata": {}, "source": [ "### Aplikujemy model do danych" ] }, { "cell_type": "code", "execution_count": 7, "id": "8498deb3-8148-4814-aac3-64f1aa35fabf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Cluster\n", "Cluster 0 48\n", "Cluster 3 38\n", "Cluster 1 34\n", "Cluster 6 33\n", "Cluster 4 26\n", "Cluster 2 23\n", "Cluster 7 18\n", "Cluster 5 9\n", "Name: count, dtype: int64" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_with_clusters = predict_model(kmeans_pipeline, data= df)\n", "df_with_clusters['Cluster'].value_counts()" ] }, { "cell_type": "markdown", "id": "084e92f6-1c58-4a8f-a255-34ec5e47ec10", "metadata": {}, "source": [ "### Stworzymy teraz prompt, który prześlemy do LLM-a w celu znalezienia odpowiednich nazw i opisów dla klastrów" ] }, { "cell_type": "code", "execution_count": 8, "id": "13cf588e-c20b-4fe6-a1db-3c8c8fbe6555", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['Cluster 5', 'Cluster 7', 'Cluster 3', 'Cluster 4', 'Cluster 0',\n", " 'Cluster 2', 'Cluster 1', 'Cluster 6'], dtype=object)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_with_clusters['Cluster'].unique()" ] }, { "cell_type": "code", "execution_count": 9, "id": "d65473eb-51b5-4f10-adf2-928ce8b0a2c7", "metadata": {}, "outputs": [], "source": [ "cluster_descriptions = {}\n", "for cluster_id in df_with_clusters['Cluster'].unique():\n", " cluster_df = df_with_clusters[df_with_clusters['Cluster'] == cluster_id]\n", " summary = \"\"\n", " for column in df_with_clusters:\n", " if column == 'Cluster':\n", " continue\n", "\n", " value_counts = cluster_df[column].value_counts()\n", " value_counts_str = ', '.join([f\"{idx}: {cnt}\" for idx, cnt in value_counts.items()])\n", " summary += f\"{column} - {value_counts_str}\\n\"\n", "\n", " cluster_descriptions[cluster_id] = summary" ] }, { "cell_type": "code", "execution_count": 10, "id": "636c1df1-18e3-4fc6-85f9-c2cd41d146c2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "age - 35-44: 31, 25-34: 9, 55-64: 5, >=65: 2, unknown: 1, 18-24: 0, 45-54: 0, <18: 0\n", "edu_level - Wyższe: 48, Podstawowe: 0, Średnie: 0\n", "fav_animals - Psy: 37, Koty: 6, Inne: 5, Brak ulubionych: 0, Koty i Psy: 0\n", "fav_place - Nad wodą: 36, Inne: 2, W górach: 0, W lesie: 0\n", "gender - Mężczyzna: 35, Kobieta: 13\n", "\n" ] } ], "source": [ "print(cluster_descriptions[\"Cluster 0\"])" ] }, { "cell_type": "code", "execution_count": 11, "id": "c4a1b945-6a3d-4f5c-9f37-4c7c14d3a61e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Użyliśmy algorytmu klastrowania.\n", "\n", "Klaster Cluster 5:\n", "age - 35-44: 5, 45-54: 1, <18: 1, >=65: 1, unknown: 1, 18-24: 0, 25-34: 0, 55-64: 0\n", "edu_level - Wyższe: 8, Podstawowe: 1, Średnie: 0\n", "fav_animals - Brak ulubionych: 9, Inne: 0, Koty: 0, Koty i Psy: 0, Psy: 0\n", "fav_place - Nad wodą: 5, Inne: 0, W górach: 0, W lesie: 0\n", "gender - Mężczyzna: 6, Kobieta: 2\n", "\n", "\n", "Klaster Cluster 7:\n", "age - 35-44: 8, 45-54: 4, 25-34: 3, 18-24: 2, >=65: 1, 55-64: 0, <18: 0, unknown: 0\n", "edu_level - Średnie: 18, Podstawowe: 0, Wyższe: 0\n", "fav_animals - Psy: 13, Koty: 3, Brak ulubionych: 1, Inne: 1, Koty i Psy: 0\n", "fav_place - Nad wodą: 12, W lesie: 2, Inne: 0, W górach: 0\n", "gender - Mężczyzna: 13, Kobieta: 5\n", "\n", "\n", "Klaster Cluster 3:\n", "age - 45-54: 18, 35-44: 8, 25-34: 7, 55-64: 4, >=65: 1, 18-24: 0, <18: 0, unknown: 0\n", "edu_level - Wyższe: 38, Podstawowe: 0, Średnie: 0\n", "fav_animals - Psy: 23, Brak ulubionych: 5, Inne: 5, Koty: 5, Koty i Psy: 0\n", "fav_place - W lesie: 38, Inne: 0, Nad wodą: 0, W górach: 0\n", "gender - Mężczyzna: 29, Kobieta: 9\n", "\n", "\n", "Klaster Cluster 4:\n", "age - 45-54: 9, 25-34: 7, 18-24: 6, 35-44: 4, 55-64: 0, <18: 0, >=65: 0, unknown: 0\n", "edu_level - Średnie: 26, Podstawowe: 0, Wyższe: 0\n", "fav_animals - Koty: 9, Inne: 7, Psy: 7, Brak ulubionych: 3, Koty i Psy: 0\n", "fav_place - W górach: 18, W lesie: 5, Inne: 3, Nad wodą: 0\n", "gender - Mężczyzna: 24, Kobieta: 2\n", "\n", "\n", "Klaster Cluster 0:\n", "age - 35-44: 31, 25-34: 9, 55-64: 5, >=65: 2, unknown: 1, 18-24: 0, 45-54: 0, <18: 0\n", "edu_level - Wyższe: 48, Podstawowe: 0, Średnie: 0\n", "fav_animals - Psy: 37, Koty: 6, Inne: 5, Brak ulubionych: 0, Koty i Psy: 0\n", "fav_place - Nad wodą: 36, Inne: 2, W górach: 0, W lesie: 0\n", "gender - Mężczyzna: 35, Kobieta: 13\n", "\n", "\n", "Klaster Cluster 2:\n", "age - 35-44: 19, 25-34: 3, >=65: 1, 18-24: 0, 45-54: 0, 55-64: 0, <18: 0, unknown: 0\n", "edu_level - Wyższe: 23, Podstawowe: 0, Średnie: 0\n", "fav_animals - Koty: 11, Brak ulubionych: 4, Inne: 4, Koty i Psy: 2, Psy: 2\n", "fav_place - W górach: 21, Inne: 2, Nad wodą: 0, W lesie: 0\n", "gender - Mężczyzna: 14, Kobieta: 9\n", "\n", "\n", "Klaster Cluster 1:\n", "age - 45-54: 15, 25-34: 8, 35-44: 8, 18-24: 1, 55-64: 1, >=65: 1, <18: 0, unknown: 0\n", "edu_level - Wyższe: 34, Podstawowe: 0, Średnie: 0\n", "fav_animals - Psy: 25, Brak ulubionych: 4, Inne: 3, Koty: 2, Koty i Psy: 0\n", "fav_place - W górach: 34, Inne: 0, Nad wodą: 0, W lesie: 0\n", "gender - Mężczyzna: 27, Kobieta: 6\n", "\n", "\n", "Klaster Cluster 6:\n", "age - 45-54: 27, 55-64: 5, 18-24: 1, 25-34: 0, 35-44: 0, <18: 0, >=65: 0, unknown: 0\n", "edu_level - Wyższe: 33, Podstawowe: 0, Średnie: 0\n", "fav_animals - Psy: 16, Inne: 8, Koty: 5, Koty i Psy: 4, Brak ulubionych: 0\n", "fav_place - Nad wodą: 20, Inne: 2, W górach: 0, W lesie: 0\n", "gender - Mężczyzna: 23, Kobieta: 10\n", "\n", "Wygeneruj najlepsze nazwy dla każdego z klastrów oraz ich opisy\n", "\n", "Użyj formatu JSON. Przykładowo:\n", "{\n", " \"Cluster 0\": {\n", " \"name\": \"Klaster 0\",\n", " \"description\": \"W tym klastrze znajdują się osoby, które...\"\n", " },\n", " \"Cluster 1\": {\n", " \"name\": \"Klaster 1\",\n", " \"description\": \"W tym klastrze znajdują się osoby, które...\"\n", " }\n", "}\n", "\n" ] } ], "source": [ "prompt = \"Użyliśmy algorytmu klastrowania.\"\n", "for cluster_id, description in cluster_descriptions.items():\n", " prompt += f\"\\n\\nKlaster {cluster_id}:\\n{description}\"\n", "\n", "prompt += \"\"\"\n", "Wygeneruj najlepsze nazwy dla każdego z klastrów oraz ich opisy\n", "\n", "Użyj formatu JSON. Przykładowo:\n", "{\n", " \"Cluster 0\": {\n", " \"name\": \"Klaster 0\",\n", " \"description\": \"W tym klastrze znajdują się osoby, które...\"\n", " },\n", " \"Cluster 1\": {\n", " \"name\": \"Klaster 1\",\n", " \"description\": \"W tym klastrze znajdują się osoby, które...\"\n", " }\n", "}\n", "\"\"\"\n", "print(prompt)" ] }, { "cell_type": "code", "execution_count": 12, "id": "5a0c357d-d97f-40d4-b8a9-fb53d1038d90", "metadata": {}, "outputs": [], "source": [ "response = openai_client.chat.completions.create(\n", " model=\"gpt-4o\",\n", " temperature=0,\n", " messages=[\n", " {\n", " \"role\": \"user\",\n", " \"content\": [{\"type\": \"text\", \"text\": prompt}],\n", " }\n", " ],\n", ")" ] }, { "cell_type": "code", "execution_count": 13, "id": "7a484a46-61a3-4c65-93a4-8c8c16683372", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Cluster 0': {'name': 'Profesjonaliści nad wodą',\n", " 'description': 'W tym klastrze znajdują się osoby, które mają wyższe wykształcenie, są w wieku 35-44 lat, preferują spędzanie czasu nad wodą i w większości są mężczyznami. Ich ulubionymi zwierzętami są psy.'},\n", " 'Cluster 1': {'name': 'Miłośnicy gór z wyższym wykształceniem',\n", " 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu w górach. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są psy.'},\n", " 'Cluster 2': {'name': 'Kociarze górscy',\n", " 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu w górach. Są to głównie osoby w wieku 35-44 lat, a ich ulubionymi zwierzętami są koty.'},\n", " 'Cluster 3': {'name': 'Leśni profesjonaliści',\n", " 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu w lesie. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są psy.'},\n", " 'Cluster 4': {'name': 'Miłośnicy gór ze średnim wykształceniem',\n", " 'description': 'W tym klastrze znajdują się osoby ze średnim wykształceniem, które preferują spędzanie czasu w górach. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są koty.'},\n", " 'Cluster 5': {'name': 'Nadwodni bez ulubionych zwierząt',\n", " 'description': 'W tym klastrze znajdują się osoby, które preferują spędzanie czasu nad wodą, nie mają ulubionych zwierząt i są w różnym wieku. Są to głównie mężczyźni z wyższym wykształceniem.'},\n", " 'Cluster 6': {'name': 'Nadwodni profesjonaliści',\n", " 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu nad wodą. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są psy.'},\n", " 'Cluster 7': {'name': 'Nadwodni miłośnicy psów',\n", " 'description': 'W tym klastrze znajdują się osoby ze średnim wykształceniem, które preferują spędzanie czasu nad wodą. Są to głównie mężczyźni w wieku 35-44 lat, a ich ulubionymi zwierzętami są psy.'}}" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "result = response.choices[0].message.content.replace(\"```json\", \"\").replace(\"```\", \"\").strip()\n", "cluster_names_and_descriptions = json.loads(result)\n", "cluster_names_and_descriptions" ] }, { "cell_type": "markdown", "id": "553108c6-55aa-4cbd-a6ae-2feb29e82091", "metadata": {}, "source": [ "### Zapisujemy nasze nazwy i opisy klastrów do pliku JSON" ] }, { "cell_type": "code", "execution_count": 14, "id": "a2a4b2d1-5482-4e57-b84e-4935f9ed4e0f", "metadata": {}, "outputs": [], "source": [ "with open(\"welcome_survey_cluster_names_and_descriptions_v2.json\", \"w\") as f:\n", " f.write(json.dumps(cluster_names_and_descriptions))" ] }, { "cell_type": "markdown", "id": "a0811f20-c035-4a15-9eed-1d423781c324", "metadata": {}, "source": [ "### Odczytujemy z naszego pliku JSON - nazwy i opisy klastrów" ] }, { "cell_type": "code", "execution_count": 17, "id": "eceafdc1-e835-4c14-817e-34300a7b7d97", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'Cluster 0': {'name': 'Profesjonaliści nad wodą', 'description': 'W tym klastrze znajdują się osoby, które mają wyższe wykształcenie, są w wieku 35-44 lat, preferują spędzanie czasu nad wodą i w większości są mężczyznami. Ich ulubionymi zwierzętami są psy.'}, 'Cluster 1': {'name': 'Miłośnicy gór z wyższym wykształceniem', 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu w górach. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są psy.'}, 'Cluster 2': {'name': 'Kociarze górscy', 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu w górach. Są to głównie osoby w wieku 35-44 lat, a ich ulubionymi zwierzętami są koty.'}, 'Cluster 3': {'name': 'Leśni profesjonaliści', 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu w lesie. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są psy.'}, 'Cluster 4': {'name': 'Miłośnicy gór ze średnim wykształceniem', 'description': 'W tym klastrze znajdują się osoby ze średnim wykształceniem, które preferują spędzanie czasu w górach. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są koty.'}, 'Cluster 5': {'name': 'Nadwodni bez ulubionych zwierząt', 'description': 'W tym klastrze znajdują się osoby, które preferują spędzanie czasu nad wodą, nie mają ulubionych zwierząt i są w różnym wieku. Są to głównie mężczyźni z wyższym wykształceniem.'}, 'Cluster 6': {'name': 'Nadwodni profesjonaliści', 'description': 'W tym klastrze znajdują się osoby z wyższym wykształceniem, które preferują spędzanie czasu nad wodą. Są to głównie mężczyźni w wieku 45-54 lat, a ich ulubionymi zwierzętami są psy.'}, 'Cluster 7': {'name': 'Nadwodni miłośnicy psów', 'description': 'W tym klastrze znajdują się osoby ze średnim wykształceniem, które preferują spędzanie czasu nad wodą. Są to głównie mężczyźni w wieku 35-44 lat, a ich ulubionymi zwierzętami są psy.'}}\n" ] } ], "source": [ "with open(\"welcome_survey_cluster_names_and_descriptions_v2.json\", \"r\") as f:\n", " data = json.loads(f.read())\n", " print(data)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.9" } }, "nbformat": 4, "nbformat_minor": 5 }