<jupyter_start><jupyter_text>Table of Contents- [Introduction](introduction) - [Breastfeeding](breastfeeding)  - [What is breastfeeding and why is it important?](w_breastfeeding) - [Variables](variables)  - [Age](age)  - [Civil Status](civil_status)  - [Health Insurance Status](hel_ins_status)  - [Initiate Breastfeeding](int_breastfeeding)- [Dataset](dataset)- [References](references)- [Other Sources](other_sources) IntroductionThe project requires us to simulate a real-world phenomenon of our choosing.We have been asked to model and synthesise data related to this phenomenon using Python, particularly the numpy.random library. The output of the project should be a synthesised data set.I will be examining the rate of breastfeeding initiation in Ireland. I will create a dataset of variables associated with breastfeeding. I will simulate the distribution of breastfeeding initiation in a random sample of an identified segment of the population. I will explore the relationships between these factors and how they may influence the rate of breastfeeding initiation.This will include:1.	The distribution of breastfeeding initiation in an identified segment of the population2.	The factors contributing to breastfeeding initiation3.	How these factors are distributed in the identified segment of the populationThis topic is of particular interest to me as I have been successfully breastfeeding my daughter for the past year. The publication of the Irish Maternity Indicator System National Report 2019 report [4] received widespread news coverage and highlighted the low breastfeeding rates in Ireland [5]. On reflection, I was unable to identify how I had decided to breastfeed. I began to read more on the topic, including how Irish rates compare to international rates and breastfeeding socio-cultural changes. From this, I identified influencing factors on breastfeeding initiation. While I meet some of the criteria, I do not meet all. And yet as a mother in Ireland exclusively breastfeeding for over 12 months, I am one of only 7%. This intrigued me, and I wanted to examine what factors may have influenced my breastfeeding journey. Breastfeeding![Lactation Image]("https://github.com/SharonNicG/52465-Project/blob/main/Lactation%20Image%20OS.jpg") What is breastfeeding and why is it important?Breastfeeding, or nursing, is the process of providing an infant with their mother's breastmilk [6]. This is usually done directly from the breast but can also be provided indirectly using expressed breast milk [*Ibid.*]. Breastfeeding is important as it offers numerous health benefits for both mother and infant.**Benefits to infant:*** Breast milk is naturally designed to meet the calorific and nutritional needs of an infant [7] and adapts to meet the needs of the infant as they change [8]* Breast milk provides natural antibodies that help to protect against common infections and diseases [*Ibid.*]* Breastfeeding is associated with better long-term health and wellbeing outcomes including less likelihood of developing asthma or obesity, and higher income in later life [9]**Benefits to mother:** * Breastfeeding lowers the mother's risk of breast and ovarian cancer, osteoporosis, cardiovascular disease, and obesity [10]. * Breastfeeding is associated with lower rates of post-natal depression and fewer depressive symptoms for women who do develop post-natal depression while breastfeeding [11, 12].  * Breastfeeding is a cost-effective, safe and hygienic method of infant feeding [13]. The World Health Organisation (WHO), and numerous other organizations recommend exclusively breastfeeding for the first six months of an infant's life and breastfeeding supplemented by other foods from 6 months on [14, 15, 16, 17]. However, globally nearly 2 out of 3 infants are not exclusively breastfed for the first six months [18]. Ireland has one of the lowest breastfeeding initiation rates in the world, with 63.8% of mothers breastfeeding for their child's first feed [19]. The rate of breastfeeding drops substantially within days as on average, only 37.3% of mothers are breastfeeding on discharge from hospital [*Ibid.*].Given the physical, social and economic advantages to breastfeeding over artificial and combination feeding (a mix of breast and artificial) both the WHO and the HSE have undertaken a number of measures to increase the rates of breastfeeding initiation and exclusive breastfeeding for the first six months in Ireland [20, 21].Funded research is one of these measures, including national longitudinal studies to identify factors that may influence breastfeeding rates [22]. VariablesA review of some of the completed research projects has identified common factors that have been researched and for which there is a bank of data to refer to. These are identified in the table below:| Variable Name            | Description                         | Data Type | Distribution      ||--------------------------|-------------------------------------|-----------|-------------------|| Age                      | Age of mother                       | Numeric   | Normal/Triangular || Civil Status             | Civil status of mother              | Boolean   | Normal/Triangular || Private Health Insurance | Whether mother has health insurance | Boolean   | Normal/Triangular |These factors will be used as the variables for the development of the dataset. The fourth variable will be 'Breastfeeding Initiation'. This will be informed by data from existing research and dependent on values assigned to records under the other variables. | Variable Name            | Description        | Data Type | Distribution      ||--------------------------|--------------------|-----------|-------------------|| Breastfeeding Initiation | Dependent Variable | Boolean   | Normal/Triangular |A trawl of information sources led to the decision to use data from 2016. While National Perinatal Reporting System (NPRS) produce annual reports [*Ibid.*], they are published with a 12-month delay, and final versions (following feedback and review) are available after 24 months. This means the 2016 report is the latest final version available. An initial search for information on Civil Status statistics led to the 2016 census data. While this ultimately wasn't used, it guided the use of the 2016 NPRS data. Similarily historical data on Private Health Insurance rates in Ireland varies greatly, and 2016 seemed to produce the most applicable data for use here. Below is an outline of each variable; the data is based on and how it will be used for the development of a dataset. As the expected distributions for each variable are the same different approaches will be taken with each to generate them for the dataset.  AgeA review of data provided by the NPRS study is used here to determine how maternal age is distributed across the population - mothers with live births in 2016 [23].While age is a numerical value, it is presented by NPRS as a categorical variable/discrete groups, ranging from under 20 years of age to 45 years of age and older. The NPRS study provides the frequency and percentages of births within each group.<jupyter_code># Downloaded NPRS_Age.csv from NPRS 2016 Report
age = pd.read_csv("Data/Age_and_Feeding_Type.csv", index_col='Age Group')

# Transpose index and columns 
age = age.T

# Integer based indexing for selection by position - See References #24
age = age.iloc[0:4, 0:7]

age<jupyter_output><empty_output><jupyter_text>The grouping of data by age group reduces the usefulness of the `describe()` function on the data frame. However, an initial view of the NPRS data indicates that the data is somewhat normally distributed with births increasing in the 25 - 29 age group, peaking at 30 - 34 years of age and beginning to decline in the 35 - 39 age set. Visualising the data set supports this analysis. It shows a minimum value of fewer than 20 years of age increasing in a positive direction until it significant peak around 32 years of age - the midpoint of the age group with the greatest frequency of births.<jupyter_code># Creates a figure and a set of subplots.
fig, ax = plt.subplots(figsize=(5, 5), dpi=100)
x_pos = np.arange(7)

# Plot x versus y as markers
ax.plot(x_pos, age.iloc[0, :], marker='^', label='Breast')
ax.plot(x_pos, age.iloc[1, :], marker='^', label='Artificial')
ax.plot(x_pos, age.iloc[2, :], marker='^', label='Combined')

# Set labels for chart and axes
ax.set_title('Age and Feeding Type')
ax.set_xlabel('Maternal Age at Time of Birth')
ax.set_ylabel('Frequency')

# Create names on the x-axis
ax.set_xticks(x_pos)

# Rotate to make labels easier to read
ax.set_xticklabels(age.columns, rotation=90)

# Position legend
ax.legend(loc="best")

# Show plot
plt.show()<jupyter_output><empty_output><jupyter_text>The initial approach taken was to create a function that generated a random number using the percentages from the csv file and assigned this to each record.<jupyter_code>def age_distribution():
        y = rng.integers(1,100)
        if y <= 23:
                return random.randint(15,19)
        elif 23 < y <= 43:
                return random.randint(20,24)
        elif 43 < y <= 62:
                return random.randint(25,29)
        elif 62 < y <= 77:
                return random.randint(30,34)
        elif 77 < y <= 88:
                return random.randint(35,39)
        elif 88 < y <= 95:
                return random.randint(40,44)
        else:
                return random.randint(45,49)
            
Age = age

data = {'Age': age}<jupyter_output><empty_output><jupyter_text>Then I realised that the distribution visualised above could be replicated using a Triangular Distribution. This generates a random number from a weighted range by distributing events between the maximum and minimum values provided, based on a third value that indicates what the most likely outcome will be [25, 26]. Here we are looking for 100 events (births) distributed between the ages of 16 and 50 with a known peak where the mothers age is 32.<jupyter_code># Here we are looking for a random array with a lower limit of 16 an upper limit of 50
# and 32 being the number that appears most frequently (the midpoint of the most frequent age group)
# over n number of instances where n is the total number of births
# and for the out to be presented on a Triangular Distribution plot

Tri_var = np.random.triangular(left = 20, mode = 30, right = 50, size = 100).astype(int)
print ("Here is your triangular continuous random variable:\n % s" % (Tri_var)) # [55]

# Triangular Distribution - See References #27
plt.hist(np.ma.round(np.random.triangular(left = 20, mode = 30, right = 50, size = 100)).astype(int),
        range = (16, 50), bins = 300, density = True)

# Set labels for chart and axes
plt.title('Randomised Distribution of Age')
plt.xlabel('Maternal Age at Birth of Child')
plt.ylabel('Frequency')

# Show plot
plt.show()<jupyter_output>Here is your triangular continuous random variable:
 [28 23 21 28 29 34 41 42 46 37 25 45 46 38 29 32 24 22 31 29 26 37 32 31
 31 44 44 22 27 28 37 32 24 42 32 31 37 44 23 27 32 36 35 32 37 47 39 32
 31 39 41 43 36 25 32 39 35 33 45 33 43 36 26 37 42 26 30 37 26 32 37 34
 35 25 38 44 32 35 22 29 27 29 43 33 44 22 23 44 29 29 28 25 29 36 27 32
 43 39 36 40]<jupyter_text>Civil Status Research has shown that maternal civil status at the time of birth is significantly associated with breastfeeding initiation [28,29,30].Data captured in the 2016 NPRS survey does not capture relational data between breastfeeding initiation and maternal civil status at the time of birth [31]. However, it does provide percentage values for maternal civil status across all age groups:| Maternal Civil Status at Birth | Percentage of Total births ||--------------------------------|----------------------------|| Married                        | 62.2                       || Single                         | 36.4                       || Other                          | 1.4                        |Central Statistics Office (CSO) data on civil status for 2016 does record information across all age groups [32]. However, as it only captures data for * Marriages* Civil partnerships* Divorces, Judicial Separation and Nullity applications received by the courts * Divorces, Judicial Separation and Nullity applications granted by the courts It does not capture other civil arrangements such as informal separations or co-habitants.For the purposes of this simulation, the NPRS data will be used.This is a categorical variable that has three possible values1. Married2. Single3. Other (encompassing all other civil statutes as identified by the survey respondent)Note, that same sex marriage wasn't legal in 2016 and Civil Partnerships are recorded as Other in the NPRS Report.The first approach was to link the age of a person to a civil status by calculating how many people within each age group may fall into each civil status category, based on the NPRS data. This was excessively complicated - requiring an If statement, a dictionary and a For Loop. While it produced a good distribution, it wasn't easily amendable if the figures changed as each line needed to be amended in the dictionary.<jupyter_code>def civil_status(x):
        
        def distribution(st):
                x = rng.integers(0,100)
                if x <= chances[0][0]:
                        return chances[0][1]
                elif x <= chances[0][0] + chances[1][0]:
                        return chances[1][1]
                return chances[2][1]
            
        status = { range(15,20) : [(0,'other'),(95,'Single'),(5,'Married')]}

        for i in status:
            if x in i:
                return distribution(status[i])<jupyter_output><empty_output><jupyter_text>Instead, a much simpler way based on the information in the NPRS report `rng.choice` can be used to randomly distribute these values across the dataset population.<jupyter_code># Classifying Civil Status
# 'single' if single, 'married' if married and 'other' for all other categories
civil_options = ['single', 'married', 'other']

# Randomisation of civil status based on the probability provided
civil_status = rng.choice(civil_options, n, p=[.364, .622, .014])

# Count of zero elements in array - See References #33 
print("Single: ", np.count_nonzero(civil_status == 'single'))
print("Married: ", np.count_nonzero(civil_status == 'married'))
print("Other: ", np.count_nonzero(civil_status == 'other'))<jupyter_output>Single:  23360
Married:  39496
Other:  883<jupyter_text>Health Insurance StatusGallagher's research also highlighted a significant association between the health insurance status of a mother and breastfeeding initiation [34]. A review of other research into factors affecting breastfeeding initiation showed that access to enhanced peri- and postnatal medical care have considerable influence on breastfeeding initiation and continuance [35, 36, 37]. These were primarily completed in countries without a funded, or part-funded national health service. While these demonstrated that mothers with private health insurance were more likely to initiate breastfeeding, they weren't comparable in an Irish context. However, a follow-on study from Gallagher's research further supported her findings that maternal access to private health insurance increased the likelihood of breastfeeding [38].The Health Insurance Authority (HIA) in Ireland offers a comparison tool for health insurance policies, including the services available under each plan [39]. A review, carried out in December 2020, shows that of 314 plans on offer 237 provide outpatient maternity benefits which cover peri and postnatal cover care and support systems. These include one-to-one postnatal consultation with a lactation consultant. For mothers without health insurance, maternity care in Ireland is provided under the Maternity and Infant Care Scheme [40]. This is a combined hospital and GP service for the duration of pregnancy and six weeks postpartum. No specific resources are made available to support breastfeeding, though maternity hospitals and units may offer breastfeeding information sessions and one-to-one lactation consultations where needed. Access to these supports is limited. The Coombe Women's and Children's Hospital, for example, handles around 8,000 births per year [41] and provides breastfeeding information sessions to less than 1,000 mothers per year [42]. There are a number of community supports for breastfeeding, including [Le Leche](https://www.lalecheleagueireland.com/), [Friends of Breastfeeding](https://www.friendsofbreastfeeding.ie/) and [Cuidiu](https://www.cuidiu.ie/) and private lactation consultants. Interestingly, neither Irish study assessed whether mothers accessed these services perinatally. Gallagher's research showed that 66% of the insured mothers initiated breastfeeding [43]. As insurance status can only have two possible outcomes (True or False), a binomial distribution was initially used to evaluate distribution across `n` number of births.<jupyter_code># Here we are looking for a Binomial Distribution 
# with probability of 0.66 for each trial
# repeated `n` times
# to be presented as a Binomial Bistribution plot
sns.distplot(rng.binomial(n=10, p=0.66, size=n), hist=True, kde=False)

# Set labels for chart and axes
plt.title('Insurance Distribution Based on Percentage Insured')
plt.xlabel('Age Distribution')
plt.ylabel('Number Insured')

# Show plot
plt.show()<jupyter_output><empty_output><jupyter_text>While this randomly allocated health insurance status, it didn't distribute this across the age groups in an informed way.The HIA also provide historical market statistics on insurance in Ireland [44]. Data for 2016 based on the age groups previously used, the number of the total population insured within these groupings that are insured and the percentage of the total insured population these represent was extracted from the HIA historical market statistics into a csv file.<jupyter_code># Downloaded HIA historicial market statistics
ins = pd.read_csv("Data/Insurance_by_Age.csv")
ins<jupyter_output><empty_output><jupyter_text>The extracted data shows a positive increase in the number of people insured from ages 20 to 35. Peaking significantly in the 35-39 category and declining thereafter. Visualising the data supports this analysis.<jupyter_code># Downloaded HIA historicial market statistics
ins = pd.read_csv('Data/Insurance_by_Age.csv', index_col='Age')

# Transpose index and columns 
ins = ins.T
ins

# Creates a figure and a set of subplots
fig, ax = plt.subplots(figsize=(5,3), dpi=100)
x_pos = np.arange(7)

# Integer based indexing for selection by position - See References #24 
# Scaled down
y = ins.iloc[1, :] / 100
y = y*ins.iloc[0, :]

# Plot x versus y as markers
ax.plot(x_pos, y, marker='o', label='Insurance')

# Set labels for chart and axes
ax.set_title('Insurance by Age')
ax.set_xlabel('Maternal Age')
ax.set_ylabel('Number Insured')

# Create names on the x-axis
ax.set_xticks(x_pos)

# Rotate to make labels easier to read
ax.set_xticklabels(age.columns, rotation=90)

# Show plot
plt.show()<jupyter_output><empty_output><jupyter_text>While it isn't possible to get a breakdown of insurance status by gender or linked to the parity of women within the given age groups, the above analysis has provided two points to work from in the generated dataset: the percentage of people within the age groups that are likely to have health insurance, and that 66% of pregnant women have health insurance.<jupyter_code># ins_by_age(x) takes one argument - the age of the person
# based on this number and the percentages identified from HIA 
# it gives each record a value of True or False

# a dict that holds the HIA statistics
def ins_by_age (x):
        
        agerange_insurance = {range(15,20) : 10,
                                  range(20,25) : 9,
                                  range(25,30) : 9,
                                  range(30,35) : 14,
                                  range(35,40) : 19,
                                  range(40,45) : 19,
                                  range(45,50) : 20}
        
# Introduce randomisation by assigning True or False based on
# a randomly assigned number generated by rng.integers
 
        for i in agerange_insurance:
                if x in i:
                        y =  rng.integers(1,100)
                        if y <= agerange_insurance[i]:
                              return True  
                        return False
                    
health_ins_status = np.array([ins_by_age(i) for i in age])<jupyter_output><empty_output><jupyter_text>Initiate BreastfeedingThis variable is based on the data used above and in Gallagher's study [45]. Using the data from the NPRS report the percentage of women within each age group that are likely to initiate breastfeeding can be calculated.<jupyter_code># Percentage of total births that initiate breastfeeding
age = pd.read_csv("Data/Age_and_Feeding_Type.csv")
age = age.iloc[0:7, 0:8]
age['pct']=age['Breast']/(age['Total'])*100  

age<jupyter_output><empty_output><jupyter_text>Additionally, this variable will be a dependant variable influenced by data from the other variables and information Gallagher's study:1. Women with health insurance are more likely to initiate breastfeeding * 66% of women have access to health insurance [*Ibid*]2. Civil Status influences the likelihood of breastfeeding * Married women are three times more likely to breastfeed  Dataset<jupyter_code># the number of records
n = 100<jupyter_output><empty_output><jupyter_text>Variable 1 - Age<jupyter_code># A Triangular Distribution with a lower limit of 16 an upper limit of 50
# and 32 being the number that appears most frequently (the midpoint of the most frequent age group)
# over n number of instances where n is the total number of births

age_dist = (np.random.triangular(left = 16, mode = 30, right = 50, size = 500)).astype(int)

# Using rng.choice to randomise the output
age = rng.choice(age_dist, n)

# generating the dataframe using the the age distribution
df = pd.DataFrame(age, columns = ['Maternal Age'])<jupyter_output><empty_output><jupyter_text>Variable 2 - Civil Status<jupyter_code># Classifying Civil Status
# 'single' if single, 'married' if married and 'other' for all other categories
civil_status = ['single', 'married', 'other']

# Randomisation of civil status based on the probability provided
civil_status = rng.choice(civil_status, n, p=[.364, .622, .014])<jupyter_output><empty_output><jupyter_text>Varible 3 - Insurance Status<jupyter_code># ins_by_age(x) takes one argument - the age of the person
# based on this number and the percentages identified from HIA 
# it gives each record a value of True or False

# a dictionary that holds the HIA statistics

def ins_by_age (x):
        
        agerange_insurance = {range(15,20) : 10,
                                  range(20,25) : 9,
                                  range(25,30) : 9,
                                  range(30,35) : 14,
                                  range(35,40) : 19,
                                  range(40,45) : 19,
                                  range(45,50) : 20}

        # Introduce randomisation by assigning True or False based on
        # a randomly assigned number generated by rng.integers

        for i in agerange_insurance:
                if x in i:
                        y =  rng.integers(1,100)
                        if y <= agerange_insurance[i]:
                              return True  
                        return False
                    
health_ins_status = np.array([ins_by_age(i) for i in age])

df['Health Insurance Status'] = health_ins_status<jupyter_output><empty_output><jupyter_text>Variable 4 - Initate Breastfeeding<jupyter_code># ins_by_age(x) takes one argument - the age of the person
# based on this number and the percentages identified from HIA 
# it gives each record a value of True or False

# a dictionary that holds the calculated percentage statistics

def breastfeeding(x):
        
        bf_status = {range(15,20) : 23,
                     range(20,25) : 32,
                     range(25,30) : 43,
                     range(30,35) : 53,
                     range(35,40) : 55,
                     range(40,45) : 53,
                     range(45,50) : 50}

        a = age[x]  # the age of the person
        b = health_ins_status[x]  # the person's health insurance status
        c = civil_status[x]  # the person's civil status

        q = 3 if c == 'Married' else 2 if c == 'Other' else 1 
        # If married they are 3 times more likely to start the program
        # Assigning 2 for people with Other as they may have an informal arrangemnt
        # Assigning 1 for people who identify as single

        # Introduce randomisation by assigning True or False based on
        # a randomly assigned number generated by rng.integers
        for i in bf_status:
                if a in i:
                        y =  rng.integers(1,1000)
                        if y <= q*bf_status[i] or (b == True and y <= 66): # Using 66 as ^^% of insured women initiate breastfeeding
                              return True  
                        return False

# generating the variable based on the function
initiate_bf = np.array([breastfeeding(i) for i in age])

df['Initiate Breastfeeding'] = initiate_bf<jupyter_output><empty_output><jupyter_text>Dataset<jupyter_code># See References #46 and #47 

pd.set_option("expand_frame_repr", True)

df<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0725253312548714, 'fraction_numerical': 0.030631332813717847, 'mean_word_length': 3.421261199172984, 'pattern_counts': {'":': 0, '<': 84, '<?xml version=': 0, '>': 67, 'https://': 4, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '11515', 'license': 'MIT', 'n_tokens_mistral': 7329, 'n_tokens_neox': 6222, 'n_words': 3196, 'path': 'Simulated Phenomenon.ipynb', 'repo_name': 'SharonNicG/52465-Project', 'size': '25660'}