#!/usr/bin/env python # coding: utf-8 # # Who will be the Mormon prophet in year 2028? # # Summary October 3, 2015 # # * Method 1: Winner takes all predicts Dallin H. Oaks # * Method 2: Monte-Carlo simulation predicts Jeffery R. Holland with an approx. 25% chance. # * Method 3: Subjectively adjusted health predicts Dallin H. Oaks with an approx. 28% chance. # # Summary January 1, 2018 # # * Method 1: Winner takes all predicts David A. Bednar in 2028 and Russle M. Nelson lives to 2020 # * Method 2: Monte-Carlo simulation predicts David A. Bednar in 2028 with approx. 26% chance and Russle M. Nelson lives to 2020 with an approx. 42% chance. # * Method 3: Subjectively adjusted health predicts Other in 2028 with approx. 99% chance and Russle M. Nelson lives to 2022 with approx. 25% chance. # # ## Notes # # * Adds qgrid dependency # ## Overview # It just so happens that there's a a convenient pattern to whom is usually called to be the next prophet of *The Church of Jesus Christ of Latter-day Saints*. For most of the 20th century and all of the 21st century so far, the pattern has been that the prophet of the church is the most senior apostle (by date of calling to the Quorum of the Twelve) becomes the prophet when the previous prophet dies. There are 15 of these apostles at any given time: three in the "First Presidency", comprising the prophet and his two counselors, and twelve in the Quorum of the Twelve Apostles. # # Given the ages of the apostles and some average actuarial life tables (which we use here despite knowing that these men are generally far healthier than the average population), we can fairly easily calculate the likely age of death of the current apostles and rank them by seniority to find some likely scenarios for new prophets. # In[17]: get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib.pyplot as plt from matplotlib import rcParams import numpy as np import pandas as pd import qgrid as qg from datetime import datetime, timedelta from collections import defaultdict import seaborn as sns rcParams['figure.figsize'] = (10.0, 2.0) sns.set(style="darkgrid") # In[3]: now = datetime.now() CURRENT_YEAR = now.year # Here we load some actuarial life tables which give the population-level probability of death at any particular age. # In[4]: full_life_table = pd.read_csv('../data/life_table.csv') full_life_table.set_index('Age',inplace=True) full_life_table[80:99] # In[5]: # grab the values for the "Male" column prob_death = full_life_table.M.values # It would be slightly more convient to work with these values if we knew, for a man of any particular age, the probability of being alive at any age. We calculate a new life table which has along each row $x$ the probability that a man of age $x$ will live to reach age $y$. # In[6]: # Create a new life table l = len(prob_death) life_table = np.ones((l,l)) for i in range(0,l,1): for j in range(i,l,1): life_table[i][j]=np.prod(1 - prob_death[i:j+1]) # In[30]: # Load current apostle ages and seniority apostle_data = pd.read_csv('../data/apostles.csv', parse_dates=['Birth', 'Twelve', 'Ordained']) now = pd.Timestamp(datetime.now()) apostle_data['Current Age'] = (now - apostle_data['Birth']).astype(' np.random.random(len(life_table[0]))) return self.birth.year + death_year def simulate_life_state(self,year,life_table): """Return True if the apostle is alive given a year of death drawn from the distribution of likely death years given by a particular life table.""" life_state = self.simulate_death_year(life_table) return year <= self.simulate_death_year(life_table) # In[32]: # Create apostle objects and print their ages apostles = [] for i,row in apostle_data.iterrows(): apostle = Apostle(row.Name,row.Birth,row.Twelve,row.Ordained,row.Seniority) apostles.append(apostle) dy = apostle.most_probable_death_year(life_table) age_death = dy - apostle.birth.year msg = """ {}. {} is {} years old. Life table predicts he will live to age {}.""" print(msg.format(apostle.seniority,apostle.name,apostle.current_age(),age_death)) # ### Methodology # Now we define two more functions to help us calculate who is prophet in a particular year. # Each of these functions uses a different method to calculate who will be prophet: # # #### Method 1: Winner takes all # The simplest method simply calculates which year each apostle is likely to die in (by # taking the first year they are more likely to be dead than alive) and returns the most # senior living apostle who is more likely to be alive than dead. # # #### Method 2: Monte-Carlo simulation # A slightly more interesting (and more robust) method runs a simulation for each apostle, # making draws from the whole distribution of probable years of death. If we run this # simulation many many times, we will end up with estimates of the probability that each # apostle will be prophet in any particular year. This method will end up giving us a # clearer picture than the winner takes all method. # # #### Method 3: Accounting for health # This method repeats the Monte-Carlo simulation but allows for manual adjustment of the health of # the apostles be adding or subtracting years from their life. By default, since all have lived very healthy # lives, eight years are subtracted from each of their ages (to simulate an average life expectancy of 85. From there, up to two years is added or subtracted to account for perceived health status (very unhealthy, unhealty, normal, healthy, very healthy). # In[33]: # define some helper functions for calculating who is prophet in a particular year # using two different methods def most_probable_prophet_in_year(apostles,year,life_table): """Return the apostle (given a list of apostles) most likely to be prophet in a particular year""" apostles_alive = [apostle for apostle in apostles if apostle.most_probable_life_state(year,life_table)] if len(apostles_alive) == 0: return None apostle_index = np.argmin([apostle.seniority for apostle in apostles_alive]) return apostles_alive[apostle_index] def simulate_prophet_in_year(apostles,year,life_table): """Return the apostle (given a list of apostles) who is prophet in a particular year after simulating each apostle's life state in the given year.""" apostles_alive = [apostle for apostle in apostles if apostle.simulate_life_state(year,life_table)] if len(apostles_alive) == 0: return None apostle_index = np.argmin([apostle.seniority for apostle in apostles_alive]) return apostles_alive[apostle_index] # In[34]: # Plot a histogram of each apostle's likely death years for apostle in apostles: death_year_dist = [] for i in range(10000): death_year_dist.append(apostle.simulate_death_year(life_table)) plt.hist(death_year_dist,bins=range(CURRENT_YEAR,2040)) plt.title("Histogram of year of death of {}".format(apostle.name)) plt.show() # In[35]: # Given our model, who is most likely to be prophet in the year 2020? print(most_probable_prophet_in_year(apostles,2020,life_table)) # ### Method 1 # In[36]: # Given our model, who is most likely to be prophet in every year from now until 2040? for year in range(CURRENT_YEAR,CURRENT_YEAR+25): print("{}: {}".format(year, most_probable_prophet_in_year(apostles,year,life_table))) # ### Method 2 - simulation: # # What if we looked at the probabilities over 10000 trials? This would give us a # more accurate picture of how likely it is that any of the current apostles # will be prophet in any particular year. Note that it is possible (and probable) # that in some of the later years none of the current apostles will be alive. In # these cases, I have assigned a probability of prophethood to "other". # In[37]: def run_simulation(n_trials,apostles,life_table): for year in range(CURRENT_YEAR,CURRENT_YEAR+25): prophets = defaultdict(list) for i in range(n_trials): prophet = simulate_prophet_in_year(apostles,year,life_table) if prophet is not None: prophets[prophet.name].append(1) else: prophets["other"].append(1) probabilities = [] for key,count in prophets.items(): probabilities.append((key,float(len(count))/n_trials)) probabilities = sorted(probabilities,key=lambda x: x[1],reverse=True) print(year) for name,probability in probabilities: print(" {} ({})\n".format(name,probability)) # In[38]: run_simulation(10000,apostles,life_table) # ### Method 2 - conclusions # # Interestingly, for many of the years far down the line, the apostle most likely to be prophet is far from clear. # # By 2029 our model says that it is more likely that someone other than one of the current apostles will be prophet. However, since our model systematically underestimates the age of death of these men, we should take this number with a grain of salt. In 25 years there is virtually no possiblity that anyone of the apostles will be living. it's extraordinarily unlikely that any of the current apostles will still be alive. Gary E. Stevenson is the youngest apostle living and our model only predicts a .01% chance of living that long. # # #### Caveats # This model did not explicitly take health state into account, but approximated it using current age. Method 3 is one way of accounting for this. # # ### Method 3 - adjusting for health and systematic mortality biases. # One way to approximate of actual health status is to adjust their ages to reflect both their current health and the greater-than-average overall health of their demographic. # In[65]: default = 5 apostle_age_adjustments = { # All defaults - church has done a solid job limiting news of apostles health "Russell M. Nelson": default, "Dallin H. Oaks": default, "M. Russell Ballard": default, "Jeffrey R. Holland": default, "Henry B. Eyring": default, "Dieter F. Uchtdorf": default, "David A. Bednar": default, "Quentin L. Cook": default, "D. Todd Christofferson": default, "Neil L. Andersen": default, "Ronald A. Rasband": default, "Gary E. Stevenson": default, "Dale G. Renlund": default, } # In[66]: adj_apostles = [] for apostle in apostles: adg_adj = apostle_age_adjustments[apostle.name] adj_apostles.append(Apostle( apostle.name, (a.birth + timedelta(days=8*365)), apostle.twelve, apostle.ordained, apostle.seniority)) # In[67]: run_simulation(10000,adj_apostles,life_table) # In[ ]: