<jupyter_start><jupyter_text>A model of the intergenerational movement of traits for populations reproducing under polygenic inheritance  Abstract This work describes and presents the results from a mathematical model based on the standard understanding of polygenic inheritance. When applied to intergenerational movement between quintiles, the model obtained an r2 of 0.92 and 0.93 with the Brookings Institution measures of intergenerational education and income mobility, respectively. The model better predicted measures of education and income mobility than those measures predicted one another: r2 = 0.84. One original question motivated the creation of the model: consider the tallest one fifth of trees in a forest. Under polygenic inheritance, are a majority of them the offspring of the previous generation's tallest one fifth of trees or are a majority of them the offspring of the previous generation's shorter four fifths of trees? While tall trees are more likely to have tall offspring, there are far more average/short trees than tall trees. It is not immediately clear whether or at what point the effect of a higher probability of tall offspring outweighs the effect of a far greater number of offspring. A simulation of the model showed that a minority (43%) of trees above the 80th percentile are the offspring of the previous generation’s tallest one fifth. The 72nd percentile is the equilibrium point at which the proportion is 50%. That is, of the trees above the 72nd percentile, half are the offspring of parents also above the 72nd percentile and half are the offspring of parents below the 72nd percentile.  Introduction In biology, a phenotypic trait is a measurable trait that results from the expression of genes. As an example, the phenotype of hair color is the observed color while the genotype is the underlying genes that determine the color. The phenotypic traits Mendel studied in pea plants were unique in that they were determined single genes. However, it is often the case that phenotypic traits are determined by many genes. - sometimes hundreds or thousands. These traits are termed polygenic traits (many genes). In general, the population distribution for the phenotype of a polygenic trait falls into what is called a [normal or gaussian distribution](https://en.wikipedia.org/wiki/Normal_distribution). This phenomenon has been observed by plotting the frequency of phenotypes for a polygenic trait and finding a close approximation to a normal distribution. The greater the number of genes influencing the trait, the closer the approximation. This is thought to occur as a result of the many possible allelic combinations among individual genes. In this model, genes code for alleles with additive effects, either + or - on a measurement of the trait. One example of a polygenic trait is height: there are about 700 genes that influence human height, each of which has a very small effect, either positive or negative. The resultant population distribution of height is therefore Gaussian. The polygenic inheritance in this case is analogous to flipping 700 coins and recording the number of heads minus the number of tails. If one were to do this many times, one would obtain a normal distribution: Often obtaining a more or less equal number of heads and tails and occasionally obtaining a far greater number of heads than tails or vice versa. In the case of height, the trait is univariate, meaning that it can be measured by only one value. However, traits are sometimes multivariate, and though the work presented here does not discuss such cases, future work likely will. As the phenotypes of a population fall under a normal distribution, their frequencies can be described by the following probability density function. \begin{equation*}\LARGE f(x)=\frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{1}{2}(\frac{x-\mu}{\sigma})^2} \end{equation*}The parameter μ is the mean or expectation of the distribution (and also its median and mode); σ is its standard deviation. If the population is the parent-generation, then the distribution is made up of all the parent phenotypic values xp and their corresponding frequencies f(xp) as shown below. \begin{equation*}\LARGE f(x_p)=\frac{1}{\sigma_{pd}\sqrt{2\pi}}e^{-\frac{1}{2}(\frac{x_p-\mu_{pd}}{\sigma_{pd}})^2} \end{equation*}The parameters μpd and σpd are the mean and standard deviation of the parent-generation population. It is generally understood that polygenic traits are heritable, which means that a correlation exists between the phenotypes of parents and offspring. For example, as measured by [Luo et al](https://www.nature.com/articles/pr1998502), the correlation coefficient - also termed the heritability value - between parent and offspring for human height is 0.55-0.60. Under this model of regression toward the mean, parents whose height is 1 standard deviation above the mean have offspring whose height is on average 0.55-0.60 standard deviations above the mean. The model presented in their paper is based on the linear regression model, in which there is a straight regression line that provides the 'best' fit for the data points. Its equation is shown below. \begin{equation*}\LARGE \hat y = \hat \alpha + \hat{\beta} x\end{equation*}In the case of polygenic inheritance, x represents the phenotypic value of a set of parents and $\hat y$ represents the predicted offspring's phenotypic value. In future equations presented here, $\bar{x}_{o}$ will be used in place of $\hat y$. The parameters α and β are found by minimizing the sum of squared residuals. It can be [shown](https://en.wikipedia.org/wiki/Regression_toward_the_meanDefinition_for_simple_linear_regression_of_data_points) that if the mean and standard deviation of x and y are equal then the expected y can be given by the following equation. \begin{equation*}\LARGE \hat y = \bar{x} + r(x - \bar{x})\end{equation*}Where r is given by the following equation:\begin{equation*}\LARGE r = \frac{Cov[x,y]}{\sqrt{Var[x] Var[y]}}\end{equation*}When applied to polygenic inheritance, the expected phenotypic value for the offspring of the parents at the phenotypic value xp is given by Luo et al. in the following equation [1].     \begin{equation*}\LARGE \bar{x}_{o} = \mu_{pd} + r(x_p - \mu_{pd})\end{equation*}The parameter μpd is the mean of the parent population distribution and the parameter r is the correlation coefficient or heritability value between parent and offspring. This equation represents the current understanding of polygenic inheritance. While it gives the mean phenotypic value of the offspring of parents at xp it fails to describe their general distribution. In this work, it is suggested that the offspring of members of the parent population with phenotypic value xp are normally distributed with a mean at $\bar{x}_o$. The offspring distributions from each xp in the parent distribution sum to form the total offspring distribution. By keeping track of the contribution of sections of the parent distribution to sections of the total offspring distribution, it is possible to make meaningful statements about the intergenerational movement of traits for reproducing populations in nature and society.   One Offspring Distribution This work proposes that the frequency of the phenotypic values for the offspring of parents at xp is normally distributed about $\bar{x}_o$. The distribution of the phenotypic values of the offspring of parents at xp is then given by the following equation:\begin{equation*}\LARGE g(x)=f(x_p)\frac{1}{r_s\sigma_{pd}\sqrt{2\pi}}e^{-\frac{1}{2}(\frac{x-\bar{x}_o}{r_s\,\sigma_{pd}})^2}\end{equation*}The offspring distribution is a centered at $\bar{x}_o$. Its standard deviation is the parent generation population standard deviation σpd scaled by rs and each of its values are scaled by the frequency of the parent phenotypic value f(xp). If rs=1, then the variance of the offspring from parents at xp is equal to the variance of the entire parent-generation population. While there are not yet literature measurements of rs, it would seem to be more likely that the variance is less than, and almost certainly not greater than that of the entire parent population. In that case, rs is more likely less than 1 as opposed to equal to or greater than 1. In a more complicated scenario not considered here, rs varies with xp. Note that the phenotypic value xp corresponds to the z-score zp - relative to the parent-generation population. A complete description of the one offspring distribution can be made with the following statement and two equations:The distribution of the offspring of parents at xp is a normal distribution centered at z-score zo (relative to the parent-generation population), with standard deviation σo, and proportional to the value at f(xp).\begin{equation*}\LARGE z_o=r\,z_p\end{equation*}\begin{equation*}\LARGE \sigma_o=r_s\,\sigma_{pd}\end{equation*}The statement and two equations do not supply any additional information about the one offspring distribution. Instead, they provide an alternative way of describing the one offspring distribution that more clearly indicates the role of r and rs.  Total Offspring Distribution While g(x) describes the distribution of offspring from only one xp, a function is needed to describe the distribution of the entire offspring-generation population. This distribution is made up of the combined one-offspring-distributions from each xp in the parent-generation population. The frequencies of the phenotypes of the offspring-generation population can then be described by the following probability density function.\begin{equation*}\LARGE G(x)=\int_{-\infty}^{\infty} g(x) \, dx_p\end{equation*}The frequency of each phenotypic value x in the offspring-generation population is obtained by summing the frequency at x for each one-offspring-distribution g(x). It is important to remark that this distribution G(x) appears by all measures to be a normal distribution. This lends credence to the model as the offspring-generation population should indeed be normally distributed, and in most cases have a mean and standard deviation equal to those of the parent-generation distribution. The mean of the total offspring distribution is always equal the mean of the (total) parent distribution. On the other hand, the standard deviation of the total offspring distribution varies proportionally with both r and rs.   Answering the Motivating Quesiton At this point, it would seem to be possible to answer the motivating question: Are a majority of the tallest one fifth of trees in a forest the offspring of the previous generation's tallest one fifth? It is important to recognize that the area under a specific section of a population distribution bounded by phenotypic values represents the size of the population with those phenotypic values. In the case of the tallest one fifth of trees in a forest, the section is bound by k2 and ∞, where k2 represents the phenotypic value (height) at the 80th percentile of the population distribution. For a given phenotypic value xp in the parent-generation population, it is necessary to find the size of its offspring population that is located in the top quintile. This is achieved by integrating xp's one offspring distribution from k2 to ∞:\begin{equation*}\LARGE f(x_p)\frac{1}{\sigma_o\sqrt{2\pi}}\int_{k_2}^{\infty} e^{-\frac{1}{2}(\frac{x-\bar{x}_{\small o}}{\sigma_{\small o}})^2} dx\end{equation*}The integral provides the amount of offspring with a phenotypic value above k2 from parents with the phenotypic value xp . To find what proportion of the offspring in the top fifth of the offspring-generation population are from parents in the top fifth of the parent-generation population, it is necessary to divide the amount of top fifth offspring from only those xp in the top fifth of the parent population by the amount of top fifth offspring from all xp in the parent population. This fraction gives the proportion of top fifth offspring from top fifth parents, the answer to the motivating question. The xp in the top fifth of the parent distribution are bounded by k1 and ∞, where k1 represents the height at the 80th percentile of the parent distribution. The following expression gives the amount of top fifth offspring from the top fifth parents.\begin{equation*} \LARGE\int_{k_1}^{\infty}f(x_p)\frac{1}{\sigma_o\sqrt{2\pi}}\int_{k_2}^{\infty} e^{-\frac{1}{2}(\frac{x-\bar{x}_{\small o}}{\sigma_{\small o}})^2}dx\,dx_p\end{equation*}This expression is then divided by the amount of top fifth offspring from all parents, which is a similar expression. The only difference is that the outer integral ranges over all members of the parent distribution (-∞ to +∞). The inner integral can be simplified with the [cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function).   Intergenerational Movement and Two Types of Questions The calculations involved in answering the motivating question can be generalized to answer two types of questions. The first type of question is to ask what proportion of an arbitrary section of the total offspring distribution is from another arbitrary section of the parent distribution. For example, one could ask what proportion of the offspring-generation population with z-scores of between 1 and 1.5 are the offspring of members of the parent-generation population with z-scores of between -0.5 and 0. The motivating question was of this type, as it asked what proportion of a top section of the total offspring distribution was from the same top section of the parent distribution. The second type of question is to ask what proportion of the offspring of parents in an arbitrary section of the parent distribution end up in another arbitrary section of the total offpsring distribuiton. For example, one could ask what proportion of the offspring from parents with z-scores of between -2 and -1, have z-scores of between 1 and 2. In answering these questions, it is helpful to define a Φ term as follows. \begin{equation*} \LARGE\Phi(k_1,k_2,k_3,k_4) \equiv \int_{k_1}^{k_2}f(x_p)\frac{1}{\sigma_o\sqrt{2\pi}}\int_{k_3}^{k_4} e^{-\frac{1}{2}(\frac{x-\bar{x}_{\small o}}{\sigma_{\small o}})^2}dx\,dx_p\end{equation*}This term gives the size of the population with phenotypic values between k3 and k4 that are the offspring of members of the parent generation with phenotypic values between k1 and k2. In other words, it provides the amount of a specific section of the offspring-generation population from a specific section of the parent-generation population.   Proportion Attributable  To answer the first type of question, it is necessary to find the ratio of the Φ term for the specific section of the parent and offspring-generation population divided by the Φ term for the specific section of the offspring-generation population, but the entire parent-generation population. This gives the proportion of the arbitrary section of the total offspring distribuiton that is the offspring of or 'attributable to' the arbitrary section of the parent distribution. The proportion is equivalent to the probability that a given member of the arbitrary section of the total offspring distribuiton is the offspring of a member of the arbitrary section of the parent distribution. The proportion attributable is given by the following equation. \begin{equation*} \LARGEP_a(k_1,k_2,k_3,k_4) = \frac{\Phi(k_1,k_2,k_3,k_4)}{\Phi(-\infty,\infty,k_3,k_4)}\end{equation*}The parameters k3 and k4 give the bounds of the arbitrary section of the total offspring distribution and the parameters k1 and k2 give the bounds of the arbitrary section of the parent distribution.  Proportion Destined To answer the second type of question, it is necessary to find the ratio of the Φ term for the specific section of the parent and offspring-generation population divided by the Φ term for the specific section of the parent-generation population, but the entire offspring-generation population. This gives the proportion of the offspring from the arbitrary section of the parent distribuiton that end up in or are 'destined to' the arbitrary section of the total offspring distribution. The proportion is equivalent to the probability that a given offspring of a parent in the arbitrary section of the parent distribuiton is a member of the arbitrary section of the total offspring distribution. The proportion destined is given by the following equation. \begin{equation*} \LARGEP_d(k_1,k_2,k_3,k_4) = \frac{\Phi(k_1,k_2,k_3,k_4)}{\Phi(k_1,k_2,-\infty,\infty)}\end{equation*}The parameters k3 and k4 give the bounds of the arbitrary section of the total offspring distribution and the parameters k1 and k2 give the bounds of the arbitrary section of the parent distribution.  Discussion While the equations in the model do not have closed form solutions, they can be simulated with code. As a result, the answers to the questions presented here are approximations as the simulations are limited by computational speed. To obtain values for intergenerational movement between quintiles, Pd was obtained for each quintile of the parent and total offspring distributions. The Pd's were then compared to the measured values for education and income mobility provided by the Brookings Institution. If income and education are normally distributed in the population with regression towards the mean between parent and offspring, then a high correlation between the values provided by this model and those provided by the Brookings Institution might indicate that the equations presented here provide a good model of reproducing normal population distributions with regression towards the mean.   References [1] https://www.nature.com/articles/pr1998502  Demonstration of Code<jupyter_code>import imp 
import tree_functions as tree
imp.reload(tree)
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as st
import time
number_of_iterations = 500  # this number is related to the number of operations - 
                            # if slow, then reduce. Multiples of 100 tend to work best. 
z_range = 8
r = 0.5
r_s = 0.9
mean_gen = 0
sd_gen = 1 

fig_size = (12, 8)
fig_size1 = (8, 5.333)<jupyter_output><empty_output><jupyter_text>Parent Generation Population Distribution The proportion of the population with each phenotypic value is plotted for the parent generation population.Technical Note: - We use the classic mean of zero and standard deviation of 1, although the code handles any mean and sd.<jupyter_code>n_iterations_dem = 100  # Make n_iterations small for demonstration purposes
parent_distribution_dem = tree.normal_distribution(n_iterations_dem, z_range, mean_gen, sd_gen)
parent_distribution = tree.normal_distribution(number_of_iterations, z_range, mean_gen, sd_gen)
plt.figure(figsize=fig_size1)
plt.title('Parent generation distribution')
tree.plot_distribution(parent_distribution_dem, label='parent population')
plt.savefig('images/hi.png')<jupyter_output><empty_output><jupyter_text>One Offspring Distribution  The Role of the Mean Regression Coefficient (r) If r = 1, then parents at xp have offspring centered at xp as well. There is no regression toward the mean. \begin{equation*}\large \bar{x}_{o} = \mu_{pd} + 1(x_p - \mu_{pd}) = x_p\end{equation*}<jupyter_code>parent_index = tree.z_score_to_index(z_score=1, number_of_steps=number_of_iterations, \
                                     z_score_range=z_range)
single_offspring_distribution1 = \
tree.one_offspring_distribution(parent_distribution, parent_index, 1, r_s)
plt.figure(figsize=fig_size1)
plt.xlim(-4.5, 4.5)
plt.title('No regression to the mean. Perfect inheritance. r = 1')
tree.plot_distribution(parent_distribution_dem, label='parent population')
plt.axvline(x=1, linestyle='--', ymax=tree.f_norm(1,0,1)/0.41, label='parents at x_p')
tree.plot_distribution(single_offspring_distribution1, label='offspring of parents at x_p')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>At the opposite extreme, if r = 0 then parents at xp have offspring centered at the mean of the entire parent generation population (μpd). There is complete regression toward the mean. \begin{equation*}\large \bar{x}_{o} = \mu_{pd} + 0(x_p - \mu_{pd}) = \mu_{pd}\end{equation*}<jupyter_code>single_offspring_distribution3 = tree.one_offspring_distribution(parent_distribution, \
                                                                 parent_index, 0, r_s)
plt.figure(figsize=fig_size1)
plt.title('Complete regression to the mean. No inheritance. r = 0')
tree.plot_distribution(parent_distribution_dem, label='parent population')
plt.axvline(x=1, linestyle='--', ymax=tree.f_norm(1,0,1)/0.41, label='parents at x_p')
tree.plot_distribution(single_offspring_distribution3, label='offspring of parents at x_p')
plt.axvline(x=0, linestyle='--', label='x = 0', color='orange')
plt.xlim(-4.5, 4.5)
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>In reality, r ≈ 0.5, which means that parents at xp have offspring centered at the average of μpd and xp, halfway between the mean of the entire parent generation population and the value of the parents. There is some regression toward the mean.\begin{equation*}\large \bar{x}_{o} = \mu_{pd} + 0.5(x_p - \mu_{pd}) = \frac{\mu_{pd} + x_p}{2}\end{equation*}<jupyter_code>single_offspring_distribution2 = tree.one_offspring_distribution(parent_distribution, \
                                                                 parent_index, 0.5, r_s)
plt.figure(figsize=fig_size1)
plt.title('True (some) regression to the mean. Inheritance. r = 0.5.')
tree.plot_distribution(parent_distribution_dem, label='parent population')
plt.axvline(x=1, linestyle='--', ymax=tree.f_norm(1,0,1)/0.41, label='parents at x_p')
tree.plot_distribution(single_offspring_distribution2, label='offspring of x_p')
plt.axvline(x=0.5, linestyle='--', label='x = 0.5', color='orange')
plt.xlim(-4.5, 4.5)
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>The Role of the Standard Deviation Regression Coefficient (rs) The one-offspring-distributons shown so far have used rs = 0.9. If however rs = 0.5, then the standard deviation of the offspring of parents at xp is one half the standard deviation of the entire parent generation population. \begin{equation*}\large \sigma_o=r_s\,\sigma_{pd} = 0.5\,\sigma_{pd}\end{equation*}<jupyter_code>single_offspring_distribution4 = tree.one_offspring_distribution(parent_distribution, \
                                                                 parent_index, 0.5, 0.5)
plt.figure(figsize=fig_size1)
tree.plot_distribution(parent_distribution_dem, label='parent population')
plt.axvline(x=1, linestyle='--', ymax=tree.f_norm(1,0,1)/0.41, label='parents at x_p')
tree.plot_distribution(single_offspring_distribution4, label='offspring of parents at x_p')
plt.axvline(x=0.5, linestyle='--', label='x = 0.5', color='orange')
plt.xlim(-4.5, 4.5)
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>As can be observed, the offspring of parents at xp are far less spread out than when rs was 0.9 in the plots before.   Total Offspring Distribution<jupyter_code>offspring_distributions_ = tree.offspring_distributions(parent_distribution_dem, r, r_s)<jupyter_output><empty_output><jupyter_text>Instead of showing only the one offspring distribution from parents at xp = 1, we can show all the one offspring distributions from each xp in the parent distribution.<jupyter_code>plt.figure(figsize=fig_size1)
plt.xlim(-4.5, 4.5)
tree.plot_distribution(parent_distribution, label='parent population')
tree.plot_distributions(offspring_distributions_) 
plt.legend()
plt.show()
total_offspring_distribution = \
tree.final_superimposed_distribution_all_area_adj(parent_distribution, r, r_s)<jupyter_output><empty_output><jupyter_text>The individual one offspring distributions shown above are combined by the following equation to form the total offspring distribution.\begin{equation*}\large G(x)=\int_{-\infty}^{\infty} g(x) \, dx_p\end{equation*}<jupyter_code>plt.figure(figsize=fig_size1)
plt.xlim(-4.5, 4.5)
tree.plot_distribution(parent_distribution, label='parent population') 
tree.plot_distribution(total_offspring_distribution, label='offspring-generation population') 
plt.legend()
plt.show()
print(tree.st_dev_of_distribution(parent_distribution))
print(tree.st_dev_of_distribution(total_offspring_distribution))
1/1.029<jupyter_output><empty_output><jupyter_text>Technical Note: - The total offspring distribution shown above is normed to the area of the parent distribution, which basically means that the offspring-generation population size is set to be equal to the parent population size.  If There Were No Regression Toward The Mean (r = 1)<jupyter_code># Make total_offspring_distribution1 into a parent generation
total_offspring_distribution1 = tree.final_superimposed_distribution_all_area_adj(parent_distribution, 1, r_s)
parent_distribution1 = tree.final_super_to_parent(total_offspring_distribution1)
total_offspring_distribution2 = tree.final_superimposed_distribution_all_area_adj(parent_distribution1, 1, r_s)
parent_distribution2 = tree.final_super_to_parent(total_offspring_distribution2)
total_offspring_distribution3 = tree.final_superimposed_distribution_all_area_adj(parent_distribution2, 1, r_s)<jupyter_output><empty_output><jupyter_text>With no regression toward the mean (r = 1), successive generations become increasingly spread out. This is why there must be regression (r ≈ 0.5) to maintain a stable population distribution. Blitzstein discusses this in [a talk](https://youtu.be/dzFf3r1yph8?t=728) in which he says: 'only after a few generations, one would see giant 10 foot people and little four inch people'. The model presented here demonstrates these same effects.<jupyter_code>plt.figure(figsize=fig_size1)
plt.xlim(-4.5, 4.5)
tree.plot_distribution(parent_distribution)  # plot the parent distribution
tree.plot_distribution(total_offspring_distribution1)  # plot the total offspring distribution 1
tree.plot_distribution(total_offspring_distribution2)  # plot the total offspring distribution 2
tree.plot_distribution(total_offspring_distribution3)  # plot the total offspring distribution 3
plt.legend(labels=['1st (parent) generation', '2nd (offspring) generation', \
                   '3rd generation', '4th generation'])
plt.show()<jupyter_output><empty_output><jupyter_text>The standard deviation of each generation increases in a linear fashion from 1 to 2.3 over the course of four generations.<jupyter_code>generations_list = [parent_distribution, total_offspring_distribution1, total_offspring_distribution2, total_offspring_distribution3]
plt.figure(figsize=fig_size1)
tree.plot_generations_sd(generations_list)<jupyter_output><empty_output><jupyter_text>Note to self:Talk about if r_s = 0.5. Make that a section. Then, make a new section about how in nature the offspring distribution tends to have the same standard deviation as the parent population. Make plots of the error between the standard deviation when r is fixed at 0.5 and r_s ranges from 0.5 to 1.5 in increments of 0.1, use the graphing code as a template. Then do the same such that r_s is fixed at 0.9 and r ranges from 0.5 to 1.5. Then, make a 3d plot of error as r *and* r_s range from 0.5 to 1.5. Perhaps there's a local minimum somewhere or not? Perhaps eventually make the graph I was talking about with Aidan where you do r vs r_s such that the error is less than some threshold - such as the current error used in the notebook.   Answering the Motivating Question<jupyter_code>top_fifth_value_parent = tree.percentile_to_value(0.8, parent_distribution)  # Get the value at the 80th percentile
top_fifth_value_offspring = tree.percentile_to_value(0.8, parent_distribution, total_offspring_distribution) 
offspring_top_fifth = tree.final_superimposed_distribution(parent_distribution, r, r_s, above_k_v_o=top_fifth_value_offspring)
offspring_top_fifth_par_top_fifth = tree.final_superimposed_distribution(parent_distribution, r, r_s, above_k_v_p=top_fifth_value_parent, above_k_v_o=top_fifth_value_offspring)
offspring_top_fifth_par_bottom_four_fifth = tree.final_superimposed_distribution(parent_distribution, r, r_s, below_k_v_p=top_fifth_value_parent, above_k_v_o=top_fifth_value_offspring)<jupyter_output><empty_output><jupyter_text>In order to answer the motivating question, we need find whether a majority of the offspring-generation population above the 80th percentile can be attributed to members of the parent-generation population above the 80th percentile. In the plot below, this means finding out if the area under the green line is greater than the area under the red line. The answer to the motivating question is given by the following equation. \begin{equation*} \largeP_a(k_1,\infty,k_2,\infty) = \frac{\Phi(k_1,\infty,k_2,\infty)}{\Phi(-\infty,\infty,k_2,\infty)}\end{equation*}The parameters k1 and k2 give the values for the 80th percentile of the parent and total offspring distributions, respectively.<jupyter_code>plt.figure(figsize=fig_size1)
plt.xlim(-4.5, 4.5)
tree.plot_distribution(parent_distribution)
tree.plot_distribution(offspring_top_fifth)
tree.plot_distribution(offspring_top_fifth_par_top_fifth)
tree.plot_distribution(offspring_top_fifth_par_bottom_four_fifth)
plt.legend(labels=['parent distribution', 'offspring above 80%', 'offspring from parents above 80%', 'offspring from parents below 80%'], loc='upper right') 
plt.show()<jupyter_output><empty_output><jupyter_text>This cell gives the Pa (the probability that a tree in the top fifth of the offspring-generation population is from a parent in the top fifth of the parent-generation population).<jupyter_code>tree.proportion_attributable_percentile(parent_distribution, r, r_s, above_k_p=0.8, above_k_o=0.8, offspring_distribution=total_offspring_distribution)<jupyter_output><empty_output><jupyter_text>As we can see, a minority (43%) of the tallest one fifth of trees are the offspring of the last generation's 'average' trees (shorter four fifths). We've answered the tree problem! (Most of the tallest one fifth in a population are from the last generation's bottom four fiths.)   Equilibrium Point for the Motivating Question<jupyter_code>tree_problem_range = tree.step_tree_question_z_score(parent_distribution, r, r_s, z_score_increment=0.125, z_score_bound=8)<jupyter_output><empty_output><jupyter_text>We've been using percentile, only because it's a more accesible way of explaining the problem than using standard deviation. However, it probably makes more mathematical sense to use standard deviation. This plot shows the answer to the tree question for all z-scores from -4 to 4. That is, for each z-score, it gives the percent of the population above the z-score that are offspring of parents below the z-score. A horizontal line is drawn when the proportion is 50%, and a vertical line is drawn to estimate what the z-score is at that equilibrium.<jupyter_code>plt.figure(figsize=fig_size)
plt.xlim(-4.5, 4.5)
plt.scatter(np.arange(-4, 4.125, 0.125), tree_problem_range)
plt.axhline(y=0.5, linestyle='--')
plt.axvline(x=0.57, linestyle='--')
plt.show()<jupyter_output><empty_output><jupyter_text>There seems to be an equilibrium point at a z-score of about 0.57. That is, those above 0.57 seem to be equally the offspring of parents below 0.57 and parents above 0.57. Note that the z-score 0.57 is equivalent to the 72nd percentile.<jupyter_code>st.norm.cdf(0.57)
eq = 0.57
offspring_top_equil = tree.final_superimposed_distribution(parent_distribution, r, r_s, above_k_v_o=eq)
offspring_top_par_top_equil = tree.final_superimposed_distribution(parent_distribution, r, r_s, above_k_v_p=eq, above_k_v_o=eq)
offspring_top_par_bottom_equil = tree.final_superimposed_distribution(parent_distribution, r, r_s, below_k_v_p=eq, above_k_v_o=eq)<jupyter_output><empty_output><jupyter_text>This plot shows a similar plot to the one shown before, although at the equilibrium 72nd percentile, rather than at the 80th percentile. From looking at the plot, it's somewhat believable that the area under the red line (the parents being below the equilibrium z-score) is equal to the area under the green line (the parents being above the equilibirum z-score).<jupyter_code>plt.figure(figsize=fig_size)
plt.xlim(-4.5, 4.5)
tree.plot_distribution(parent_distribution)  # plot the parent distribution
tree.plot_distribution(offspring_top_equil)  # plot offspring above the equilibrium
tree.plot_distribution(offspring_top_par_top_equil)  # plot offspring from parents above the equilibrium
tree.plot_distribution(offspring_top_par_bottom_equil)  # plot offspring from parents below the equilibrium
plt.legend(labels=['parent distribution', 'offspring above equilibrium', 'offspring from parents above equilibrium', 'offspring from parents below equilibrium'])
plt.show()
eq = 0.57
offspring_top_equil = tree.final_superimposed_distribution(parent_distribution, r, r_s, above_k_v_o=eq)
offspring_par_top_equil = tree.final_superimposed_distribution(parent_distribution, r, r_s, above_k_v_p=eq)
offspring_par_bottom_equil = tree.final_superimposed_distribution(parent_distribution, r, r_s, below_k_v_p=eq)<jupyter_output><empty_output><jupyter_text>This is the same plot as before except now we can see the full distributions for all the offspring, the offspring from parents above the equilibrium z-score, and the offspring from parents below the equilibrium z-score. The equilibrium z-score is denoted with a blue dashed line.<jupyter_code>plt.figure(figsize=fig_size)
plt.xlim(-4.5, 4.5)
tree.plot_distribution(parent_distribution)  # plot the parent distribution
tree.plot_distribution(total_offspring_distribution)  # plot the total offspring distribution
tree.plot_distribution(offspring_par_top_equil)  # plot offspring from parents above equilibrium
tree.plot_distribution(offspring_par_bottom_equil)  # plot the offspring from parents below equillibrium
plt.axvline(x=0.57, linestyle='--')
plt.legend(labels=['parent distribution', 'offspring distribution', 'offspring from parents above equilibrium', 'offspring from parents below equilibrium'])
plt.show()<jupyter_output><empty_output><jupyter_text>It's clear that while the offspring distribution from parents above the equilibrium is farther to the right, it is much smaller than the offspring distriubtion from parents below the equilibrium. Those two forces (size and probability) exactly balance each other out above the equilibrium point. One interesting thing to note is that the are two gaps between the green and red lines to the right of the equilibrium point: One in which the green line is below the red line and another in which the green line is above the red line. The area of those two gaps must be equal to each other.   Intergenerational Mobility We've been talking only about the limited case in which we're comparing the amount of offspring from parents below a certain percentile/z-score to the total amount of offspring above that percentile/z-score. However, we can be much more general than that. For instance, we can answer questions such as: consider the offspring in some quintile of the offspring distribution, what percent are the offspring of the last generation's top quintile? What percent are the offspring of parents in the last generation's fourth quintile? Etc. I call this getting the step_proportion_attributable, because for each quintile in the offspring distribution we're getting the proportion that can be attributed to each quintile of the parent distribution.We can also answer a different but related question: consider the parents in some quintile of the parent distribution - for example the top quintile  - what percent of their offspring end up in the top quintile (just like them)? What percent move down a bit to end up in the fourth quintile? What percent end up all the way over in the bottom quintile? I call this getting the step_proportion_destined, because for each quintile in the parent distribution we're getting the proportion of their offspring that are destined to end up in each of the five quintiles. The step_proportion_destined is a measure of intergenerational mobility.It turns out that when using percentiles as steps, such as asking this question for each quintile rather than for each z-score-range of 1 from -2 to 2, some simple math can show that the step_proportion_attributable and step_proportion_destined are exactly the same. If there were no regression toward the mean, we would expect that nearly all the offspring of parents in the top quintile would end up also in the top quintile. On the other hand, if there were complete regression toward the mean - with no correlation between parent and offspring, we would expect the offspring of parents in the top quintile to be evenly split amount all quintiles. The truth is in the middle of these two extremes.<jupyter_code># Make the number of iterations large to be accurate
n_iterations_large = 100  # reduce this if too slow  # WAS 2000
parent_distribution_large = tree.normal_distribution(n_iterations_large, z_range, mean_gen, sd_gen)<jupyter_output><empty_output><jupyter_text>Here we calculate the step_proportion_destined for the five quintiles, which is equivalent to the step_proportion_attributable.<jupyter_code>percent_step_five = 0.2
step_percentile = tree.step_proportion_destined_percentile(parent_distribution_large, \
                                                           r, r_s, percent_step_five)<jupyter_output><empty_output><jupyter_text>This plot shows, for each quintile of the parent distribution, the probability that their offspring end up in each of the five quintiles. The parent quintile is labeled at the bottom of the graph. The offspring quintiles are displayed with colors: the lightest blue corresponds to the probability that the offspring of those parents end up in the top quintile while the darkest blue corresponds to the probability that the offspring of those parents end up in the bottom quintile. For example: 5% of offspring of parents in the top quintile end up in the bottom quintile, while 44% stay in the top quintile - like their parents.<jupyter_code>plt.figure(figsize=fig_size)
tree.bar_graph_step(step_percentile)<jupyter_output><empty_output><jupyter_text>As metioned before, the same plot can correctly be interpreted differently: The bottom quintiles represent quintiles of the offspring distribution and the colors represent the quintiles of the parents of those offspring. This would mean that 5% of those in the top quintile are the offspring of parents in the bottom quintile while 44% of those in the top quintile are the offspring of parents who were also in the top quintile.It's interesting to note that offspring of parents in the middle quintile have a roughly uniform chance of ending up in any of the five quintiles. While offspring of parents in the bottom quintile or top quintile are about 9 times more likely to end up in the same quintile as their parents than move to the opposite extreme quintile. We have the opportunity here to compare the intergenerational mobility of our simulated polygenic distribution to the measured, real-life intergenerational mobility of various things. While I wasn't able to find the intergenerational mobility of height, the brooking's institute provides measurments of the the intergenerational mobility of education and income.  It's interesting to note the similarities between the values (and yes I took inspiration from their colors and formatting). Listing the values for each of the offspring and parent quintiles side by side yields r2 = 0.92 between our simulated polygenic and the Brookings education measurements, and r2 = 0.93 between our simulated polygenic and the Brookings income measurements. Interestingly, the simulated polygenic values are more correlated with both the education and income measurements than they are with each other: The Brookings education and income measurements compared to each other have r2 = 0.84. Note that we can create this plot using any percentile of our choice, for example percentile steps of 33%. You can do this by running the below.<jupyter_code># percent_step_three = 0.3333
# step_three_labels = ['Bottom Third', 'Middle Third', 'Top Third']
# step_percentile_3 = tree.step_proportion_destined_percentile(parent_distribution_large, r, r_s, percent_step_three)
# plt.figure(figsize=fig_size)
# tree.bar_graph_step(step_percentile_3, step_labels=step_three_labels)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06300492610837438, 'fraction_numerical': 0.012487684729064039, 'mean_word_length': 5.470278884462151, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 97, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '24', 'dir': 'jupyter-structured-clean-dedup', 'id': '496739', 'license': 'MIT', 'n_tokens_mistral': 11311, 'n_tokens_neox': 10346, 'n_words': 4947, 'path': 'archive/tree_project_explainer.ipynb', 'repo_name': 'jessebmurray/polygenic', 'size': '40600'}