You built a survey with several questions that are supposed to measure the same thing (say, "job satisfaction" or "stats anxiety"). Before you average those items into one score, you should check that they actually hang together. That is what Cronbach's alpha does: it estimates the internal consistency of a multi-item scale.
This post covers:
- What alpha measures, and what it doesn't
- The formula
- A worked example with real numbers (including item-deleted analysis)
- Code in Python and R to reproduce it
- The mistakes that wreck your alpha
- A free calculator if you'd rather paste data than write code
What alpha measures
Alpha ranges from 0 to 1 (it can go negative when something is wrong, usually un-recoded items). Higher means the items correlate more strongly with each other, which suggests they are tapping a shared underlying trait.
Common rules of thumb, which are conventions rather than laws:
| Alpha | Typical label |
|---|---|
| ≥ .90 | Excellent (but check for redundant items) |
| .80 – .89 | Good |
| .70 – .79 | Acceptable |
| .60 – .69 | Questionable |
| < .60 | Poor |
Context matters. A 3-item scale with α = .68 can be fine. A 30-item scale with α = .68 means the items barely correlate, because alpha rises with the number of items.
The formula
α = (k / (k − 1)) × (1 − Σσ²ᵢ / σ²ₓ)
-
k= number of items -
σ²ᵢ= variance of item i -
σ²ₓ= variance of the total score (sum of all items per respondent)
The intuition: if items are positively correlated, the variance of the total score is much larger than the sum of the individual item variances. A big gap pushes alpha toward 1.
There is also a standardized alpha, based on the average inter-item correlation r̄:
α_std = (k × r̄) / (1 + (k − 1) × r̄)
Use it when your items are on very different scales. For items on the same Likert scale, raw and standardized alpha are usually close.
Worked example
Eight respondents answered a 4-item scale on a 1–5 Likert scale:
| Respondent | Item 1 | Item 2 | Item 3 | Item 4 | Total |
|---|---|---|---|---|---|
| 1 | 4 | 5 | 4 | 3 | 16 |
| 2 | 3 | 3 | 4 | 4 | 14 |
| 3 | 5 | 5 | 5 | 2 | 17 |
| 4 | 2 | 3 | 2 | 3 | 10 |
| 5 | 4 | 4 | 5 | 5 | 18 |
| 6 | 3 | 2 | 3 | 2 | 10 |
| 7 | 5 | 4 | 5 | 4 | 18 |
| 8 | 2 | 2 | 3 | 4 | 11 |
Step 1: sample variance of each item (divide by n − 1)
Item 1: 1.4286
Item 2: 1.4286
Item 3: 1.2679
Item 4: 1.1250
Σσ²ᵢ = 5.25
Step 2: variance of the total scores
σ²ₓ = 12.2143
Step 3: plug in (k = 4)
α = (4 / 3) × (1 − 5.25 / 12.2143)
= 1.3333 × 0.5702
≈ 0.760
An alpha of about .76 is "acceptable". But the interesting part is the item-level breakdown.
Item-deleted analysis
| Item | Corrected item-total r | Alpha if item deleted |
|---|---|---|
| 1 | .767 | .578 |
| 2 | .642 | .655 |
| 3 | .901 | .502 |
| 4 | .057 | .922 |
Items 1 to 3 pull their weight: removing any of them lowers alpha. Item 4 barely correlates with the rest of the scale (r ≈ .06), and dropping it would raise alpha from .76 to about .92. That is the signal to go look at that question. Maybe it is badly worded, maybe it is reverse-keyed and you forgot to recode it, or maybe it measures something else.
One caveat: don't delete items on statistics alone. If an item is conceptually essential to the construct, think hard before removing it just to bump the number.
Reproduce it in code
Python (no extra libraries beyond NumPy)
import numpy as np
X = np.array([
[4, 5, 4, 3],
[3, 3, 4, 4],
[5, 5, 5, 2],
[2, 3, 2, 3],
[4, 4, 5, 5],
[3, 2, 3, 2],
[5, 4, 5, 4],
[2, 2, 3, 4],
])
def cronbach_alpha(items: np.ndarray) -> float:
k = items.shape[1]
item_vars = items.var(axis=0, ddof=1)
total_var = items.sum(axis=1).var(ddof=1)
return k / (k - 1) * (1 - item_vars.sum() / total_var)
print(f"alpha = {cronbach_alpha(X):.3f}") # alpha = 0.760
# Item-deleted alpha and corrected item-total correlation
for i in range(X.shape[1]):
rest = np.delete(X, i, axis=1)
r = np.corrcoef(X[:, i], rest.sum(axis=1))[0, 1]
print(f"Item {i+1}: r_it = {r:.3f}, alpha if deleted = {cronbach_alpha(rest):.3f}")
Python with pingouin
import pandas as pd
import pingouin as pg
df = pd.DataFrame(X, columns=["q1", "q2", "q3", "q4"])
alpha, ci = pg.cronbach_alpha(data=df)
print(alpha, ci) # also gives a 95% confidence interval
R
library(psych)
X <- matrix(c(4,5,4,3,
3,3,4,4,
5,5,5,2,
2,3,2,3,
4,4,5,5,
3,2,3,2,
5,4,5,4,
2,2,3,4), ncol = 4, byrow = TRUE)
alpha(X) # raw alpha, standardized alpha, item-deleted stats
SPSS
Analyze > Scale > Reliability Analysis, then tick "Scale if item deleted" under Statistics.
Skip the code: free online calculator
If you just want to paste responses and get a result, this is a free tool that handles it:
What it offers:
- Raw data mode: paste one respondent per row, items separated by spaces, tabs or commas
-
Summary statistics mode: if you already have
k, the sum of item variances and the total variance - Raw alpha and standardized alpha
- An item-total table with corrected item-total correlations and alpha-if-item-deleted
- A step-by-step breakdown of the math
- An APA-style sentence you can adapt for your write-up
Paste the 8×4 table from the example above and you should get α ≈ .76, with Item 4 standing out as the weak one.
Common mistakes
-
Forgetting to reverse-code negatively worded items. If "I enjoy statistics" and "Statistics makes me anxious" are on the same scale, one of them must be flipped first. For a 1 to 5 scale, use
new = 6 − old. Un-recoded items create negative covariances and can push alpha toward zero or below. - Treating a high alpha as proof of one dimension. Alpha measures consistency, not unidimensionality. A long scale made of two unrelated subscales can still produce a high alpha. Run a factor analysis if dimensionality matters.
- Ignoring scale length. More items inflate alpha. Look at the average inter-item correlation too.
- Chasing α > .95. Very high values often mean redundant, near-duplicate questions.
-
Computing it on tiny samples. With small
Nthe estimate is unstable. Report a confidence interval, whichpingouingives you. - Assuming alpha is a fixed property of the questionnaire. It describes the scores in your sample. Recompute it for each study.
Alpha's assumptions (and when to reach for omega)
Alpha assumes essential tau-equivalence: every item measures the construct with equal strength. In real scales the items usually have unequal factor loadings, in which case alpha tends to underestimate reliability. McDonald's omega (ω), computed from a factor model, doesn't have that limitation, and many journals now like to see it reported alongside alpha. In R, psych::omega() is a good starting point.
Reporting it (APA style)
APA drops the leading zero for values that can't exceed 1:
The 4-item scale showed acceptable internal consistency (N = 8, Cronbach's α = .76).
If you removed items, report alpha before and after and say which items you dropped and why.
TL;DR
- Alpha = how well a set of items hangs together as one scale.
- Compute it with
k/(k−1) × (1 − Σ item variances / total variance). - Always look at item-total correlations and alpha-if-deleted, not just the headline number.
- Reverse-code first, check dimensionality, and consider omega.
If you try the calculator or run your own data through the code above, I'd like to hear what you get. Questions or edge cases (ordinal data, missing responses, subscales) are welcome in the comments.
Top comments (0)