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

Dynamic AI Project Estimation
Latest   Machine Learning

Dynamic AI Project Estimation

Last Updated on August 7, 2023 by Editorial Team

Author(s): Stavros Theocharis

Originally published on Towards AI.

Mastering the Basics for Agile Success

Photo by Tom Parkes on Unsplash

Estimations

Nowadays, estimations are used by almost everyone. The customers need them to both plan and control when they will start using the results of the project. Estimations also help the project manager figure out the scope, total amount of work, and rough cost of each task or the whole project.

Estimation is helpful in a number of situations, such as:

  • Knowing how work is set up: Split a task into several smaller tasks to see the main steps you need to take.
  • Understanding complexity: It’s hard to give an estimation for a complex task by itself, but it’s easier to give an estimate for each part of the work structure. It helps to figure out how hard the job is and how long it will take to finish.
  • Figuring out costs: In most businesses, you won’t be able to start working on a project until you’ve explained and defended how much it will cost and what resources it will need.

What is the reality?

Let’s face a specific truth…. Estimations, in general, don’t work, and this is their biggest issue. Our plans are wrong, not complete, and often have nothing to do with how the work will actually be done. Even if the team has faced a similar task many times, it’s hard for even the most experienced software developers to guess how many hours it will take to finish it. You need relevant samples and a good estimation process to use relative estimates in AI projects. Relevant estimates can, for example, be some simple statistical estimations that take the average length of all relevant tasks done in the past. To make this kind of estimator, we must first gather a set of data.

The trick, as mentioned above, is to break down each task into its own level. Because of this, Scrum says you should use relative story points instead of exact hours. First, your estimations become more accurate at the level of the task, then at the level of the sprint, and finally at the level of the project. If you don’t have any past experience that can help you make relative estimations, you should only make an absolute estimation for the first sprint of the project. From here on, you should use the tasks you’ve already done to make new estimations.

Business and implementation estimations

Estimations can be identified from two different points of view. The first point of view is the implementation part, which is mostly understandable to both project managers and team leaders who are willing to get the project done. At this point, the main goal of the estimations is to better understand the time and money needed to build the final solution.

The second point of view has a lot to do with the business goals of the project. This point of view is usually not visible to the implementation team. Most of the projects usually have a business model to set goals for increased revenue, making customers happy, lowering costs, and so on. When someone is proceeding with the implementation estimations, this business model should be taken into account because it somehow sets the possible restrictions. In AI projects, business estimations can be made by first taking into consideration the business model’s budget constraints and then making a set of business metrics that can be used to calculate how well the project is performing.

You should start by laying out the general steps, and then go into more detail. If you’ve done projects like this before, you can look at their plans to figure out where to start. Collecting and using data from other projects can be a great way to get estimates, so don’t discount your past work.

When your outline has enough information, it’s time to make a proposal for the software architecture. This is a very important step because it’s not always possible or even cost-effective to match up outlines with customer or end-user needs. You should have at least a general idea of what technologies you will use, how they will work with the rest of the customer’s system, and how your solution should be deployed. If there are important non-functional requirements, like being available 24 hours a day, 7 days a week, the software architect should also think about how to make them happen in terms of technology and system design. Putting together a high-level architectural vision will help this outline make sense. If you think the outline needs to be changed, don’t be afraid to do so. Software design is a difficult task that should be done by an experienced engineer. If you don’t have a lot of experience designing software solutions, ask someone on your team for help, or even better, make software design a group effort.

Once the outline is done and you have a plan for the software architecture, you can start estimating the project. Simple statistical methods like the Program Evaluation and Review technique to estimate numbers (PERT) can do the job.

What is PERT?

PERT, known as the Program Evaluation and Review Technique, serves the purpose of estimating the anticipated duration required for task completion. This method proves exceptionally valuable when dealing with scenarios featuring an abundance of unfamiliar variables. Initially crafted within the United States Navy, PERT has since gained substantial traction among numerous project overseers.

Within the framework of PERT, there exists the capability to assign a rating to each task, utilizing a range from 1 to 3. Specifically, this involves contemplating the time investment a task would demand under optimal conditions. Furthermore, the potential for minor technical glitches or complications arising from prerequisites that hinder the progress must also be factored into the developmental trajectory.

Therefore, the primary factors that necessitate computation encompass the following:

  1. Most likely estimation: This entails providing the most precise assessment feasible for the given task.
  2. A pessimistic estimation: This represents the duration required for task completion in the event of adverse circumstances. This category encompasses higher risks, such as unsuccessful experiments and intricate debugging sessions.
  3. An optimistic estimation: This refers to the anticipated time span to accomplish the task should conditions proceed optimally.

PERT estimation = (optimistic estimation + 4 x most likely estimation + pessimistic estimation) / 6

PERT standard deviation = (pessimistic estimation — optimistic estimation)/6

In order to have a confidence interval of about 99.7% (be sure of the extent of probability) you can calculate: Pert estimation ± 3 x PERT standard deviation (3 can be set to 2 for restricting the range).

Do not forget to use data from projects that are already done as a starting point for relative estimation. When estimating, the more outside sources you use, the more accurate and risk-averse your estimates will be.

Goals of estimations

While formulating projections, maintaining a steadfast focus on the ultimate objective holds the utmost significance. Crafting and sustaining accurate estimations demands a substantial investment of effort and time. Particularly within the realm of AI ventures, prognosticating outcomes proves intricate due to their intricate nature, thereby amplifying the significance of garnering trust from both your team and clients in these forecasts. This trust is pivotal as it correlates positively with the likelihood of successful execution.

It’s worth noting that the level of certainty tied to estimations diminishes when confronted with uncharted territories, such as crafting solutions for novel business domains or the integration of pioneering algorithms and technologies. In these instances, possessing a coherent roadmap toward the culmination becomes a guiding beacon.

However, it’s judicious to avoid excessive reliance on exact calculations pinpointing the temporal aspect or meticulously detailed blueprints. Instead, a discerning application of estimates is advisable. They serve as tools not only for ensuring congruence between implementation strategies and customer expectations but also for steering projects in alignment with these desires.

Risks

In the realm of AI projects, the initial and pivotal point of vulnerability lies in delineating the project’s objectives. The main point of success in a good understanding of the desired outcomes. It is very interesting when the project implementation begins in a quick way, but if there is a lack of precision, this can diverge significantly from the actual business requisites. Hence, it is very important to have well-established and well-defined objectives. These objectives can operate like a compass for the team, enabling them to discern between accurate and erroneous resolutions.

How to approach research projects?

A research endeavor encompasses any project geared towards unraveling solutions to previously unencountered predicaments. Notably, the motivation behind research projects extends beyond the enhancement of scientific knowledge. They encompass scenarios where teams delve into unexplored realms, such as novel business domains or emerging AI libraries, and strive to uncover innovative applications of AI within business contexts. This holds true for almost every AI initiative, wherein a subsidiary research project takes charge of the modeling process.

Nevertheless, a fundamental issue with research projects is their tendency to lack comprehensive breadth. Each research undertaking mandates a well-defined objective; without such clarity, successful culmination remains elusive. Moreover, addressing external challenges holds equal importance in the realm of research endeavors. The financial allocations for research naturally escalate in proportion to the expansiveness of the project scope. Budget constraints, if present, can also impose limitations on the depth and duration of the research.

Once the quantum of research feasible is determined, collaborative efforts can be directed towards tackling the pending experiments. Each entry on the backlog should embody an idea capable of enriching model quality or facilitating the realization of desired functionalities. The SMART criteria — specific, measurable, achievable, relevant, and time-bound — serve as a pertinent framework for articulating the specifics of each experiment.

Conduct swift yet comprehensive quality assessments on all ongoing experiments within your current research cycle. This practice aids in gauging the anticipated time investments for each experiment. To safeguard the trajectory of your research projects and prevent potential missteps, it’s imperative to adhere to the following guidelines:

  • Set an exact goal
  • Set the criteria for success
  • Define the limits, such as the time and money limits
  • Fill up the queue of experiments
  • Prioritise based on what you want
  • Keep track of all the tests and their results
  • Make the code easy to copy
  • Write down what you find

Some additional parts that need to be considered are:

  • Identify what the nice-to-have is and what is the main part
  • Reduce effort for not important parts in the beginning
  • Try to be as lean as possible (based on the budget you have)

A considerable portion of projects relies on a top-down estimation approach, wherein the process originates with the overarching budget allocation for the project and subsequently deconstructs it into smaller components. This method is particularly employed when the project’s financial framework and pricing are already established. However, this approach encounters a notable predicament: initial estimates tend to be less reliable at the project’s outset. The challenge arises from the fact that determining the required budget is intricate before a comprehensive understanding of the project’s requirements and a detailed plan are in place.

This challenge can be further exacerbated, particularly when gauging the initial quote’s accuracy against the eventual project outcome is unfeasible. The efficacy of top-down estimation is optimized when there exists a profound comprehension of how each task within the project’s scope contributes to the initial fixed price. Nonetheless, this level of understanding demands substantial time and effort, which is often not feasible to ascertain manually.

Some additional helpful parts

  • No one can work on projects all the time because everyone needs breaks, goes to meetings, gets stuck in traffic, and so on. So, you should assume that a resource isn’t available 20% of the time but is available 80% of the time. If a project resource is only available half the time, set the maximum availability units to 40%. When setting up the schedule for your project, don’t forget to account for each resource’s holidays, plant shutdowns, training, and vacations. No plan ever goes exactly as planned. You need some wiggle room because some tasks will be late.
  • Include a buffer: No plan ever goes exactly as planned. You need to have some margin for error because some tasks will be late. A good idea is to add a buffer task at the end of certain phases (like those that use new technology that your team has little or no experience with) or to extend the project’s overview deadline for that phase by 20% from its original length. For instance, if the original length of a phase is 100 days, you could make it 120 days.
  • Try to identify some of the possible risks at the beginning of the project and make this a continuous procedure.

Conclusions

  • Estimations are used to plan and control projects, understand complexity, and figure out costs.
  • Estimation is difficult and inaccurate, so a relevant sample and a good estimation process are needed.
  • Use relative story points instead of exact hours to improve accuracy.
  • Differentiate between business and implementation estimates, and consider the business model’s budget constraints.
  • Outline steps, make a proposal for software architecture, and use statistical methods like PERT to estimate projects.
  • PERT involves rating for each task on a scale of 1–3 (best case, most likely, and pessimistic estimates).

References

Dubovikov K. (2019). Managing Data Science. Packt Publishing

Creating a Project Budget – A Complete Guide

Discover all you need to create a realistic project budget, with or without a system to help you, in one simple guide.

www.forecast.app

https://projectmanagementacademy.net/resources/blog/a-three-point-estimating-technique-pert

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