seyled/Phantom_Hallucination_Detection
Phantom: A Benchmark for Hallucination Detection in Financial Long-Context QA Authors: Lanlan Ji, Dominic Seyler, Gunkirat Kaur, Manjunath Hegde, Koustuv Dasgupta, Bing Xiang This is the repository containing the dataset for the submission mentioned above. This dataset is designed for hallucination detection in language models. It includes multiple variants of the Phantom dataset with different token lengths (seed, 2k, 5K, 10K, 20K, 30K) for long context experiments , segments… See the full description on the dataset page: https://huggingface.co/datasets/seyled/Phantom_Hallucination_Detection.
2241
1{2 "cells": [3 {4 "cell_type": "code",5 "execution_count": null,6 "id": "a83aa077-2fe2-4f10-9b61-738217cf4946",7 "metadata": {},8 "outputs": [],9 "source": [10 "import time\n",11 "\n",12 "import matplotlib.pyplot as plt\n",13 "import pandas as pd\n",14 "import spacy"15 ]16 },17 {18 "cell_type": "markdown",19 "id": "94f496c6-0449-4d2b-b257-3f2ccb7cb107",20 "metadata": {},21 "source": [22 "### Load existing data"23 ]24 },25 {26 "cell_type": "code",27 "execution_count": null,28 "id": "d5e12b01-5124-48fe-b9e3-8efeb80da9c5",29 "metadata": {},30 "outputs": [],31 "source": [32 "df_data_chunk = pd.read_csv('df_10k_llama3_3_v1.csv', index_col = 0) # Load seed dataset created in Phantom_generate_seed_hallucination_data.ipynb\n",33 "df_data_chunk['chunk_token_count'] = df_data_chunk['chunk_token_count'].astype(int)\n",34 "df_data_chunk['document_token_count'] = df_data_chunk['document_token_count'].astype(int)\n",35 "df_data_chunk['chunk_starting_sentence_idx'] = df_data_chunk['chunk_starting_sentence_idx'].astype(int)"36 ]37 },38 {39 "cell_type": "code",40 "execution_count": null,41 "id": "b7776398-3c7d-4e6c-84e5-d0106ace7138",42 "metadata": {},43 "outputs": [],44 "source": [45 "df_data_chunk.head()"46 ]47 },48 {49 "cell_type": "code",50 "execution_count": null,51 "id": "e9fc1edf-5ef8-43a4-a3e7-b7ecc6a2ef88",52 "metadata": {},53 "outputs": [],54 "source": [55 "df_data_chunk.shape"56 ]57 },58 {59 "cell_type": "code",60 "execution_count": null,61 "id": "1bd11b6e-8022-4b30-889f-1e433344649b",62 "metadata": {},63 "outputs": [],64 "source": [65 "expand_token_count = 10000 ## Context Limit update for 2k,5k,10k,20k,30k\n",66 "token_limit = 10500"67 ]68 },69 {70 "cell_type": "code",71 "execution_count": null,72 "id": "daedd1c9-e57f-4494-9b23-8f1ef4483d1c",73 "metadata": {},74 "outputs": [],75 "source": [76 "df_data_chunk = df_data_chunk[df_data_chunk[\"document_token_count\"] >= expand_token_count].copy()\n",77 "df_data_chunk = df_data_chunk.reset_index(drop = True)\n",78 "df_data_chunk.shape"79 ]80 },81 {82 "cell_type": "code",83 "execution_count": null,84 "id": "29027aa7-9fdc-4f6e-80fc-672070149b52",85 "metadata": {},86 "outputs": [],87 "source": [88 "df_data_chunk.head()"89 ]90 },91 {92 "cell_type": "markdown",93 "id": "510a2000-0be4-4466-ae0a-8b29d826ae57",94 "metadata": {95 "jp-MarkdownHeadingCollapsed": true96 },97 "source": [98 "## Long context Expansion - END"99 ]100 },101 {102 "cell_type": "code",103 "execution_count": null,104 "id": "69f8ec0d-84a0-4a20-b6e3-67c113173cbc",105 "metadata": {},106 "outputs": [],107 "source": [108 "df_generated_data_end = df_data_chunk"109 ]110 },111 {112 "cell_type": "code",113 "execution_count": null,114 "id": "05fd2afe-e16e-4930-95a3-9436f2935cb8",115 "metadata": {},116 "outputs": [],117 "source": [118 "df_generated_data_end.head()"119 ]120 },121 {122 "cell_type": "code",123 "execution_count": null,124 "id": "436f8da7-dbee-415d-8350-a0a795e1a5ab",125 "metadata": {},126 "outputs": [],127 "source": [128 "nlp = spacy.load(\"en_core_web_sm\")\n",129 "\n",130 "def expand_chunk_end(nlp, chunk_context, chunk_token_count, doc_text, chunk_starting_sentence_idx, expand_token_count=2000, token_limit=2200):\n",131 " \n",132 " doc = nlp(doc_text)\n",133 " \n",134 " # Extract sentences\n",135 " sentences = list(doc.sents)\n",136 " n_sent = len(sentences)\n",137 " \n",138 " chunk = [chunk_context]\n",139 "\n",140 " current_sent_idx = chunk_starting_sentence_idx - 1\n",141 " while True:\n",142 " current_sent_idx %= n_sent\n",143 " sent = sentences[current_sent_idx]\n",144 "\n",145 " new_token_count = chunk_token_count + len(sent)\n",146 " if new_token_count >= expand_token_count and new_token_count <= token_limit:\n",147 " chunk_token_count = new_token_count\n",148 " chunk = [sent.text] + chunk\n",149 " chunk_starting_sentence_idx = current_sent_idx\n",150 " break\n",151 " elif new_token_count >= expand_token_count and new_token_count > token_limit: \n",152 " partial_first_sentence = \" \".join([token.text for token in sent[(len(sent) - (token_limit - chunk_token_count)):]])\n",153 " chunk = [partial_first_sentence] + chunk\n",154 " chunk_token_count = token_limit\n",155 " break\n",156 " chunk_token_count = new_token_count\n",157 " chunk = [sent.text] + chunk\n",158 " chunk_starting_sentence_idx = current_sent_idx\n",159 " \n",160 " current_sent_idx -= 1\n",161 " \n",162 " # Join the sentences to form the chunk\n",163 " chunk_text = \" \".join(chunk)\n",164 " \n",165 " return {\n",166 " \"chunk\": chunk_text,\n",167 " \"chunk_token_count\": chunk_token_count,\n",168 " \"chunk_starting_sentence_idx\": chunk_starting_sentence_idx\n",169 " }"170 ]171 },172 {173 "cell_type": "code",174 "execution_count": null,175 "id": "72eb1fa4-d621-4b21-8e48-2d265bc9f98e",176 "metadata": {},177 "outputs": [],178 "source": [179 "## END\n",180 "\n",181 "start_time_total = time.time()\n",182 "start_time = time.time()\n",183 "for i in range(df_generated_data_end.shape[0]):\n",184 " if i % 50 == 0:\n",185 " print(i)\n",186 " print(\"Process time: \", round(time.time()-start_time, 2), \" seconds.\")\n",187 " start_time = time.time()\n",188 "\n",189 " chunk_context = df_data_chunk.at[i, 'context']\n",190 " chunk_token_count = df_generated_data_end.at[i, 'chunk_token_count']\n",191 " doc_text = df_generated_data_end.at[i, 'filing_text']\n",192 " chunk_starting_sentence_idx = df_generated_data_end.at[i, 'chunk_starting_sentence_idx'] \n",193 "\n",194 " chunk_result = expand_chunk_end(nlp, chunk_context, chunk_token_count, doc_text, chunk_starting_sentence_idx,\n",195 " expand_token_count, token_limit)\n",196 "\n",197 " df_generated_data_end.at[i, 'context'] = chunk_result[\"chunk\"]\n",198 " df_generated_data_end.at[i, 'chunk_token_count'] = chunk_result[\"chunk_token_count\"]\n",199 " df_generated_data_end.at[i, 'chunk_starting_sentence_idx'] = chunk_result[\"chunk_starting_sentence_idx\"]\n",200 "print(\"Total process time: \", round(time.time()-start_time_total, 2), \" seconds.\")"201 ]202 },203 {204 "cell_type": "code",205 "execution_count": null,206 "id": "44956d88-0a7d-4c5c-ad8a-4040d67f3e03",207 "metadata": {},208 "outputs": [],209 "source": [210 "plt.hist(df_generated_data_end['chunk_token_count'], bins=30)\n",211 "plt.xlabel('Token count')\n",212 "plt.ylabel('Frequency')\n",213 "plt.title('Distribution of chunk length (token count)')\n",214 "plt.show()"215 ]216 },217 {218 "cell_type": "code",219 "execution_count": null,220 "id": "32c5cf84-ed41-4e41-bf52-3edcb949270b",221 "metadata": {},222 "outputs": [],223 "source": [224 "df_generated_data_end.to_csv('Phantom_10k_10000tokens_end_full.csv')"225 ]226 },227 {228 "cell_type": "code",229 "execution_count": null,230 "id": "b9d4a185-1002-41f2-a86e-e7814dc3dfbb",231 "metadata": {},232 "outputs": [],233 "source": [234 "df_final_end = pd.DataFrame(columns = ['query', 'context', 'answer', 'ground_truth_label'])"235 ]236 },237 {238 "cell_type": "code",239 "execution_count": null,240 "id": "d25dd2bd-c511-4e24-8c8d-897b67ed0f03",241 "metadata": {},242 "outputs": [],243 "source": [244 "for i in range(df_generated_data_end.shape[0]):\n",245 " query = df_generated_data_end.at[i, 'query']\n",246 " context = df_generated_data_end.at[i, 'context']\n",247 " row_data1 = [query, context, df_generated_data_end.at[i, 'gold_answer'], 'not hallucination']\n",248 " row_data2 = [query, context, df_generated_data_end.at[i, 'hallucination_answer'], 'hallucination']\n",249 " df_final_end.loc[len(df_final_end)] = row_data1\n",250 " df_final_end.loc[len(df_final_end)] = row_data2"251 ]252 },253 {254 "cell_type": "code",255 "execution_count": null,256 "id": "fd40906a-dd36-475d-9a4b-1dc183537b95",257 "metadata": {},258 "outputs": [],259 "source": [260 "df_final_end.to_csv('Phantom_10k_10000tokens_end.csv')"261 ]262 },263 {264 "cell_type": "markdown",265 "id": "f38466c2-4be2-4c29-a8ea-f233bc0c74c3",266 "metadata": {},267 "source": [268 "## Long context - BEGINNING"269 ]270 },271 {272 "cell_type": "code",273 "execution_count": null,274 "id": "72ee4bd9-4791-477f-8ffb-48cbf5cef7b5",275 "metadata": {},276 "outputs": [],277 "source": [278 "df_generated_data_begin = df_data_chunk"279 ]280 },281 {282 "cell_type": "code",283 "execution_count": null,284 "id": "e1510ff7-2255-4d9e-9087-715284ccedf0",285 "metadata": {},286 "outputs": [],287 "source": [288 "nlp = spacy.load(\"en_core_web_sm\")\n",289 "\n",290 "def expand_chunk_begin(nlp, doc_text, chunk_starting_sentence_idx, expand_token_count=2000, token_limit=2200):\n",291 " \n",292 " doc = nlp(doc_text)\n",293 " \n",294 " # Extract sentences\n",295 " sentences = list(doc.sents)\n",296 " n_sent = len(sentences)\n",297 " \n",298 " chunk = []\n",299 " chunk_token_count = 0\n",300 "\n",301 " current_sent_idx = chunk_starting_sentence_idx\n",302 " while True:\n",303 " current_sent_idx %= n_sent\n",304 " sent = sentences[current_sent_idx]\n",305 " \n",306 " chunk.append(sent.text)\n",307 " new_token_count = chunk_token_count + len(sent)\n",308 " if new_token_count >= expand_token_count and new_token_count <= token_limit:\n",309 " chunk_token_count = new_token_count\n",310 " break\n",311 " elif new_token_count >= expand_token_count and new_token_count > token_limit: \n",312 " partial_last_sentence = \" \".join([token.text for token in sent[:(token_limit - chunk_token_count)]])\n",313 " chunk[-1] = partial_last_sentence\n",314 " chunk_token_count = token_limit\n",315 " break\n",316 " chunk_token_count = new_token_count \n",317 " current_sent_idx += 1\n",318 " \n",319 " # Join the sentences to form the chunk\n",320 " chunk_text = \" \".join(chunk)\n",321 " \n",322 " return {\n",323 " \"chunk\": chunk_text,\n",324 " \"chunk_token_count\": chunk_token_count,\n",325 " \"chunk_starting_sentence_idx\": chunk_starting_sentence_idx\n",326 " }"327 ]328 },329 {330 "cell_type": "code",331 "execution_count": null,332 "id": "a60bbb0f-fa76-4848-95c9-dda2344f74b8",333 "metadata": {},334 "outputs": [],335 "source": [336 "start_time = time.time()\n",337 "for i in range(df_generated_data_begin.shape[0]):\n",338 " if i % 50 == 0:\n",339 " print(i)\n",340 " print(\"Process time: \", round(time.time()-start_time, 2), \" seconds.\")\n",341 " start_time = time.time()\n",342 " \n",343 " doc_text = df_generated_data_begin.at[i, 'filing_text']\n",344 " chunk_starting_sentence_idx = df_generated_data_begin.at[i, 'chunk_starting_sentence_idx'] \n",345 " \n",346 " chunk_result = expand_chunk_begin(nlp, doc_text, chunk_starting_sentence_idx, expand_token_count, token_limit)\n",347 "\n",348 " df_generated_data_begin.at[i, 'context'] = chunk_result[\"chunk\"]\n",349 " df_generated_data_begin.at[i, 'chunk_token_count'] = chunk_result[\"chunk_token_count\"]\n",350 " df_generated_data_begin.at[i, 'chunk_starting_sentence_idx'] = chunk_result[\"chunk_starting_sentence_idx\"]"351 ]352 },353 {354 "cell_type": "code",355 "execution_count": null,356 "id": "930296a8-fb13-436d-b83f-c83ec33e9b41",357 "metadata": {},358 "outputs": [],359 "source": [360 "plt.hist(df_generated_data_begin['chunk_token_count'], bins=30)\n",361 "plt.xlabel('Token count')\n",362 "plt.ylabel('Frequency')\n",363 "plt.title('Distribution of chunk length (token count)')\n",364 "plt.show()"365 ]366 },367 {368 "cell_type": "code",369 "execution_count": null,370 "id": "4f495add-b19c-4079-87dc-8eaa342a0b33",371 "metadata": {},372 "outputs": [],373 "source": [374 "df_generated_data_begin.to_csv('Phantom_10k_10000tokens_beginning_full.csv')"375 ]376 },377 {378 "cell_type": "code",379 "execution_count": null,380 "id": "3f446593-47fd-4d56-99f4-9144924ca919",381 "metadata": {},382 "outputs": [],383 "source": [384 "df_final_begin = pd.DataFrame(columns = ['query', 'context', 'answer', 'ground_truth_label'])"385 ]386 },387 {388 "cell_type": "code",389 "execution_count": null,390 "id": "18606b4a-e0a9-4d48-b535-15b90b588c6c",391 "metadata": {},392 "outputs": [],393 "source": [394 "for i in range(df_generated_data_begin.shape[0]):\n",395 " query = df_generated_data_begin.at[i, 'query']\n",396 " context = df_generated_data_begin.at[i, 'context']\n",397 " row_data1 = [query, context, df_generated_data_begin.at[i, 'gold_answer'], 'not hallucination']\n",398 " row_data2 = [query, context, df_generated_data_begin.at[i, 'hallucination_answer'], 'hallucination']\n",399 " df_final_begin.loc[len(df_final_begin)] = row_data1\n",400 " df_final_begin.loc[len(df_final_begin)] = row_data2"401 ]402 },403 {404 "cell_type": "code",405 "execution_count": null,406 "id": "7ff7c49e-02a9-4eb4-b6c7-2c86b8ca9bcf",407 "metadata": {},408 "outputs": [],409 "source": [410 "df_final_begin.to_csv('Phantom_10k_10000tokens_beginning.csv')"411 ]412 },413 {414 "cell_type": "markdown",415 "id": "c72e92cd-6ffb-43b6-a337-8e7e6c5cc550",416 "metadata": {},417 "source": [418 "## Long context - MIDDLE"419 ]420 },421 {422 "cell_type": "code",423 "execution_count": null,424 "id": "f92879c5-67db-471d-9c8e-4bd69023d40a",425 "metadata": {},426 "outputs": [],427 "source": [428 "df_generated_data_middle = df_data_chunk"429 ]430 },431 {432 "cell_type": "code",433 "execution_count": null,434 "id": "29ec8845-b48b-4315-9114-42100c84f777",435 "metadata": {},436 "outputs": [],437 "source": [438 "nlp = spacy.load(\"en_core_web_sm\")\n",439 "\n",440 "def expand_chunk_middle_1(nlp, doc_text, chunk_starting_sentence_idx, expand_token_count=2000, token_limit=2200):\n",441 " \n",442 " doc = nlp(doc_text)\n",443 " \n",444 " # Extract sentences\n",445 " sentences = list(doc.sents)\n",446 " n_sent = len(sentences)\n",447 " \n",448 " chunk = []\n",449 " chunk_token_count = 0\n",450 "\n",451 " current_sent_idx = chunk_starting_sentence_idx\n",452 " while True:\n",453 " current_sent_idx %= n_sent\n",454 " sent = sentences[current_sent_idx]\n",455 " \n",456 " chunk.append(sent.text)\n",457 " new_token_count = chunk_token_count + len(sent)\n",458 " if new_token_count >= expand_token_count and new_token_count <= token_limit:\n",459 " chunk_token_count = new_token_count\n",460 " break\n",461 " elif new_token_count >= expand_token_count and new_token_count > token_limit: \n",462 " partial_last_sentence = \" \".join([token.text for token in sent[:(token_limit - chunk_token_count)]])\n",463 " chunk[-1] = partial_last_sentence\n",464 " chunk_token_count = token_limit\n",465 " break\n",466 " chunk_token_count = new_token_count \n",467 " current_sent_idx += 1\n",468 " \n",469 " # Join the sentences to form the chunk\n",470 " chunk_text = \" \".join(chunk)\n",471 " \n",472 " return {\n",473 " \"chunk\": chunk_text,\n",474 " \"chunk_token_count\": chunk_token_count,\n",475 " \"chunk_starting_sentence_idx\": chunk_starting_sentence_idx,\n",476 " \"sentences\": sentences\n",477 " }\n",478 "\n",479 "\n",480 "\n",481 "def expand_chunk_middle_2(sentences, chunk_context, chunk_token_count, doc_text, chunk_starting_sentence_idx, \n",482 " expand_token_count=2000, token_limit=2200):\n",483 " n_sent = len(sentences)\n",484 " \n",485 " chunk = [chunk_context]\n",486 "\n",487 " current_sent_idx = chunk_starting_sentence_idx - 1\n",488 " while True:\n",489 " current_sent_idx %= n_sent\n",490 " sent = sentences[current_sent_idx]\n",491 "\n",492 " new_token_count = chunk_token_count + len(sent)\n",493 " if new_token_count >= expand_token_count and new_token_count <= token_limit:\n",494 " chunk_token_count = new_token_count\n",495 " chunk = [sent.text] + chunk\n",496 " chunk_starting_sentence_idx = current_sent_idx\n",497 " break\n",498 " elif new_token_count >= expand_token_count and new_token_count > token_limit: \n",499 " partial_first_sentence = \" \".join([token.text for token in sent[(len(sent) - (token_limit - chunk_token_count)):]])\n",500 " chunk = [partial_first_sentence] + chunk\n",501 " chunk_token_count = token_limit\n",502 " break\n",503 " chunk_token_count = new_token_count\n",504 " chunk = [sent.text] + chunk\n",505 " chunk_starting_sentence_idx = current_sent_idx\n",506 " \n",507 " current_sent_idx -= 1\n",508 " \n",509 " # Join the sentences to form the chunk\n",510 " chunk_text = \" \".join(chunk)\n",511 " \n",512 " return {\n",513 " \"chunk\": chunk_text,\n",514 " \"chunk_token_count\": chunk_token_count,\n",515 " \"chunk_starting_sentence_idx\": chunk_starting_sentence_idx\n",516 " }"517 ]518 },519 {520 "cell_type": "code",521 "execution_count": null,522 "id": "0ebb5cab-935c-432e-8eea-500def7b0633",523 "metadata": {},524 "outputs": [],525 "source": [526 "start_time = time.time()\n",527 "for i in range(df_generated_data_middle.shape[0]):\n",528 " if i % 50 == 0:\n",529 " print(i)\n",530 " print(\"Process time: \", round(time.time()-start_time, 2), \" seconds.\")\n",531 " start_time = time.time()\n",532 "\n",533 "\n",534 " chunk_context = df_generated_data_middle.at[i, 'context']\n",535 " chunk_token_count = df_generated_data_middle.at[i, 'chunk_token_count']\n",536 " doc_text = df_generated_data_middle.at[i, 'filing_text']\n",537 " chunk_starting_sentence_idx = df_generated_data_middle.at[i, 'chunk_starting_sentence_idx'] \n",538 "\n",539 " temp_target_token_count = chunk_token_count + (expand_token_count - chunk_token_count) // 2\n",540 " temp_token_limit = temp_target_token_count + token_limit - expand_token_count\n",541 " temp_chunk_result = expand_chunk_middle_1(nlp, doc_text, chunk_starting_sentence_idx, temp_target_token_count, temp_token_limit)\n",542 "\n",543 " chunk_context = temp_chunk_result['chunk']\n",544 " chunk_token_count = temp_chunk_result['chunk_token_count']\n",545 " chunk_starting_sentence_idx = temp_chunk_result['chunk_starting_sentence_idx']\n",546 " sentences = temp_chunk_result['sentences']\n",547 "\n",548 " chunk_result = expand_chunk_middle_2(sentences, chunk_context, chunk_token_count, doc_text, chunk_starting_sentence_idx,\n",549 " expand_token_count, token_limit) \n",550 "\n",551 " df_generated_data_middle.at[i, 'context'] = chunk_result[\"chunk\"]\n",552 " df_generated_data_middle.at[i, 'chunk_token_count'] = chunk_result[\"chunk_token_count\"]\n",553 " df_generated_data_middle.at[i, 'chunk_starting_sentence_idx'] = chunk_result[\"chunk_starting_sentence_idx\"]"554 ]555 },556 {557 "cell_type": "code",558 "execution_count": null,559 "id": "8ba8cdca-c9ff-4f29-8943-25371ece606e",560 "metadata": {},561 "outputs": [],562 "source": [563 "plt.hist(df_generated_data_middle['chunk_token_count'], bins=30)\n",564 "plt.xlabel('Token count')\n",565 "plt.ylabel('Frequency')\n",566 "plt.title('Distribution of chunk length (token count)')\n",567 "plt.show()"568 ]569 },570 {571 "cell_type": "code",572 "execution_count": null,573 "id": "9a7f8b93-5db7-47c6-8547-efefb20498c0",574 "metadata": {},575 "outputs": [],576 "source": [577 "df_data_chunk.to_csv('Phantom_10k_10000tokens_middle_full.csv')"578 ]579 },580 {581 "cell_type": "code",582 "execution_count": null,583 "id": "4188af5b-fb12-40fd-98d8-990bc6c66287",584 "metadata": {},585 "outputs": [],586 "source": [587 "df_final_middle = pd.DataFrame(columns = ['query', 'context', 'answer', 'ground_truth_label'])"588 ]589 },590 {591 "cell_type": "code",592 "execution_count": null,593 "id": "0b9d4498-fa1c-4cf9-8d2e-4ad0ffd6f5d9",594 "metadata": {},595 "outputs": [],596 "source": [597 "for i in range(df_generated_data_middle.shape[0]):\n",598 " query = df_generated_data_middle.at[i, 'query']\n",599 " context = df_generated_data_middle.at[i, 'context']\n",600 " row_data1 = [query, context, df_generated_data_middle.at[i, 'gold_answer'], 'not hallucination']\n",601 " row_data2 = [query, context, df_generated_data_middle.at[i, 'hallucination_answer'], 'hallucination']\n",602 " df_final_middle.loc[len(df_final_middle)] = row_data1\n",603 " df_final_middle.loc[len(df_final_middle)] = row_data2"604 ]605 },606 {607 "cell_type": "code",608 "execution_count": null,609 "id": "88f88fd2-4f40-48e3-9802-2533128b7363",610 "metadata": {},611 "outputs": [],612 "source": [613 "df_final_middle.to_csv('Phantom_10k_10000tokens_middle.csv')"614 ]615 }616 ],617 "metadata": {618 "kernelspec": {619 "display_name": "Python 3 (ipykernel)",620 "language": "python",621 "name": "python3"622 },623 "language_info": {624 "codemirror_mode": {625 "name": "ipython",626 "version": 3627 },628 "file_extension": ".py",629 "mimetype": "text/x-python",630 "name": "python",631 "nbconvert_exporter": "python",632 "pygments_lexer": "ipython3",633 "version": "3.11.11"634 }635 },636 "nbformat": 4,637 "nbformat_minor": 5638}639 