Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save axluca/f56c77dab5a9d667f3cce4fe5cabc2ee to your computer and use it in GitHub Desktop.

Select an option

Save axluca/f56c77dab5a9d667f3cce4fe5cabc2ee to your computer and use it in GitHub Desktop.
Scientific Knowledge Retrieval (Entreprenerdly.com)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Solution Architecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"https://entreprenerdly.com/wp-content/uploads/2024/02/architecture-diagram.gif\" width=\"540\" alt=\"alt text\">\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Install Libraries"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install scipy tenacity tiktoken termcolor openai requests arxiv pandas PyPDF2 tqdm"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Import Libraries"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"import arxiv\n",
"import ast\n",
"import concurrent\n",
"from csv import writer\n",
"from IPython.display import display, Markdown, Latex\n",
"import json\n",
"import openai\n",
"import os\n",
"import pandas as pd\n",
"from PyPDF2 import PdfReader\n",
"import requests\n",
"from scipy import spatial\n",
"from tenacity import retry, wait_random_exponential, stop_after_attempt\n",
"import tiktoken\n",
"from tqdm import tqdm\n",
"from termcolor import colored"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1. Set API Keys"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# set open ai api environment variable\n",
"#openai.api_key = os.getenv(\"\")\n",
"\n",
"openai.api_key = \"\"\n",
"\n",
"GPT_MODEL = \"gpt-3.5-turbo-0613\"\n",
"EMBEDDING_MODEL = \"text-embedding-ada-002\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2. Create Directory"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Directory './data/papers' created successfully.\n"
]
}
],
"source": [
"directory = './data/papers'\n",
"\n",
"# 1) CREATE DIRECTORY TO STORE PAPERS\n",
"# Check if the directory already exists\n",
"if not os.path.exists(directory):\n",
" # If the directory doesn't exist, create it and any necessary intermediate directories\n",
" os.makedirs(directory)\n",
" print(f\"Directory '{directory}' created successfully.\")\n",
"else:\n",
" # If the directory already exists, print a message indicating it\n",
" print(f\"Directory '{directory}' already exists.\")\n",
"\n",
"# 2) SET DIRECTORY TO STORE DOWNLOADED PAPERS\n",
"data_dir = os.path.join(os.curdir, \"data\", \"papers\")\n",
"paper_dir_filepath = \"./data/arxiv_library.csv\"\n",
"\n",
"# Generate a blank dataframe where we can store downloaded files\n",
"df = pd.DataFrame(list())\n",
"df.to_csv(paper_dir_filepath)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3. Core Functions"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"\n",
"# Function to get embeddings vectors on text from OpenAI\n",
"@retry(wait=wait_random_exponential(min=1, max=40), stop=stop_after_attempt(3))\n",
"def embedding_request(text):\n",
" \"\"\"\n",
" Retrieves an embedding vector for a specified text string using OpenAI's API. \n",
" The function sends the text to OpenAI's Embedding model, defined by EMBEDDING_MODEL, and receives an embedding vector in response. \n",
" This vector is a numerical representation of the text's semantic meaning, useful for various NLP tasks like text similarity.\n",
" The function is decorated with a retry mechanism that attempts up to 3 retries with increasing wait times between attempts, \n",
" to handle potential issues like network errors or API rate limits.\n",
" \"\"\"\n",
" response = openai.Embedding.create(input=text, model=EMBEDDING_MODEL)\n",
" return response\n",
"\n",
" \n",
" \n",
"# Function to get articles from arXiv\n",
"def get_articles(query, library=paper_dir_filepath, top_k=5):\n",
" \"\"\"\n",
" Searches for and retrieves the top 'k' academic papers related to a user's query from the arXiv database. \n",
" The function uses the arXiv API to search for papers, with the search criteria being the user's query and the number of results limited to 'top_k'. \n",
" For each article found, it stores relevant information such as the title, summary, and URLs in a list. \n",
" It also downloads the PDF of each paper and stores references, including the title, download path, and embedding of the paper title, in a CSV file specified by 'library'.\n",
" This is useful for keeping a record of the papers and their embeddings for later retrieval and analysis. \n",
" This function will be used by the read_article_and_summarize\n",
" \"\"\"\n",
" search = arxiv.Search(\n",
" query=query, max_results=top_k, sort_by=arxiv.SortCriterion.Relevance\n",
" )\n",
" result_list = []\n",
" for result in search.results():\n",
" result_dict = {}\n",
" result_dict.update({\"title\": result.title})\n",
" result_dict.update({\"summary\": result.summary})\n",
"\n",
" # Taking the first url provided\n",
" result_dict.update({\"article_url\": [x.href for x in result.links][0]})\n",
" result_dict.update({\"pdf_url\": [x.href for x in result.links][1]})\n",
" result_list.append(result_dict)\n",
"\n",
" # Store references in library file\n",
" response = embedding_request(text=result.title)\n",
" file_reference = [\n",
" result.title,\n",
" result.download_pdf(data_dir),\n",
" response[\"data\"][0][\"embedding\"],\n",
" ]\n",
"\n",
" # Write to file\n",
" with open(library, \"a\") as f_object:\n",
" writer_object = writer(f_object)\n",
" writer_object.writerow(file_reference)\n",
" f_object.close()\n",
" return result_list\n",
"\n",
" \n",
"\n",
"# Function to rank strings by relatedness to a query string\n",
"def strings_ranked_by_relatedness(\n",
" query: str,\n",
" df: pd.DataFrame,\n",
" relatedness_fn=lambda x, y: 1 - spatial.distance.cosine(x, y),\n",
" top_n: int = 100,\n",
" ) -> list[str]:\n",
"\n",
" \"\"\"\n",
" Ranks and returns a list of strings from a DataFrame based on their relatedness to a given query string.\n",
" The function first obtains an embedding for the query string. Then, it calculates the relatedness of each string in the DataFrame to the query, \n",
" using the provided 'relatedness_fn', which defaults to computing the cosine similarity between their embeddings.\n",
" It sorts these strings in descending order of relatedness and returns the top 'n' strings.\n",
" \"\"\"\n",
" query_embedding_response = embedding_request(query)\n",
" query_embedding = query_embedding_response[\"data\"][0][\"embedding\"]\n",
"\n",
" strings_and_relatednesses = [\n",
" (row[\"filepath\"], relatedness_fn(query_embedding, row[\"embedding\"]))\n",
" for i, row in df.iterrows()\n",
" ]\n",
" \n",
" strings_and_relatednesses.sort(key=lambda x: x[1], reverse=True)\n",
" strings, relatednesses = zip(*strings_and_relatednesses)\n",
" return strings[:top_n]\n",
"\n",
"\n",
"\n",
"# Function to read PDFs and return text\n",
"def read_pdf(filepath):\n",
" \"\"\"\n",
" Extracts and returns the textual content from a PDF file located at the given file path. \n",
" It reads through the pages of the PDF file and concatenates the text of each page, \n",
" appending the page number to keep track of where each text segment originated.\n",
" \"\"\"\n",
" # creating a pdf reader object\n",
" reader = PdfReader(filepath)\n",
" pdf_text = \"\"\n",
" page_number = 0\n",
" for page in reader.pages:\n",
" page_number += 1\n",
" pdf_text += page.extract_text() + f\"\\nPage Number: {page_number}\"\n",
" return pdf_text\n",
"\n",
"\n",
"\n",
"# Functon to split a text into smaller chunks of size n, preferably ending at the end of a sentence\n",
"def create_chunks(text, n, tokenizer):\n",
" \"\"\"\n",
" Splits a large block of text into smaller chunks of a specified size 'n', \n",
" using a tokenizer to ensure that chunks ideally end at sentence boundaries. \n",
" This is done by first encoding the text into tokens, then iteratively creating chunks \n",
" while attempting to end each chunk at a sentence end, within a specified token range.\n",
" \"\"\"\n",
" tokens = tokenizer.encode(text)\n",
" i = 0\n",
" while i < len(tokens):\n",
" # Find the nearest end of sentence within a range of 0.5 * n and 1.5 * n tokens\n",
" j = min(i + int(1.5 * n), len(tokens))\n",
" while j > i + int(0.5 * n):\n",
" # Decode the tokens and check for full stop or newline\n",
" chunk = tokenizer.decode(tokens[i:j])\n",
" if chunk.endswith(\".\") or chunk.endswith(\"\\n\"):\n",
" break\n",
" j -= 1\n",
" # If no end of sentence found, use n tokens as the chunk size\n",
" if j == i + int(0.5 * n):\n",
" j = min(i + n, len(tokens))\n",
" yield tokens[i:j]\n",
" i = j\n",
"\n",
"\n",
"\n",
"# Function to extract a chunk of text from a larger text\n",
"def extract_chunk(content, template_prompt):\n",
" \"\"\"\n",
" This function applies a prompt to some input content.\n",
" It then extracts and returns the response from OpenAI's ChatCompletion API content. \n",
" In this case it returns a summarized chunk of text.\n",
" \"\"\"\n",
" prompt = template_prompt + content\n",
" response = openai.ChatCompletion.create(\n",
" model=GPT_MODEL, messages=[{\"role\": \"user\", \"content\": prompt}], temperature=0\n",
" )\n",
" return response[\"choices\"][0][\"message\"][\"content\"]\n",
"\n",
"\n",
" \n",
"# Function to summarize chunks and return an overall summary\n",
"def summarize_text(query):\n",
" \"\"\"\n",
" Automates summarizing academic papers relevant to a user's query. The process includes:\n",
" 1. Reading Data: Reads 'arxiv_library.csv' containing information about papers and their embeddings.\n",
" 2. Identifying Relevant Paper: Compares query's embedding to embeddings in the CSV to find closest match.\n",
" 3. Extracting Text: Reads the PDF of the identified paper and converts its content into a string.\n",
" 4. Chunking Text: Divides the extracted text into manageable chunks for efficient processing.\n",
" 5. Summarizing Chunks: Each text chunk is summarized using the 'extract_chunk' function in parallel.\n",
" 6. Compiling Summaries: Combines individual summaries into a final comprehensive summary.\n",
" 7. Returning Summary: Provides a condensed overview of the paper, focusing on key insights relevant to the user's query.\n",
" \"\"\"\n",
"\n",
" # A prompt to dictate how the recursive summarizations should approach the input paper\n",
" summary_prompt = \"\"\"Summarize this text from an academic paper. Extract any key points with reasoning.\\n\\nContent:\"\"\"\n",
"\n",
" # If the library is empty (no searches have been performed yet), we perform one and download the results\n",
" library_df = pd.read_csv(paper_dir_filepath).reset_index()\n",
" if len(library_df) == 0:\n",
" print(\"No papers searched yet, downloading first.\")\n",
" get_articles(query)\n",
" print(\"Papers downloaded, continuing\")\n",
" library_df = pd.read_csv(paper_dir_filepath).reset_index()\n",
" library_df.columns = [\"title\", \"filepath\", \"embedding\"]\n",
" library_df[\"embedding\"] = library_df[\"embedding\"].apply(ast.literal_eval)\n",
" strings = strings_ranked_by_relatedness(query, library_df, top_n=1)\n",
" print(\"Chunking text from paper\")\n",
" pdf_text = read_pdf(strings[0])\n",
"\n",
" # Initialise tokenizer\n",
" tokenizer = tiktoken.get_encoding(\"cl100k_base\")\n",
" results = \"\"\n",
"\n",
" # Chunk up the document into 1500 token chunks\n",
" chunks = create_chunks(pdf_text, 1500, tokenizer)\n",
" text_chunks = [tokenizer.decode(chunk) for chunk in chunks]\n",
" print(\"Summarizing each chunk of text\")\n",
"\n",
" # Parallel process the summaries\n",
" with concurrent.futures.ThreadPoolExecutor(\n",
" max_workers=len(text_chunks)\n",
" ) as executor:\n",
" futures = [\n",
" executor.submit(extract_chunk, chunk, summary_prompt)\n",
" for chunk in text_chunks\n",
" ]\n",
" with tqdm(total=len(text_chunks)) as pbar:\n",
" for _ in concurrent.futures.as_completed(futures):\n",
" pbar.update(1)\n",
" for future in futures:\n",
" data = future.result()\n",
" results += data\n",
"\n",
" # Final summary\n",
" print(\"Summarizing into overall summary\")\n",
" response = openai.ChatCompletion.create(\n",
" model=GPT_MODEL,\n",
" messages=[\n",
" {\n",
" \"role\": \"user\",\n",
" \"content\": f\"\"\"Write a summary collated from this collection of key points extracted from an academic paper.\n",
" The summary should highlight the core argument, conclusions and evidence, and answer the user's query.\n",
" User query: {query}\n",
" The summary should be structured in bulleted lists following the headings Core Argument, Evidence, and Conclusions.\n",
" Key points:\\n{results}\\nSummary:\\n\"\"\",\n",
" }\n",
" ],\n",
" temperature=0,\n",
" )\n",
" return response\n",
"\n",
" \n",
" \n",
"# Function to make a request to the OpenAI ChatCompletion API\n",
"@retry(wait=wait_random_exponential(min=1, max=40), stop=stop_after_attempt(3))\n",
"def chat_completion_request(messages, functions=None, model=GPT_MODEL):\n",
" \n",
" \"\"\"\n",
" Makes a request to the OpenAI ChatCompletion API. Handles API interactions, \n",
" includes additional functions in the request, uses a retry mechanism for \n",
" potential API issues, and parses the API's JSON response. Accepts a list \n",
" of messages for the chat completion, optional functions for extended \n",
" processing, and the model specification.\n",
" \"\"\"\n",
" headers = {\n",
" \"Content-Type\": \"application/json\",\n",
" \"Authorization\": \"Bearer \" + openai.api_key,\n",
" }\n",
" json_data = {\"model\": model, \"messages\": messages}\n",
" if functions is not None:\n",
" json_data.update({\"functions\": functions})\n",
" try:\n",
" response = requests.post(\n",
" \"https://api.openai.com/v1/chat/completions\",\n",
" headers=headers,\n",
" json=json_data,\n",
" )\n",
" return response\n",
" except Exception as e:\n",
" print(\"Unable to generate ChatCompletion response\")\n",
" print(f\"Exception: {e}\")\n",
" return e\n",
"\n",
" \n",
" \n",
"# Class to manage conversation history\n",
"class Conversation:\n",
" def __init__(self):\n",
" # Initialise conversation history\n",
" self.conversation_history = []\n",
"\n",
" def add_message(self, role, content):\n",
" # Add message to conversation history\n",
" message = {\"role\": role, \"content\": content}\n",
" self.conversation_history.append(message)\n",
"\n",
" def display_conversation(self, detailed=False):\n",
" # Display conversation history\n",
" role_to_color = {\n",
" \"system\": \"red\",\n",
" \"user\": \"green\",\n",
" \"assistant\": \"blue\",\n",
" \"function\": \"magenta\",\n",
" }\n",
" for message in self.conversation_history:\n",
" print(\n",
" colored(\n",
" f\"{message['role']}: {message['content']}\\n\\n\",\n",
" role_to_color[message[\"role\"]],\n",
" )\n",
" )\n",
"\n",
" \n",
" \n",
"# Function to initiate our get_articles and read_article_and_summarize functions\n",
"arxiv_functions = [\n",
" {\n",
" \"name\": \"get_articles\",\n",
" \"description\": \"\"\"Use this function to get academic papers from arXiv to answer user questions.\"\"\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"query\": {\n",
" \"type\": \"string\",\n",
" \"description\": f\"\"\"\n",
" User query in JSON. Responses should be summarized and should include the article URL reference\n",
" \"\"\",\n",
" }\n",
" },\n",
" \"required\": [\"query\"],\n",
" },\n",
" },\n",
" {\n",
" \"name\": \"read_article_and_summarize\",\n",
" \"description\": \"\"\"Use this function to read whole papers and provide a summary for users.\n",
" You should NEVER call this function before get_articles has been called in the conversation.\"\"\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"query\": {\n",
" \"type\": \"string\",\n",
" \"description\": f\"\"\"\n",
" Description of the article in plain text based on the user's query\n",
" \"\"\",\n",
" }\n",
" },\n",
" \"required\": [\"query\"],\n",
" },\n",
" }\n",
"]\n",
"\n",
"\n",
"\n",
"# Function to manage a ChatCompletion API call with optional function execution\n",
"def chat_completion_with_function_execution(messages, functions=[None]):\n",
" \"\"\"\n",
" Manages a ChatCompletion API call with optional function execution. Handles \n",
" API calls, determines the need for function execution based on the API's \n",
" response, and manages the conversation flow.\n",
" \"\"\"\n",
" response = chat_completion_request(messages, functions)\n",
" full_message = response.json()[\"choices\"][0]\n",
" if full_message[\"finish_reason\"] == \"function_call\":\n",
" print(f\"Function generation requested, calling function\")\n",
" return call_arxiv_function(messages, full_message)\n",
" else:\n",
" print(f\"Function not required, responding to user\")\n",
" return response.json()\n",
"\n",
"\n",
"\n",
"# Function to call arXiv-related functions\n",
"def call_arxiv_function(messages, full_message):\n",
"\n",
" \"\"\"\n",
" Executes arXiv-related functions based on the model's output. Determines \n",
" the appropriate function ('get_articles' or 'read_article_and_summarize'), \n",
" parses input for the function and arguments, and integrates the results \n",
" back into the conversation flow.\n",
" \"\"\"\n",
"\n",
" if full_message[\"message\"][\"function_call\"][\"name\"] == \"get_articles\":\n",
" try:\n",
" parsed_output = json.loads(\n",
" full_message[\"message\"][\"function_call\"][\"arguments\"]\n",
" )\n",
" print(\"Getting search results\")\n",
" results = get_articles(parsed_output[\"query\"])\n",
" except Exception as e:\n",
" print(parsed_output)\n",
" print(f\"Function execution failed\")\n",
" print(f\"Error message: {e}\")\n",
" messages.append(\n",
" {\n",
" \"role\": \"function\",\n",
" \"name\": full_message[\"message\"][\"function_call\"][\"name\"],\n",
" \"content\": str(results),\n",
" }\n",
" )\n",
" try:\n",
" print(\"Got search results, summarizing content\")\n",
" response = chat_completion_request(messages)\n",
" return response.json()\n",
" except Exception as e:\n",
" print(type(e))\n",
" raise Exception(\"Function chat request failed\")\n",
"\n",
" elif (\n",
" full_message[\"message\"][\"function_call\"][\"name\"] == \"read_article_and_summarize\"\n",
" ):\n",
" parsed_output = json.loads(\n",
" full_message[\"message\"][\"function_call\"][\"arguments\"]\n",
" )\n",
" print(\"Finding and reading paper\")\n",
" summary = summarize_text(parsed_output[\"query\"])\n",
" return summary\n",
"\n",
" else:\n",
" raise Exception(\"Function does not exist and cannot be called\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4. Interacting with the Research Chatbot"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Function generation requested, calling function\n",
"Getting search results\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\cosor\\AppData\\Local\\Temp\\ipykernel_29552\\855077976.py:30: DeprecationWarning: The 'Search.results' method is deprecated, use 'Client.results' instead\n",
" for result in search.results():\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Got search results, summarizing content\n"
]
},
{
"data": {
"text/markdown": [
"Here are some recent papers on market efficiency:\n",
"\n",
"1. Title: \"Market-Aware Models for Efficient Cross-Market Recommendation\"\n",
" Summary: The paper proposes market-aware models for cross-market recommendation, which directly model a market via market embeddings. The experiments show that these models are effective and efficient alternatives to meta-learning methods.\n",
" Article URL: [Link to the paper](http://dx.doi.org/10.1007/978-3-031-28244-7_9)\n",
"\n",
"2. Title: \"A Theory of Market Efficiency\"\n",
" Summary: This paper introduces a mathematical theory called market connectivity that measures market efficiency and identifies inefficiencies. It provides methods for testing the efficient markets hypothesis and evaluates the impact of policies and regulations on market efficiency.\n",
" Article URL: [Link to the paper](http://arxiv.org/abs/1702.03290v1)\n",
"\n",
"3. Title: \"Two-Step market clearing for local energy trading in feeder-based markets\"\n",
" Summary: The paper proposes a feeder-based market for local energy trading and a Two-Step Market Clearing mechanism for market clearing. The method is scalable, reduces computation overheads, and enhances social welfare.\n",
" Article URL: [Link to the paper](http://dx.doi.org/10.1049/joe.2018.9312)\n",
"\n",
"4. Title: \"Is the Indian Stock Market efficient - A comprehensive study of Bombay Stock Exchange Indices\"\n",
" Summary: This study analyzes the efficiency of the Indian Stock Market and tests the random walk nature of the stock market. The findings suggest evidence in favor of the inefficient form of the Indian Stock Market.\n",
" Article URL: [Link to the paper](http://arxiv.org/abs/1510.03704v1)\n",
"\n",
"5. Title: \"Micro-economic Analysis of the Physical Constrained Markets: Game Theory Application to Competitive Electricity Markets\"\n",
" Summary: The paper discusses the application of game theory to physical constrained electricity markets. It provides tools for assessing market performance and identifying critical network constraints that impact market efficiency.\n",
" Article URL: [Link to the paper](http://dx.doi.org/10.1140/epjb/e2006-00122-1)\n",
"\n",
"Feel free to click on the article URLs to access the full papers."
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Start with a system message\n",
"paper_system_message = \"\"\"You are arXivGPT, a helpful assistant pulls academic papers to answer user questions.\n",
"You summarize the papers clearly so the customer can decide which to read to answer their question.\n",
"You always provide the article_url and title so the user can understand the name of the paper and click through to access it.\n",
"Begin!\"\"\"\n",
"paper_conversation = Conversation()\n",
"paper_conversation.add_message(\"system\", paper_system_message)\n",
"\n",
"\n",
"# Add a user message\n",
"paper_conversation.add_message(\"user\", \"What are the latest on Market Efficiency?\") # How does PPO reinforcement learning work?\n",
"chat_response = chat_completion_with_function_execution(\n",
" paper_conversation.conversation_history, functions=arxiv_functions\n",
")\n",
"\n",
"assistant_message = chat_response[\"choices\"][0][\"message\"][\"content\"]\n",
"paper_conversation.add_message(\"assistant\", assistant_message)\n",
"display(Markdown(assistant_message))"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Function generation requested, calling function\n",
"Finding and reading paper\n",
"Chunking text from paper\n",
"Summarizing each chunk of text\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 7/7 [00:05<00:00, 1.17it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Summarizing into overall summary\n"
]
},
{
"data": {
"text/markdown": [
"Core Argument:\n",
"- The paper discusses the task of cross-market recommendation (CMR) and proposes market-aware (MA) models that directly model a market via market embeddings instead of using meta-learning across markets.\n",
"\n",
"Evidence:\n",
"- The experiments conducted in the paper show that MA models outperform market-unaware models in 85% of cases on nDCG@10 in a pairwise setting with a single target-source market.\n",
"- MA models require only 15% of the training time compared to meta-learning models.\n",
"- In the global setting, MA models consistently outperform market-unaware models for some markets and outperform meta-learning-based methods for all but one market.\n",
"\n",
"Conclusions:\n",
"- The authors conclude that MA models are an efficient and effective alternative to meta-learning, especially in the global setting.\n",
"- MA models achieve better generalization by capturing both common behaviors across markets and market-specific behaviors.\n",
"- The paper highlights the importance of explicitly modeling markets in CMR and demonstrates the effectiveness of the proposed models compared to existing approaches."
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Add another user message to induce our system to use the second tool\n",
"paper_conversation.add_message(\n",
" \"user\",\n",
" \"Can you read the Market-Aware Models for Efficient Cross-Market Recommendation paper for me and give me a summary\", # \"Can you read the PPO sequence generation paper for me and give me a summary\"\n",
")\n",
"updated_response = chat_completion_with_function_execution(\n",
" paper_conversation.conversation_history, functions=arxiv_functions\n",
")\n",
"display(Markdown(updated_response[\"choices\"][0][\"message\"][\"content\"]))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.10.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment