Corame commited on
Commit
9922ae0
·
verified ·
1 Parent(s): c274531

Upload gradio_show.ipynb

Browse files
Files changed (1) hide show
  1. gradio_show.ipynb +1248 -0
gradio_show.ipynb ADDED
@@ -0,0 +1,1248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 18,
6
+ "id": "bbac0476",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "name": "stdout",
11
+ "output_type": "stream",
12
+ "text": [
13
+ "The gradio extension is already loaded. To reload it, use:\n",
14
+ " %reload_ext gradio\n"
15
+ ]
16
+ }
17
+ ],
18
+ "source": [
19
+ "%load_ext gradio"
20
+ ]
21
+ },
22
+ {
23
+ "cell_type": "code",
24
+ "execution_count": null,
25
+ "id": "a83f8fbf",
26
+ "metadata": {},
27
+ "outputs": [],
28
+ "source": [
29
+ "%%blocks\n",
30
+ "import gradio as gr\n",
31
+ "from llama_cpp import Llama\n",
32
+ "import llama_cpp\n",
33
+ "from langchain.callbacks.manager import CallbackManager\n",
34
+ "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n",
35
+ "\n",
36
+ "\n",
37
+ "llm = Llama(\n",
38
+ " model_path=r\"C:\\Users\\user\\breeze-7b-instruct-v1_0-q4_k_m.gguf\",\n",
39
+ " n_gpu_layers=100,\n",
40
+ " n_batch=512,\n",
41
+ " n_ctx=3000,\n",
42
+ " f16_kv=True,\n",
43
+ " callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]),\n",
44
+ " verbose=False,\n",
45
+ ")\n",
46
+ "\n",
47
+ "with gr.Blocks() as demo:\n",
48
+ " name=\"cora\"\n",
49
+ " gr.Markdown(f\"# Greetings {name}!\")\n",
50
+ " inp = gr.Textbox()\n",
51
+ " out = gr.Textbox()\n",
52
+ "\n",
53
+ " inp.change(fn=lambda x: x, inputs=inp, outputs=out)\n"
54
+ ]
55
+ },
56
+ {
57
+ "cell_type": "code",
58
+ "execution_count": null,
59
+ "id": "c51b8778",
60
+ "metadata": {
61
+ "scrolled": true
62
+ },
63
+ "outputs": [],
64
+ "source": [
65
+ "import gradio as gr\n",
66
+ "\n",
67
+ "# 定義處理函數\n",
68
+ "def process_user_input(message):\n",
69
+ " return message\n",
70
+ "\n",
71
+ "# 定義主函數\n",
72
+ "def main_pipeline(message, history):\n",
73
+ " # 呼叫處理函數\n",
74
+ " response = process_user_input(message)\n",
75
+ " # 將輸出加入歷史訊息\n",
76
+ " return response\n",
77
+ "\n",
78
+ "# 創建 Gradio 介面\n",
79
+ "chat_interface = gr.Interface(fn=main_pipeline,inputs=\"text\",outputs=\"text\",live=True)\n",
80
+ "\n",
81
+ "# 啟動應用程式\n",
82
+ "if __name__ == \"__main__\":\n",
83
+ " \n",
84
+ " chat_interface.launch()\n"
85
+ ]
86
+ },
87
+ {
88
+ "cell_type": "code",
89
+ "execution_count": null,
90
+ "id": "3ff36b6c-1b1d-4703-96f7-65642fae5722",
91
+ "metadata": {},
92
+ "outputs": [],
93
+ "source": [
94
+ "import gradio as gr\n",
95
+ "\n",
96
+ "def process_user_input(message):\n",
97
+ " return message\n",
98
+ "\n",
99
+ "def main_pipeline(message, history):\n",
100
+ " response = process_user_input(message)\n",
101
+ " return response\n",
102
+ "\n",
103
+ "chat_interface = gr.ChatInterface(main_pipeline, type=\"messages\")\n",
104
+ "\n",
105
+ "if __name__ == \"__main__\":\n",
106
+ " chat_interface.launch()"
107
+ ]
108
+ },
109
+ {
110
+ "cell_type": "code",
111
+ "execution_count": null,
112
+ "id": "ee5766db-3500-4082-a634-2b1cdad5859b",
113
+ "metadata": {},
114
+ "outputs": [],
115
+ "source": []
116
+ },
117
+ {
118
+ "cell_type": "code",
119
+ "execution_count": null,
120
+ "id": "4d1d8fe7",
121
+ "metadata": {},
122
+ "outputs": [],
123
+ "source": [
124
+ "import gradio as gr\n",
125
+ "from llama_cpp import Llama\n",
126
+ "from langchain_community.llms import LlamaCpp\n",
127
+ "from langchain.prompts import PromptTemplate\n",
128
+ "import llama_cpp\n",
129
+ "from langchain.callbacks.manager import CallbackManager\n",
130
+ "from sentence_transformers import SentenceTransformer\n",
131
+ "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n",
132
+ "import numpy as np\n",
133
+ "import pandas as pd\n",
134
+ "import re\n",
135
+ "import os\n",
136
+ "from sklearn.metrics.pairwise import cosine_similarity\n",
137
+ "\n",
138
+ "# 定義輔助函式\n",
139
+ "def process_user_input(message):\n",
140
+ " return message\n",
141
+ "\n",
142
+ "# # 假設 PromptTemplate 和 invoke_with_temperature 已正確定義\n",
143
+ "# user_mental_state4 = PromptTemplate(\n",
144
+ "# input_variables=[\"input\"],\n",
145
+ "# template=\"\"\"...\"\"\"\n",
146
+ "# )\n",
147
+ " \n",
148
+ "# df_user = pd.DataFrame(columns=[\"輸入內容\", \"形容詞1\", \"形容詞2\", \"形容詞3\", \"角色1\", \"角色2\", \"角色3\"])\n",
149
+ "# prompt_value1 = user_mental_state4.invoke({\"input\": message})\n",
150
+ "# string = invoke_with_temperature(prompt_value1)\n",
151
+ "# adjectives = [adj.strip() for adj in re.split('[,、,]', string)]\n",
152
+ "# index = len(df_user)\n",
153
+ "# df_user.loc[index, '輸入內容'] = message\n",
154
+ "# if len(adjectives) == 3:\n",
155
+ "# df_user.loc[index, '形容詞1'] = adjectives[0]\n",
156
+ "# df_user.loc[index, '形容詞2'] = adjectives[1]\n",
157
+ "# df_user.loc[index, '形容詞3'] = adjectives[2]\n",
158
+ "# df_user.to_excel(\"user_gradio系統.xlsx\")\n",
159
+ "# return message\n",
160
+ "\n",
161
+ "# 主邏輯\n",
162
+ "def main_pipeline(message, history):\n",
163
+ " df_user = process_user_input(message)\n",
164
+ " return df_user\n",
165
+ "\n",
166
+ "demo=gr.ChatInterface(main_pipeline)\n",
167
+ "\n",
168
+ "# 主程式進入點\n",
169
+ "if __name__ == \"__main__\":\n",
170
+ " \n",
171
+ " demo.launch()\n",
172
+ " \n",
173
+ "# import gradio as gr\n",
174
+ "\n",
175
+ "# # 定義處理函數\n",
176
+ "# def process_user_input(message):\n",
177
+ "# return message\n",
178
+ "\n",
179
+ "# # 定義主函數\n",
180
+ "# def main_pipeline(message, history):\n",
181
+ "# # 呼叫處理函數\n",
182
+ "# response = process_user_input(message)\n",
183
+ "# # 將輸出加入歷史訊息\n",
184
+ "# return response\n",
185
+ "\n",
186
+ "# # 創建 Gradio 介面\n",
187
+ "# chat_interface = gr.ChatInterface(main_pipeline)\n",
188
+ "\n",
189
+ "# # 啟動應用程式\n",
190
+ "# if __name__ == \"__main__\":\n",
191
+ "# chat_interface.launch()\n",
192
+ " "
193
+ ]
194
+ },
195
+ {
196
+ "cell_type": "code",
197
+ "execution_count": 4,
198
+ "id": "4df2a74d",
199
+ "metadata": {},
200
+ "outputs": [
201
+ {
202
+ "name": "stdout",
203
+ "output_type": "stream",
204
+ "text": [
205
+ "WARNING:tensorflow:From C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\tf_keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n",
206
+ "\n",
207
+ "Running on local URL: http://127.0.0.1:7864\n",
208
+ "\n",
209
+ "To create a public link, set `share=True` in `launch()`.\n"
210
+ ]
211
+ },
212
+ {
213
+ "data": {
214
+ "text/html": [
215
+ "<div><iframe src=\"http://127.0.0.1:7864/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
216
+ ],
217
+ "text/plain": [
218
+ "<IPython.core.display.HTML object>"
219
+ ]
220
+ },
221
+ "metadata": {},
222
+ "output_type": "display_data"
223
+ },
224
+ {
225
+ "name": "stderr",
226
+ "output_type": "stream",
227
+ "text": [
228
+ "C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\analytics.py:106: UserWarning: IMPORTANT: You are using gradio version 4.44.0, however version 4.44.1 is available, please upgrade. \n",
229
+ "--------\n",
230
+ " warnings.warn(\n",
231
+ "Traceback (most recent call last):\n",
232
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\queueing.py\", line 536, in process_events\n",
233
+ " response = await route_utils.call_process_api(\n",
234
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\route_utils.py\", line 322, in call_process_api\n",
235
+ " output = await app.get_blocks().process_api(\n",
236
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\blocks.py\", line 1935, in process_api\n",
237
+ " result = await self.call_function(\n",
238
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\blocks.py\", line 1518, in call_function\n",
239
+ " prediction = await fn(*processed_input)\n",
240
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\utils.py\", line 793, in async_wrapper\n",
241
+ " response = await f(*args, **kwargs)\n",
242
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\chat_interface.py\", line 623, in _submit_fn\n",
243
+ " response = await anyio.to_thread.run_sync(\n",
244
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\anyio\\to_thread.py\", line 56, in run_sync\n",
245
+ " return await get_async_backend().run_sync_in_worker_thread(\n",
246
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\anyio\\_backends\\_asyncio.py\", line 2441, in run_sync_in_worker_thread\n",
247
+ " return await future\n",
248
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\anyio\\_backends\\_asyncio.py\", line 943, in run\n",
249
+ " result = context.run(func, *args)\n",
250
+ " File \"C:\\Users\\user\\AppData\\Local\\Temp\\ipykernel_17468\\2638884024.py\", line 229, in main_pipeline\n",
251
+ " df_filter=filter(sorted_df)\n",
252
+ " File \"C:\\Users\\user\\AppData\\Local\\Temp\\ipykernel_17468\\2638884024.py\", line 162, in filter\n",
253
+ " p=len(df_user)-1\n",
254
+ "NameError: name 'df_user' is not defined\n"
255
+ ]
256
+ }
257
+ ],
258
+ "source": [
259
+ "import gradio as gr\n",
260
+ "from llama_cpp import Llama\n",
261
+ "from langchain_community.llms import LlamaCpp\n",
262
+ "from langchain.prompts import PromptTemplate\n",
263
+ "import llama_cpp\n",
264
+ "from langchain.callbacks.manager import CallbackManager\n",
265
+ "from sentence_transformers import SentenceTransformer\n",
266
+ "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n",
267
+ "import numpy as np\n",
268
+ "import pandas as pd\n",
269
+ "import re\n",
270
+ "import os\n",
271
+ "from sklearn.metrics.pairwise import cosine_similarity\n",
272
+ "\n",
273
+ "model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-mpnet-base-v2',device='cpu')\n",
274
+ "\n",
275
+ "# llm = LlamaCpp(\n",
276
+ "# model_path=r\"C:\\Users\\Cora\\.cache\\lm-studio\\models\\YC-Chen\\Breeze-7B-Instruct-v1_0-GGUF\\breeze-7b-instruct-v1_0-q4_k_m.gguf\",\n",
277
+ "# n_gpu_layers=100,\n",
278
+ "# n_batch=512,\n",
279
+ "# n_ctx=3000,\n",
280
+ "# f16_kv=True,\n",
281
+ "# callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]),\n",
282
+ "# verbose=False,\n",
283
+ "# )\n",
284
+ "\n",
285
+ "llm = LlamaCpp(\n",
286
+ " model_path=r\"C:\\Users\\user\\breeze-7b-instruct-v1_0-q4_k_m.gguf\",\n",
287
+ " n_gpu_layers=100,\n",
288
+ " n_batch=512,\n",
289
+ " n_ctx=3000,\n",
290
+ " f16_kv=True,\n",
291
+ " callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]),\n",
292
+ " verbose=False,\n",
293
+ ")\n",
294
+ "\n",
295
+ "embedd_bk=pd.read_pickle(r\"C:\\Users\\user\\推薦系統實作\\bk_description1_角色形容詞_677.pkl\")\n",
296
+ "df_bk=pd.read_excel(r\"C:\\Users\\user\\推薦系統實作\\bk_description1_角色形容詞.xlsx\")\n",
297
+ "\n",
298
+ "def invoke_with_temperature(prompt, temperature=0.4):\n",
299
+ " return llm.invoke(prompt, temperature=temperature)\n",
300
+ "\n",
301
+ "def process_user_input(message):\n",
302
+ " user_mental_state4= PromptTemplate(\n",
303
+ " input_variables=[\"input\"],\n",
304
+ " template=\"\"\"[INST]<<SYS>>你是一位具有同理心的專業心理諮商師,沒有性別歧視,你可以客觀的根據談話內容的描述,判斷說話的人的心理困擾<</SYS>> \n",
305
+ " 請根據{input}描述三個最有可能心理困擾,輸出只包含三個心理困擾,回答格式只採用CSV格式,分隔符號使用逗號,參考以下範例:名詞1,名詞2,名詞3。[/INST]\"\"\"\n",
306
+ " )\n",
307
+ " \n",
308
+ " user_character= PromptTemplate(\n",
309
+ " input_variables=[\"input\"],\n",
310
+ " template=\"\"\"[INST]<<SYS>>你是一位具有同理心的專業心理諮商師,沒有性別歧視,你可以客觀的根據談話內容的描述,判斷說話的大學生,在生活中的多重角色身分<</SYS>> \n",
311
+ " 請你根據談話內容{input},客觀的判斷說話的大學生,在談話內容中的角色,以及他生活中其他角色的身分,提供三個最有可能的角色身分名詞,\n",
312
+ " 輸出只包含三個身分名詞,回答格式只採用CSV格式,分隔符號使用逗號,參考以下範例:名詞1,名詞2,名詞3。[/INST]\"\"\"\n",
313
+ " )\n",
314
+ " \n",
315
+ "\n",
316
+ " df_user=pd.DataFrame(columns=[\"輸入內容\",\"形容詞1\", \"形容詞2\", \"形容詞3\", \"角色1\", \"角色2\", \"角色3\"])\n",
317
+ " #df_user_record=pd.read_excel(r\"C:\\Users\\Cora\\推薦系統實作\\gradio系統歷史紀錄.xlsx\")\n",
318
+ " \n",
319
+ "\n",
320
+ " prompt_value1=user_mental_state4.invoke({\"input\":message})\n",
321
+ " string=invoke_with_temperature(prompt_value1)\n",
322
+ " #print(\"\\n\")\n",
323
+ "\n",
324
+ " # 將字符串分割為名詞\n",
325
+ " adjectives = [adj.strip() for adj in re.split('[,、,]', string)]\n",
326
+ " \n",
327
+ " index=len(df_user)\n",
328
+ " df_user.loc[index, '輸入內容'] = message\n",
329
+ "\n",
330
+ " # 確保形容詞數量符合欄位數量\n",
331
+ " if len(adjectives) == 3:\n",
332
+ " df_user.loc[index, '形容詞1'] = adjectives[0]\n",
333
+ " df_user.loc[index, '形容詞2'] = adjectives[1]\n",
334
+ " df_user.loc[index, '形容詞3'] = adjectives[2]\n",
335
+ " df_user.to_excel(\"user_gradio系統.xlsx\")\n",
336
+ " return df_user\n",
337
+ "\n",
338
+ "def embedd_df_user(df_user):\n",
339
+ " \n",
340
+ " columns_to_encode=df_user.loc[:,[\"形容詞1\", \"形容詞2\", \"形容詞3\"]]\n",
341
+ "\n",
342
+ " # 初始化一個空的 DataFrame,用來存儲向量化結果\n",
343
+ " embedd_user=df_user[[\"輸入內容\"]]\n",
344
+ " #user_em= user_em.assign(形容詞1=None, 形容詞2=None, 形容詞3=None,角色1=None,角色2=None,角色3=None)\n",
345
+ " embedd_user= embedd_user.assign(形容詞1=None, 形容詞2=None, 形容詞3=None)\n",
346
+ " \n",
347
+ "\n",
348
+ " # 遍歷每一個單元格,將結果存入新的 DataFrame 中\n",
349
+ " i=len(df_user)-1\n",
350
+ " for col in columns_to_encode:\n",
351
+ " #print(i,col)\n",
352
+ " # 將每個單元格的內容進行向量化\n",
353
+ " embedd_user.at[i, col] = model.encode(df_user.at[i, col]) \n",
354
+ " \n",
355
+ " embedd_user.to_pickle(r\"C:\\Users\\user\\推薦系統實作\\user_gradio系統.pkl\")\n",
356
+ " \n",
357
+ " return embedd_user\n",
358
+ "\n",
359
+ "def top_n_books_by_average(df, n=3):\n",
360
+ " \n",
361
+ " # 根据 `average` 列降序排序\n",
362
+ " sorted_df = df.sort_values(by='average', ascending=False)\n",
363
+ " \n",
364
+ " # 选择前 N 行\n",
365
+ " top_n_df = sorted_df.head(n)\n",
366
+ " \n",
367
+ " # 提取书名列\n",
368
+ " top_books = top_n_df['書名'].tolist()\n",
369
+ " \n",
370
+ " return top_books,sorted_df\n",
371
+ "\n",
372
+ "def similarity(embedd_user,embedd_bk,df_bk):\n",
373
+ " df_similarity= pd.DataFrame(df_bk[['書名',\"內容簡介\",\"URL\",\"形容詞1\", \"形容詞2\", \"形容詞3\", '角色1', '角色2', '角色3']])\n",
374
+ " df_similarity['average'] = np.nan\n",
375
+ " #for p in range(len(embedd_user)): \n",
376
+ " index=len(embedd_user)-1 \n",
377
+ " for k in range(len(embedd_bk)):\n",
378
+ " list=[]\n",
379
+ " for i in range(1,4):\n",
380
+ " for j in range(3,6):\n",
381
+ " vec1=embedd_user.iloc[index,i]#i是第i個形容詞,數字是第幾個是使用者輸入\n",
382
+ " vec2=embedd_bk.iloc[k,j]\n",
383
+ " similarity = cosine_similarity([vec1], [vec2])\n",
384
+ " list.append(similarity[0][0])\n",
385
+ " # 计算总和\n",
386
+ " total_sum = sum(list)\n",
387
+ " # 计算数量\n",
388
+ " count = len(list)\n",
389
+ " # 计算平均值\n",
390
+ " average = total_sum / count\n",
391
+ " df_similarity.loc[k,'average']=average\n",
392
+ "\n",
393
+ " top_books,sorted_df = top_n_books_by_average(df_similarity)\n",
394
+ " return sorted_df \n",
395
+ "\n",
396
+ "def filter(sorted_df):\n",
397
+ " filter_prompt4 = PromptTemplate(\n",
398
+ " input_variables=[\"mental_issue\", \"user_identity\",\" book\",\"book_reader\", \"book_description\"],\n",
399
+ " template=\"\"\"[INST]<<SYS>>你是專業的心理諮商師和書籍推薦專家,擅長根據使用者的心理問題、身份特質,以及書名、書籍針對的主題和適合的讀者,判斷書籍是否適合推薦給使用者。\n",
400
+ "\n",
401
+ " 你的目的是幫助讀者找到可以緩解心理問題的書籍。請注意:\n",
402
+ " 1. 若書籍針對的問題與使用者的心理問題有關聯,即使書籍適合的讀者群與使用者身份沒有直接關聯,應偏向推薦。\n",
403
+ " 2. 若使用者身份的需求與書籍針對的問題有潛在關聯,應偏向推薦。\n",
404
+ " 3. 若書籍適合的讀者與使用者身份特質有任何關聯,應傾向推薦。\n",
405
+ " 4. 若書名跟使用者的心理問題或身分特質有任何關聯,應偏向推薦<</SYS>>\n",
406
+ "\n",
407
+ " 使用者提供的資訊如下:\n",
408
+ " 使用者身份是「{user_identity}」,其心理問題是「{mental_issue}」。書名是{book},書籍適合的讀者群為「{book_reader}」,書籍針對的問題是「{book_description}」。\n",
409
+ "\n",
410
+ " 請根據以上資訊判斷這本書是否適合推薦給該使用者。\n",
411
+ " 僅輸出「是」或「否」,輸出後即停止。[/INST]\"\"\"\n",
412
+ " )\n",
413
+ " df_filter=sorted_df.iloc[:20,:]\n",
414
+ " df_filter = df_filter.reset_index(drop=True)\n",
415
+ " df_filter=df_filter.assign(推薦=None)\n",
416
+ " #df_similarity= pd.DataFrame(df_bk[['書名',\"內容簡介\",\"URL\",\"形容詞1\", \"形容詞2\", \"形容詞3\", '角色1', '角色2', '角色3']])\n",
417
+ " #df_similarity['average'] = np.nan\n",
418
+ "\n",
419
+ " \n",
420
+ " p=len(df_user)-1\n",
421
+ " for k in range(len(df_filter)): \n",
422
+ " word=df_user[\"輸入內容\"].iloc[p]\n",
423
+ " #book_reader = df_filter[\"角色1\"].iloc[p] + \"or\" + df_filter[\"角色2\"].iloc[p] + \"or\" + df_filter[\"角色3\"].iloc[p]\n",
424
+ " book=df_filter[\"書名\"].iloc[k] \n",
425
+ " book_reader = df_filter[\"角色1\"].iloc[k] \n",
426
+ " user_identity = df_user[\"角色1\"].iloc[p]\n",
427
+ " mental_issue=df_user[\"形容詞1\"].iloc[p]+\"、\"+df_user[\"形容詞2\"].iloc[p]+\"、\"+df_user[\"形容詞3\"].iloc[p]\n",
428
+ " book_description=df_filter[\"形容詞1\"].iloc[k]+\"、\"+df_filter[\"形容詞2\"].iloc[k]+\"、\"+df_filter[\"形容詞3\"].iloc[k]\n",
429
+ " print(book_reader)\n",
430
+ " print(user_identity)\n",
431
+ " #output = filter_prompt1.invoke({\"user_identity\": user_identity, \"book_reader\": book_reader})\n",
432
+ " output = filter_prompt4.invoke({\"mental_issue\":mental_issue,\"user_identity\": user_identity, \"book\":book,\"book_description\":book_description,\"book_reader\": book_reader})\n",
433
+ " string2=invoke_with_temperature(output)\n",
434
+ " df_filter.loc[k, '推薦'] =string2\n",
435
+ " df_recommend=df_filter[df_filter[\"推薦\"].str.strip() == \"是\"]\n",
436
+ " \n",
437
+ " return df_recommend\n",
438
+ "def output_content(df_recommend):\n",
439
+ " content_prompt = PromptTemplate(\n",
440
+ " input_variables=[\"content\"],\n",
441
+ " template=\"\"\"[INST]<<SYS>>你是一個有同理心的心理師,負責推薦相關書籍給使用者<</SYS>>你是一個有同理心的心理師,\n",
442
+ " 請根據{content},用平易近人且不官方的語氣,先介紹這本書的內容,總共約50-70字[/INST]\"\"\"\n",
443
+ " )\n",
444
+ "\n",
445
+ " a=0\n",
446
+ " title=df_recommend.loc[a,\"書名\"]\n",
447
+ " #URL=sorted_df.iloc[a,1]\n",
448
+ " #content=sorted_df.iloc[a,2]\n",
449
+ " \n",
450
+ "# prompt_value2=content_prompt.invoke({\"content\":content})\n",
451
+ "# summary=invoke_with_temperature(prompt_value2)\n",
452
+ "# recommend_prompt = PromptTemplate(\n",
453
+ "# input_variables=[\"title\",\"URL\",\"summary\"],\n",
454
+ "# template=\"\"\"<<SYS>>\n",
455
+ "# 你是一個有同理心的心理師,負責推薦相關書籍給使用者<</SYS>>\n",
456
+ "# [INST] \n",
457
+ "# 請根據{title}{URL}{summary}產出訊息,開頭不要有空格,並在最後面加入一句或兩句鼓勵的話\n",
458
+ "# 格式為:根據您的狀態,這裡提供一本書供您參考\\n\n",
459
+ "# 書名:{title}\\n\n",
460
+ "# 本書介紹:{summary}\\n\n",
461
+ "# 購書網址:{URL}\\n\n",
462
+ "# 希望對您有所幫助\n",
463
+ "# [/INST]\"\"\"\n",
464
+ "# )\n",
465
+ "# prompt_value1=recommend_prompt.invoke({\"title\":title,\"URL\":URL,\"summary\":summary})\n",
466
+ " \n",
467
+ " recommend_prompt = PromptTemplate(\n",
468
+ " input_variables=[\"title\"],\n",
469
+ " template=\"\"\"<<SYS>>\n",
470
+ " 你是一個有同理心的心理師,負責推薦相關書籍給使用者<</SYS>>\n",
471
+ " [INST] \n",
472
+ " 請根據{title}產出訊息,開頭不要有空格,並在最後面加入一句或兩句鼓勵的話\n",
473
+ " 格式為:根據您的狀態,這裡提供一本書供您參考\\n\n",
474
+ " 書名:{title}\\n\n",
475
+ " 希望對您有所幫助\n",
476
+ " [/INST]\"\"\"\n",
477
+ " )\n",
478
+ " prompt_value1=recommend_prompt.invoke({\"title\":title})\n",
479
+ " output=invoke_with_temperature(prompt_value1,temperature=0.4)\n",
480
+ " return output \n",
481
+ " \n",
482
+ "def main_pipeline(message,history):\n",
483
+ " \n",
484
+ " df_user=process_user_input(message)\n",
485
+ " embedd_user=embedd_df_user(df_user)\n",
486
+ " sorted_df=similarity(embedd_user,embedd_bk,df_bk)\n",
487
+ " df_filter=filter(sorted_df)\n",
488
+ " final=output_content(df_filter)\n",
489
+ " return final \n",
490
+ " \n",
491
+ "\n",
492
+ "# def recommend(message,history):\n",
493
+ "# result=main_pipeline(message)\n",
494
+ "# return result\n",
495
+ "\n",
496
+ "demo=gr.ChatInterface(main_pipeline,type=\"messages\")\n",
497
+ "\n",
498
+ "# with gr.Blocks() as demo:\n",
499
+ "# gr.Markdown(\"Start typing below and then click **Run** to see the output.\")\n",
500
+ "# with gr.Row():\n",
501
+ "# inp = gr.Textbox(placeholder=\"What is your name?\")\n",
502
+ "# out = gr.Textbox()\n",
503
+ "# btn = gr.Button(\"Run\")\n",
504
+ "# btn.click(fn=recommend, inputs=inp, outputs=out)\n",
505
+ "if __name__ == \"__main__\":\n",
506
+ " demo.launch()"
507
+ ]
508
+ },
509
+ {
510
+ "cell_type": "code",
511
+ "execution_count": 6,
512
+ "id": "487c853d",
513
+ "metadata": {},
514
+ "outputs": [
515
+ {
516
+ "name": "stdout",
517
+ "output_type": "stream",
518
+ "text": [
519
+ "Running on local URL: http://127.0.0.1:7866\n",
520
+ "\n",
521
+ "To create a public link, set `share=True` in `launch()`.\n"
522
+ ]
523
+ },
524
+ {
525
+ "data": {
526
+ "text/html": [
527
+ "<div><iframe src=\"http://127.0.0.1:7866/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
528
+ ],
529
+ "text/plain": [
530
+ "<IPython.core.display.HTML object>"
531
+ ]
532
+ },
533
+ "metadata": {},
534
+ "output_type": "display_data"
535
+ },
536
+ {
537
+ "name": "stderr",
538
+ "output_type": "stream",
539
+ "text": [
540
+ "C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\analytics.py:106: UserWarning: IMPORTANT: You are using gradio version 4.44.0, however version 4.44.1 is available, please upgrade. \n",
541
+ "--------\n",
542
+ " warnings.warn(\n"
543
+ ]
544
+ },
545
+ {
546
+ "name": "stdout",
547
+ "output_type": "stream",
548
+ "text": [
549
+ " 情緒控制困難,壓力負荷過高,人際衝突"
550
+ ]
551
+ },
552
+ {
553
+ "name": "stderr",
554
+ "output_type": "stream",
555
+ "text": [
556
+ "Traceback (most recent call last):\n",
557
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\queueing.py\", line 536, in process_events\n",
558
+ " response = await route_utils.call_process_api(\n",
559
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\route_utils.py\", line 322, in call_process_api\n",
560
+ " output = await app.get_blocks().process_api(\n",
561
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\blocks.py\", line 1935, in process_api\n",
562
+ " result = await self.call_function(\n",
563
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\blocks.py\", line 1518, in call_function\n",
564
+ " prediction = await fn(*processed_input)\n",
565
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\utils.py\", line 793, in async_wrapper\n",
566
+ " response = await f(*args, **kwargs)\n",
567
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\chat_interface.py\", line 623, in _submit_fn\n",
568
+ " response = await anyio.to_thread.run_sync(\n",
569
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\anyio\\to_thread.py\", line 56, in run_sync\n",
570
+ " return await get_async_backend().run_sync_in_worker_thread(\n",
571
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\anyio\\_backends\\_asyncio.py\", line 2441, in run_sync_in_worker_thread\n",
572
+ " return await future\n",
573
+ " File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\anyio\\_backends\\_asyncio.py\", line 943, in run\n",
574
+ " result = context.run(func, *args)\n",
575
+ " File \"C:\\Users\\user\\AppData\\Local\\Temp\\ipykernel_17468\\1758736236.py\", line 78, in main_pipeline\n",
576
+ " df_filter=filter(sorted_df)\n",
577
+ " File \"C:\\Users\\user\\AppData\\Local\\Temp\\ipykernel_17468\\2638884024.py\", line 162, in filter\n",
578
+ " p=len(df_user)-1\n",
579
+ "NameError: name 'df_user' is not defined\n"
580
+ ]
581
+ }
582
+ ],
583
+ "source": [
584
+ "import gradio as gr\n",
585
+ "from llama_cpp import Llama\n",
586
+ "from langchain_community.llms import LlamaCpp\n",
587
+ "from langchain.prompts import PromptTemplate\n",
588
+ "import llama_cpp\n",
589
+ "from langchain.callbacks.manager import CallbackManager\n",
590
+ "from sentence_transformers import SentenceTransformer\n",
591
+ "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n",
592
+ "import numpy as np\n",
593
+ "import pandas as pd\n",
594
+ "import re\n",
595
+ "import os\n",
596
+ "from sklearn.metrics.pairwise import cosine_similarity\n",
597
+ "\n",
598
+ "model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-mpnet-base-v2',device='cpu')\n",
599
+ "\n",
600
+ "llm = LlamaCpp(\n",
601
+ " model_path=r\"C:\\Users\\user\\breeze-7b-instruct-v1_0-q4_k_m.gguf\",\n",
602
+ " n_gpu_layers=100,\n",
603
+ " n_batch=512,\n",
604
+ " n_ctx=3000,\n",
605
+ " f16_kv=True,\n",
606
+ " callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]),\n",
607
+ " verbose=False,\n",
608
+ ")\n",
609
+ "\n",
610
+ "embedd_bk=pd.read_pickle(r\"C:\\Users\\user\\推薦系統實作\\bk_description1_角色形容詞_677.pkl\")\n",
611
+ "df_bk=pd.read_excel(r\"C:\\Users\\user\\推薦系統實作\\bk_description1_角色形容詞.xlsx\")\n",
612
+ "\n",
613
+ "def invoke_with_temperature(prompt, temperature=0.4):\n",
614
+ " return llm.invoke(prompt, temperature=temperature)\n",
615
+ "\n",
616
+ "def process_user_input(message):\n",
617
+ " \n",
618
+ " user_mental_state4= PromptTemplate(\n",
619
+ " input_variables=[\"input\"],\n",
620
+ " template=\"\"\"[INST]<<SYS>>你是一位具有同理心的專業心理諮商師,沒有性別歧視,你可以客觀的根據談話內容的描述,判斷說話的人的心理困擾<</SYS>> \n",
621
+ " 請根據{input}描述三個最有可能心理困擾,輸出只包含三個心理困擾,回答格式只採用CSV格式,分隔符號使用逗號,參考以下範例:名詞1,名詞2,名詞3。[/INST]\"\"\"\n",
622
+ " )\n",
623
+ " \n",
624
+ " user_character= PromptTemplate(\n",
625
+ " input_variables=[\"input\"],\n",
626
+ " template=\"\"\"[INST]<<SYS>>你是一位具有同理心的專業心理諮商師,沒有性別歧視,你可以客觀的根據談話內容的描述,判斷說話的大學生,在生活中的多重角色身分<</SYS>> \n",
627
+ " 請你根據談話內容{input},客觀的判斷說話的大學生,在談話內容中的角色,以及他生活中其他角色的身分,提供三個最有可能的角色身分名詞,\n",
628
+ " 輸出只包含三個身分名詞,回答格式只採用CSV格式,分隔符號使用逗號,參考以下範例:名詞1,名詞2,名詞3。[/INST]\"\"\"\n",
629
+ " )\n",
630
+ " \n",
631
+ "\n",
632
+ " df_user=pd.DataFrame(columns=[\"輸入內容\",\"形容詞1\", \"形容詞2\", \"形容詞3\", \"角色1\", \"角色2\", \"角色3\"])\n",
633
+ " #df_user_record=pd.read_excel(r\"C:\\Users\\Cora\\推薦系統實作\\gradio系統歷史紀錄.xlsx\")\n",
634
+ " \n",
635
+ "\n",
636
+ " prompt_value1=user_mental_state4.invoke({\"input\":message})\n",
637
+ " string=invoke_with_temperature(prompt_value1)\n",
638
+ " #print(\"\\n\")\n",
639
+ "\n",
640
+ " # 將字符串分割為名詞\n",
641
+ " adjectives = [adj.strip() for adj in re.split('[,、,]', string)]\n",
642
+ " \n",
643
+ " index=len(df_user)\n",
644
+ " df_user.loc[index, '輸入內容'] = message\n",
645
+ "\n",
646
+ " # 確保形容詞數量符合欄位數量\n",
647
+ " if len(adjectives) == 3:\n",
648
+ " df_user.loc[index, '形容詞1'] = adjectives[0]\n",
649
+ " df_user.loc[index, '形容詞2'] = adjectives[1]\n",
650
+ " df_user.loc[index, '形容詞3'] = adjectives[2]\n",
651
+ " df_user.to_excel(\"user_gradio系統.xlsx\")\n",
652
+ " return df_user\n",
653
+ "\n",
654
+ " \n",
655
+ " \n",
656
+ "def main_pipeline(message,history):\n",
657
+ " \n",
658
+ " df_user=process_user_input(message)\n",
659
+ " embedd_user=embedd_df_user(df_user)\n",
660
+ " sorted_df=similarity(embedd_user,embedd_bk,df_bk)\n",
661
+ " df_filter=filter(sorted_df)\n",
662
+ " final=output_content(df_filter)\n",
663
+ " return final \n",
664
+ " \n",
665
+ "\n",
666
+ "\n",
667
+ "demo=gr.ChatInterface(main_pipeline,type=\"messages\")\n",
668
+ "\n",
669
+ "\n",
670
+ "if __name__ == \"__main__\":\n",
671
+ " demo.launch()"
672
+ ]
673
+ },
674
+ {
675
+ "cell_type": "code",
676
+ "execution_count": 19,
677
+ "id": "b3cadc4a-6f63-4038-bcfb-ef419ad5394a",
678
+ "metadata": {},
679
+ "outputs": [
680
+ {
681
+ "name": "stdout",
682
+ "output_type": "stream",
683
+ "text": [
684
+ "Running on local URL: http://127.0.0.1:7873\n",
685
+ "\n",
686
+ "To create a public link, set `share=True` in `launch()`.\n"
687
+ ]
688
+ },
689
+ {
690
+ "data": {
691
+ "text/html": [
692
+ "<div><iframe src=\"http://127.0.0.1:7873/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
693
+ ],
694
+ "text/plain": [
695
+ "<IPython.core.display.HTML object>"
696
+ ]
697
+ },
698
+ "metadata": {},
699
+ "output_type": "display_data"
700
+ },
701
+ {
702
+ "name": "stderr",
703
+ "output_type": "stream",
704
+ "text": [
705
+ "C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\gradio\\analytics.py:106: UserWarning: IMPORTANT: You are using gradio version 4.44.0, however version 4.44.1 is available, please upgrade. \n",
706
+ "--------\n",
707
+ " warnings.warn(\n"
708
+ ]
709
+ }
710
+ ],
711
+ "source": [
712
+ "import gradio as gr\n",
713
+ "from llama_cpp import Llama\n",
714
+ "from langchain_community.llms import LlamaCpp\n",
715
+ "from langchain.prompts import PromptTemplate\n",
716
+ "import llama_cpp\n",
717
+ "from langchain.callbacks.manager import CallbackManager\n",
718
+ "from sentence_transformers import SentenceTransformer\n",
719
+ "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n",
720
+ "import numpy as np\n",
721
+ "import pandas as pd\n",
722
+ "import re\n",
723
+ "import os\n",
724
+ "from sklearn.metrics.pairwise import cosine_similarity\n",
725
+ "\n",
726
+ "model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-mpnet-base-v2',device='cpu')\n",
727
+ "\n",
728
+ "title=\"書籍推薦平台\"\n",
729
+ "\n",
730
+ "# llm = LlamaCpp(\n",
731
+ "# model_path=r\"C:\\Users\\Cora\\.cache\\lm-studio\\models\\YC-Chen\\Breeze-7B-Instruct-v1_0-GGUF\\breeze-7b-instruct-v1_0-q4_k_m.gguf\",\n",
732
+ "# n_gpu_layers=100,\n",
733
+ "# n_batch=512,\n",
734
+ "# n_ctx=3000,\n",
735
+ "# f16_kv=True,\n",
736
+ "# callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]),\n",
737
+ "# verbose=False,\n",
738
+ "# )\n",
739
+ "\n",
740
+ "llm = LlamaCpp(\n",
741
+ " model_path=r\"C:\\Users\\user\\breeze-7b-instruct-v1_0-q4_k_m.gguf\",\n",
742
+ " n_gpu_layers=100,\n",
743
+ " n_batch=512,\n",
744
+ " n_ctx=3000,\n",
745
+ " f16_kv=True,\n",
746
+ " callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]),\n",
747
+ " verbose=False,\n",
748
+ ")\n",
749
+ "\n",
750
+ "embedd_bk=pd.read_pickle(r\"C:\\Users\\user\\推薦系統實作\\bk_description1_角色形容詞_677.pkl\")\n",
751
+ "df_bk=pd.read_excel(r\"C:\\Users\\user\\推薦系統實作\\bk_description1_角色形容詞.xlsx\")\n",
752
+ "\n",
753
+ "def invoke_with_temperature(prompt, temperature=0.4):\n",
754
+ " return llm.invoke(prompt, temperature=temperature)\n",
755
+ "\n",
756
+ "def process_user_input(message):\n",
757
+ " user_mental_state4= PromptTemplate(\n",
758
+ " input_variables=[\"input\"],\n",
759
+ " template=\"\"\"[INST]<<SYS>>你是一位具有同理心的專業心理諮商師,沒有性別歧視,你可以客觀的根據談話內容的描述,判斷說話的人的心理困擾<</SYS>> \n",
760
+ " 請根據{input}描述三個最有可能心理困擾,輸出只包含三個心理困擾,回答格式只採用CSV格式,分隔符號使用逗號,參考以下��例:名詞1,名詞2,名詞3。[/INST]\"\"\"\n",
761
+ " )\n",
762
+ " \n",
763
+ " user_character= PromptTemplate(\n",
764
+ " input_variables=[\"input\"],\n",
765
+ " template=\"\"\"[INST]<<SYS>>你是一位具有同理心的專業心理諮商師,沒有性別歧視,你可以客觀的根據談話內容的描述,判斷說話的大學生,在生活中的多重角色身分<</SYS>> \n",
766
+ " 請你根據談話內容{input},客觀的判斷說話的大學生,在談話內容中的角色,以及他生活中其他角色的身分,提供三個最有可能的角色身分名詞,\n",
767
+ " 輸出只包含三個身分名詞,回答格式只採用CSV格式,分隔符號使用逗號,參考以下範例:名詞1,名詞2,名詞3。[/INST]\"\"\"\n",
768
+ " )\n",
769
+ " \n",
770
+ "\n",
771
+ " df_user=pd.DataFrame(columns=[\"輸入內容\",\"形容詞1\", \"形容詞2\", \"形容詞3\", \"角色1\", \"角色2\", \"角色3\"])\n",
772
+ " #df_user_record=pd.read_excel(r\"C:\\Users\\Cora\\推薦系統實作\\gradio系統歷史紀錄.xlsx\")\n",
773
+ " \n",
774
+ "\n",
775
+ " prompt_value1=user_mental_state4.invoke({\"input\":message})\n",
776
+ " string=invoke_with_temperature(prompt_value1)\n",
777
+ " #print(\"\\n\")\n",
778
+ "\n",
779
+ " # 將字符串分割為名詞\n",
780
+ " adjectives = [adj.strip() for adj in re.split('[,、,]', string)]\n",
781
+ " \n",
782
+ " index=len(df_user)\n",
783
+ " df_user.loc[index, '輸入內容'] = message\n",
784
+ "\n",
785
+ " # 確保形容詞數量符合欄位數量\n",
786
+ " if len(adjectives) == 3:\n",
787
+ " df_user.loc[index, '形容詞1'] = adjectives[0]\n",
788
+ " df_user.loc[index, '形容詞2'] = adjectives[1]\n",
789
+ " df_user.loc[index, '形容詞3'] = adjectives[2]\n",
790
+ " df_user.to_excel(\"user_gradio系統.xlsx\")\n",
791
+ " return df_user\n",
792
+ " #return message\n",
793
+ "\n",
794
+ "def embedd_df_user(df_user):\n",
795
+ " \n",
796
+ " columns_to_encode=df_user.loc[:,[\"形容詞1\", \"形容詞2\", \"形容詞3\"]]\n",
797
+ "\n",
798
+ " # 初始化一個空的 DataFrame,用來存儲向量化結果\n",
799
+ " embedd_user=df_user[[\"輸入內容\"]]\n",
800
+ " #user_em= user_em.assign(形容詞1=None, 形容詞2=None, 形容詞3=None,角色1=None,角色2=None,角色3=None)\n",
801
+ " embedd_user= embedd_user.assign(形容詞1=None, 形容詞2=None, 形容詞3=None)\n",
802
+ " \n",
803
+ "\n",
804
+ " # 遍歷每一個單元格,將結果存入新的 DataFrame 中\n",
805
+ " i=len(df_user)-1\n",
806
+ " for col in columns_to_encode:\n",
807
+ " #print(i,col)\n",
808
+ " # 將每個單元格的內容進行向量化\n",
809
+ " embedd_user.at[i, col] = model.encode(df_user.at[i, col]) \n",
810
+ " \n",
811
+ " embedd_user.to_pickle(r\"C:\\Users\\user\\推薦系統實作\\user_gradio系統.pkl\")\n",
812
+ " \n",
813
+ " return embedd_user\n",
814
+ " #word=\"happy\"\n",
815
+ " #return word\n",
816
+ "\n",
817
+ "def top_n_books_by_average(df, n=3):\n",
818
+ " \n",
819
+ " # 根据 `average` 列降序排序\n",
820
+ " sorted_df = df.sort_values(by='average', ascending=False)\n",
821
+ " \n",
822
+ " # 选择前 N 行\n",
823
+ " top_n_df = sorted_df.head(n)\n",
824
+ " \n",
825
+ " # 提取书名列\n",
826
+ " top_books = top_n_df['書名'].tolist()\n",
827
+ " \n",
828
+ " return top_books,sorted_df\n",
829
+ "\n",
830
+ "def similarity(embedd_user,embedd_bk,df_bk):\n",
831
+ " df_similarity= pd.DataFrame(df_bk[['書名',\"內容簡介\",\"URL\",\"形容詞1\", \"形容詞2\", \"形容詞3\", '角色1', '角色2', '角色3']])\n",
832
+ " df_similarity['average'] = np.nan\n",
833
+ " #for p in range(len(embedd_user)): \n",
834
+ " index=len(embedd_user)-1 \n",
835
+ " for k in range(len(embedd_bk)):\n",
836
+ " list=[]\n",
837
+ " for i in range(1,4):\n",
838
+ " for j in range(3,6):\n",
839
+ " vec1=embedd_user.iloc[index,i]#i是第i個形容詞,數字是第幾個是使用者輸入\n",
840
+ " vec2=embedd_bk.iloc[k,j]\n",
841
+ " similarity = cosine_similarity([vec1], [vec2])\n",
842
+ " list.append(similarity[0][0])\n",
843
+ " # 计算总和\n",
844
+ " total_sum = sum(list)\n",
845
+ " # 计算数量\n",
846
+ " count = len(list)\n",
847
+ " # 计算平均值\n",
848
+ " average = total_sum / count\n",
849
+ " df_similarity.loc[k,'average']=average\n",
850
+ "\n",
851
+ " top_books,sorted_df = top_n_books_by_average(df_similarity)\n",
852
+ " return sorted_df \n",
853
+ "\n",
854
+ "def filter(sorted_df,df_user):\n",
855
+ " filter_prompt4 = PromptTemplate(\n",
856
+ " input_variables=[\"mental_issue\", \"user_identity\",\" book\",\"book_reader\", \"book_description\"],\n",
857
+ " template=\"\"\"[INST]<<SYS>>你是專業的心理諮商師和書籍推薦專家,擅長根據使用者的心理問題、身份特質,以及書名、書籍針對的主題和適合的讀者,判斷書籍是否適合推薦給使用者。\n",
858
+ "\n",
859
+ " 你的目的是幫助讀者找到可以緩解心理問題的書籍。請注意:\n",
860
+ " 1. 若書籍針對的問題與使用者的心理問題有關聯,即使書籍適合的讀者群與使用者身份沒有直接關聯,應偏向推薦。\n",
861
+ " 2. 若使用者身份的需求與書籍針對的問題有潛在關聯,應偏向推薦。\n",
862
+ " 3. 若書籍適合的讀者與使用者身份特質有任何關聯,應傾向推薦。\n",
863
+ " 4. 若書名跟使用者的心理問題或身分特質有任何關聯,應偏向推薦<</SYS>>\n",
864
+ "\n",
865
+ " 使用者提供的資訊如下:\n",
866
+ " 使用者身份是「{user_identity}」,其心理問題是「{mental_issue}」。書名是{book},書籍適合的讀者群為「{book_reader}」,書籍針對的問題是「{book_description}」。\n",
867
+ "\n",
868
+ " 請根據以上資訊判斷這本書是否適合推薦給該使用者。\n",
869
+ " 僅輸出「是」或「否」,輸出後即停止。[/INST]\"\"\"\n",
870
+ " )\n",
871
+ " df_filter=sorted_df.iloc[:20,:]\n",
872
+ " df_filter = df_filter.reset_index(drop=True)\n",
873
+ " df_filter=df_filter.assign(推薦=None)\n",
874
+ " #df_similarity= pd.DataFrame(df_bk[['書名',\"內容簡介\",\"URL\",\"形容詞1\", \"形容詞2\", \"形容詞3\", '角色1', '角色2', '角色3']])\n",
875
+ " #df_similarity['average'] = np.nan\n",
876
+ "\n",
877
+ " \n",
878
+ " p=len(df_user)-1\n",
879
+ " for k in range(len(df_filter)): \n",
880
+ " word=df_user[\"輸入內容\"].iloc[p]\n",
881
+ " #book_reader = df_filter[\"角色1\"].iloc[p] + \"or\" + df_filter[\"角色2\"].iloc[p] + \"or\" + df_filter[\"角色3\"].iloc[p]\n",
882
+ " book=df_filter[\"書名\"].iloc[k] \n",
883
+ " book_reader = df_filter[\"角色1\"].iloc[k] \n",
884
+ " user_identity = df_user[\"角色1\"].iloc[p]\n",
885
+ " mental_issue=df_user[\"形容詞1\"].iloc[p]+\"、\"+df_user[\"形容詞2\"].iloc[p]+\"、\"+df_user[\"形容詞3\"].iloc[p]\n",
886
+ " book_description=df_filter[\"形容詞1\"].iloc[k]+\"、\"+df_filter[\"形容詞2\"].iloc[k]+\"、\"+df_filter[\"形容詞3\"].iloc[k]\n",
887
+ " print(book_reader)\n",
888
+ " print(user_identity)\n",
889
+ " #output = filter_prompt1.invoke({\"user_identity\": user_identity, \"book_reader\": book_reader})\n",
890
+ " output = filter_prompt4.invoke({\"mental_issue\":mental_issue,\"user_identity\": user_identity, \"book\":book,\"book_description\":book_description,\"book_reader\": book_reader})\n",
891
+ " string2=invoke_with_temperature(output)\n",
892
+ " df_filter.loc[k, '推薦'] =string2\n",
893
+ " df_recommend=df_filter[df_filter[\"推薦\"].str.strip() == \"是\"]\n",
894
+ " \n",
895
+ " return df_recommend\n",
896
+ " \n",
897
+ "def output_content(df_recommend):\n",
898
+ " content_prompt = PromptTemplate(\n",
899
+ " input_variables=[\"content\"],\n",
900
+ " template=\"\"\"[INST]<<SYS>>你是一個有同理心的心理師,負責推薦相關書籍給使用者<</SYS>>你是一個有同理心的心理師,\n",
901
+ " 請根據{content},用平易近人且不官方的語氣,先介紹這本書的內容,總共約50-70字[/INST]\"\"\"\n",
902
+ " )\n",
903
+ "\n",
904
+ " a=0\n",
905
+ " title=df_recommend.iloc[a,0]#不用loc,因為filter的時候index沒有重新歸零\n",
906
+ " #URL=sorted_df.iloc[a,1]\n",
907
+ " #content=sorted_df.iloc[a,2]\n",
908
+ " \n",
909
+ "# prompt_value2=content_prompt.invoke({\"content\":content})\n",
910
+ "# summary=invoke_with_temperature(prompt_value2)\n",
911
+ "# recommend_prompt = PromptTemplate(\n",
912
+ "# input_variables=[\"title\",\"URL\",\"summary\"],\n",
913
+ "# template=\"\"\"<<SYS>>\n",
914
+ "# 你是一個有同理心的心理師,負責推薦相關書籍給使用者<</SYS>>\n",
915
+ "# [INST] \n",
916
+ "# 請根據{title}{URL}{summary}產出訊息,開頭不要有空格,並在最後面加入一句或兩句鼓勵的話\n",
917
+ "# 格式為:根據您的狀態,這裡提供一本書供您參考\\n\n",
918
+ "# 書名:{title}\\n\n",
919
+ "# 本書介紹:{summary}\\n\n",
920
+ "# 購書網址:{URL}\\n\n",
921
+ "# 希望對您有所幫助\n",
922
+ "# [/INST]\"\"\"\n",
923
+ "# )\n",
924
+ "# prompt_value1=recommend_prompt.invoke({\"title\":title,\"URL\":URL,\"summary\":summary})\n",
925
+ " \n",
926
+ " recommend_prompt = PromptTemplate(\n",
927
+ " input_variables=[\"title\"],\n",
928
+ " template=\"\"\"<<SYS>>\n",
929
+ " 你是一個有同理心的心理師,負責推薦相關書籍給使用者<</SYS>>\n",
930
+ " [INST] \n",
931
+ " 請根據{title}產出訊息,開頭不要有空格���並在最後面加入一句或兩句鼓勵的話\n",
932
+ " 格式為:根據您的狀態,這裡提供一本書供您參考\\n\n",
933
+ " 書名:{title}\\n\n",
934
+ " 希望對您有所幫助\n",
935
+ " [/INST]\"\"\"\n",
936
+ " )\n",
937
+ " prompt_value1=recommend_prompt.invoke({\"title\":title})\n",
938
+ " output=invoke_with_temperature(prompt_value1,temperature=0.4)\n",
939
+ " return output \n",
940
+ " \n",
941
+ "def main_pipeline(message,history):\n",
942
+ " \n",
943
+ " df_user=process_user_input(message)\n",
944
+ " embedd_user=embedd_df_user(df_user)\n",
945
+ " sorted_df=similarity(embedd_user,embedd_bk,df_bk)\n",
946
+ " df_filter=filter(sorted_df,df_user)\n",
947
+ " final=output_content(df_filter)\n",
948
+ " return final\n",
949
+ " #return embedd_user\n",
950
+ " \n",
951
+ " \n",
952
+ " \n",
953
+ "\n",
954
+ "# def recommend(message,history):\n",
955
+ "# result=main_pipeline(message)\n",
956
+ "# return result\n",
957
+ "\n",
958
+ "demo=gr.ChatInterface(main_pipeline,type=\"messages\")\n",
959
+ "\n",
960
+ "\n",
961
+ "if __name__ == \"__main__\":\n",
962
+ " demo.launch()"
963
+ ]
964
+ },
965
+ {
966
+ "cell_type": "code",
967
+ "execution_count": null,
968
+ "id": "aaad2fb2-a8d8-46e4-b9d4-c276f5ef0cb0",
969
+ "metadata": {
970
+ "scrolled": true
971
+ },
972
+ "outputs": [],
973
+ "source": [
974
+ "pip install tf-keras"
975
+ ]
976
+ },
977
+ {
978
+ "cell_type": "code",
979
+ "execution_count": 16,
980
+ "id": "cc344ace-81f1-45f2-ad4a-9cca508aa053",
981
+ "metadata": {},
982
+ "outputs": [
983
+ {
984
+ "data": {
985
+ "text/html": [
986
+ "<div>\n",
987
+ "<style scoped>\n",
988
+ " .dataframe tbody tr th:only-of-type {\n",
989
+ " vertical-align: middle;\n",
990
+ " }\n",
991
+ "\n",
992
+ " .dataframe tbody tr th {\n",
993
+ " vertical-align: top;\n",
994
+ " }\n",
995
+ "\n",
996
+ " .dataframe thead th {\n",
997
+ " text-align: right;\n",
998
+ " }\n",
999
+ "</style>\n",
1000
+ "<table border=\"1\" class=\"dataframe\">\n",
1001
+ " <thead>\n",
1002
+ " <tr style=\"text-align: right;\">\n",
1003
+ " <th></th>\n",
1004
+ " <th>書名</th>\n",
1005
+ " <th>內容簡介</th>\n",
1006
+ " <th>URL</th>\n",
1007
+ " <th>形容詞1</th>\n",
1008
+ " <th>形容詞2</th>\n",
1009
+ " <th>形容詞3</th>\n",
1010
+ " <th>角色1</th>\n",
1011
+ " <th>角色2</th>\n",
1012
+ " <th>角色3</th>\n",
1013
+ " </tr>\n",
1014
+ " </thead>\n",
1015
+ " <tbody>\n",
1016
+ " <tr>\n",
1017
+ " <th>0</th>\n",
1018
+ " <td>這僅有一次的人生, 我不想說抱歉</td>\n",
1019
+ " <td>你走太快了,容易迷路,要等靈魂跟上來,才能走更遠的路。那些你想要做成的事情,你做成了的事情,...</td>\n",
1020
+ " <td>https://www.eslite.com/product/100120106326824...</td>\n",
1021
+ " <td>自我期許</td>\n",
1022
+ " <td>自我反思</td>\n",
1023
+ " <td>人生目標</td>\n",
1024
+ " <td>自我提升</td>\n",
1025
+ " <td>人生感悟</td>\n",
1026
+ " <td>內心成長</td>\n",
1027
+ " </tr>\n",
1028
+ " <tr>\n",
1029
+ " <th>1</th>\n",
1030
+ " <td>我只是想分手而已: 親密殺人, 被深愛的男人殺死的女人們</td>\n",
1031
+ " <td>親密殺人不是約會暴力是整個社會必須全力阻止的連續殺人!只是想跟他分手的我,為何最後卻送了命?...</td>\n",
1032
+ " <td>https://www.eslite.com/product/100120106326824...</td>\n",
1033
+ " <td>心理創傷</td>\n",
1034
+ " <td>暴力受暴經驗</td>\n",
1035
+ " <td>感情困境</td>\n",
1036
+ " <td>法律系學生</td>\n",
1037
+ " <td>社會工作者</td>\n",
1038
+ " <td>性別平權運動者</td>\n",
1039
+ " </tr>\n",
1040
+ " <tr>\n",
1041
+ " <th>2</th>\n",
1042
+ " <td>輕鬆思考法: 培養靈活觀點的150個啟示</td>\n",
1043
+ " <td>本書特色150則啟示點醒沉浮於忙碌生活的現代人!篇幅短小、內容精闢,1分鐘打開新思維!擁有不...</td>\n",
1044
+ " <td>https://www.eslite.com/product/100121372526824...</td>\n",
1045
+ " <td>焦慮</td>\n",
1046
+ " <td>孤獨</td>\n",
1047
+ " <td>成長</td>\n",
1048
+ " <td>職場人</td>\n",
1049
+ " <td>旅行愛好者</td>\n",
1050
+ " <td>追求自我成長的人</td>\n",
1051
+ " </tr>\n",
1052
+ " <tr>\n",
1053
+ " <th>3</th>\n",
1054
+ " <td>因為人類思維太僵化, 所以需要創新心理學: 心態革命, 大腦中的髮夾彎, 掀起你的思路風暴</td>\n",
1055
+ " <td>大腦中的髮夾彎,掀起你的思路風暴!從理性到感性,不同思考方式將會開啟新的視角、新的世界!逆向...</td>\n",
1056
+ " <td>https://www.eslite.com/product/100122024826824...</td>\n",
1057
+ " <td>焦慮</td>\n",
1058
+ " <td>壓��</td>\n",
1059
+ " <td>抑鬱</td>\n",
1060
+ " <td>好奇心旺盛的思考愛好者</td>\n",
1061
+ " <td>希望提高日常解決問題技巧的人</td>\n",
1062
+ " <td>渴望提升創新思維能力的人</td>\n",
1063
+ " </tr>\n",
1064
+ " <tr>\n",
1065
+ " <th>4</th>\n",
1066
+ " <td>人生心理學</td>\n",
1067
+ " <td>找出人生發展的路向從來都不容易,無論你是臨近畢業的大專生,或是已在職場上打滾了好些年正在瓶頸...</td>\n",
1068
+ " <td>https://www.eslite.com/product/100121238026824...</td>\n",
1069
+ " <td>生涯規劃</td>\n",
1070
+ " <td>自我覺察</td>\n",
1071
+ " <td>人生意義</td>\n",
1072
+ " <td>大學生</td>\n",
1073
+ " <td>職場工作者</td>\n",
1074
+ " <td>心理學研究者</td>\n",
1075
+ " </tr>\n",
1076
+ " <tr>\n",
1077
+ " <th>...</th>\n",
1078
+ " <td>...</td>\n",
1079
+ " <td>...</td>\n",
1080
+ " <td>...</td>\n",
1081
+ " <td>...</td>\n",
1082
+ " <td>...</td>\n",
1083
+ " <td>...</td>\n",
1084
+ " <td>...</td>\n",
1085
+ " <td>...</td>\n",
1086
+ " <td>...</td>\n",
1087
+ " </tr>\n",
1088
+ " <tr>\n",
1089
+ " <th>672</th>\n",
1090
+ " <td>你想要的一切, 宇宙早已為你預備</td>\n",
1091
+ " <td>宇宙會把最好的獻給你。如果你願意放下自我限制的信念,全然信任這股奇妙的力量,豐盛的人生自然會...</td>\n",
1092
+ " <td>https://www.eslite.com/product/100120176426824...</td>\n",
1093
+ " <td>困惑</td>\n",
1094
+ " <td>壓力</td>\n",
1095
+ " <td>不滿</td>\n",
1096
+ " <td>焦慮症患者</td>\n",
1097
+ " <td>心理負荷過重者</td>\n",
1098
+ " <td>靈性追求者</td>\n",
1099
+ " </tr>\n",
1100
+ " <tr>\n",
1101
+ " <th>673</th>\n",
1102
+ " <td>妄想的力量: 迷信、儀式感與過度樂觀的非理性心理學</td>\n",
1103
+ " <td>妄想雖然可恥但是有用!亞馬遜讀者五星強推!最熱愛怪力亂神的美國心理學暢銷作家帶你重新認識幻想...</td>\n",
1104
+ " <td>https://www.eslite.com/product/100120106326824...</td>\n",
1105
+ " <td>妄想</td>\n",
1106
+ " <td>心理假象</td>\n",
1107
+ " <td>樂觀</td>\n",
1108
+ " <td>心理學家</td>\n",
1109
+ " <td>精神病患者家屬</td>\n",
1110
+ " <td>普通大眾</td>\n",
1111
+ " </tr>\n",
1112
+ " <tr>\n",
1113
+ " <th>674</th>\n",
1114
+ " <td>悲傷復原力: 一位心理學專家, 也是位失去愛女的母親, 透過復原力心理學, 走過分離崩解的悲傷</td>\n",
1115
+ " <td>面對至親至愛的離去,如果悲傷難免,我們可以做些什麼,度過這場巨大風暴?紐約時報、華爾街日報,...</td>\n",
1116
+ " <td>https://www.eslite.com/product/100121380726824...</td>\n",
1117
+ " <td>喪親之痛</td>\n",
1118
+ " <td>悲傷</td>\n",
1119
+ " <td>復原力</td>\n",
1120
+ " <td>親人失去</td>\n",
1121
+ " <td>悲傷修復</td>\n",
1122
+ " <td>心理健康</td>\n",
1123
+ " </tr>\n",
1124
+ " <tr>\n",
1125
+ " <th>675</th>\n",
1126
+ " <td>淬鍊幸福, 剛剛好的回憶練習 (限量贈暖心陪伴藏書卡)</td>\n",
1127
+ " <td>為什麼自己會突然情緒崩潰?從什麼時候開始,變得越來越少話?每當回憶起某件事時,就會止不住的落...</td>\n",
1128
+ " <td>https://www.eslite.com/product/100120303926824...</td>\n",
1129
+ " <td>創傷後壓力症候群</td>\n",
1130
+ " <td>自我懷疑</td>\n",
1131
+ " <td>內心傷痛</td>\n",
1132
+ " <td>創傷癒後者</td>\n",
1133
+ " <td>單親父母</td>\n",
1134
+ " <td>成長經歷過困難的讀者</td>\n",
1135
+ " </tr>\n",
1136
+ " <tr>\n",
1137
+ " <th>676</th>\n",
1138
+ " <td>不是為了爭吵才跟你在一起: 如何在溝通中改善親密關係</td>\n",
1139
+ " <td>為什麼開始親密無間的兩個人,會在關係中越走越遠、越來越疏離?外人對你們羨慕不已,但其實是假性...</td>\n",
1140
+ " <td>https://www.eslite.com/product/100120106326824...</td>\n",
1141
+ " <td>焦慮</td>\n",
1142
+ " <td>疏離</td>\n",
1143
+ " <td>衝突</td>\n",
1144
+ " <td>兩性關係人士</td>\n",
1145
+ " <td>婚姻治療師或專家</td>\n",
1146
+ " <td>伴侶或夫妻</td>\n",
1147
+ " </tr>\n",
1148
+ " </tbody>\n",
1149
+ "</table>\n",
1150
+ "<p>677 rows × 9 columns</p>\n",
1151
+ "</div>"
1152
+ ],
1153
+ "text/plain": [
1154
+ " 書名 \\\n",
1155
+ "0 這僅有一次的人生, 我不想說抱歉 \n",
1156
+ "1 我只是想分手而已: 親密殺人, 被深愛的男人殺死的女人們 \n",
1157
+ "2 輕鬆思考法: 培養靈活觀點的150個啟示 \n",
1158
+ "3 因為人類思維太僵化, 所以需要創新心理學: 心態革命, 大腦中的髮夾彎, 掀起你的思路風暴 \n",
1159
+ "4 人生心理學 \n",
1160
+ ".. ... \n",
1161
+ "672 你想要的一切, 宇宙早已為你預備 \n",
1162
+ "673 妄想的力量: 迷信、儀式感與過度樂觀的非理性心理學 \n",
1163
+ "674 悲傷復原力: 一位心理學專家, 也是位失去愛女的母親, 透過復原力心理學, 走過分離崩解的悲傷 \n",
1164
+ "675 淬鍊幸福, 剛剛好的回憶練習 (限量贈暖心陪伴藏書卡) \n",
1165
+ "676 不是為了爭吵才跟你在一起: 如何在溝通中改善親密關係 \n",
1166
+ "\n",
1167
+ " 內容簡介 \\\n",
1168
+ "0 你走太快了,容易迷路,要等靈魂跟上來,才能走更遠的路。那些你想要做成的事情,你做成了的事情,... \n",
1169
+ "1 親密殺人不是約會暴力是整個社會必須全力阻止的連續殺人!只是想跟他分手的我,為何最後卻送了命?... \n",
1170
+ "2 本書特色150則啟示點醒沉浮於忙碌生活的現代人!篇幅短小、內容精闢,1分鐘打開新思維!擁有不... \n",
1171
+ "3 大腦中的髮夾彎,掀起你的思路風暴!從理性到感性,不同思考方式將會開啟新的視角、新的世界!逆向... \n",
1172
+ "4 找出人生發展的路向從來都不容易,無論你是臨近畢業的大專生,或是已在職場上打滾了好些年正在瓶頸... \n",
1173
+ ".. ... \n",
1174
+ "672 宇宙會把最好的獻給你。如果你願意放下自我限制的信念,全然信任這股奇妙的力量,豐盛的人生自然會... \n",
1175
+ "673 妄想雖然可恥但是有用!亞馬遜讀者五星強推!最熱愛怪力亂神的美國心理學暢銷作家帶你重新認識幻想... \n",
1176
+ "674 面對至親至愛的離去,如果悲傷難免,我們可以做些什麼,度過這場巨大風暴?紐約時報、華爾街日報,... \n",
1177
+ "675 為什麼自己會突然情緒崩潰?從什麼時候開始,變得越來越少話?每當回憶起某件事時,就會止不住的落... \n",
1178
+ "676 為什麼開始親密無間的兩個人,會在關係中越走越遠、越來越疏離?外人對你們羨慕不已,但其實是假性... \n",
1179
+ "\n",
1180
+ " URL 形容詞1 形容詞2 \\\n",
1181
+ "0 https://www.eslite.com/product/100120106326824... 自我期許 自我反思 \n",
1182
+ "1 https://www.eslite.com/product/100120106326824... 心理創傷 暴力受暴經驗 \n",
1183
+ "2 https://www.eslite.com/product/100121372526824... 焦慮 孤獨 \n",
1184
+ "3 https://www.eslite.com/product/100122024826824... 焦慮 壓力 \n",
1185
+ "4 https://www.eslite.com/product/100121238026824... 生涯規劃 自我覺察 \n",
1186
+ ".. ... ... ... \n",
1187
+ "672 https://www.eslite.com/product/100120176426824... 困惑 壓力 \n",
1188
+ "673 https://www.eslite.com/product/100120106326824... 妄想 心理假象 \n",
1189
+ "674 https://www.eslite.com/product/100121380726824... 喪親之痛 悲傷 \n",
1190
+ "675 https://www.eslite.com/product/100120303926824... 創傷後壓力症候群 自我懷疑 \n",
1191
+ "676 https://www.eslite.com/product/100120106326824... 焦慮 疏離 \n",
1192
+ "\n",
1193
+ " 形容詞3 角色1 角色2 角色3 \n",
1194
+ "0 人生目標 自我提升 人生感悟 內心成長 \n",
1195
+ "1 感情困境 法律系學生 社會工作者 性別平權運動者 \n",
1196
+ "2 成長 職場人 旅行愛好者 追求自我成長的人 \n",
1197
+ "3 抑鬱 好奇心旺盛的思考愛好者 希望提高日常解決問題技巧的人 渴望提升創新思維能力的人 \n",
1198
+ "4 人生意義 大學生 職場工作者 心理學研究者 \n",
1199
+ ".. ... ... ... ... \n",
1200
+ "672 不滿 焦慮症患者 心理負荷過重者 靈性追求者 \n",
1201
+ "673 樂觀 心理學家 精神病患者家屬 普通大眾 \n",
1202
+ "674 復原力 親人失去 悲傷修復 心理健康 \n",
1203
+ "675 內心傷痛 創傷癒後者 單親父母 成長經歷過困難的讀者 \n",
1204
+ "676 衝突 兩性關係人士 婚姻治療師或專家 伴侶或夫妻 \n",
1205
+ "\n",
1206
+ "[677 rows x 9 columns]"
1207
+ ]
1208
+ },
1209
+ "execution_count": 16,
1210
+ "metadata": {},
1211
+ "output_type": "execute_result"
1212
+ }
1213
+ ],
1214
+ "source": [
1215
+ "df_bk"
1216
+ ]
1217
+ },
1218
+ {
1219
+ "cell_type": "code",
1220
+ "execution_count": null,
1221
+ "id": "b88bb194-7064-4dcb-8907-b392d8f1e82f",
1222
+ "metadata": {},
1223
+ "outputs": [],
1224
+ "source": []
1225
+ }
1226
+ ],
1227
+ "metadata": {
1228
+ "kernelspec": {
1229
+ "display_name": "Python 3 (ipykernel)",
1230
+ "language": "python",
1231
+ "name": "python3"
1232
+ },
1233
+ "language_info": {
1234
+ "codemirror_mode": {
1235
+ "name": "ipython",
1236
+ "version": 3
1237
+ },
1238
+ "file_extension": ".py",
1239
+ "mimetype": "text/x-python",
1240
+ "name": "python",
1241
+ "nbconvert_exporter": "python",
1242
+ "pygments_lexer": "ipython3",
1243
+ "version": "3.10.8"
1244
+ }
1245
+ },
1246
+ "nbformat": 4,
1247
+ "nbformat_minor": 5
1248
+ }