{"course":{"slug":"machine-learning-foundations","title":"Machine Learning, Foundations","url":"https://addaly.com/learn/machine-learning-foundations","level":"intermediate","track":"start"},"lesson":{"slug":"where-the-rows-came-from","title":"Where the rows came from, and who is missing","url":"https://addaly.com/learn/machine-learning-foundations/where-the-rows-came-from","position":30,"of":92,"minutes":9,"answer":"A held-out set cannot detect a sample that misrepresents the population, because it is drawn from the same sample, so the composition of the data must be reasoned about from how it was collected.","keyIdea":"A held-out set cannot detect a sample that misrepresents the population, because it is drawn from the same sample, so the composition of the data must be reasoned about from how it was collected, not measured from within it."},"body":{"format":"markdown","text":"## The assumption underneath every model\n\nEvery method in this course assumes your training rows are drawn from the same distribution as the rows you will predict on. When that fails, no amount of modelling repairs it, and the failure does not appear in any validation score, because the validation set is drawn from the same flawed sample as the training set.\n\nThis is the one class of problem that a held-out set cannot detect. It is worth sitting with for a moment, because everything else in this course is a variation on \"hold data out and measure\".\n\n## Four ways the sample goes wrong\n\n**Selection bias.** Your data records only the cases that reached you. A loan model trained on approved applicants has no rows for anyone rejected, so it learns to predict default *among people the previous process approved*, and it cannot tell you anything about the people it was designed to help you evaluate. The formal name is the rejection inference problem, it is well known in credit, and it has no clean solution. The partial ones are expensive: approve a random small fraction regardless of score, and accept the losses as the price of knowing.\n\n**Survivorship bias.** Only the survivors are in the table. Analysing customer behaviour using currently active customers excludes everyone who left, which is precisely the group a churn model needs. Abraham Wald's wartime example remains the clearest: armour the parts of returning aircraft with *no* bullet holes, because planes hit there did not return.\n\n**Measurement differences between groups.** The same quantity measured differently across subsets. A hospital that records blood pressure in a triage queue and another that records it in a quiet room produce different numbers for the same patient. A model trained mostly on one will misread the other.\n\n**Feedback loops.** The model's own predictions change the data it is later trained on. Predict high crime in a district, send more officers, record more incidents, retrain, predict higher crime. Nothing about the district changed. This is covered again in module 9 because it is a production problem, but it starts here, in how the next dataset is generated.\n\n## Two questions, asked out loud\n\nBefore you build anything:\n\n> **Who is in this data, and who is not?**\n>\n> **What had to happen for a row to exist?**\n\nThe second is the sharper one. For a customer support dataset: someone had a problem, knew the support channel existed, had the time and language to use it, and completed the form. Everyone who gave up before completing it is absent, and they may be the group you most need to understand.\n\nFor Addaly's own data, the same question has an uncomfortable answer: rows exist for people with a working internet connection, a device, and enough literacy to use the site. That is a real limit on what the data can tell us about learners in general, and stating it is better than discovering it later.\n\n## What you can actually do\n\n**Reweight**, when you know the target population's composition. If your sample is 70% urban and the population is 35%, weight rural rows up. This corrects the marginal distribution and does nothing about groups with zero rows.\n\n**Collect deliberately.** Oversample small groups so you have enough rows to measure per-group performance, which is different from making the model treat them equally, and is a prerequisite for the fairness work in module 5.\n\n**Randomise a slice.** In selection-bias settings, the only reliable fix is a small random exploration policy: approve 2% at random, show a random result to 1% of searches. It costs money and it is the only way to get unbiased data about the region your policy currently excludes.\n\n**Document the limits.** Write down who the model was trained on and who it should not be used for. This is what a model card is, and module 9 builds one.\n\n## Distribution shift after deployment\n\nThe sample can also be right on day one and wrong by month six. Three named forms, because the distinction guides the fix:\n\n- **Covariate shift**: the input distribution moves, the relationship holds. Your users get younger; age still predicts what it did. Reweighting can help.\n- **Label shift**: the base rate moves. Fraud rises from 1% to 4%. Recalibration helps; the ranking may still be fine.\n- **Concept drift**: the relationship itself changes. Fraudsters adapt to your model. Nothing helps except new labelled data and retraining.\n\nThey are detected differently, they are fixed differently, and calling all three \"drift\" is how teams end up applying the wrong remedy for a quarter.\n\n## The position\n\nThere is no statistical test that tells you your sample is unrepresentative of a population you did not sample. You can compare your data against a census, against another source, against what a domain expert expects, and those comparisons are worth doing. But the definitive check does not exist, and the appropriate response is to write down what you know about how the rows came to be, and to say the limits out loud in whatever document accompanies the model."},"check":{"question":"A bank's default model is trained only on approved applicants and validates well. Why does that validation not tell you how the model will perform on the full applicant pool?","options":[{"text":"The validation set is smaller than the applicant pool, so its confidence interval is too wide to support a conclusion.","correct":false,"tempting":"Sample size affects precision of the estimate, but the problem persists at any size because the missing population is absent from both training and validation."},{"text":"Approved applicants have a lower default rate, so the model's threshold is calibrated to the wrong base rate.","correct":false,"tempting":"Base-rate mismatch is a genuine consequence, but recalibration would not repair a model that has never seen the rejected population's behaviour."},{"text":"The validation set is drawn from the same approved population, so it shares the selection bias and cannot reveal how the model behaves on applicants the old policy rejected.","correct":true},{"text":"The approval decision itself is a leaked feature, since it was made using information correlated with default.","correct":false,"tempting":"Approval-related columns can indeed leak, but the defect here is which rows exist at all, and it remains even if every leaked column is removed."}]},"prev":{"slug":"the-fit-transform-contract","title":"Fit on train, transform everywhere: the contract that keeps you honest","url":"https://addaly.com/learn/machine-learning-foundations/the-fit-transform-contract"},"next":{"slug":"imbalanced-classes","title":"When one class is 0.3% of the data","url":"https://addaly.com/learn/machine-learning-foundations/imbalanced-classes"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Where the rows came from, and who is missing', in Machine Learning, Foundations. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/machine-learning-foundations/where-the-rows-came-from (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Where the rows came from, and who is missing","courseTitle":"Machine Learning, Foundations","module":{"index":3,"slug":"the-data-is-the-job","title":"The data is the job"},"answer":null,"keyIdea":"A held-out set cannot detect a sample that misrepresents the population, because it is drawn from the same sample, so the composition of the data must be reasoned about from how it was collected, not measured from within it.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"the-assumption-underneath-every-model","runs":[{"text":"The assumption underneath every model"}]},{"t":"p","runs":[{"text":"Every method in this course assumes your training rows are drawn from the same distribution as the rows you will predict on. When that fails, no amount of modelling repairs it, and the failure does not appear in any validation score, because the validation set is drawn from the same flawed sample as the training set."}]},{"t":"p","runs":[{"text":"This is the one class of problem that a held-out set cannot detect. It is worth sitting with for a moment, because everything else in this course is a variation on “hold data out and measure”."}]},{"t":"h2","id":"four-ways-the-sample-goes-wrong","runs":[{"text":"Four ways the sample goes wrong"}]},{"t":"p","runs":[{"text":"Selection bias.","b":true},{"text":" Your data records only the cases that reached you. A loan model trained on approved applicants has no rows for anyone rejected, so it learns to predict default "},{"text":"among people the previous process approved","i":true},{"text":", and it cannot tell you anything about the people it was designed to help you evaluate. The formal name is the rejection inference problem, it is well known in credit, and it has no clean solution. The partial ones are expensive: approve a random small fraction regardless of score, and accept the losses as the price of knowing."}]},{"t":"p","runs":[{"text":"Survivorship bias.","b":true},{"text":" Only the survivors are in the table. Analysing customer behaviour using currently active customers excludes everyone who left, which is precisely the group a churn model needs. Abraham Wald’s wartime example remains the clearest: armour the parts of returning aircraft with "},{"text":"no","i":true},{"text":" bullet holes, because planes hit there did not return."}]},{"t":"p","runs":[{"text":"Measurement differences between groups.","b":true},{"text":" The same quantity measured differently across subsets. A hospital that records blood pressure in a triage queue and another that records it in a quiet room produce different numbers for the same patient. A model trained mostly on one will misread the other."}]},{"t":"p","runs":[{"text":"Feedback loops.","b":true},{"text":" The model’s own predictions change the data it is later trained on. Predict high crime in a district, send more officers, record more incidents, retrain, predict higher crime. Nothing about the district changed. This is covered again in module 9 because it is a production problem, but it starts here, in how the next dataset is generated."}]},{"t":"h2","id":"two-questions-asked-out-loud","runs":[{"text":"Two questions, asked out loud"}]},{"t":"p","runs":[{"text":"Before you build anything:"}]},{"t":"quote","runs":[{"text":"Who is in this data, and who is not?","b":true}]},{"t":"quote","runs":[]},{"t":"quote","runs":[{"text":"What had to happen for a row to exist?","b":true}]},{"t":"p","runs":[{"text":"The second is the sharper one. For a customer support dataset: someone had a problem, knew the support channel existed, had the time and language to use it, and completed the form. Everyone who gave up before completing it is absent, and they may be the group you most need to understand."}]},{"t":"p","runs":[{"text":"For Addaly’s own data, the same question has an uncomfortable answer: rows exist for people with a working internet connection, a device, and enough literacy to use the site. That is a real limit on what the data can tell us about learners in general, and stating it is better than discovering it later."}]},{"t":"h2","id":"what-you-can-actually-do","runs":[{"text":"What you can actually do"}]},{"t":"p","runs":[{"text":"Reweight","b":true},{"text":", when you know the target population’s composition. If your sample is 70% urban and the population is 35%, weight rural rows up. This corrects the marginal distribution and does nothing about groups with zero rows."}]},{"t":"p","runs":[{"text":"Collect deliberately.","b":true},{"text":" Oversample small groups so you have enough rows to measure per-group performance, which is different from making the model treat them equally, and is a prerequisite for the fairness work in module 5."}]},{"t":"p","runs":[{"text":"Randomise a slice.","b":true},{"text":" In selection-bias settings, the only reliable fix is a small random exploration policy: approve 2% at random, show a random result to 1% of searches. It costs money and it is the only way to get unbiased data about the region your policy currently excludes."}]},{"t":"p","runs":[{"text":"Document the limits.","b":true},{"text":" Write down who the model was trained on and who it should not be used for. This is what a model card is, and module 9 builds one."}]},{"t":"h2","id":"distribution-shift-after-deployment","runs":[{"text":"Distribution shift after deployment"}]},{"t":"p","runs":[{"text":"The sample can also be right on day one and wrong by month six. Three named forms, because the distinction guides the fix:"}]},{"t":"ul","items":[[{"text":"Covariate shift","b":true},{"text":": the input distribution moves, the relationship holds. Your users get younger; age still predicts what it did. Reweighting can help."}],[{"text":"Label shift","b":true},{"text":": the base rate moves. Fraud rises from 1% to 4%. Recalibration helps; the ranking may still be fine."}],[{"text":"Concept drift","b":true},{"text":": the relationship itself changes. Fraudsters adapt to your model. Nothing helps except new labelled data and retraining."}]]},{"t":"p","runs":[{"text":"They are detected differently, they are fixed differently, and calling all three “drift” is how teams end up applying the wrong remedy for a quarter."}]},{"t":"h2","id":"the-position","runs":[{"text":"The position"}]},{"t":"p","runs":[{"text":"There is no statistical test that tells you your sample is unrepresentative of a population you did not sample. You can compare your data against a census, against another source, against what a domain expert expects, and those comparisons are worth doing. But the definitive check does not exist, and the appropriate response is to write down what you know about how the rows came to be, and to say the limits out loud in whatever document accompanies the model."}]}],"check":{"question":[{"text":"A bank’s default model is trained only on approved applicants and validates well. Why does that validation not tell you how the model will perform on the full applicant pool?"}],"options":[{"text":[{"text":"The validation set is smaller than the applicant pool, so its confidence interval is too wide to support a conclusion."}],"correct":false,"tempting":[{"text":"Sample size affects precision of the estimate, but the problem persists at any size because the missing population is absent from both training and validation."}]},{"text":[{"text":"Approved applicants have a lower default rate, so the model’s threshold is calibrated to the wrong base rate."}],"correct":false,"tempting":[{"text":"Base-rate mismatch is a genuine consequence, but recalibration would not repair a model that has never seen the rejected population’s behaviour."}]},{"text":[{"text":"The validation set is drawn from the same approved population, so it shares the selection bias and cannot reveal how the model behaves on applicants the old policy rejected."}],"correct":true,"tempting":null},{"text":[{"text":"The approval decision itself is a leaked feature, since it was made using information correlated with default."}],"correct":false,"tempting":[{"text":"Approval-related columns can indeed leak, but the defect here is which rows exist at all, and it remains even if every leaked column is removed."}]}],"order":[0,1,3,2],"why":null},"prev":{"slug":"the-fit-transform-contract","title":"Fit on train, transform everywhere: the contract that keeps you honest","minutes":8},"next":{"slug":"imbalanced-classes","title":"When one class is 0.3% of the data","minutes":9}}}