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

5 Paradoxes in Statistics Every Data Scientist Should be Familiar With
Latest   Machine Learning

5 Paradoxes in Statistics Every Data Scientist Should be Familiar With

Last Updated on July 17, 2023 by Editorial Team

Author(s): Simranjeet Singh

Originally published on Towards AI.

Introduction

Statistics is an essential part of data science, and it provides us with various tools and techniques to analyze and understand data. However, sometimes statistical results can be counterintuitive or even paradoxical, leading to confusion and misinterpretation. In this blog, we will explore five statistical paradoxes that every data scientist should be familiar with. We will explain what each paradox is, why it occurs, and how to avoid common pitfalls associated with it.

U+1F449 Before Starting the Blog, Please Subscribe to my YouTube Channel and Follow Me on Instagram U+1F447
U+1F4F7 YouTube — https://bit.ly/38gLfTo
U+1F4C3 Instagram — https://bit.ly/3VbKHWh

U+1F449 Do Donate U+1F4B0 or Give me Tip U+1F4B5 If you really like my blogs, Because I am from India and not able to get into Medium Partner Program. Click Here to Donate or Tip U+1F4B0 — https://bit.ly/3oTHiz3

Fig.1–5 Paradoxes in Statistics

By the end of this blog, you will have a better understanding of some of the strange and unexpected outcomes that can arise from statistical analysis, and be better equipped to handle them in your work.

Table of Contents

  1. Accuracy Paradox
  2. False Positive Paradox
  3. Gambler’s Fallacy
  4. Simpson’s Paradox
  5. Berkson’s Paradox
  6. Conclusion

Accuracy Paradox

The Accuracy Paradox refers to the situation where a high level of accuracy can be achieved even when a model is not predictive. It can occur when there is an imbalance in the distribution of classes in the dataset. For example, consider a dataset where 90% of the observations belong to one class and 10% to another class. A model that predicts the majority class for all observations will achieve an accuracy of 90%, even though it is not really predicting anything.

Here is an example in Python to illustrate the concept:

import numpy as np
from sklearn.metrics import accuracy_score

# create imbalanced dataset
y_true = np.array([0] * 900 + [1] * 100)
y_pred = np.zeros(1000)

# calculate accuracy
accuracy = accuracy_score(y_true, y_pred)
print('Accuracy:', accuracy)

In this example, we create an imbalanced dataset with 900 observations in one class and 100 in another class. We then create a model that predicts the majority class (0) for all observations. Despite not actually predicting anything, the model achieves an accuracy of 90%.

A real-world example of the Accuracy Paradox can be seen in medical testing. Consider a rare disease that affects only 1 in 100,000 people. If a test is created that is 99.9% accurate in detecting the disease, but is given to a population where only 0.1% of people have the disease, the test will have a high accuracy rate of 99.9%. However, it will result in a large number of false positives, meaning many healthy people will be incorrectly diagnosed with the disease.

Evaluating classification tasks using accuracy may not be the best choice. Precision and recall are better alternatives. These metrics are related to the False Positive Paradox, which will be discussed in the following section.

False Positive Paradox

The False Positive Paradox occurs when the accuracy of a model is high but the false positive rate is also high. In other words, the model may classify a large number of instances as positive when they are actually negative. This paradox can lead to incorrect conclusions and decision-making.

Simple Example of Python explaining the False Positive Paradox:

import pandas as pd
import numpy as np

# Define variables
normal_count = 9999
fraud_count = 1
false_positives = 499.95
false_negatives = 0

# Calculate precision
precision = fraud_count / (fraud_count + false_positives)
print(f"Precision: {precision:.2f}")

# Calculate recall
recall = fraud_count / (fraud_count + false_negatives)
print(f"Recall: {recall:.2f}")

# Calculate accuracy
true_negatives = normal_count - false_positives
accuracy = (true_negatives + fraud_count) / (normal_count + fraud_count)
print(f"Accuracy: {accuracy:.2f}")

Output:
Precision: 0.00
Recall: 1.00
Accuracy: 0.95

For example, imagine a medical test for a disease that only affects 1% of the population. If the test is 99% accurate, then 99% of the time it correctly identifies the presence or absence of the disease. However, if 1000 people are tested, 10 people will test positive for the disease even though only 1 actually has it. This means that a positive test result is more likely to be a false positive than a true positive.

Here’s an example of Python code for the False Positive Paradox:

from sklearn.metrics import confusion_matrix
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

# generate a binary classification dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=42)

# split the dataset into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# train a logistic regression model
model = LogisticRegression(random_state=42)
model.fit(X_train, y_train)

# predict on test set and get the confusion matrix
y_pred = model.predict(X_test)
tn, fp, fn, tp = confusion_matrix(y_test, y_pred).ravel()

# calculate the accuracy, precision, and recall
accuracy = (tp + tn) / (tp + tn + fp + fn)
precision = tp / (tp + fp)
recall = tp / (tp + fn)

print(f"Accuracy: {accuracy:.2f}")
print(f"Precision: {precision:.2f}")
print(f"Recall: {recall:.2f}")

Output:
Accuracy: 0.79
Precision: 0.82
Recall: 0.75

In such cases, precision and recall are better measures to evaluate the model’s performance. Precision measures the proportion of true positives among all positive classifications, while recall measures the proportion of true positives among all actual positive instances. These measures can help avoid the False Positive Paradox and provide a more accurate evaluation of the model’s performance.

Gambler’s Fallacy

The Gambler’s Fallacy is the belief that past events can influence the probability of future events in a random process. For example, in a game of roulette, some players believe that if the ball has landed on black for several consecutive spins, the chances of it landing on red next time are higher, even though the outcome is still equally random.

Fig.2 — Gambler’s Fallacy

To illustrate this with a python example, we can simulate flipping a fair coin using the numpy module:

import numpy as np

# Simulate flipping a coin 10 times
results = np.random.randint(0, 2, size=10)
print(f"Coin flips: {results}")

# Count the number of consecutive heads or tails
consecutive = 0
for i in range(1, len(results)):
if results[i] == results[i-1]:
consecutive += 1
else:
consecutive = 0

# Print the result
if consecutive > 0:
print(f"Number of consecutive flips: {consecutive + 1}")
else:
print("No consecutive flips")

Output:
Coin flips: [0 1 0 0 0 0 0 0 1 0]
No consecutive flips

In the above example, the code simulates flipping a coin 10 times and then counts the number of consecutive heads or tails. The Gambler’s Fallacy would suggest that if there have been several heads in a row, the next flip is more likely to be tails, and vice versa. However, in reality, each flip of the coin is independent and has an equal chance of resulting in heads or tails.

A real-world example of the Gambler’s Fallacy could be seen in the stock market. Some investors may believe that if a stock has been consistently rising in value for several days, it is more likely to fall soon, even though market movements are still inherently unpredictable and subject to a range of factors.

Simpson’s Paradox

Simpson’s Paradox is a statistical phenomenon that occurs when a trend appears in a small dataset, but the trend disappears or reverses when the dataset is divided into subgroups. This can lead to incorrect conclusions if the data is not analyzed correctly.

Fig.3 — Simpsons Paradox

Let’s consider an example to understand this phenomenon better. Suppose we want to compare the admission rates of male and female applicants to a university. We have data for two departments: department A and department B.

Fig.4 — Example of Admission Rates of Male and Female Applicants

In the above table, the combined admission rate for male and female applicants is 50%. However, when we analyze the data by department, we see that in each department, the admission rate for women is higher than the admission rate for men. This seems counterintuitive since the overall admission rate is higher for men.

This paradox occurs because the number of applicants and admission rates are different for each department. Department A has a higher admission rate overall, but a lower percentage of female applicants. Department B has a lower admission rate overall but a higher percentage of female applicants.

In Python, we can replicate this example using the following code:

import pandas as pd

# Create a dataframe
df = pd.DataFrame({'Department': ['A', 'A', 'B', 'B'],
'Gender': ['Male', 'Female', 'Male', 'Female'],
'Applicants': [100, 80, 500, 400],
'Admitted': [60, 40, 40, 70]})

# Calculate admission rates
df['Admission Rate'] = df['Admitted'] / df['Applicants'] * 100

# Display the dataframe
print(df)

# Calculate overall admission rate
overall_rate = df['Admitted'].sum() / df['Applicants'].sum() * 100
print(f"Overall Admission Rate: {overall_rate:.2f}%")

# Calculate admission rates by department and gender
department_rates = df.groupby(['Department', 'Gender'])['Admission Rate'].mean()
print(department_rates)

Ouput:
Department Gender Applicants Admitted Admission Rate
0 A Male 100 60 60.0
1 A Female 80 40 50.0
2 B Male 500 40 8.0
3 B Female 400 70 17.5
Overall Admission Rate: 19.44%
Department Gender
A Female 50.0
Male 60.0
B Female 17.5
Male 8.0
Name: Admission Rate, dtype: float64

In the above code, we create a dataframe with the same data as in the table above. We then calculate the admission rates and display the dataframe. Next, we calculate the overall admission rate, which is 19.44%. Finally, we group the data by department and gender and calculate the admission rates for each subgroup. We see that the admission rate for women is higher in both departments, even though the overall admission rate is higher for men. This is an example of Simpson’s Paradox.

Berkson’s Paradox

Berkson’s paradox is a statistical phenomenon where a negative correlation appears between two independent variables or when there is a negative correlation between two variables, but a positive correlation appears when the data is split into subgroups or if that there is no actual correlation between them. This paradox occurs when both independent variables have a common influence or cause that is not included in the analysis.

To explain this paradox using the iris dataset, let’s consider the sepal length and width as the two variables of interest. We can calculate the correlation coefficient between these two variables using the corr() method in pandas:

import pandas as pd
import seaborn as sns

iris = sns.load_dataset('iris')

correlation = iris['sepal_length'].corr(iris['sepal_width'])
print('Correlation between sepal length and width:', correlation)

Correlation between sepal length and width: -0.11756978413300208

As we can see, there is a negative correlation between sepal length and width in the overall dataset.

However, if we split the dataset by species and calculate the correlation coefficient for each species separately, we might get a different result. For example, if we only consider the setosa species, we get a positive correlation:

setosa = iris[iris['species'] == 'setosa']
correlation_setosa = setosa['sepal_length'].corr(setosa['sepal_width'])
print('Correlation between sepal length and width for setosa:', correlation_setosa)

Correlation between sepal length and width for setosa: 0.7425466856651597

This means that there is a positive correlation between sepal length and width for the setosa species, which is opposite to the overall negative correlation.

This paradox occurs because the setosa species has a smaller range of values for both sepal length and width compared to the other species. As a result, when we only consider the setosa species, the negative correlation within the overall dataset is overshadowed by the positive correlation within the setosa species.

Conclusion

In conclusion, understanding statistical paradoxes is crucial for data scientists as they can help in avoiding common mistakes and biases in data analysis.

  1. The Accuracy Paradox teaches us that accuracy alone is not enough to evaluate classification tasks, and precision and recall are more informative.
  2. The False Positive Paradox highlights the importance of understanding the cost of false positives in relation to the cost of false negatives.
  3. The Gambler’s Fallacy reminds us that each event is independent and past outcomes do not affect future ones.
  4. The Simpson’s Paradox shows how aggregating data can obscure relationships between variables and lead to incorrect conclusions.
  5. Finally, Berkson’s Paradox shows how sampling bias can occur when selecting non-random samples from a population.
Fig.5— 5 Paradoxes in Statistics

Being aware of these paradoxes can help data scientists make more accurate and informed decisions in their work.

If you like the article and would like to support me make sure to:

U+1F44F Clap for the story (100 Claps) and follow me U+1F449U+1F3FBSimranjeet Singh

U+1F4D1 View more content on my Medium Profile

U+1F514 Follow Me: LinkedIn U+007C Medium U+007C GitHub U+007C Twitter U+007C Telegram

U+1F680 Help me in reaching to a wider audience by sharing my content with your friends and colleagues.

U+1F393 If you want to start a career in Data Science and Artificial Intelligence and you do not know how? I offer data science and AI mentoring sessions and long-term career guidance.

U+1F4C5 Consultation or Career Guidance

U+1F4C5 1:1 Mentorship — About Python, Data Science, and Machine Learning

Book your Appointment

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'); -->