Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Read by thought-leaders and decision-makers around the world. Phone Number: +1-650-246-9381 Email: pub@towardsai.net
228 Park Avenue South New York, NY 10003 United States
Website: Publisher: https://towardsai.net/#publisher Diversity Policy: https://towardsai.net/about Ethics Policy: https://towardsai.net/about Masthead: https://towardsai.net/about
Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Founders: Roberto Iriondo, , Job Title: Co-founder and Advisor Works for: Towards AI, Inc. Follow Roberto: X, LinkedIn, GitHub, Google Scholar, Towards AI Profile, Medium, ML@CMU, FreeCodeCamp, Crunchbase, Bloomberg, Roberto Iriondo, Generative AI Lab, Generative AI Lab Denis Piffaretti, Job Title: Co-founder Works for: Towards AI, Inc. Louie Peters, Job Title: Co-founder Works for: Towards AI, Inc. Louis-François Bouchard, Job Title: Co-founder Works for: Towards AI, Inc. Cover:
Towards AI Cover
Logo:
Towards AI Logo
Areas Served: Worldwide Alternate Name: Towards AI, Inc. Alternate Name: Towards AI Co. Alternate Name: towards ai Alternate Name: towardsai Alternate Name: towards.ai Alternate Name: tai Alternate Name: toward ai Alternate Name: toward.ai Alternate Name: Towards AI, Inc. Alternate Name: towardsai.net Alternate Name: pub.towardsai.net
5 stars – based on 497 reviews

Frequently Used, Contextual References

TODO: Remember to copy unique IDs whenever it needs used. i.e., URL: 304b2e42315e

Resources

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

Publication

Predict Health Outcomes of Horses — A Classification Project in Machine Learning
Data Science   Latest   Machine Learning

Predict Health Outcomes of Horses — A Classification Project in Machine Learning

Last Updated on February 27, 2024 by Editorial Team

Author(s): Kamireddy Mahendra

Originally published on Towards AI.

Keeping a horse healthy is like maintaining a prized possession; it’s the key to enjoying countless joyful moments together.

Predict Health Outcomes of Horses — A Classification Project in Machine Learning
Photo by Helena Lopes on Unsplash

Before getting into Machine Learning Project Series — Part II, Click Here to see Machine Learning Project Series — Part I.

Table of Contents

1. Introduction

Project Objectives or Goals

Dataset features Description

Summary of the Approach

2. Data Collection Exploration and Analysis

Data Collection

Visualization of data and summary of observations

3. Data Pre-Processing

Handling Missing Values

Encoding Categorical Variables

Feature Scaling

Data Splitting (Training and Validation)

4. Model Development & Model Evaluation

Algorithm Selection

Model Training

Model Evaluation Metrics

1. Introduction

Project Objective or Goal:
Given various medical indicators of horses, we are going to predict the health outcomes of horses based on the given indicators.
Evaluation:
Submissions are evaluated on micro-averaged F1-Score between predicted and actual values.

Dataset features Description:

Given a comprehensive set of features for diagnosing and assessing the health condition of horses.

  1. ‘id’: Unique identifier for each horse.
  2. ‘surgery’: Whether the horse underwent surgery.
  3. ‘age’: Age of the horse.
  4. ‘hospital number’: Identifier for the hospital or facility where the horse was treated.
  5. ‘rectal temp’: Rectal temperature of the horse.
  6. ‘pulse’: Pulse rate of the horse.
  7. ‘respiratory rate’: Respiratory rate of the horse.
  8. ‘temp of extremities’: Temperature of the horse’s extremities.
  9. ‘peripheral pulse’: Peripheral pulse quality.
  10. ‘mucous membrane’: Condition of the horse’s mucous membranes.
  11. ‘capillary refill time’: Time taken for capillaries to refill after pressure.
  12. ‘pain’: Pain level experienced by the horse.
  13. ‘peristalsis’: Peristalsis quality.
  14. ‘abdominal distention’: Degree of abdominal distention.
  15. ‘nasogastric tube’: Presence of a nasogastric tube.
  16. ‘nasogastric reflux’: Presence of nasogastric reflux.
  17. ‘nasogastric reflux ph’: pH level of nasogastric reflux.
  18. ‘rectal exam feces’: Findings from rectal examination related to feces.
  19. ‘abdomen’: Condition of the horse’s abdomen.
  20. ‘packed cell volume’: Packed cell volume in the horse’s blood.
  21. ‘total protein’: Total protein level in the horse’s blood.
  22. ‘abdomo appearance’: Appearance of the abdomen.
  23. ‘abdomo protein’: Protein level in the abdominal fluid.
  24. ‘surgical lesion’: Presence of surgical lesions.
  25. ‘lesion_1’, ‘lesion_2’, ‘lesion_3’: Details about the lesions.
  26. ‘cp data’: Possibly a binary indicator or categorical variable related to the presence of certain clinical pathology data.
  27. ‘outcome’: Outcome of the horse’s health condition.

Summary of the Approach:
Start with collecting and pre-processing data, selecting features, and training classification models, then Evaluating those model performances.

2. Data Collection & Exploration Data Analysis

Data Collection
Data was collected from the Kaggle input directory, and exploratory data analysis was performed using pandas and matplotlib python libraries.

Here I started building all actions using Python scripts and their libraries. You can see the code as mentioned below to gather data and to do exploratory data analysis.

import numpy as np
import pandas as pd
import os
for dirname, _, filenames in os.walk('/kaggle/input'):
for filename in filenames:
print(os.path.join(dirname, filename))
traindata = pd.read_csv('/kaggle/input/playground-series-s3e22/train.csv')
testdata = pd.read_csv('/kaggle/input/playground-series-s3e22/test.csv')
sample_submissiondata = pd.read_csv('/kaggle/input/playground-series-s3e22/sample_submission.csv')
print(traindata.shape, testdata.shape, sample_submissiondata.shape)
traindata.columns
traindata.info()
traindata.drop('id',axis=1, inplace=True)
targetdata=traindata['outcome']
targetdata=targetdata.map({'died':0,'euthanized':1,'lived':2})
traindata.describe()

Visualization of data and summary of observations:
We can use different plots to infer insights from the data that we collected and can start thinking about what the predictions can be, and we can start intuition that particular things will be approximate predictions.

columns_cat = [column for column in traindata.columns]

def countplot(dframe,cols,numsofcols,hue):
numsofrows = (len(cols) - 1) // numsofcols + 1
fig, ax = plt.subplots(numsofrows, numsofcols, figsize=(17, 4 * numsofrows))
ax = ax.flatten()
for i, column in enumerate(cols):
sns.countplot(data=dframe, x=column, ax=ax[i],hue=hue)

ax[i].set_title(f'{column} Counts', fontsize=16)
ax[i].set_xlabel(None, fontsize=15)
ax[i].set_ylabel(None, fontsize=15)
ax[i].tick_params(axis='x', rotation=12)

for p in ax[i].patches:
value = int(p.get_height())
ax[i].annotate(f'{value:.0f}', (p.get_x() + p.get_width() / 2, p.get_height()),
ha='center', va='bottom', fontsize=9)
ylim_top = ax[i].get_ylim()[1]
ax[i].set_ylim(top=ylim_top * 1.1)
for i in range(len(cols), len(ax)):
ax[i].axis('off')

# fig.suptitle(plotname, fontsize=25, fontweight='bold')
plt.tight_layout()
plt.show()
image by author Kamireddy Mahendra.

From the above plots, we can infer many insights. few of them are mentioned below.

  • There are three categories of outcomes lived, died, and euthanized. As we can observe, the number of deaths and deaths are almost the same and high in cases, even surgeries are done as compared to not taking any surgery.
  • The number of adult horses is more than the number of young horses, and therefore, the outcomes also proportion to their count of ages.
  • There are more deaths of young horses percentage as we can observe from the plots.
  • We can also observe horses' outcomes in different temperatures. As we can observe, there are more likely to live horses where the temperature is normal and cool, but in cool temperatures, there are more horses that are dead.
  • We can also observe that as pulse count is normal and reduced ones are more horse and their lived and death ratios are almost similar and high as in reduced pulse counts and less in deaths in normal pulse counts.

Similarly, there are many other features that affect the prediction of the health of horses, as you can see in the plots below.

image by author kamireddy Mahendra
image by author kamireddy Mahendra
image by author Kamireddy Mahendra

3. Data Pre-Processing

In the domain of machine learning, data cleaning stands as a pivotal step wherein we undertake various actions to ensure our dataset is free from anomalies, thereby facilitating the extraction of meaningful insights and enabling accurate predictions.

Handling Missing Values:

  • Ensuring the absence of missing values in our dataset before model fitting is paramount for accurate predictions. It’s incumbent upon us to meticulously examine our data for null values and responsibly address them through techniques such as imputation or elimination.
  • While dropping null values may impact the accuracy of our results, the decision hinges on factors such as the number of missing values and their significance in the dataset, thereby necessitating thoughtful consideration akin to feature engineering or selection in machine learning.
traindata.isnull().sum()
image by author kamireddy Mahendra

Encoding Categorical Variables:
Encoding categorical variables is a crucial pre-processing step in machine learning when working with datasets that contain non-numeric or categorical data.

Categorical variables represent qualitative characteristics or groups that do not have a natural ordering, such as colors, types of objects, or categories of data.
Feature Scaling:
Feature scaling is a pre-processing technique used in machine learning to standardize or normalize the range of independent variables or features in a dataset. It is particularly important when working with algorithms sensitive to the scale of input features.

The main goal of feature scaling is to bring all features to a similar scale without distorting the differences in the range of values. This helps in improving the performance and convergence of machine learning algorithms. Here I just considered numerical features for the first iteration.

numerical_features = []

for column in traindata.columns:

if pd.api.types.is_numeric_dtype(traindata[column]):

numerical_features.append(column)

features=numerical_features
xtrain=pd.get_dummies(xtrain)
xval=pd.get_dummies (xval)
print (xtrain.shape, xval.shape, ytrain.shape, yval.shape)

Data Splitting (Training and Validation):

  • To design efficient ML models, we need to train the model on a particular portion of data and then will have to check how our designed model works on another data set, and that is what we call validation data.
  • Training a model of one data and testing the model with the same data will give us a 100% accurate model, and that is a blender since we don’t know what kind of data we need to predict, so it is recommended to split our data into train and validation data for testing our model.
xtrain, xval, ytrain, yval = train_test_split(traindata[features], targetdata, test_size=0.1, random_state=1)
print (xtrain.shape, xval.shape, ytrain.shape, yval.shape)

4. Model Development & Model Evaluation

Algorithm Selection:

Algorithm selection is a crucial aspect of the machine learning workflow, involving the careful consideration and choice of the most appropriate algorithm for a given problem. This process is essential because different algorithms have varying strengths, weaknesses, and suitability for specific types of data and tasks.

Here’s some information about algorithm selection:

  1. Understanding Algorithm Types: Machine learning algorithms can be broadly categorized into various types, such as supervised learning, unsupervised learning, and reinforcement learning. Within each type, there are further subcategories, including classification, regression, clustering, and dimensionality reduction algorithms.
  2. Matching Algorithm to Task: The first step in algorithm selection is understanding the nature of the task at hand. For example, if the task involves predicting a categorical outcome, classification algorithms such as logistic regression, decision trees, or support vector machines may be suitable. If the task involves predicting a continuous outcome, regression algorithms like linear regression or random forests might be more appropriate.
  3. Consideration of Data Characteristics: The characteristics of the dataset, such as size, complexity, and feature types, play a significant role in algorithm selection. Some algorithms are better suited for large datasets, while others perform well with high-dimensional data or data with non-linear relationships.
  4. Performance Metrics: It’s essential to consider the performance metrics relevant to the task when selecting an algorithm. For example, if the goal is to minimize prediction errors, algorithms that optimize for accuracy, precision, recall, or F1 score may be preferred. In contrast, for unsupervised tasks like clustering, metrics such as silhouette score or Davies–Bouldin index may be used.
  5. Model Interpretability: Depending on the application, the interpretability of the model may also be a crucial factor. Some algorithms, like decision trees or linear models, offer interpretability by providing insights into feature importance or coefficients. In contrast, other algorithms, such as neural networks or ensemble methods, may sacrifice interpretability for predictive performance.
  6. Cross-Validation and Evaluation: Before finalizing the algorithm selection, it’s essential to perform thorough evaluation and validation using techniques like cross-validation to ensure the chosen algorithm generalizes well to unseen data and performs consistently across different subsets of the dataset.

In summary, algorithm selection involves a comprehensive assessment of the task requirements, data characteristics, performance metrics, and model interpretability to choose the most suitable algorithm that aligns with the objectives of the machine learning project.

Here I considered the Random forest algorithm for predictions.

model=RandomForestClassifier(n_estimators=100, max_depth=7, random_state=1 )

Model Training:
In this step we are going to train the model by fitting the train data to model and predict the results.

model=model.fit(xtrain, ytrain)
pred=model.predict(xval)

Model Evaluation Metrics:
Due to classification problems, we will check accuracy, precision, recall, and f1scores. Here it is asked to check especially f1score. So we will find f1score in this problem.

# precision = precision_score(yval, pred)
# recall = recall_score(yval, pred)
from sklearn.metrics import f1_score

# Assuming y_true and y_pred are your true and predicted labels
f1 = f1_score(yval, predi, average='micro')

testdata = pd.read_csv('/kaggle/input/playground-series-s3e22/test.csv')
testdf=testdata[features]
testdf.shape
testdf.isnull().sum()
testdf=pd.get_dummies(testdf)
modelpred=model.predict(testdf)
modelpred
mapping = {0: 'died', 1: 'euthanized', 2: 'lived'}

# Convert numerical labels to categorical labels
prediction = [mapping[i] for i in modelpred ]
prediction=np.array(prediction)
prediction=pd.DataFrame({'id': testdata['id'], 'outcome':prediction})
prediction.to_csv('submission1.csv', index=False)

This is the project series from the Kaggle playground series. Click Here to see the details on Kaggle.

Kindly support me by clapping or by giving feedback, which helps me to work on delivering quality content and gives me the motivation to move forward to share more content.

Thank you 🙂

Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI

Feedback ↓

Sign Up for the Course
`; } else { console.error('Element with id="subscribe" not found within the page with class "home".'); } } }); // Remove duplicate text from articles /* Backup: 09/11/24 function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag elements.forEach(el => { const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 2) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); */ // Remove duplicate text from articles function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag // List of classes to be excluded const excludedClasses = ['medium-author', 'post-widget-title']; elements.forEach(el => { // Skip elements with any of the excluded classes if (excludedClasses.some(cls => el.classList.contains(cls))) { return; // Skip this element if it has any of the excluded classes } const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 10) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); //Remove unnecessary text in blog excerpts document.querySelectorAll('.blog p').forEach(function(paragraph) { // Replace the unwanted text pattern for each paragraph paragraph.innerHTML = paragraph.innerHTML .replace(/Author\(s\): [\w\s]+ Originally published on Towards AI\.?/g, '') // Removes 'Author(s): XYZ Originally published on Towards AI' .replace(/This member-only story is on us\. Upgrade to access all of Medium\./g, ''); // Removes 'This member-only story...' }); //Load ionic icons and cache them if ('localStorage' in window && window['localStorage'] !== null) { const cssLink = 'https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css'; const storedCss = localStorage.getItem('ionicons'); if (storedCss) { loadCSS(storedCss); } else { fetch(cssLink).then(response => response.text()).then(css => { localStorage.setItem('ionicons', css); loadCSS(css); }); } } function loadCSS(css) { const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); } //Remove elements from imported content automatically function removeStrongFromHeadings() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, h6, span'); elements.forEach(el => { const strongTags = el.querySelectorAll('strong'); strongTags.forEach(strongTag => { while (strongTag.firstChild) { strongTag.parentNode.insertBefore(strongTag.firstChild, strongTag); } strongTag.remove(); }); }); } removeStrongFromHeadings(); "use strict"; window.onload = () => { /* //This is an object for each category of subjects and in that there are kewords and link to the keywods let keywordsAndLinks = { //you can add more categories and define their keywords and add a link ds: { keywords: [ //you can add more keywords here they are detected and replaced with achor tag automatically 'data science', 'Data science', 'Data Science', 'data Science', 'DATA SCIENCE', ], //we will replace the linktext with the keyword later on in the code //you can easily change links for each category here //(include class="ml-link" and linktext) link: 'linktext', }, ml: { keywords: [ //Add more keywords 'machine learning', 'Machine learning', 'Machine Learning', 'machine Learning', 'MACHINE LEARNING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ai: { keywords: [ 'artificial intelligence', 'Artificial intelligence', 'Artificial Intelligence', 'artificial Intelligence', 'ARTIFICIAL INTELLIGENCE', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, nl: { keywords: [ 'NLP', 'nlp', 'natural language processing', 'Natural Language Processing', 'NATURAL LANGUAGE PROCESSING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, des: { keywords: [ 'data engineering services', 'Data Engineering Services', 'DATA ENGINEERING SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, td: { keywords: [ 'training data', 'Training Data', 'training Data', 'TRAINING DATA', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ias: { keywords: [ 'image annotation services', 'Image annotation services', 'image Annotation services', 'image annotation Services', 'Image Annotation Services', 'IMAGE ANNOTATION SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, l: { keywords: [ 'labeling', 'labelling', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, pbp: { keywords: [ 'previous blog posts', 'previous blog post', 'latest', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, mlc: { keywords: [ 'machine learning course', 'machine learning class', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, }; //Articles to skip let articleIdsToSkip = ['post-2651', 'post-3414', 'post-3540']; //keyword with its related achortag is recieved here along with article id function searchAndReplace(keyword, anchorTag, articleId) { //selects the h3 h4 and p tags that are inside of the article let content = document.querySelector(`#${articleId} .entry-content`); //replaces the "linktext" in achor tag with the keyword that will be searched and replaced let newLink = anchorTag.replace('linktext', keyword); //regular expression to search keyword var re = new RegExp('(' + keyword + ')', 'g'); //this replaces the keywords in h3 h4 and p tags content with achor tag content.innerHTML = content.innerHTML.replace(re, newLink); } function articleFilter(keyword, anchorTag) { //gets all the articles var articles = document.querySelectorAll('article'); //if its zero or less then there are no articles if (articles.length > 0) { for (let x = 0; x < articles.length; x++) { //articles to skip is an array in which there are ids of articles which should not get effected //if the current article's id is also in that array then do not call search and replace with its data if (!articleIdsToSkip.includes(articles[x].id)) { //search and replace is called on articles which should get effected searchAndReplace(keyword, anchorTag, articles[x].id, key); } else { console.log( `Cannot replace the keywords in article with id ${articles[x].id}` ); } } } else { console.log('No articles found.'); } } let key; //not part of script, added for (key in keywordsAndLinks) { //key is the object in keywords and links object i.e ds, ml, ai for (let i = 0; i < keywordsAndLinks[key].keywords.length; i++) { //keywordsAndLinks[key].keywords is the array of keywords for key (ds, ml, ai) //keywordsAndLinks[key].keywords[i] is the keyword and keywordsAndLinks[key].link is the link //keyword and link is sent to searchreplace where it is then replaced using regular expression and replace function articleFilter( keywordsAndLinks[key].keywords[i], keywordsAndLinks[key].link ); } } function cleanLinks() { // (making smal functions is for DRY) this function gets the links and only keeps the first 2 and from the rest removes the anchor tag and replaces it with its text function removeLinks(links) { if (links.length > 1) { for (let i = 2; i < links.length; i++) { links[i].outerHTML = links[i].textContent; } } } //arrays which will contain all the achor tags found with the class (ds-link, ml-link, ailink) in each article inserted using search and replace let dslinks; let mllinks; let ailinks; let nllinks; let deslinks; let tdlinks; let iaslinks; let llinks; let pbplinks; let mlclinks; const content = document.querySelectorAll('article'); //all articles content.forEach((c) => { //to skip the articles with specific ids if (!articleIdsToSkip.includes(c.id)) { //getting all the anchor tags in each article one by one dslinks = document.querySelectorAll(`#${c.id} .entry-content a.ds-link`); mllinks = document.querySelectorAll(`#${c.id} .entry-content a.ml-link`); ailinks = document.querySelectorAll(`#${c.id} .entry-content a.ai-link`); nllinks = document.querySelectorAll(`#${c.id} .entry-content a.ntrl-link`); deslinks = document.querySelectorAll(`#${c.id} .entry-content a.des-link`); tdlinks = document.querySelectorAll(`#${c.id} .entry-content a.td-link`); iaslinks = document.querySelectorAll(`#${c.id} .entry-content a.ias-link`); mlclinks = document.querySelectorAll(`#${c.id} .entry-content a.mlc-link`); llinks = document.querySelectorAll(`#${c.id} .entry-content a.l-link`); pbplinks = document.querySelectorAll(`#${c.id} .entry-content a.pbp-link`); //sending the anchor tags list of each article one by one to remove extra anchor tags removeLinks(dslinks); removeLinks(mllinks); removeLinks(ailinks); removeLinks(nllinks); removeLinks(deslinks); removeLinks(tdlinks); removeLinks(iaslinks); removeLinks(mlclinks); removeLinks(llinks); removeLinks(pbplinks); } }); } //To remove extra achor tags of each category (ds, ml, ai) and only have 2 of each category per article cleanLinks(); */ //Recommended Articles var ctaLinks = [ /* ' ' + '

Subscribe to our AI newsletter!

' + */ '

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

'+ '

Towards AI has published Building LLMs for Production—our 470+ page guide to mastering LLMs with practical projects and expert insights!

' + '
' + '' + '' + '

Note: Content contains the views of the contributing authors and not Towards AI.
Disclosure: This website may contain sponsored content and affiliate links.

' + 'Discover Your Dream AI Career at Towards AI Jobs' + '

Towards AI has built a jobs board tailored specifically to Machine Learning and Data Science Jobs and Skills. Our software searches for live AI jobs each hour, labels and categorises them and makes them easily searchable. Explore over 10,000 live jobs today with Towards AI Jobs!

' + '
' + '

🔥 Recommended Articles 🔥

' + 'Why Become an LLM Developer? Launching Towards AI’s New One-Stop Conversion Course'+ 'Testing Launchpad.sh: A Container-based GPU Cloud for Inference and Fine-tuning'+ 'The Top 13 AI-Powered CRM Platforms
' + 'Top 11 AI Call Center Software for 2024
' + 'Learn Prompting 101—Prompt Engineering Course
' + 'Explore Leading Cloud Providers for GPU-Powered LLM Training
' + 'Best AI Communities for Artificial Intelligence Enthusiasts
' + 'Best Workstations for Deep Learning
' + 'Best Laptops for Deep Learning
' + 'Best Machine Learning Books
' + 'Machine Learning Algorithms
' + 'Neural Networks Tutorial
' + 'Best Public Datasets for Machine Learning
' + 'Neural Network Types
' + 'NLP Tutorial
' + 'Best Data Science Books
' + 'Monte Carlo Simulation Tutorial
' + 'Recommender System Tutorial
' + 'Linear Algebra for Deep Learning Tutorial
' + 'Google Colab Introduction
' + 'Decision Trees in Machine Learning
' + 'Principal Component Analysis (PCA) Tutorial
' + 'Linear Regression from Zero to Hero
'+ '

', /* + '

Join thousands of data leaders on the AI newsletter. It’s free, we don’t spam, and we never share your email address. Keep up to date with the latest work in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

',*/ ]; var replaceText = { '': '', '': '', '
': '
' + ctaLinks + '
', }; Object.keys(replaceText).forEach((txtorig) => { //txtorig is the key in replacetext object const txtnew = replaceText[txtorig]; //txtnew is the value of the key in replacetext object let entryFooter = document.querySelector('article .entry-footer'); if (document.querySelectorAll('.single-post').length > 0) { //console.log('Article found.'); const text = entryFooter.innerHTML; entryFooter.innerHTML = text.replace(txtorig, txtnew); } else { // console.log('Article not found.'); //removing comment 09/04/24 } }); var css = document.createElement('style'); css.type = 'text/css'; css.innerHTML = '.post-tags { display:none !important } .article-cta a { font-size: 18px; }'; document.body.appendChild(css); //Extra //This function adds some accessibility needs to the site. function addAlly() { // In this function JQuery is replaced with vanilla javascript functions const imgCont = document.querySelector('.uw-imgcont'); imgCont.setAttribute('aria-label', 'AI news, latest developments'); imgCont.title = 'AI news, latest developments'; imgCont.rel = 'noopener'; document.querySelector('.page-mobile-menu-logo a').title = 'Towards AI Home'; document.querySelector('a.social-link').rel = 'noopener'; document.querySelector('a.uw-text').rel = 'noopener'; document.querySelector('a.uw-w-branding').rel = 'noopener'; document.querySelector('.blog h2.heading').innerHTML = 'Publication'; const popupSearch = document.querySelector$('a.btn-open-popup-search'); popupSearch.setAttribute('role', 'button'); popupSearch.title = 'Search'; const searchClose = document.querySelector('a.popup-search-close'); searchClose.setAttribute('role', 'button'); searchClose.title = 'Close search page'; // document // .querySelector('a.btn-open-popup-search') // .setAttribute( // 'href', // 'https://medium.com/towards-artificial-intelligence/search' // ); } // Add external attributes to 302 sticky and editorial links function extLink() { // Sticky 302 links, this fuction opens the link we send to Medium on a new tab and adds a "noopener" rel to them var stickyLinks = document.querySelectorAll('.grid-item.sticky a'); for (var i = 0; i < stickyLinks.length; i++) { /* stickyLinks[i].setAttribute('target', '_blank'); stickyLinks[i].setAttribute('rel', 'noopener'); */ } // Editorial 302 links, same here var editLinks = document.querySelectorAll( '.grid-item.category-editorial a' ); for (var i = 0; i < editLinks.length; i++) { editLinks[i].setAttribute('target', '_blank'); editLinks[i].setAttribute('rel', 'noopener'); } } // Add current year to copyright notices document.getElementById( 'js-current-year' ).textContent = new Date().getFullYear(); // Call functions after page load extLink(); //addAlly(); setTimeout(function() { //addAlly(); //ideally we should only need to run it once ↑ }, 5000); }; function closeCookieDialog (){ document.getElementById("cookie-consent").style.display = "none"; return false; } setTimeout ( function () { closeCookieDialog(); }, 15000); console.log(`%c 🚀🚀🚀 ███ █████ ███████ █████████ ███████████ █████████████ ███████████████ ███████ ███████ ███████ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ Towards AI is looking for contributors! │ │ Join us in creating awesome AI content. │ │ Let's build the future of AI together → │ │ https://towardsai.net/contribute │ │ │ └───────────────────────────────────────────────────────────────────┘ `, `background: ; color: #00adff; font-size: large`); //Remove latest category across site document.querySelectorAll('a[rel="category tag"]').forEach(function(el) { if (el.textContent.trim() === 'Latest') { // Remove the two consecutive spaces (  ) if (el.nextSibling && el.nextSibling.nodeValue.includes('\u00A0\u00A0')) { el.nextSibling.nodeValue = ''; // Remove the spaces } el.style.display = 'none'; // Hide the element } }); // Add cross-domain measurement, anonymize IPs 'use strict'; //var ga = gtag; ga('config', 'G-9D3HKKFV1Q', 'auto', { /*'allowLinker': true,*/ 'anonymize_ip': true/*, 'linker': { 'domains': [ 'medium.com/towards-artificial-intelligence', 'datasets.towardsai.net', 'rss.towardsai.net', 'feed.towardsai.net', 'contribute.towardsai.net', 'members.towardsai.net', 'pub.towardsai.net', 'news.towardsai.net' ] } */ }); ga('send', 'pageview'); -->