Poisson Distribution for Generating Counts
The pattern in count data lives in how often each value occurs, not in any single entry. That is why the next step is to tally the values.
Guessing the Shape of Login Counts
Imagine recording, for thousands of users, how many times each one logged in during a month. Most users log in a handful of times, a few log in many times, and nobody logs in a negative number of times. This kind of feature is called count data, and it shows up constantly in real measurements. Counting how often something happened is one of the most common ways data is produced, so learning to recognize count data and to predict its shape is a practical skill for anyone preparing data for a model.
What do you think happens?
Before reading further, what would the histogram of tallied monthly login counts look like: a symmetric bell, a skewed shape with a long tail to the right, or a flat line?
Reveal answer
A skewed shape with a long tail to the right: a crowd of small values, a steady fall-off as values grow, and an occasional very large value far out on the right.
The two defining properties of count data, integer values and a hard floor at zero, tend to produce a lopsided distribution rather than a bell curve.
This article moves from observation to explanation. You will first trace a short counting routine line by line to see where a tally can silently go wrong, then examine why count histograms look the way they do, and finally see why a log transformation is often applied before modeling.
What Makes a Feature Count Data
Count data is integer-valued, records how often something happened, and is never negative.
The first property, integer values, means the feature can take only a discrete set of possible numbers. The possible values are 0, 1, 2, and so on, with no fractional counts between two whole values. The second property, that counts are never negative, means the lowest possible value is a hard floor, usually zero.
These two properties have consequences for shape. Together they often produce a distribution that is lopsided: a crowd of small values, a steady fall-off as values grow, and an occasional very large value far out on the right. A feature that is merely a whole number is not automatically count data, but a feature that records how often something happened, and that cannot dip below zero, has the structure described here.
Tracing Where the Tally Diverges
Counting code fails quietly more often than it fails loudly, so it helps to know where to look when a tally disagrees with expectation. The routine below is a generated illustration of the pattern described in the source: it creates a list of slots sized from the largest value, and then uses each observed value directly as an index into that list. This assumes every value is a non-negative integer. The indexing step is where that assumption can break, so that is where a trace should focus.
[1, 0, 2, 1, 0, 2]- The list of slots is sized from the largest value, so there are indices 0 through 5.
- Each observed value is used directly as an index into tally.
- The value -1 is not a valid slot for a count, and the loop does not reject it.
Trace the loop one pass at a time to find the first moment the output stops matching what the data should produce.- 1Pass 1, value 2: slot 2 goes from 0 to 1. The tally is [0, 0, 1, 0, 0, 0].
- 2Pass 2, value 0: slot 0 goes from 0 to 1. The tally is [1, 0, 1, 0, 0, 0].
- 3Pass 3, value 3: slot 3 goes from 0 to 1. The tally is [1, 0, 1, 1, 0, 0].
- 4Pass 4, value -1: this is the divergence. The index -1 does not belong to the count of any valid value, and the increment lands in the last slot, index 5. The tally becomes [1, 0, 1, 1, 0, 1], and nothing crashes.
- 5Pass 5, value 2: slot 2 goes from 1 to 2. The tally is [1, 0, 2, 1, 0, 1].
- 6Pass 6, value 5: slot 5 goes from 1 to 2. The final tally is [1, 0, 2, 1, 0, 2], which is wrong for the valid values.
How Count Features Are Generated
The source's synthetic dataset was built to mimic counts found in real settings. It starts with values drawn from a standard normal distribution, which are bell-shaped. Each of those values is then passed through the exponential function and scaled by 10. The scaled result is used as the rate for a Poisson distribution, and each final count feature entry is a random draw from a Poisson distribution with that rate. A Poisson distribution is a probability distribution used to model count data, so the final features are counts even though an intermediate step was bell-shaped.
This sequence shows that the shape of a feature is not fixed by its underlying meaning alone. The bell-shaped latent values are pushed through an exponential, which stretches the upper end, and then the discrete Poisson sampling converts them into integers. The result has the integer-valued, non-negative, skewed character described earlier. The first ten entries of the first feature are all integers and all positive, yet reading them one by one reveals no clear pattern.
The pattern in count data lives in how often each value occurs, not in any single entry. That is why the next step is to tally the values.
Reading a Tally with bincount
NumPy's bincount function is the tool the source uses for this job. It counts how many times each non-negative integer appears in an array and returns a sequence in which position k holds the number of appearances of the value k. Because positions start at zero, the first entry always refers to the value zero, even when zero never occurs in the data. That detail is the source of many off-by-one confusions, so keep it in mind when reading any bincount output.
[1 0 2 1 0 1]- Position 0 holds the count for the value 0, which appears once.
- Position 1 holds the count for the value 1, which never occurs, so it is 0.
- Position 2 holds 2 because the value 2 appears twice.
In the source's tally for the first feature, the lower values are the most frequent, the counts for higher values fall off quickly, and the long right-hand tail still contains a few large values. The source notes one especially high value that appears only twice. The overall picture is a sharply peaked, right-skewed histogram. A histogram is the natural way to view count data for this reason: it turns a long list of integers into a picture of how frequently each value occurs. When you visualize count data, the horizontal axis should show the count values themselves and the vertical axis should show how often each value occurred.
What do you think happens?
In the small tally above, the value 4 never appears. What does position 4 of the bincount output hold?
Reveal answer
0, because position k holds the number of appearances of the value k, and the value 4 never occurs.
Positions start at zero, so each position always corresponds to one value, even values that never appear.
Why Models Prefer Loosely Gaussian Features
Before a model learns anything, the features it receives have a shape, and that shape can make learning easy or hard. Many modeling methods work best when each input feature, and in regression also the target, is loosely Gaussian distributed. In practice this means that if you draw a histogram of one feature, it should look something like the familiar bell curve. Real measurements rarely arrive in that form, so a common job of a data practitioner is to reshape features before modeling them.
The contrast between a raw count histogram and a bell curve is the central motivation for transforming count features. Count features, as generated and tallied, depart from the bell shape in predictable ways. The gap between the two is what a transformation is meant to close.
The source describes using transformations like log and exp to move a feature toward a Gaussian shape, and it calls this approach hacky but simple and efficient. The transformation is especially useful for integer count data, because counts pile up at small values and stretch out at large ones, and a logarithm compresses that stretch. The exponential function is the mirror image of the logarithm, which is why both appear in the source's workflow: exp appears when the data is generated, and log appears when the data is reshaped toward a bell curve. Applying $\log(x)$ to a count compresses the long right tail, while $e^{x}$ maps a logged value back to the original count scale.
Mistakes Beginners Make with Count Tallies
Common mistake Treating the first bincount entry as the value 1
What it looks likeIn the output [1 0 2 1 0 1], reading the first 1 as the number of ones in the data.
Why it failsPositions start at zero, so the first entry always refers to the value zero.
Do this insteadRead position k as the count for the value k, and remember that position 0 is the value 0 even when 0 never occurs.
Common mistake Assuming a tally is correct because nothing crashed
What it looks likeThe routine in the trace finished and printed a plausible list even though a -1 value had been silently counted.
Why it failsA negative value landed in a non-negative slot without raising an error, so the failure was silent.
Do this insteadCheck that every value is a non-negative integer before counting, and treat any negative value as a data-quality problem.
Common mistake Expecting a raw count feature to look like a bell curve
Why it failsInteger values with a floor at zero tend to produce a skewed distribution with a long right tail.
Do this insteadInspect the histogram first, and consider a log transform when the shape is strongly right-skewed.
Common mistake Treating count values as fractional quantities that can sit between two whole numbers
Practice: Finding the Diverging Line
Using the routine from the trace section, change the input to counts = [4, 1, 1, 0, 3] and no negative values. Without running it, work out the expected final tally, then trace each pass. Which values in this new input would cause a silent problem, if any, and what check would you add before the loop?
Hints
- The largest value is 4, so the list has five slots at indices 0 through 4.
- Ask of each value whether it is a valid non-negative integer before using it as an index.
- A correct tally for this input has 1 at position 0, 2 at position 1, 0 at position 2, 1 at position 3, and 1 at position 4.
Summary of Count Features
- 1Count data is integer-valued, records how often something happened, and is never negative, which gives it a hard floor at zero.
- 2Tallying values reveals the lopsided shape of count data: a crowd of small values, a steady fall-off, and a long right tail.
- 3A negative value in a counting routine can fail silently, so validate inputs before the indexing step.
- 4Models prefer loosely Gaussian features, so log and exp transformations are often used to reshape count features before modeling.
At a glance
- Count data is integer-valued, records how often something happened, and is never negative.
- Raw count histograms are typically skewed, with many small values and a long right tail.
- A tally can silently go wrong when a negative value is used as an index, so check values before counting.
- Log and exp transformations can move count features toward the loosely Gaussian shape that most models prefer.