From the uDemy course on LLM engineering.
https://www.udemy.com/course/llm-engineering-master-ai-and-large-language-models
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
850 lines
23 KiB
850 lines
23 KiB
{ |
|
"cells": [ |
|
{ |
|
"cell_type": "markdown", |
|
"id": "db8736a7-ed94-441c-9556-831fa57b5a10", |
|
"metadata": {}, |
|
"source": [ |
|
"# The Product Pricer Continued\n", |
|
"\n", |
|
"A model that can estimate how much something costs, from its description.\n", |
|
"\n", |
|
"## Baseline Models\n", |
|
"\n", |
|
"Today we work on the simplest models to act as a starting point that we will beat." |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "681c717b-4c24-4ac3-a5f3-3c5881d6e70a", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# imports\n", |
|
"\n", |
|
"import os\n", |
|
"import re\n", |
|
"import math\n", |
|
"import json\n", |
|
"import random\n", |
|
"from dotenv import load_dotenv\n", |
|
"from huggingface_hub import login\n", |
|
"from items import Item\n", |
|
"import matplotlib.pyplot as plt\n", |
|
"import numpy as np\n", |
|
"import pickle\n", |
|
"from collections import Counter\n", |
|
"from openai import OpenAI" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "6c01ee5f-c4fc-44fe-9d3a-907e8a0426d2", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Constants - used for printing to stdout in color\n", |
|
"\n", |
|
"GREEN = \"\\033[92m\"\n", |
|
"YELLOW = \"\\033[93m\"\n", |
|
"RED = \"\\033[91m\"\n", |
|
"RESET = \"\\033[0m\"\n", |
|
"COLOR_MAP = {\"red\":RED, \"orange\": YELLOW, \"green\": GREEN}" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "36d05bdc-0155-4c72-a7ee-aa4e614ffd3c", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# environment\n", |
|
"\n", |
|
"load_dotenv()\n", |
|
"os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your-key-if-not-using-env')\n", |
|
"os.environ['ANTHROPIC_API_KEY'] = os.getenv('ANTHROPIC_API_KEY', 'your-key-if-not-using-env')\n", |
|
"os.environ['HF_TOKEN'] = os.getenv('HF_TOKEN', 'your-key-if-not-using-env')" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "4dd3aad2-6f99-433c-8792-e461d2f06622", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Log in to HuggingFace\n", |
|
"\n", |
|
"hf_token = os.environ['HF_TOKEN']\n", |
|
"login(hf_token, add_to_git_credential=True)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "b0a6fb86-74a4-403c-ab25-6db2d74e9d2b", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"openai = OpenAI()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "c830ed3e-24ee-4af6-a07b-a1bfdcd39278", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"%matplotlib inline" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "5c9b05f4-c9eb-462c-8d86-de9140a2d985", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Let's avoid curating all our data again! Load in the pickle files:\n", |
|
"\n", |
|
"with open('train.pkl', 'rb') as file:\n", |
|
" train = pickle.load(file)\n", |
|
"\n", |
|
"with open('test.pkl', 'rb') as file:\n", |
|
" test = pickle.load(file)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "markdown", |
|
"id": "bcccf130-125a-4958-bac3-f46dfcb29b3f", |
|
"metadata": {}, |
|
"source": [ |
|
"## Unveiling a mighty script that we will use a lot!\n", |
|
"\n", |
|
"A rather pleasing Test Harness that will evaluate any model against 250 items from the Test set\n", |
|
"\n", |
|
"And show us the results in a visually satisfying way.\n", |
|
"\n", |
|
"You write a function of this form:\n", |
|
"\n", |
|
"```\n", |
|
"def my_prediction_function(item):\n", |
|
" # my code here\n", |
|
" return my_estimate\n", |
|
"```\n", |
|
"\n", |
|
"And then you call:\n", |
|
"\n", |
|
"`TestRunner(my_prediction_function).run()`\n", |
|
"\n", |
|
"To evaluate your model." |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "b5793f5c-e23e-4a74-9496-1e30dd1e8935", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"class TestRunner:\n", |
|
"\n", |
|
" def __init__(self, predictor, title=None, data=test, size=250):\n", |
|
" self.predictor = predictor\n", |
|
" self.data = data\n", |
|
" self.title = title or predictor.__name__\n", |
|
" self.size = size\n", |
|
" self.guesses = []\n", |
|
" self.truths = []\n", |
|
" self.errors = []\n", |
|
" self.sles = []\n", |
|
" self.colors = []\n", |
|
"\n", |
|
" def color_for(self, error, truth):\n", |
|
" if error<40 or error/truth < 0.2:\n", |
|
" return \"green\"\n", |
|
" elif error<80 or error/truth < 0.4:\n", |
|
" return \"orange\"\n", |
|
" else:\n", |
|
" return \"red\"\n", |
|
" \n", |
|
" def run_datapoint(self, i):\n", |
|
" datapoint = self.data[i]\n", |
|
" guess = self.predictor(datapoint)\n", |
|
" truth = datapoint.price\n", |
|
" error = abs(guess - truth)\n", |
|
" log_error = math.log(truth+1) - math.log(guess+1)\n", |
|
" sle = log_error ** 2\n", |
|
" color = self.color_for(error, truth)\n", |
|
" title = datapoint.title if len(datapoint.title) <= 40 else datapoint.title[:40]+\"...\"\n", |
|
" self.guesses.append(guess)\n", |
|
" self.truths.append(truth)\n", |
|
" self.errors.append(error)\n", |
|
" self.sles.append(sle)\n", |
|
" self.colors.append(color)\n", |
|
" print(f\"{COLOR_MAP[color]}{i+1}: Guess: ${guess:,.2f} Truth: ${truth:,.2f} Error: ${error:,.2f} SLE: {sle:,.2f} Item: {title}{RESET}\")\n", |
|
"\n", |
|
" def chart(self, title):\n", |
|
" max_error = max(self.errors)\n", |
|
" plt.figure(figsize=(12, 8))\n", |
|
" max_val = max(max(self.truths), max(self.guesses))\n", |
|
" plt.plot([0, max_val], [0, max_val], color='deepskyblue', lw=2, alpha=0.6)\n", |
|
" plt.scatter(self.truths, self.guesses, s=3, c=self.colors)\n", |
|
" plt.xlabel('Ground Truth')\n", |
|
" plt.ylabel('Model Estimate')\n", |
|
" plt.xlim(0, max_val)\n", |
|
" plt.ylim(0, max_val)\n", |
|
" plt.title(title)\n", |
|
" plt.show()\n", |
|
"\n", |
|
" def report(self):\n", |
|
" average_error = sum(self.errors) / self.size\n", |
|
" rmsle = math.sqrt(sum(self.sles) / self.size)\n", |
|
" hits = sum(1 for color in self.colors if color==\"green\")\n", |
|
" title = f\"{self.title} Error=${average_error:,.2f} RMSLE={rmsle:,.2f} Hits={hits/self.size*100:.1f}%\"\n", |
|
" self.chart(title)\n", |
|
"\n", |
|
" def run(self):\n", |
|
" self.error = 0\n", |
|
" for i in range(self.size):\n", |
|
" self.run_datapoint(i)\n", |
|
" self.report()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "markdown", |
|
"id": "066fef03-8338-4526-9df3-89b649ad4f0a", |
|
"metadata": {}, |
|
"source": [ |
|
"# Now for something basic\n", |
|
"\n", |
|
"What's the very simplest model you could imagine?\n", |
|
"\n", |
|
"Let's start with a random number generator!" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "66ea68e8-ab1b-4f0d-aba4-a59574d8f85e", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def messages_for(item):\n", |
|
" system_message = \"You estimate prices of items. Reply only with the price, no explanation\"\n", |
|
" user_prompt = item.test_prompt().replace(\" to the nearest dollar\",\"\")\n", |
|
" return [\n", |
|
" {\"role\": \"system\", \"content\": system_message},\n", |
|
" {\"role\": \"user\", \"content\": user_prompt}\n", |
|
" ]" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "b1af1888-f94a-4106-b0d8-8a70939eec4e", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_price(s):\n", |
|
" s = s.replace('$','').replace(',','')\n", |
|
" match = re.search(r\"[-+]?\\d*\\.\\d+|\\d+\", s)\n", |
|
" return float(match.group()) if match else 0" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "f49e90d6-6749-4eb8-9347-5922b189d379", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def gpt_4o_frontier(item):\n", |
|
" response = openai.chat.completions.create(\n", |
|
" model=\"gpt-4o-2024-08-06\", \n", |
|
" messages=messages_for(item),\n", |
|
" seed=42,\n", |
|
" max_tokens=5\n", |
|
" )\n", |
|
" reply = response.choices[0].message.content\n", |
|
" return get_price(reply)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "766e697e-55bf-4521-b301-3b07d20045e0", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"TestRunner(gpt_4o_frontier).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "53d941cb-5b73-44ea-b893-3a0ce9997066", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Set the random seed\n", |
|
"\n", |
|
"random.seed(42)\n", |
|
"\n", |
|
"# Run our TestRunner\n", |
|
"\n", |
|
"TestRunner(random_predictor).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "97451c73-9c1b-43a8-b3b9-9c41942e48a2", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# That was fun!\n", |
|
"# We can do better - here's another rather trivial model\n", |
|
"\n", |
|
"training_prices = [item.price for item in train]\n", |
|
"training_average = sum(training_prices) / len(training_prices)\n", |
|
"\n", |
|
"def constant_predictor(prompt):\n", |
|
" return training_average" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "8cf384eb-30c2-40d8-b7e5-48942ac6a969", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Run our constant predictor\n", |
|
"\n", |
|
"TestRunner(constant_predictor).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "ce16eee8-bb34-4914-9aa5-57e30a567842", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Create a new \"features\" field on items, and populate it with json parsed from the details dict\n", |
|
"\n", |
|
"for item in train:\n", |
|
" item.features = json.loads(item.details)\n", |
|
"for item in test:\n", |
|
" item.features = json.loads(item.details)\n", |
|
"\n", |
|
"# Look at one" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "fd7a41c5-0c51-41be-a61d-8e80c3e90930", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Look at 20 most common features in training set\n", |
|
"\n", |
|
"import json\n", |
|
"feature_count = Counter()\n", |
|
"for item in train:\n", |
|
" for f in item.features.keys():\n", |
|
" feature_count[f]+=1\n" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "3cef84a9-4932-48fd-9f7a-51cfc06e3216", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Now some janky code to pluck out the Item Weight\n", |
|
"# Don't worry too much about this: spoiler alert, it's not going to be much use in training!\n", |
|
"\n", |
|
"def get_weight(item):\n", |
|
" weight_str = item.features.get('Item Weight')\n", |
|
" if weight_str:\n", |
|
" parts = weight_str.split(' ')\n", |
|
" amount = float(parts[0])\n", |
|
" unit = parts[1].lower()\n", |
|
" if unit==\"pounds\":\n", |
|
" return amount\n", |
|
" elif unit==\"ounces\":\n", |
|
" return amount / 16\n", |
|
" elif unit==\"grams\":\n", |
|
" return amount / 453.592\n", |
|
" elif unit==\"milligrams\":\n", |
|
" return amount / 453592\n", |
|
" elif unit==\"kilograms\":\n", |
|
" return amount / 0.453592\n", |
|
" elif unit==\"hundredths\" and parts[2].lower()==\"pounds\":\n", |
|
" return amount / 100\n", |
|
" else:\n", |
|
" print(weight_str)\n", |
|
" return None" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "f4848b4a-3c5a-4168-83a5-57a1f3ff270d", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"weights = [get_weight(t) for t in train]\n", |
|
"weights = [w for w in weights if w]" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "0cd11cc8-f16e-4991-b531-482189ddc4b6", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"average_weight = sum(weights)/len(weights)\n", |
|
"average_weight" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "efe8ec7f-9777-464f-a809-b06b7033bdb2", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_weight_with_default(item):\n", |
|
" weight = get_weight(item)\n", |
|
" return weight or average_weight" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "c2659fef-a455-431a-9a0e-59342b80084b", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_rank(item):\n", |
|
" rank_dict = item.features.get(\"Best Sellers Rank\")\n", |
|
" if rank_dict:\n", |
|
" ranks = rank_dict.values()\n", |
|
" return sum(ranks)/len(ranks)\n", |
|
" return None" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "20b9b5be-30bc-4d3a-8492-fbae119421a0", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"ranks = [get_rank(t) for t in train]\n", |
|
"ranks = [r for r in ranks if r]\n", |
|
"average_rank = sum(ranks)/len(ranks)\n", |
|
"average_rank" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "081e646a-ea50-4ec3-9512-6d5f96f8aef6", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_rank_with_default(item):\n", |
|
" rank = get_rank(item)\n", |
|
" return rank or average_rank" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "afd5daf7-cb2b-47af-bf17-dd71a9db65d0", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_text_length(item):\n", |
|
" return len(item.test_prompt())" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "85c89012-a922-401b-8a3b-94af641bf27a", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# investigate the brands\n", |
|
"\n", |
|
"brands = Counter()\n", |
|
"for t in train:\n", |
|
" brand = t.features.get(\"Brand\")\n", |
|
" if brand:\n", |
|
" brands[brand]+=1\n", |
|
"\n", |
|
"# Look at most common 40 brands" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "386dde54-e028-4a6d-b291-cce889ac1fa3", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"TOP_ELECTRONICS_BRANDS = [\"hp\", \"dell\", \"lenovo\", \"samsung\", \"asus\", \"sony\", \"canon\", \"apple\", \"intel\"]\n", |
|
"def is_top_electronics_brand(item):\n", |
|
" brand = item.features.get(\"Brand\")\n", |
|
" return brand and brand.lower() in TOP_ELECTRONICS_BRANDS" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "c31c9c59-9d0d-47a8-a046-f20ed8d38d4c", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_features(item):\n", |
|
" return {\n", |
|
" \"weight\": get_weight_with_default(item),\n", |
|
" \"rank\": get_rank_with_default(item),\n", |
|
" \"text_length\": get_text_length(item),\n", |
|
" \"is_top_electronics_brand\": 1 if is_top_electronics_brand(item) else 0\n", |
|
" }" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "88850855-f5bd-4be2-9d7c-75bf8a21609b", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Look at features in training ite," |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "ee9b5298-68b7-497d-8b2e-875287bb25b2", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"import pandas as pd\n", |
|
"import numpy as np\n", |
|
"from sklearn.linear_model import LinearRegression\n", |
|
"from sklearn.metrics import mean_squared_error, r2_score\n", |
|
"from sklearn.preprocessing import StandardScaler\n", |
|
"\n", |
|
"def list_to_dataframe(items):\n", |
|
" features = [get_features(item) for item in items]\n", |
|
" df = pd.DataFrame(features)\n", |
|
" df['price'] = [item.price for item in items]\n", |
|
" return df\n", |
|
"\n", |
|
"train_df = list_to_dataframe(train)\n", |
|
"test_df = list_to_dataframe(test[:250])" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "cc1d68e0-ab33-40f4-9334-461d426af25c", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"np.random.seed(42)\n", |
|
"\n", |
|
"# Separate features and target\n", |
|
"feature_columns = [col for col in train_df.columns if col != 'price']\n", |
|
"X_train = train_df[feature_columns]\n", |
|
"y_train = train_df['price']\n", |
|
"X_test = test_df[feature_columns]\n", |
|
"y_test = test_df['price']\n", |
|
"\n", |
|
"feature_columns = ['weight', 'rank', 'text_length', 'is_top_electronics_brand']\n", |
|
"\n", |
|
"X_train = train_df[feature_columns]\n", |
|
"y_train = train_df['price']\n", |
|
"X_test = test_df[feature_columns]\n", |
|
"y_test = test_df['price']\n", |
|
"\n", |
|
"# Create and train the model\n", |
|
"model = LinearRegression()\n", |
|
"model.fit(X_train, y_train)\n", |
|
"\n", |
|
"# Print coefficients\n", |
|
"for feature, coef in zip(feature_columns, model.coef_):\n", |
|
" print(f\"{feature}: {coef}\")\n", |
|
"print(f\"Intercept: {model.intercept_}\")\n", |
|
"\n", |
|
"# Make predictions\n", |
|
"y_pred = model.predict(X_test)\n", |
|
"\n", |
|
"# Evaluate the model\n", |
|
"mse = mean_squared_error(y_test, y_pred)\n", |
|
"r2 = r2_score(y_test, y_pred)\n", |
|
"\n", |
|
"print(f\"Mean Squared Error: {mse}\")\n", |
|
"print(f\"R-squared Score: {r2}\")\n" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "6561c3c7-ac7f-458b-983c-4a164b9d02c3", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# Function to predict price for a new item\n", |
|
"def linear_regression_predictor(item):\n", |
|
" features = get_features(item)\n", |
|
" features_df = pd.DataFrame([features])\n", |
|
" return model.predict(features_df)[0]" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "9bf2caa4-657a-4fc6-9dcb-bed7eaf8dd65", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# test it\n", |
|
"\n", |
|
"TestRunner(linear_regression_predictor).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "e126c22e-53e7-4967-9ebb-6b7dd7fe4ade", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"from sklearn.feature_extraction.text import CountVectorizer\n", |
|
"\n", |
|
"np.random.seed(42)\n", |
|
"\n", |
|
"prices = np.array([float(item.price) for item in train])\n", |
|
"documents = [item.test_prompt() for item in train]\n", |
|
"vectorizer = CountVectorizer(max_features=1000, stop_words='english')\n", |
|
"X = vectorizer.fit_transform(documents)\n", |
|
"regressor = LinearRegression()\n", |
|
"regressor.fit(X, prices)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "4b7148d3-3202-4536-a75c-1627495c51d3", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def linear_regression_nlp_predictor(item):\n", |
|
" x = vectorizer.transform([item.test_prompt()])\n", |
|
" return max(regressor.predict(x)[0], 0)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "38f7f7d0-d22c-4282-92e5-9666a7b8535d", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"# test it\n", |
|
"TestRunner(linear_regression_nlp_predictor).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "b623079e-54fa-418f-b209-7d54ebbcc23a", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"import numpy as np\n", |
|
"from sklearn.linear_model import LinearRegression\n", |
|
"from gensim.models import Word2Vec\n", |
|
"from gensim.utils import simple_preprocess\n", |
|
"from sklearn.metrics import mean_squared_error, r2_score\n", |
|
"\n", |
|
"np.random.seed(42)\n", |
|
"\n", |
|
"# Preprocess the documents\n", |
|
"processed_docs = [simple_preprocess(doc) for doc in documents]\n", |
|
"\n", |
|
"# Train Word2Vec model\n", |
|
"w2v_model = Word2Vec(sentences=processed_docs, vector_size=300, window=5, min_count=1, workers=8)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "3de4efc7-68a6-4443-b9fd-70ee9d722362", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def document_vector(doc):\n", |
|
" doc_words = simple_preprocess(doc)\n", |
|
" word_vectors = [w2v_model.wv[word] for word in doc_words if word in w2v_model.wv]\n", |
|
" return np.mean(word_vectors, axis=0) if word_vectors else np.zeros(w2v_model.vector_size)\n", |
|
"\n", |
|
"# Create feature matrix\n", |
|
"X = np.array([document_vector(doc) for doc in documents])" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "9f05eeec-dab8-4007-8e8c-dcf4175b8861", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"word2vec_lr_regressor = LinearRegression()\n", |
|
"word2vec_lr_regressor.fit(X, prices)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "e43d3fb9-e013-4573-90bf-9a522132b555", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def word2vec_lr_predictor(item):\n", |
|
" doc = item.test_prompt()\n", |
|
" doc_vector = document_vector(doc)\n", |
|
" return max(0, word2vec_lr_regressor.predict([doc_vector])[0])" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "6740319d-5c8e-4125-9106-97e2e8ab72c7", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"TestRunner(word2vec_lr_predictor).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "fefaa7ff-23e8-4834-9c13-a8c074a2b2ed", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"from sklearn.ensemble import RandomForestRegressor\n", |
|
"\n", |
|
"rf_model = RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=8)\n", |
|
"rf_model.fit(X, prices)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "aec04c82-0d5d-4d2b-9c3c-f619a5dc766b", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def random_forest_predictor(item):\n", |
|
" doc = item.test_prompt()\n", |
|
" doc_vector = document_vector(doc)\n", |
|
" return max(0, rf_model.predict([doc_vector])[0])" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "aa836ee2-f4ff-4e03-a0e4-c7faa4d99ed5", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"TestRunner(random_forest_predictor).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "f4ff4e3c-5abc-4647-a637-43e1ff05148f", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"from sklearn.svm import SVR\n", |
|
"np.random.seed(42)\n", |
|
"\n", |
|
"svr_regressor = SVR(kernel='linear')\n", |
|
"svr_regressor.fit(X[:100_000], prices[:100_000])" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "3d026284-a6ba-44e8-85aa-dad86a094e85", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def svr_predictor(item):\n", |
|
" np.random.seed(42)\n", |
|
" doc = item.test_prompt()\n", |
|
" doc_vector = document_vector(doc)\n", |
|
" return max(float(svr_regressor.predict([doc_vector])[0]),0)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "d47bc121-9717-4d42-b1f1-e9f54dcf7fa6", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"TestRunner(svr_predictor).run()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "b6a41596-9065-414f-9c45-4a4b18494e13", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [] |
|
} |
|
], |
|
"metadata": { |
|
"kernelspec": { |
|
"display_name": "Python 3 (ipykernel)", |
|
"language": "python", |
|
"name": "python3" |
|
}, |
|
"language_info": { |
|
"codemirror_mode": { |
|
"name": "ipython", |
|
"version": 3 |
|
}, |
|
"file_extension": ".py", |
|
"mimetype": "text/x-python", |
|
"name": "python", |
|
"nbconvert_exporter": "python", |
|
"pygments_lexer": "ipython3", |
|
"version": "3.11.10" |
|
} |
|
}, |
|
"nbformat": 4, |
|
"nbformat_minor": 5 |
|
}
|
|
|