Naive Bayes. What may seem like a very confusing algorithm is actually one of the simplest algorithms once understood. Part of why it’s so simple to understand and implement is because of the assumptions that it inherently makes. However, that’s not to say that it’s a poor algorithm despite the strong assumptions that it holds — in fact, Naive Bayes is widely used in the data science world and has a lot of real-life applications.
In this article, we’ll look at what Naive Bayes is, how it works with an example to make it easy to understand, the different types of Naive Bayes, the pros and cons, and some real-life applications of it…
Evrone spoke to Rob Pike, the co-author of the Go programming language, about a career spanning four decades, the evolution of Go over the last ten years, and into the future.
The goal of this piece is to provide a cheat sheet that guides the architect in deciding when to use an API gateway and when to use a service mesh. Please skip to the “Cheat sheet” section at the end if you want to jump straight into it.
The rise of distributed data stores and the general decomposition of systems into smaller pieces means that coordination between each server, service, or function is less available. In my first applications, unique ID generation meant setting
auto_increment=True on a column in the SQL database. Easy, done, no problem. Today, each microservice has its own data source(s) and NoSQL stores are common. Every NoSQL DB is “NoSQL” in its own way, but they usually eschew coordinated and single-writer solutions in the name of reliability/performance/both. You can’t have an auto-increment column without implementing the coordination client-side.
Using numbers as identifiers also creates problems. Auto-incrementing can lead to enumeration-based attacks. Fields can have fixed sizes. These issues can go unrealized until you overflow the
uint32 field, and now your logs are a pile of ID conflict errors. Instead of integers, we can use a different kind of fixed-length field and make it non-sequential so that different hosts can generate IDs without a central coordinating point.
UUID’s are an improvement and avoid collisions in distributed settings, but being strictly random you don’t have a way to easily sort them or determine rough order. Segment blogged a while ago about one replacement for UUIDs with the KSUID (K-Sortable Universal ID) but it has limitations and uses a strange
14e8 offset to avoid running out of epoch time in the next 100 years.
Enter the Unique Lexicographically Sortable Identifier (ULID). These are sortable, high-entropy identifiers that we can generate anywhere in our pipeline without coordination and have confidence that there won’t be collisions. A ULID looks like
01E5TZRCM5WZYPB2BH7KMYR5HT, and the first 10 characters are a timestamp, and the next 16 characters are random.
With many of us around the globe under shelter in place due to COVID-19 video calls have become a lot more common. In particular, ZOOM has controversially become very popular. Arguably Zoom’s most interesting feature is the “Virtual Background” support which allows users to replace the background behind them in their webcam video feed with any image (or video)…
signal provides signal handlers and allows our Go program to interact with the incoming signals. Let’s start with the listeners before diving into the internals.
We are pleased to announce the release of a major revision of the Go API for protocol buffers, Google’s language-neutral data interchange format.
Motivations for a new API
The first protocol buffer bindings for Go were announced by Rob Pike in March of 2010. Go 1 would not be released for another two years.
In the decade since that first release, the package has grown and developed along with Go. Its users’ requirements have grown too.
Many people want to write programs that use reflection to examine protocol buffer messages. The
reflect package provides a view of Go types and values, but omits information from the protocol buffer type system. For example, we might want to write a function that traverses a log entry and clears any field annotated as containing sensitive data. The annotations are not part of the Go type system.
Another common desire is to use data structures other than the ones generated by the protocol buffer compiler, such as a dynamic message type capable of representing messages whose type is not known at compile time.
We also observed that a frequent source of problems was that the
proto.Message interface, which identifies values of generated message types, does very little to describe the behavior of those types. When users create types that implement that interface (often inadvertently by embedding a message in another struct) and pass values of those types to functions expecting a generated message value, programs crash or behave unpredictably.
All three of these problems have a common cause, and a common solution: The
Message interface should fully specify the behavior of a message, and functions operating on
Message values should freely accept any type that correctly implements the interface.
Since it is not possible to change the existing definition of the
Message type while keeping the package API compatible, we decided that it was time to begin work on a new, incompatible major version of the protobuf module.
Today, we’re pleased to release that new module. We hope you like it.