--- title: What's in your cocktails? author: Xuxin Zhang date: '2020-09-21' slug: cocktails-analysis categories: - R project tags: - data visualization - Rshiny subtitle: '' summary: '' authors: [] lastmod: '2020-09-21T12:00:34+08:00' featured: no image: caption: '' focal_point: '' preview_only: yes output: blogdown::html_page: toc: false runtime: shiny projects: [] ---
Several days ago, I went to a bar to celebrate one of my friends’ birthday. We ordered some cocktails. However, when my drink was served, since I am not an alcoholic person, I couldn’t really recognize what was in my margarita after a few sippings, which makes me wonder if I could develop some interactive web application so that people would know what are the ingredients added to their booze.
This project explore the recipes of cocktails. The main focus would be put on analyzing ingredients of different types of cocktails. At the end of the project, we wil create an interactive bar plot to show the composition of certain type of cocktail drinks.
First, we need to import the two datasets we are going to use.
library(tidyverse)
library(DT)
theme_set(theme_light())
cocktails <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-05-26/cocktails.csv')
boston_cocktails <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-05-26/boston_cocktails.csv')
After importing the data, I wonder what is the difference between these two datasets, so I calculate the number of drinks incorporated and find out that the boston_cocktails
contains more type of drinks. In addition, notice that the boston_cocktails
has a more uniform units for the measure column, which would facilitate our construction of the interactive bar plot. Thus, we will stick with the boston datasets for the rest of the project.
library(stringr)
library(knitr)
cocktails%>%distinct(drink)
## # A tibble: 546 x 1
## drink
## <chr>
## 1 '57 Chevy with a White License Plate
## 2 1-900-FUK-MEUP
## 3 110 in the shade
## 4 151 Florida Bushwacker
## 5 155 Belmont
## 6 24k nightmare
## 7 252
## 8 3 Wise Men
## 9 3-Mile Long Island Iced Tea
## 10 410 Gone
## # … with 536 more rows
kable(head(cocktails,20))
| row_id | drink | date_modified | id_drink | alcoholic | category | drink_thumb | glass | iba | video | ingredient_number | ingredient | measure |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ’57 Chevy with a White License Plate | 2016-07-18 22:49:04 | 14029 | Alcoholic | Cocktail | http://www.thecocktaildb.com/images/media/drink/qyyvtu1468878544.jpg | Highball glass | NA | NA | 1 | Creme de Cacao | 1 oz white |
| 0 | ’57 Chevy with a White License Plate | 2016-07-18 22:49:04 | 14029 | Alcoholic | Cocktail | http://www.thecocktaildb.com/images/media/drink/qyyvtu1468878544.jpg | Highball glass | NA | NA | 2 | Vodka | 1 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 1 | Absolut Kurant | 1/2 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 2 | Grand Marnier | 1/4 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 3 | Chambord raspberry liqueur | 1/4 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 4 | Midori melon liqueur | 1/4 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 5 | Malibu rum | 1/4 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 6 | Amaretto | 1/4 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 7 | Cranberry juice | 1/2 oz |
| 1 | 1-900-FUK-MEUP | 2016-07-18 22:27:04 | 15395 | Alcoholic | Shot | http://www.thecocktaildb.com/images/media/drink/uxywyw1468877224.jpg | Old-fashioned glass | NA | NA | 8 | Pineapple juice | 1/4 oz |
| 2 | 110 in the shade | 2016-02-03 14:51:57 | 15423 | Alcoholic | Beer | http://www.thecocktaildb.com/images/media/drink/xxyywq1454511117.jpg | Beer Glass | NA | NA | 1 | Lager | 16 oz |
| 2 | 110 in the shade | 2016-02-03 14:51:57 | 15423 | Alcoholic | Beer | http://www.thecocktaildb.com/images/media/drink/xxyywq1454511117.jpg | Beer Glass | NA | NA | 2 | Tequila | 1.5 oz |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 1 | Malibu rum | 1/2 oz |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 2 | Light rum | 1/2 oz |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 3 | 151 proof rum | 1/2 oz Bacardi |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 4 | Dark Creme de Cacao | 1 oz |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 5 | Cointreau | 1 oz |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 6 | Milk | 3 oz |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 7 | Coconut liqueur | 1 oz |
| 3 | 151 Florida Bushwacker | 2016-07-18 22:28:43 | 14588 | Alcoholic | Milk / Float / Shake | http://www.thecocktaildb.com/images/media/drink/rvwrvv1468877323.jpg | Beer mug | NA | NA | 8 | Vanilla ice-cream | 1 cup |
boston_cocktails%>%distinct(name)
## # A tibble: 989 x 1
## name
## <chr>
## 1 Gauguin
## 2 Fort Lauderdale
## 3 Apple Pie
## 4 Cuban Cocktail No. 1
## 5 Cool Carlos
## 6 John Collins
## 7 Cherry Rum
## 8 Casa Blanca
## 9 Caribbean Champagne
## 10 Amber Amour
## # … with 979 more rows
kable(head(boston_cocktails,20))
| name | category | row_id | ingredient_number | ingredient | measure |
|---|---|---|---|---|---|
| Gauguin | Cocktail Classics | 1 | 1 | Light Rum | 2 oz |
| Gauguin | Cocktail Classics | 1 | 2 | Passion Fruit Syrup | 1 oz |
| Gauguin | Cocktail Classics | 1 | 3 | Lemon Juice | 1 oz |
| Gauguin | Cocktail Classics | 1 | 4 | Lime Juice | 1 oz |
| Fort Lauderdale | Cocktail Classics | 2 | 1 | Light Rum | 1 1/2 oz |
| Fort Lauderdale | Cocktail Classics | 2 | 2 | Sweet Vermouth | 1/2 oz |
| Fort Lauderdale | Cocktail Classics | 2 | 3 | Juice of Orange | 1/4 oz |
| Fort Lauderdale | Cocktail Classics | 2 | 4 | Juice of a Lime | 1/4 oz |
| Apple Pie | Cordials and Liqueurs | 3 | 1 | Apple schnapps | 3 oz |
| Apple Pie | Cordials and Liqueurs | 3 | 2 | Cinnamon schnapps | 1 oz |
| Cuban Cocktail No. 1 | Cocktail Classics | 4 | 1 | Juice of a Lime | 1/2 oz |
| Cuban Cocktail No. 1 | Cocktail Classics | 4 | 2 | Powdered Sugar | 1/2 oz |
| Cuban Cocktail No. 1 | Cocktail Classics | 4 | 3 | Light Rum | 2 oz |
| Cool Carlos | Cocktail Classics | 5 | 1 | Dark rum | 1 1/2 oz |
| Cool Carlos | Cocktail Classics | 5 | 2 | Cranberry Juice | 2 oz |
| Cool Carlos | Cocktail Classics | 5 | 3 | Pineapple Juice | 2 oz |
| Cool Carlos | Cocktail Classics | 5 | 4 | Orange curacao | 1 oz |
| Cool Carlos | Cocktail Classics | 5 | 5 | Sour Mix | 1 oz |
| John Collins | Whiskies | 6 | 1 | Bourbon whiskey | 2 oz |
| John Collins | Whiskies | 6 | 2 | Fresh lemon juice | 1 oz |
Next, we will find out the ingredients used the most in the recipes. In this way, even though you may have no idea about what’s in your cocktails, chances are that if you pick one of most frequently used ingredients listed below, you may get the correct answer (and you can show off a little bit in front of your friends). The following is a list of the top 10 ingredients used to create cocktails.
boston_cocktails%>%count(ingredient, sort = TRUE)%>%head(10)%>%
ggplot(aes(x = reorder(ingredient,n), y = n))+
geom_point(aes(size = n), alpha = 0.2)+
geom_segment(aes(x=reorder(ingredient,n),
xend = reorder(ingredient,n),
y = 0, yend = n,size = n), alpha = 0.2)+
ylim(0,180)+theme_minimal()+
theme(
axis.text.x = element_text(vjust = 0.8),
axis.text.y = element_blank(),
axis.title.y = element_blank(),
legend.position = "null")+
labs(x = "Ingredient", y = "Count",
title = "Top 10 ingredients used in cocktail recipes")+
coord_polar(clip = "off")
We can visualize in another way by drawing a word cloud plot.
From these two graphs, we can see that the top ingredients are gin, fresh lemon juice,simple syrup, and vodka.
I also wonder which category requires the most ingredients on average. We start by finding out how many types of cocktails are there. Based on the list below, we can see there are altogether 11 types of drinks.
boston_cocktails%>%count(category,sort = TRUE)%>%kable()
| category | n |
|---|---|
| Cocktail Classics | 1560 |
| Vodka | 545 |
| Whiskies | 457 |
| Rum - Daiquiris | 437 |
| Tequila | 371 |
| Brandy | 169 |
| Gin | 67 |
| Cordials and Liqueurs | 24 |
| Shooters | 6 |
| Rum | 4 |
| Non-alcoholic Drinks | 3 |
Then we summarize the average number of ingredients for each type. We can take a look at which cocktail has the most ingredients. As the table shows, the greatest number of ingredients is 6, and there are quite a lot of drinks which are made from 6 ingredients.
number_ingredient<-boston_cocktails%>%group_by(category,name)%>%summarise(num_ing = max(ingredient_number))
## `summarise()` regrouping output by 'category' (override with `.groups` argument)
kable(head(number_ingredient%>%arrange(desc(num_ing)),20))
| category | name | num_ing |
|---|---|---|
| Brandy | Cherry Blossom | 6 |
| Brandy | Deauville Cocktail | 6 |
| Cocktail Classics | Applejack Punch | 6 |
| Cocktail Classics | Betsy Ross Cocktail | 6 |
| Cocktail Classics | Eye-Opener | 6 |
| Cocktail Classics | Frankenjack Cocktail | 6 |
| Cocktail Classics | Gloom Lifter | 6 |
| Cocktail Classics | Green Hornet (Dry) | 6 |
| Cocktail Classics | Hyatt’s Jamaican Banana | 6 |
| Cocktail Classics | New Orleans Gin Fizz | 6 |
| Cocktail Classics | Prairie Oyster Cocktail | 6 |
| Cocktail Classics | Ramos Fizz | 6 |
| Cocktail Classics | Red Swizzle | 6 |
| Cocktail Classics | Sand-Martini Cocktail | 6 |
| Cocktail Classics | Sidecar | 6 |
| Cocktail Classics | Tahitian Tea | 6 |
| Gin | The Winkle | 6 |
| Gin | Vow Of Silence | 6 |
| Rum - Daiquiris | Fog Cutter | 6 |
| Rum - Daiquiris | Hai Karate | 6 |
After knowing this, we can draw boxplot to show the distribution of number of ingredients for each type.
number_ingredient%>%
ggplot(aes(x = num_ing, y = reorder(category, num_ing)))+
geom_boxplot()+
labs(x = "Number of ingredients",
y ="Category of cocktails",
title = "The distribution of number of ingredients for different cocktail categories ")+
xlim(0,7)
Based on the graph above, we konw that tequila cocktails and whiskies cocktails have the highest average number of incredients being used.
After knowing these rudimentary facts about cocktails, we are ready to build the interactive web application.
Our goal is to create an interactive application that shows you which ingredients are added to your cocktail as well as the corresponding proportions. In order to do so, we need to first make the measure column to be uniform since right now that column has both integers and fraction. What we need to do is to convert the fractions into integers.
My method is to first use separate_rows()
to separate the entries with composite fraction format such as “1 1/2” into a digit part (1) and fraction part(1/2). Then, I use str_detect()
to distinguish between integers and fraction. Next, I count how many types of fractions are there. Luckily, we only have 5 types of fractions, so we can use the case_when()
to change the 5 types of fractions into the digit format. After finishing these steps, we can unify the measure with ease, and the following is our final result.
# find out how many types of fractions are there
boston_cocktails%>%
mutate(measure = str_remove(measure, "oz"))%>%
separate_rows(measure, sep = " ")%>%
mutate(frac = str_detect(measure, "/"))%>%
filter(frac==TRUE)%>%count(measure)
## # A tibble: 5 x 2
## measure n
## <chr> <int>
## 1 1/2 1283
## 2 1/3 3
## 3 1/4 236
## 4 2/3 3
## 5 3/4 425
# convert the limited types of fraction into digits.
boston_cocktails_clean<-boston_cocktails%>%
mutate(measure = str_remove(measure, "oz"))%>%
separate_rows(measure, sep = " ")%>%
mutate(measure= case_when(measure == "1/2"~0.5,
measure == "1/3"~round(1/3,3),
measure == "1/4"~0.25,
measure == "2/3"~round(2/3,3),
measure == "3/4"~0.75,
TRUE~as.numeric(measure)))%>%
filter(!is.na(measure))%>%
group_by(name,category,ingredient_number,ingredient)%>%
summarise(measure = sum(measure))
## Warning in eval_tidy(pair$rhs, env = default_env): NAs introduced by coercion
## `summarise()` regrouping output by 'name', 'category', 'ingredient_number' (override with `.groups` argument)
boston_cocktails_clean
## # A tibble: 3,622 x 5
## # Groups: name, category, ingredient_number [3,622]
## name category ingredient_numb… ingredient measure
## <chr> <chr> <dbl> <chr> <dbl>
## 1 1626 Whiskies 1 Bourbon whiskey 2.5
## 2 1626 Whiskies 2 Gingerbread liqueur 0.75
## 3 1626 Whiskies 3 cherry-flavored brandy 0.5
## 4 1626 Whiskies 4 Angostura Bitters 2
## 5 1626 Whiskies 5 Italian preserved che… 1
## 6 19th Century Whiskies 1 Bourbon whiskey 1.5
## 7 19th Century Whiskies 2 Fresh lemon juice 0.75
## 8 19th Century Whiskies 3 White creme de cacao 0.75
## 9 19th Century Whiskies 4 Lillet Rouge 0.75
## 10 A. J. Cocktail Classi… 1 Applejack 1.5
## # … with 3,612 more rows
Our next step is to create a Shiny app. The following is the code I wrote to deploy the interactive bar plot. And the final result is shown under this chunk of code. With the help of such app, you could finally tell your friends confidently what is in your cocktails.
library(shiny)
library(tidyverse)
library(plotly)
theme_set(theme_light())
cocktails <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-05-26/cocktails.csv')
boston_cocktails <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-05-26/boston_cocktails.csv')
boston_cocktails_clean<-boston_cocktails%>%
mutate(measure = str_remove(measure, "oz"))%>%
separate_rows(measure, sep = " ")%>%
mutate(measure= case_when(measure == "1/2"~0.5,
measure == "1/3"~round(1/3,3),
measure == "1/4"~0.25,
measure == "2/3"~round(2/3,3),
measure == "3/4"~0.75,
TRUE~as.numeric(measure)))%>%
filter(!is.na(measure))%>%
group_by(name,category,ingredient_number,ingredient)%>%
summarise(measure = sum(measure))
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Interactive bar plot:"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput("name",label = "Select the cocktail name",
choices = unique(boston_cocktails_clean$name),
selected = c("Mojito","Martini"),
selectize = TRUE,
multiple = TRUE)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot"),height = 250, width = 400
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$distPlot <- renderPlot({
boston_cocktails_clean%>%
filter(name%in%input$name)%>%
ggplot(aes(x = ingredient, y = measure, fill = name))+
geom_col(position = "dodge", alpha = 0.7)+
labs(x = "Ingredient", y ="Oz",
title = "The ingredient composition for...",
fill = "Name of the cocktails")+
theme(plot.margin = margin(30, 30, 30, 30),
plot.title = element_text(size = 20, family = "Times",
face = "bold", margin = margin(20,0,5,0)),
axis.title.x = element_text(size = 12, family = "Times"),
axis.title.y = element_text(size = 12, family = "Times"),
axis.text.x = element_text(size = 12,family = "Times", angle = 45))
})
}
# Run the application
shinyApp(ui = ui, server = server)


Version: {{mnAuthServiceModel.version | mnPrettyVersionFilter}}
Cluster State ID: Please login to view your Cluster State ID.


CorrectAnswer
Assuming a 4-digit number, we want the middle two digits for the square of the key.
Use the Mid-square Method calculator to help you.
The answer is CorrectAnswer.


assert
statements that cause side effects.
Since assertions can be switched off, these side effects are not guaranteed, which can cause subtle bugs. Common unwanted side effects detected by this inspection are modifications of variables and fields. When methods calls are involved, they are analyzed one level deep.
Example:
assert i++ < 10;


EBD - Easton Bible DIctionary
Dodai
DODAI
"DODAI "loving, one of David’s captains (
1 Chronicles 27:4
). (See DODO[2].)
"DODAI "loving, one of David’s captains (1 Chronicles 27:4). (See DODO[2].)


Downloading Files from a File List Using Moderate
Selected from the Action button menu in the file list dialog.
The Download command allows you to download files directly from the file list editor. The files will be downloaded to Moderate's download directory (set in Settings Moderate) - this defaults to Ameol's download directory when Moderate is first installed.
A separate default directory is provided so that files download as part of your moderating duties can be kept separate from those you download in your general CIX usage.


EGA Beacon
By use of this Beacon Service, I agree to forego any attempt to re-identify individuals represented in Beacon Service Replies, except where expressly authorized by law or by a written prior permission from the respective DAC. (
more details
)


Two people who collaborate well will be about three times as eﬀective as each of them operating independently, because each will see what the other might miss—plus they can leverage each other’s strengths while holding each other accountable to higher standards.


Choose the correct name for respective spring
Move the cursor over the Universal Spring Testing machine to identify various parts.
Choose Test:
Tensile Test
Compression Test
Choose spring for
Measure the outer diameter of the spring
Measure the inner diameter of the spring
Fix the spring on the machine.
Perform task as mentioned in CONSOLE


awonderfulpikachu liked this art
awonderfulpikachu said: I want to do commissions. >.<
awonderfulpikachu liked this art
awonderfulpikachu liked this art
awonderfulpikachu liked this art
awonderfulpikachu liked this art
awonderfulpikachu said: pikapika~


Your browser does not support SVG
Awesome Kanban Board
Create new list
Create new list
Enter the title
Create
Your browser does not support SVG


As an user, John wants to create his own room on Plug.dj and play music.
Select a link to continue.
Start Page
persona
user-story
interaction-flow
conceptual-model


Don't Pay. Just Speak.
This is the language Meetup you've been waiting for.
Organized.
The events are organized by a community buddy. If nobody volunteers a donation pot is opened and whoever is interested in organizing an event can claim it. Donations are of course voluntary.
Goal-oriented.
We know, that you've come here to learn a language. Drinking a cold beer and meeting new interesting people can be a pleasant side-effect, but shouldn't be the focus. Our events have a itinerary and a structure that makes it easy for everybody to try themselves in a their new language.
Fun.
Sticking to a boring language course can be tough. In the end we're all just dreaming of going out there to communicate. So let's just do that and have fun!
Get started in your city.
We collect donations and help you organize a language event in your city. You set a number and as soon as we gathered the funding, the event can start up!
Find all languages.
Whatever languages you want to learn, chances are, that there is a native speaker in your city!
Teach your native language.
Teaching your language to others can be fun. And don't be afraid of not knowing everything: not everybody needs professional teachers to say 'hi' in a new language!
Community
If everybody puts something into the community, we can take more out than we put in.
Learn from natives.
What's the best way to get up and running with your new language? Listen to people, that use it everyday. This ensures you're not learning boring vocab lists you'll never use, but instead focus on what's important in every day life.
Be a buddy!
Help others learn your language and organize events in your city!
Say hi!
Sign up now for free and create an account. You can then select how you want to participate in the community.
Connect with countless other language learners. Discover intelligent Vocab-lists that enrich our in person events. Earn money by organizing events.


--- layout: page title: Wireless Village date: 2009-03-12 16:10:01.000000000 +00:00 categories: [] tags: [] status: draft type: page published: false meta: _edit_last: '1' _wp_page_template: default author: login: admin email<EMAIL_ADDRESS>display_name: Bruno Fernandez-Ruiz first_name: Bruno last_name: Fernandez-Ruiz ---
The first startup I funded a few years back was Yamigo, a mobile instant messaging solution based on the Wireless Village initiative, later integrated into the Open Mobile Alliance (OMA) and renamed as Instant Messaging and Presence Services (IMPS). Interestingly, native chat clients using OMA IMPS are found in almost 500 million handsets, yet it is little used. Yamigo did remarkably well despite operators not being friendly, building up to 150,000 users. I am not involved any longer with this service.
My second attempt to get mobile instant messaging was Onesoup. Onesoup was pretty much like Yamigo, but with a simpler user experience, and no registration required, all transparent. I am not any longer associated with Onesoup.


Note: X-max/Y-max must be greater than their respective minimum values. Values must be between 1 & 10.


Show tool window quick-access numbers on the tool window buttons.
You can hold the Alt key and press the corresponding number key to switch tool windows regardless of
this setting. Alt+1 for the Project tool window, and so on.
Mnemonics for tool windows show the corresponding key bindings only when the shortcut is configured to Alt+number,
where number is an integer number in the range from 0 to 9. With a different shortcut, there will be no
mnemonic for the tool window button.


To become a leader in the world of followers.
An opportunity to improve your communication & managerial skills.
Millions of users Start Bootstrap!
Grab official Zeitgeist 2k18 merchandise, Recieve goodies from our sponsors.
Zeitgeist is one of the biggest annual college's cultural festival of North India: A fiesta where art, talent, and diversity meets. It has a total footfall of more than 12k & a reach of more than 250 colleges. Encapsulating the spirit of times, Zeitgeist provides an opportunity to the people from all over India to showcase their talent. It provides a platform to the young talents of our nation to stir the atmosphere, rock the audience and set the stage on fire. Zeitgeist has hosted many talented and celebrated personalities like Mohit Chauhan, Alfaz, Zephyrtone and so on. Filled with the exhilaration of heated competition and exuberant events, Zeitgeist'18 is here to rock your heart.


Pedicle Screw Hybrid Instrumentation Mean Difference Mean Difference
IV, Fixed, 95% CL
Kim 2006 3B 1 2 4 9 29 5.5% ~1.00[-6.17, 4.17] 2006 Li 2008 7 5 30 8 6 30 18.8% -1.00[-3.79, 1.79] 2008 ns Helgeson 2010 82 92 37 57 56 177 15.5% 2.50 [-0.58, 5.58] 2010 a Hwang 2012 547 499 56 5.24 48 71 49.8% 0.23 [-1.49, 1.95] 2012 1 Liv 2014 ai 67) at 74 87 21 10.4% 0,70 [-3.06, 4.46] 2014 er Total (85% Cl) 173 328 100.0% 0.33 [-0.88, 1.54} >
ity: Chi? = =4 (P=0.84); = 0% Heterogeneity: Chi? = 3.08, of = 4 (P = 0.84); I = 0% to $ o t to
‘Test for overall effect:
0.54 (P = 0.59) Favours [Pedicle Screw] Favours [Hybrid Instrumentation}


The purpose of this project was to analyze how weather changes as you get closer to the equator. To accompolish analysis, we first pulled data from the OpenWeatherMap API to assemble a dataset on over 500 cities.
After assembling the dataset, we used Matplotlib to plot various aspects of the weather vs. latitude. Factors we looked at included: temperature, cloudiness, wind speed, and humidity. This site provides the source data and visualizations created as part of the analysis, as well as explanations and descriptions of any trends and correlations witnessed.


Smart Parking
Find parkings near me
Parking name
Total capacity
Vacant slots
Distance
Price
Routes and Directions


iLink Add Beacon
Place Beacon next to phone. Press ‘Start Scan':
Start Scan
Detected beacons within 1 metre(m) distance:


You can use this service for a range of submission activities as well as reports on your submissions. For help with submitting your data, including the use of this interface, please refer to our Help Guides.Please familiarise yourself with the different submission interfaces and what can be submitted through each by reading our General Guide on ENA Data Submission.All users are advised to take a moment to understand the ENA Metadata Model. You may also like to review how the release of data is managed in our Data Release FAQ.
A dedicated submission API for COVID-19 genomes is available here.
You can use this service for a range of submission activities as well as reports on your submissions.


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/noncomputable.20if.html ---
I sort of wish we had two if
s, one defined in terms of decidable
like the built-in one, and a noncomputable one defined in terms of choice
. That way we would never have to worry about which proof of decidability appears in the statements of lemmas. Is this crazy?
Thinking of lemmas such as s.prod (λ x, (ite (a = x) b 1)) = ite (a ∈ s) b 1
: of course the lemma is true whether or not the evidence of decidable (a = x)
has anything to do with the evidence of decidable (a ∈ s)
, but the lemma statement might require them to be related in a specific way (depending on exactly what instance parameters it assumes).
This is also in the spirit of "classical semantics, computable algorithms specified in terms of them"
Well, it's also the case that it's possible to write these lemmas in a way that they can be applied in any situation, regardless of the choices of decidable
instances. It's just really awkward to do so.
it seems like this is a failing of rewriting and congr stuff to not be able to properly ignore decidable args
Or subsingletons in general. Though it is also nice to just be able to apply things, without tactics.
you don't usually apply an equality
lean's term mode handling of congruence is pretty anemic
for some reason congr
thinks it's best to create congr lemmas on the fly all the time, even though there is only one for each definition so they could easily be auto-generated with the definition
Last updated: Apr 24 2020 at 19:02 UTC


Black Vultures in Athens
They don't normally live this far north, so you're not likely to see them in the wilds of Athens, GA. However they are a native species of southern Georgia. Be sure to visit Okefenokee Swamp to learn more about alligators! You can learn more than the casual observer by clicking the buttons below...
Taxonomy
| Order |
Accipitriformes |
| Family |
Cathartidae |
| Genus |
Coragyps |
| Species |
atratus |
Diet
- In the wild, the Black Vulture feeds mainly on carrion, although it also scavenges fish, vegetable material, and dung. Occasionally, Black Vultures attack small live prey, or in larger groups may attack lambs or newborn pigs. The Black Vulture relies on others in their group to warn them about approaching danger while eating; this allows them to eat particularly quickly.
- At Bear Hollow, the Black Vulture eats a rotation of fish, chicks, rats and prepared carnivore diet though he’ll often wait to let some of his food “season” before he eats his meals.
Range and Habitat
- There are two common vulture species – the Black Vulture and the Turkey Vulture. The Black Vulture occurs in more southern areas.
- In Georgia, Black Vultures can be found statewide.
- The Black Vulture roosts in dense forests with large trees, and searches open spaces for carrion.
- Black Vultures are more common in flat lowlands than in higher elevations. They often soar higher than Turkey Vultures and gather in large numbers at roadkill and other carrion.
Physical Features
- Black body with grey, featherless head.
- Wings also are tipped with white on the underside.
- They have a short hooked beak.
Life Span
- In the wild, turkeys generally life three to four years.
- In captivity, they can live as long as ten to twelve years.
Reproduction
- Instead of building a nest, the Black Vulture lays its eggs (normally two) on the bare ground of the chosen nest site. Parents incubate the young equally.
- The Black Vulture lays its eggs in isolated locations with little human disturbance. They find a dark recess in a cave, abandoned building, thicket, pile of rocks, or in a hollow log or tree. A pair of Black Vultures may assure themselves of the site’s isolation by perching nearby for a period of weeks before egg-laying.
Social Behavior
- The Black Vulture is monogamous and forms strong social bonds to its kin. They are believed to mate for life.
- The Black Vulture soars on thermals to gain altitude and to cover large distances with little energy expenditure. Black Vultures have a less well-developed sense of smell than Turkey Vultures and rely more on sight than smell to find carrion.
- One-on-one, a Black Vulture can be dominated by the slightly larger Turkey Vulture. But, Black Vultures rarely travel alone. Flocks of Black Vultures can quickly take over a carcass and drive the more solitary Turkey Vultures away.
Conservation
- They are a species of little conservation concern.
- This is the most abundant vulture in the Western Hemisphere, and populations seem to be steady or rising in North America. Black Vultures benefit from human garbage at landfills and dumpsters, but they are also sometimes trapped, shot, and poisoned.
- As migratory birds, they are completely protected by federal law.
Interpretive Information
- Vultures have a very unique defense system. When threatened they will actually induce vomiting and throw up on or near an approaching predator. Because their diet is carrion, the stench is overwhelming, but the stench is not the only part of the defense. Their stomach acids are extremely strong, which allows them to remain healthy even after eating a sick animal because the acid is so powerful that it breaks down pathogens before they can infect the vulture. This strong acid, in addition to keeping the vultures healthy, can also keep the vultures safe by literally burning attackers. Vomiting also makes the vulture lighter, making it easier for a glutted vulture to fly away to safety.
- These strong stomach acids make Vultures extremely valuable to our environment. They can safely digest and get rid of almost all harmful bacteria and pathogens that might infect humans or other animals.
- Black vultures do not have feathers on their heads in order to protect themselves from the pathogens that they might come in contact with when eating carrion. A bald head makes clean up a lot easier and helps keeps the birds safe and sanitary.
- Vomiting is also how they feed their young as they do not carry food back to their young with their beaks or feet.
- Vultures legs are grey but often appear white because they squirt urine and excrement onto their own legs which dries white. They do this to help keep themselves cool.
Bear Hollow’s Black Vultures
- Male: Victor
- Injured in the wild and rehabilitated by the UGA Veterinary School who determined that he was non-releasable and sent him to Bear Hollow in 2012.
- Unknown age – hatched in the wild.
Credits and References
- Photo and map taken from http://www.allaboutbirds.org/guide/Black_Vulture/lifehistory
- http://www.hawkmountain.org/raptorpedia/hawks-at-hawk-mountain/hawk-species-at-hawk-mountain/black-vulture/page.aspx?id=642
- http://science.howstuffworks.com/environmental/life/zoology/birds/vulture-vomit.htm
- http://www.wildflorida.com/wildlife/birds/Black_Vulture.php


SUBROUTINE SGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO ) * * -- LAPACK routine (version 3.1) -- * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. * November 2006 * * .. Scalar Arguments .. INTEGER IHI, ILO, INFO, LDA, N * .. * .. Array Arguments .. REAL A( LDA, * ), TAU( * ), WORK( * ) * .. * * Purpose * ======= * * SGEHD2 reduces a real general matrix A to upper Hessenberg form H by * an orthogonal similarity transformation: Q' * A * Q = H . * * Arguments * ========= * * N (input) INTEGER * The order of the matrix A. N >= 0. * * ILO (input) INTEGER * IHI (input) INTEGER * It is assumed that A is already upper triangular in rows * and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally * set by a previous call to SGEBAL; otherwise they should be * set to 1 and N respectively. See Further Details. * 1 <= ILO <= IHI <= max(1,N). * * A (input/output) REAL array, dimension (LDA,N) * On entry, the n by n general matrix to be reduced. * On exit, the upper triangle and the first subdiagonal of A * are overwritten with the upper Hessenberg matrix H, and the * elements below the first subdiagonal, with the array TAU, * represent the orthogonal matrix Q as a product of elementary * reflectors. See Further Details. * * LDA (input) INTEGER * The leading dimension of the array A. LDA >= max(1,N). * * TAU (output) REAL array, dimension (N-1) * The scalar factors of the elementary reflectors (see Further * Details). * * WORK (workspace) REAL array, dimension (N) * * INFO (output) INTEGER * = 0: successful exit. * < 0: if INFO = -i, the i-th argument had an illegal value. * * Further Details * =============== * * The matrix Q is represented as a product of (ihi-ilo) elementary * reflectors * * Q = H(ilo) H(ilo+1) . . . H(ihi-1). * * Each H(i) has the form * * H(i) = I - tau * v * v' * * where tau is a real scalar, and v is a real vector with * v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on * exit in A(i+2:ihi,i), and tau in TAU(i). * * The contents of A are illustrated by the following example, with * n = 7, ilo = 2 and ihi = 6: * * on entry, on exit, * * ( a a a a a a a ) ( a a h h h h a ) * ( a a a a a a ) ( a h h h h a ) * ( a a a a a a ) ( h h h h h h ) * ( a a a a a a ) ( v2 h h h h h ) * ( a a a a a a ) ( v2 v3 h h h h ) * ( a a a a a a ) ( v2 v3 v4 h h h ) * ( a ) ( a ) * * where a denotes an element of the original matrix A, h denotes a * modified element of the upper Hessenberg matrix H, and vi denotes an * element of the vector defining H(i). * * ===================================================================== * * .. Parameters .. REAL ONE PARAMETER ( ONE = 1.0E+0 ) * .. * .. Local Scalars .. INTEGER I REAL AII * .. * .. External Subroutines .. EXTERNAL SLARF, SLARFG, XERBLA * .. * .. Intrinsic Functions .. INTRINSIC MAX, MIN * .. * .. Executable Statements .. * * Test the input parameters * INFO = 0 IF( N.LT.0 ) THEN INFO = -1 ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN INFO = -2 ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN INFO = -3 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN INFO = -5 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'SGEHD2', -INFO ) RETURN END IF * DO 10 I = ILO, IHI - 1 * * Compute elementary reflector H(i) to annihilate A(i+2:ihi,i) * CALL SLARFG( IHI-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1, $ TAU( I ) ) AII = A( I+1, I ) A( I+1, I ) = ONE * * Apply H(i) to A(1:ihi,i+1:ihi) from the right * CALL SLARF( 'Right', IHI, IHI-I, A( I+1, I ), 1, TAU( I ), $ A( 1, I+1 ), LDA, WORK ) * * Apply H(i) to A(i+1:ihi,i+1:n) from the left * CALL SLARF( 'Left', IHI-I, N-I, A( I+1, I ), 1, TAU( I ), $ A( I+1, I+1 ), LDA, WORK ) * A( I+1, I ) = AII 10 CONTINUE * RETURN * * End of SGEHD2 * END


Let Ax=b be the system to be solved, and the computed solution. Let n be the dimension of A. An approximate error bound for may be obtained in one of the following two ways, depending on whether the solution is computed by a simple driver or an expert driver:
EPSMCH = SLAMCH( 'E' ) * Get infinity-norm of A ANORM = SLANGE( 'I', N, N, A, LDA, WORK ) * Solve system; The solution X overwrites B CALL SGESV( N, 1, A, LDA, IPIV, B, LDB, INFO ) IF( INFO.GT.0 ) THEN PRINT *,'Singular Matrix' ELSE IF (N .GT. 0) THEN * Get reciprocal condition number RCOND of A CALL SGECON( 'I', N, A, LDA, ANORM, RCOND, WORK, IWORK, INFO ) RCOND = MAX( RCOND, EPSMCH ) ERRBD = EPSMCH / RCOND END IF
For example, suppose4.11
,
CALL SGESVX( 'E', 'N', N, 1, A, LDA, AF, LDAF, IPIV, $ EQUED, R, C, B, LDB, X, LDX, RCOND, FERR, BERR, $ WORK, IWORK, INFO ) IF( INFO.GT.0 ) PRINT *,'(Nearly) Singular Matrix'
For the same A and b as above, , , and the actual error is .
This example illustrates that the expert driver provides an error bound with less programming effort than the simple driver, and also that it may produce a significantly more accurate answer.
Similar code fragments, with obvious adaptations, may be used with all the driver routines for linear equations listed in Table 2.2. For example, if a symmetric system is solved using the simple driver xSYSV, then xLANSY must be used to compute ANORM, and xSYCON must be used to compute RCOND.


Statisticians can be a sour bunch. Instead of considering their winnings, they only measure how much they have lost. In fact, they consider their wins as negative losses. But what's interesting is how they measure their losses.
For example, consider the following example:
A meteorologist is predicting the probability of a possible hurricane striking his city. He estimates, with 95% confidence, that the probability of it not striking is between 99% - 100%. He is very happy with his precision and advises the city that a major evacuation is unnecessary. Unfortunately, the hurricane does strike and the city is flooded.
This stylized example shows the flaw in using a pure accuracy metric to measure outcomes. Using a measure that emphasizes estimation accuracy, while an appealing and objective thing to do, misses the point of why you are even performing the statistical inference in the first place: results of inference. The author Nassim Taleb of The Black Swan and Antifragility stresses the importance of the payoffs of decisions, not the accuracy. Taleb distills this quite succinctly: "I would rather be vaguely right than very wrong."
We introduce what statisticians and decision theorists call loss functions. A loss function is a function of the true parameter, and an estimate of that parameter
$$ L( \theta, \hat{\theta} ) = f( \theta, \hat{\theta} )$$
The important point of loss functions is that it measures how bad our current estimate is: the larger the loss, the worse the estimate is according to the loss function. A simple, and very common, example of a loss function is the squared-error loss:
$$ L( \theta, \hat{\theta} ) = ( \theta - \hat{\theta} )^2$$
The squared-error loss function is used in estimators like linear regression, UMVUEs and many areas of machine learning. We can also consider an asymmetric squared-error loss function, something like:
$$ L( \theta, \hat{\theta} ) = \begin{cases} ( \theta - \hat{\theta} )^2 & \hat{\theta} \lt \theta \\\\ c( \theta - \hat{\theta} )^2 & \hat{\theta} \ge \theta, \;\; 0\lt c \lt 1 \end{cases}$$
which represents that estimating a value larger than the true estimate is preferable to estimating a value below. A situation where this might be useful is in estimating web traffic for the next month, where an over-estimated outlook is preferred so as to avoid an underallocation of server resources.
A negative property about the squared-error loss is that it puts a disproportionate emphasis on large outliers. This is because the loss increases quadratically, and not linearly, as the estimate moves away. That is, the penalty of being three units away is much less than being five units away, but the penalty is not much greater than being one unit away, though in both cases the magnitude of difference is the same:
$$ \frac{1^2}{3^2} \lt \frac{3^2}{5^2}, \;\; \text{although} \;\; 3-1 = 5-3 $$
This loss function imposes that large errors are very bad. A more robust loss function that increases linearly with the difference is the absolute-loss
$$ L( \theta, \hat{\theta} ) = | \theta - \hat{\theta} | $$
Other popular loss functions include:
Historically, loss functions have been motivated from 1) mathematical convenience, and 2) they are robust to application, i.e., they are objective measures of loss. The first reason has really held back the full breadth of loss functions. With computers being agnostic to mathematical convenience, we are free to design our own loss functions, which we take full advantage of later in this Chapter.
With respect to the second point, the above loss functions are indeed objective, in that they are most often a function of the difference between estimate and true parameter, independent of signage or payoff of choosing that estimate. This last point, its independence of payoff, causes quite pathological results though. Consider our hurricane example above: the statistician equivalently predicted that the probability of the hurricane striking was between 0% to 1%. But if he had ignored being precise and instead focused on outcomes (99% chance of no flood, 1% chance of flood), he might have advised differently.
By shifting our focus from trying to be incredibly precise about parameter estimation to focusing on the outcomes of our parameter estimation, we can customize our estimates to be optimized for our application. This requires us to design new loss functions that reflect our goals and outcomes. Some examples of more interesting loss functions:
$L( \theta, \hat{\theta} ) = \frac{ | \theta - \hat{\theta} | }{ \theta(1-\theta) }, \; \; \hat{\theta}, \theta \in [0,1]$ emphasizes an estimate closer to 0 or 1 since if the true value $\theta$ is near 0 or 1, the loss will be very large unless $\hat{\theta}$ is similarly close to 0 or 1. This loss function might be used by a political pundit whose job requires him or her to give confident "Yes/No" answers. This loss reflects that if the true parameter is close to 1 (for example, if a political outcome is very likely to occur), he or she would want to strongly agree as to not look like a skeptic.
$L( \theta, \hat{\theta} ) = 1 - \exp \left( -(\theta - \hat{\theta} )^2 \right)$ is bounded between 0 and 1 and reflects that the user is indifferent to sufficiently-far-away estimates. It is similar to the zero-one loss above, but not quite as penalizing to estimates that are close to the true parameter.
Complicated non-linear loss functions can programmed:
def loss(true_value, estimate):
if estimate*true_value > 0:
return abs(estimate - true_value)
else:
return abs(estimate)*(estimate - true_value)**2
People notice one type of mistake — the failure to predict rain — more than other, false alarms. If it rains when it isn't supposed to, they curse the weatherman for ruining their picnic, whereas an unexpectedly sunny day is taken as a serendipitous bonus.
[The Weather Channel's bias] is limited to slightly exaggerating the probability of rain when it is unlikely to occur — saying there is a 20 percent change when they know it is really a 5 or 10 percent chance — covering their butts in the case of an unexpected sprinkle.
As you can see, loss functions can be used for good and evil: with great power, comes great — well you know.
So far we have been under the unrealistic assumption that we know the true parameter. Of course if we knew the true parameter, bothering to guess an estimate is pointless. Hence a loss function is really only practical when the true parameter is unknown.
In Bayesian inference, we have a mindset that the unknown parameters are really random variables with prior and posterior distributions. Concerning the posterior distribution, a value drawn from it is a possible realization of what the true parameter could be. Given that realization, we can compute a loss associated with an estimate. As we have a whole distribution of what the unknown parameter could be (the posterior), we should be more interested in computing the expected loss given an estimate. This expected loss is a better estimate of the true loss than comparing the given loss from only a single sample from the posterior.
First it will be useful to explain a Bayesian point estimate. The systems and machinery present in the modern world are not built to accept posterior distributions as input. It is also rude to hand someone over a distribution when all they asked for was an estimate. In the course of an individual's day, when faced with uncertainty we still act by distilling our uncertainty down to a single action. Similarly, we need to distill our posterior distribution down to a single value (or vector in the multivariate case). If the value is chosen intelligently, we can avoid the flaw of frequentist methodologies that mask the uncertainty and provide a more informative result.The value chosen, if from a Bayesian posterior, is a Bayesian point estimate.
Suppose $P(\theta | X)$ is the posterior distribution of $\theta$ after observing data $X$, then the following function is understandable as the expected loss of choosing estimate $\hat{\theta}$ to estimate $\theta$:
$$ l(\hat{\theta} ) = E_{\theta}\left[ \; L(\theta, \hat{\theta}) \; \right] $$
This is also known as the risk of estimate $\hat{\theta}$. The subscript $\theta$ under the expectation symbol is used to denote that $\theta$ is the unknown (random) variable in the expectation, something that at first can be difficult to consider.
We spent all of last chapter discussing how to approximate expected values. Given $N$ samples $\theta_i,\; i=1,...,N$ from the posterior distribution, and a loss function $L$, we can approximate the expected loss of using estimate $\hat{\theta}$ by the Law of Large Numbers:
$$\frac{1}{N} \sum_{i=1}^N \;L(\theta_i, \hat{\theta} ) \approx E_{\theta}\left[ \; L(\theta, \hat{\theta}) \; \right] = l(\hat{\theta} ) $$
Notice that measuring your loss via an expected value uses more information from the distribution than the MAP estimate which, if you recall, will only find the maximum value of the distribution and ignore the shape of the distribution.
Similarly, compare this with frequentist methods, that traditionally only aim to minimize the error, and do not consider the loss associated with the result of that error. Compound this with the fact that frequentist methods are almost guaranteed to never be absolutely accurate. Bayesian point estimates fix this by planning ahead: your estimate is going to be wrong, you might as well err on the right side of wrong.
Bless you if you are ever chosen as a contestant on the Price is Right, for here we will show you how to optimize your final price on the Showcase. For those who forget the rules:
The difficulty in the game is balancing your uncertainty in the prices, keeping your bid low enough so as to not bid over, and trying to bid close to the price.
Suppose we have recorded the Showcases from previous The Price is Right episodes and have prior beliefs about what distribution the true price follows. For simplicity, suppose it follows a Normal:
$$\text{True Price} \sim \text{Normal}(\mu_p, \sigma_p )$$
In a later chapter, we will actually use real Price is Right Showcase data to form the historical prior, but this requires some advanced PyMC3 use so we will not use it here. For now, we will assume $\mu_p = 35 000$ and $\sigma_p = 7500$.
We need a model of how we should be playing the Showcase. For each prize in the prize suite, we have an idea of what it might cost, but this guess could differ significantly from the true price. (Couple this with increased pressure being onstage and you can see why some bids are so wildly off). Let's suppose your beliefs about the prices of prizes also follow Normal distributions:
$$ \text{Prize}_i \sim \text{Normal}(\mu_i, \sigma_i ),\;\; i=1,2$$
This is really why Bayesian analysis is great: we can specify what we think a fair price is through the $\mu_i$ parameter, and express uncertainty of our guess in the $\sigma_i$ parameter.
We'll assume two prizes per suite for brevity, but this can be extended to any number. The true price of the prize suite is then given by $\text{Prize}_1 + \text{Prize}_2 + \epsilon$, where $\epsilon$ is some error term.
We are interested in the updated $\text{True Price}$ given we have observed both prizes and have belief distributions about them. We can perform this using PyMC3.
Lets make some values concrete. Suppose there are two prizes in the observed prize suite:
We have some guesses about the true prices of these objects, but we are also pretty uncertain about them. I can express this uncertainty through the parameters of the Normals:
\begin{align} & \text{snowblower} \sim \text{Normal}(3 000, 500 )\\\\ & \text{Toronto} \sim \text{Normal}(12 000, 3000 )\\\\ \end{align}
For example, I believe that the true price of the trip to Toronto is 12 000 dollars, and that there is a 68.2% chance the price falls 1 standard deviation away from this, i.e. my confidence is that there is a 68.2% chance the trip is in [9 000, 15 000].
We can create some PyMC3 code to perform inference on the true price of the suite.
%matplotlib inline
import scipy.stats as stats
from IPython.core.pylabtools import figsize
import numpy as np
import matplotlib.pyplot as plt
figsize(12.5, 9)
norm_pdf = stats.norm.pdf
plt.subplot(311)
x = np.linspace(0, 60000, 200)
sp1 = plt.fill_between(x , 0, norm_pdf(x, 35000, 7500),
color = "#348ABD", lw = 3, alpha = 0.6,
label = "historical total prices")
p1 = plt.Rectangle((0, 0), 1, 1, fc=sp1.get_facecolor()[0])
plt.legend([p1], [sp1.get_label()])
plt.subplot(312)
x = np.linspace(0, 10000, 200)
sp2 = plt.fill_between(x , 0, norm_pdf(x, 3000, 500),
color = "#A60628", lw = 3, alpha = 0.6,
label="snowblower price guess")
p2 = plt.Rectangle((0, 0), 1, 1, fc=sp2.get_facecolor()[0])
plt.legend([p2], [sp2.get_label()])
plt.subplot(313)
x = np.linspace(0, 25000, 200)
sp3 = plt.fill_between(x , 0, norm_pdf(x, 12000, 3000),
color = "#7A68A6", lw = 3, alpha = 0.6,
label = "Trip price guess")
plt.autoscale(tight=True)
p3 = plt.Rectangle((0, 0), 1, 1, fc=sp3.get_facecolor()[0])
plt.legend([p3], [sp3.get_label()]);
import pymc3 as pm
data_mu = [3e3, 12e3]
data_std = [5e2, 3e3]
mu_prior = 35e3
std_prior = 75e2
with pm.Model() as model:
true_price = pm.Normal("true_price", mu=mu_prior, sd=std_prior)
prize_1 = pm.Normal("first_prize", mu=data_mu[0], sd=data_std[0])
prize_2 = pm.Normal("second_prize", mu=data_mu[1], sd=data_std[1])
price_estimate = prize_1 + prize_2
logp = pm.Normal.dist(mu=price_estimate, sd=(3e3)).logp(true_price)
error = pm.Potential("error", logp)
trace = pm.sample(50000, step=pm.Metropolis())
burned_trace = trace[10000:]
price_trace = burned_trace["true_price"]
figsize(12.5, 4)
import scipy.stats as stats
x = np.linspace(5000, 40000)
plt.plot(x, stats.norm.pdf(x, 35000, 7500), c = "k", lw = 2,
label = "prior dist. of suite price")
_hist = plt.hist(price_trace, bins = 35, normed= True, histtype= "stepfilled")
plt.title("Posterior of the true price estimate")
plt.vlines(mu_prior, 0, 1.1*np.max(_hist[0]), label = "prior's mean",
linestyles="--")
plt.vlines(price_trace.mean(), 0, 1.1*np.max(_hist[0]), \
label = "posterior's mean", linestyles="-.")
plt.legend(loc = "upper left");
Notice that because of our two observed prizes and subsequent guesses (including uncertainty about those guesses), we shifted our mean price estimate down about \$15,000 dollars from the previous mean price.
A frequentist, seeing the two prizes and having the same beliefs about their prices, would bid $\mu_1 + \mu_2 = 35000$, regardless of any uncertainty. Meanwhile, the naive Bayesian would simply pick the mean of the posterior distribution. But we have more information about our eventual outcomes; we should incorporate this into our bid. We will use the loss function above to find the best bid (best according to our loss).
What might a contestant's loss function look like? I would think it would look something like:
def showcase_loss(guess, true_price, risk = 80000):
if true_price < guess:
return risk
elif abs(true_price - guess) <= 250:
return -2*np.abs(true_price)
else:
return np.abs(true_price - guess - 250)
where risk
is a parameter that defines of how bad it is if your guess is over the true price. A lower risk
means that you are more comfortable with the idea of going over. If we do bid under and the difference is less than $250, we receive both prizes (modeled here as receiving twice the original prize). Otherwise, when we bid under the true_price
we want to be as close as possible, hence the else
loss is a increasing function of the distance between the guess and true price.
For every possible bid, we calculate the expected loss associated with that bid. We vary the risk
parameter to see how it affects our loss:
figsize(12.5, 7)
#numpy friendly showdown_loss
def showdown_loss(guess, true_price, risk = 80000):
loss = np.zeros_like(true_price)
ix = true_price < guess
loss[~ix] = np.abs(guess - true_price[~ix])
close_mask = [abs(true_price - guess) <= 250]
loss[close_mask] = -2*true_price[close_mask]
loss[ix] = risk
return loss
guesses = np.linspace(5000, 50000, 70)
risks = np.linspace(30000, 150000, 6)
expected_loss = lambda guess, risk: \
showdown_loss(guess, price_trace, risk).mean()
for _p in risks:
results = [expected_loss(_g, _p) for _g in guesses]
plt.plot(guesses, results, label = "%d"%_p)
plt.title("Expected loss of different guesses, \nvarious risk-levels of \
overestimating")
plt.legend(loc="upper left", title="Risk parameter")
plt.xlabel("price bid")
plt.ylabel("expected loss")
plt.xlim(5000, 30000);
It would be wise to choose the estimate that minimizes our expected loss. This corresponds to the minimum point on each of the curves above. More formally, we would like to minimize our expected loss by finding the solution to
$$ \text{arg} \min_{\hat{\theta}} \;\;E_{\theta}\left[ \; L(\theta, \hat{\theta}) \; \right] $$
The minimum of the expected loss is called the Bayes action. We can solve for the Bayes action using Scipy's optimization routines. The function in fmin
in scipy.optimize
module uses an intelligent search to find a minimum (not necessarily a global minimum) of any uni- or multivariate function. For most purposes, fmin
will provide you with a good answer.
We'll compute the minimum loss for the Showcase example above:
import scipy.optimize as sop
ax = plt.subplot(111)
for _p in risks:
_color = next(ax._get_lines.prop_cycler)
_min_results = sop.fmin(expected_loss, 15000, args=(_p,),disp = False)
_results = [expected_loss(_g, _p) for _g in guesses]
plt.plot(guesses, _results , color = _color['color'])
plt.scatter(_min_results, 0, s = 60, \
color= _color['color'], label = "%d"%_p)
plt.vlines(_min_results, 0, 120000, color = _color['color'], linestyles="--")
print("minimum at risk %d: %.2f" % (_p, _min_results))
plt.title("Expected loss & Bayes actions of different guesses, \n \
various risk-levels of overestimating")
plt.legend(loc="upper left", scatterpoints = 1, title = "Bayes action at risk:")
plt.xlabel("price guess")
plt.ylabel("expected loss")
plt.xlim(7000, 30000)
plt.ylim(-1000, 80000);
As intuition suggests, as we decrease the risk threshold (care about overbidding less), we increase our bid, willing to edge closer to the true price. It is interesting how far away our optimized loss is from the posterior mean, which was about 20 000.
Suffice to say, in higher dimensions being able to eyeball the minimum expected loss is impossible. Hence why we require use of Scipy's fmin
function.
For some loss functions, the Bayes action is known in closed form. We list some of them below:
If using the mean-squared loss, the Bayes action is the mean of the posterior distribution, i.e. the value $$ E_{\theta}\left[ \theta \right] $$ minimizes $E_{\theta}\left[ \; (\theta - \hat{\theta})^2 \; \right]$. Computationally this requires us to calculate the average of the posterior samples [See chapter 4 on The Law of Large Numbers]
Whereas the median of the posterior distribution minimizes the expected absolute-loss. The sample median of the posterior samples is an appropriate and very accurate approximation to the true median.
In fact, it is possible to show that the MAP estimate is the solution to using a loss function that shrinks to the zero-one loss.
Maybe it is clear now why the first-introduced loss functions are used most often in the mathematics of Bayesian inference: no complicated optimizations are necessary. Luckily, we have machines to do the complications for us.
Whereas frequentist methods strive to achieve the best precision about all possible parameters, machine learning cares to achieve the best prediction among all possible parameters. Of course, one way to achieve accurate predictions is to aim for accurate predictions, but often your prediction measure and what frequentist methods are optimizing for are very different.
For example, least-squares linear regression is the most simple active machine learning algorithm. I say active as it engages in some learning, whereas predicting the sample mean is technically simpler, but is learning very little if anything. The loss that determines the coefficients of the regressors is a squared-error loss. On the other hand, if your prediction loss function (or score function, which is the negative loss) is not a squared-error, like AUC, ROC, precision, etc., your least-squares line will not be optimal for the prediction loss function. This can lead to prediction results that are suboptimal.
Finding Bayes actions is equivalent to finding parameters that optimize not parameter accuracy but an arbitrary performance measure, however we wish to define performance (loss functions, AUC, ROC, precision/recall etc.).
The next two examples demonstrate these ideas. The first example is a linear model where we can choose to predict using the least-squares loss or a novel, outcome-sensitive loss.
The second example is adapted from a Kaggle data science project. The loss function associated with our predictions is incredibly complicated.
Suppose the future return of a stock price is very small, say 0.01 (or 1%). We have a model that predicts the stock's future price, and our profit and loss is directly tied to us acting on the prediction. How should we measure the loss associated with the model's predictions, and subsequent future predictions? A squared-error loss is agnostic to the signage and would penalize a prediction of -0.01 equally as bad a prediction of 0.03:
$$ (0.01 - (-0.01))^2 = (0.01 - 0.03)^2 = 0.004$$
If you had made a bet based on your model's prediction, you would have earned money with a prediction of 0.03, and lost money with a prediction of -0.01, yet our loss did not capture this. We need a better loss that takes into account the sign of the prediction and true value. We design a new loss that is better for financial applications below:
figsize(12.5, 4)
def stock_loss(true_return, yhat, alpha = 100.):
if true_return * yhat < 0:
#opposite signs, not good
return alpha*yhat**2 - np.sign(true_return)*yhat \
+ abs(true_return)
else:
return abs(true_return - yhat)
true_value = .05
pred = np.linspace(-.04, .12, 75)
plt.plot(pred, [stock_loss(true_value, _p) for _p in pred], \
label = "Loss associated with\n prediction if true value = 0.05", lw =3)
plt.vlines(0, 0, .25, linestyles="--")
plt.xlabel("prediction")
plt.ylabel("loss")
plt.xlim(-0.04, .12)
plt.ylim(0, 0.25)
true_value = -.02
plt.plot(pred, [stock_loss(true_value, _p) for _p in pred], alpha = 0.6, \
label = "Loss associated with\n prediction if true value = -0.02", lw =3)
plt.legend()
plt.title("Stock returns loss if true value = 0.05, -0.02");
Note the change in the shape of the loss as the prediction crosses zero. This loss reflects that the user really does not want to guess the wrong sign, especially be wrong and a large magnitude.
Why would the user care about the magnitude? Why is the loss not 0 for predicting the correct sign? Surely, if the return is 0.01 and we bet millions we will still be (very) happy.
Financial institutions treat downside risk, as in predicting a lot on the wrong side, and upside risk, as in predicting a lot on the right side, similarly. Both are seen as risky behaviour and discouraged. Hence why we have an increasing loss as we move further away from the true price. (With less extreme loss in the direction of the correct sign.)
We will perform a regression on a trading signal that we believe predicts future returns well. Our dataset is artificial, as most financial data is not even close to linear. Below, we plot the data along with the least-squares line.
## Code to create artificial data
N = 100
X = 0.025*np.random.randn(N)
Y = 0.5*X + 0.01*np.random.randn(N)
ls_coef_ = np.cov(X, Y)[0,1]/np.var(X)
ls_intercept = Y.mean() - ls_coef_*X.mean()
plt.scatter(X, Y, c="k")
plt.xlabel("trading signal")
plt.ylabel("returns")
plt.title("Empirical returns vs trading signal")
plt.plot(X, ls_coef_*X + ls_intercept, label = "Least-squares line")
plt.xlim(X.min(), X.max())
plt.ylim(Y.min(), Y.max())
plt.legend(loc="upper left");
We perform a simple Bayesian linear regression on this dataset. We look for a model like:
$$ R = \alpha + \beta x + \epsilon$$
where $\alpha, \beta$ are our unknown parameters and $\epsilon \sim \text{Normal}(0, \sigma)$. The most common priors on $\beta$ and $\alpha$ are Normal priors. We will also assign a prior on $\sigma$, so that $\sigma$ is uniform over 0 to 100.
import pymc3 as pm
with pm.Model() as model:
std = pm.Uniform("std", 0, 100)
beta = pm.Normal("beta", mu=0, sd=100)
alpha = pm.Normal("alpha", mu=0, sd=100)
mean = pm.Deterministic("mean", alpha + beta*X)
obs = pm.Normal("obs", mu=mean, sd=std, observed=Y)
trace = pm.sample(100000, step=pm.Metropolis())
burned_trace = trace[20000:]
pm.plots.traceplot(trace=burned_trace, varnames=["std", "beta", "alpha"])
pm.plot_posterior(trace=burned_trace, varnames=["std", "beta", "alpha"], kde_plot=True);
It appears the MCMC has converged so we may continue.
For a specific trading signal, call it $x$, the distribution of possible returns has the form:
$$R_i(x) = \alpha_i + \beta_ix + \epsilon $$
where $\epsilon \sim \text{Normal}(0, \sigma_i)$ and $i$ indexes our posterior samples. We wish to find the solution to
$$ \arg \min_{r} \;\;E_{R(x)}\left[ \; L(R(x), r) \; \right] $$
according to the loss given above. This $r$ is our Bayes action for trading signal $x$. Below we plot the Bayes action over different trading signals. What do you notice?
figsize(12.5, 6)
from scipy.optimize import fmin
def stock_loss(price, pred, coef = 500):
"""vectorized for numpy"""
sol = np.zeros_like(price)
ix = price*pred < 0
sol[ix] = coef*pred**2 - np.sign(price[ix])*pred + abs(price[ix])
sol[~ix] = abs(price[~ix] - pred)
return sol
std_samples = burned_trace["std"]
alpha_samples = burned_trace["alpha"]
beta_samples = burned_trace["beta"]
N = std_samples.shape[0]
noise = std_samples*np.random.randn(N)
possible_outcomes = lambda signal: alpha_samples + beta_samples*signal + noise
opt_predictions = np.zeros(50)
trading_signals = np.linspace(X.min(), X.max(), 50)
for i, _signal in enumerate(trading_signals):
_possible_outcomes = possible_outcomes(_signal)
tomin = lambda pred: stock_loss(_possible_outcomes, pred).mean()
opt_predictions[i] = fmin(tomin, 0, disp = False)
plt.xlabel("trading signal")
plt.ylabel("prediction")
plt.title("Least-squares prediction vs. Bayes action prediction")
plt.plot(X, ls_coef_*X + ls_intercept, label ="Least-squares prediction")
plt.xlim(X.min(), X.max())
plt.plot(trading_signals, opt_predictions, label ="Bayes action prediction")
plt.legend(loc="upper left");
What is interesting about the above graph is that when the signal is near 0, and many of the possible returns outcomes are possibly both positive and negative, our best (with respect to our loss) prediction is to predict close to 0, hence take on no position. Only when we are very confident do we enter into a position. I call this style of model a sparse prediction, where we feel uncomfortable with our uncertainty so choose not to act. (Compare with the least-squares prediction which will rarely, if ever, predict zero).
A good sanity check that our model is still reasonable: as the signal becomes more and more extreme, and we feel more and more confident about the positive/negativeness of returns, our position converges with that of the least-squares line.
The sparse-prediction model is not trying to fit the data the best (according to a squared-error loss definition of fit). That honor would go to the least-squares model. The sparse-prediction model is trying to find the best prediction with respect to our stock_loss
-defined loss. We can turn this reasoning around: the least-squares model is not trying to predict the best (according to a stock-loss
definition of predict). That honor would go the sparse prediction model. The least-squares model is trying to find the best fit of the data with respect to the squared-error loss.
A personal motivation for learning Bayesian methods was trying to piece together the winning solution to Kaggle's Observing Dark Worlds contest. From the contest's website:
There is more to the Universe than meets the eye. Out in the cosmos exists a form of matter that outnumbers the stuff we can see by almost 7 to 1, and we don’t know what it is. What we do know is that it does not emit or absorb light, so we call it Dark Matter. Such a vast amount of aggregated matter does not go unnoticed. In fact we observe that this stuff aggregates and forms massive structures called Dark Matter Halos. Although dark, it warps and bends spacetime such that any light from a background galaxy which passes close to the Dark Matter will have its path altered and changed. This bending causes the galaxy to appear as an ellipse in the sky.
<img src="http://timsalimans.com/wp-content/uploads/2012/12/dm.jpg" width = 730>
The contest required predictions about where dark matter was likely to be. The winner, Tim Salimans, used Bayesian inference to find the best locations for the halos (interestingly, the second-place winner also used Bayesian inference). With Tim's permission, we provided his solution [1] here:
The loss function in this problem is very complicated. For the very determined, the loss function is contained in the file DarkWorldsMetric.py in the parent folder. Though I suggest not reading it all, suffice to say the loss function is about 160 lines of code — not something that can be written down in a single mathematical line. The loss function attempts to measure the accuracy of prediction, in a Euclidean distance sense, such that no shift-bias is present. More details can be found on the metric's main page.
We will attempt to implement Tim's winning solution using PyMC3 and our knowledge of loss functions.
The dataset is actually 300 separate files, each representing a sky. In each file, or sky, are between 300 and 720 galaxies. Each galaxy has an $x$ and $y$ position associated with it, ranging from 0 to 4200, and measures of ellipticity: $e_1$ and $e_2$. Information about what these measures mean can be found here, but for our purposes it does not matter besides for visualization purposes. Thus a typical sky might look like the following:
from draw_sky2 import draw_sky
n_sky = 3 #choose a file/sky to examine.
data = np.genfromtxt("data/Train_Skies/Train_Skies/\
Training_Sky%d.csv" % (n_sky),
dtype = None,
skip_header = 1,
delimiter = ",",
usecols = [1,2,3,4])
print("Data on galaxies in sky %d."%n_sky)
print("position_x, position_y, e_1, e_2 ")
print(data[:3])
fig = draw_sky(data)
plt.title("Galaxy positions and ellipcities of sky %d." % n_sky)
plt.xlabel("x-position")
plt.ylabel("y-position");
Each sky has one, two or three dark matter halos in it. Tim's solution details that his prior distribution of halo positions was uniform, i.e.
\begin{align} & x_i \sim \text{Uniform}( 0, 4200)\\\\ & y_i \sim \text{Uniform}( 0, 4200), \;\; i=1,2,3\\\\ \end{align}
Tim and other competitors noted that most skies had one large halo and other halos, if present, were much smaller. Larger halos, having more mass, will influence the surrounding galaxies more. He decided that the large halos would have a mass distributed as a log-uniform random variable between 40 and 180 i.e.
$$ m_{\text{large} } = \log \text{Uniform}( 40, 180 ) $$
and in PyMC3,
exp_mass_large = pm.Uniform("exp_mass_large", 40, 180)
mass_large = pm.Deterministic("mass_large", np.log(exp_max_large))
(This is what we mean when we say log-uniform.) For smaller galaxies, Tim set the mass to be the logarithm of 20. Why did Tim not create a prior for the smaller mass, nor treat it as a unknown? I believe this decision was made to speed up convergence of the algorithm. This is not too restrictive, as by construction the smaller halos have less influence on the galaxies.
Tim logically assumed that the ellipticity of each galaxy is dependent on the position of the halos, the distance between the galaxy and halo, and the mass of the halos. Thus the vector of ellipticity of each galaxy, $\mathbf{e}_i$, are children variables of the vector of halo positions $(\mathbf{x},\mathbf{y})$, distance (which we will formalize), and halo masses.
Tim conceived a relationship to connect positions and ellipticity by reading literature and forum posts. He supposed the following was a reasonable relationship:
$$ e_i | ( \mathbf{x}, \mathbf{y} ) \sim \text{Normal}( \sum_{j = \text{halo positions} }d_{i,j} m_j f( r_{i,j} ), \sigma^2 ) $$
where $d_{i,j}$ is the tangential direction (the direction in which halo $j$ bends the light of galaxy $i$), $m_j$ is the mass of halo $j$, $f(r_{i,j})$ is a decreasing function of the Euclidean distance between halo $j$ and galaxy $i$.
Tim's function $f$ was defined:
$$ f( r_{i,j} ) = \frac{1}{\min( r_{i,j}, 240 ) } $$
for large halos, and for small halos
$$ f( r_{i,j} ) = \frac{1}{\min( r_{i,j}, 70 ) } $$
This fully bridges our observations and unknown. This model is incredibly simple, and Tim mentions this simplicity was purposefully designed: it prevents the model from overfitting.
For each sky, we run our Bayesian model to find the posteriors for the halo positions — we ignore the (known) halo position. This is slightly different than perhaps traditional approaches to Kaggle competitions, where this model uses no data from other skies nor the known halo location. That does not mean other data are not necessary — in fact, the model was created by comparing different skies.
import pymc3 as pm
import theano.tensor as T
def euclidean_distance(x, y):
return np.sqrt(((x - y)**2)).sum(axis=1)
def f_distance(gxy_pos, halo_pos, c):
# foo_position should be a 2-d numpy array
# T.maximum() provides our element-wise maximum as in NumPy, but instead for theano tensors
return T.maximum(euclidean_distance(gxy_pos, halo_pos), c)[:, None]
def tangential_distance(glxy_position, halo_position):
# foo_position should be a 2-d numpy array
delta = glxy_position - halo_position
t = (2*T.arctan(delta[:,1]/delta[:,0]))
return T.stack([-T.cos(t), -T.sin(t)], axis=1)
with pm.Model() as model:
#set the size of the halo's mass
mass_large = pm.Uniform("mass_large", 40, 180)
#set the initial prior position of the halos, it's a 2-d Uniform dist.
halo_position = pm.Uniform("halo_position", 0, 4200, shape=(1,2))
mean = pm.Deterministic("mean", mass_large /\
f_distance(T.as_tensor(data[:,:2]), halo_position, 240)*\
tangential_distance(T.as_tensor(data[:,:2]), halo_position))
ellpty = pm.Normal("ellipcity", mu=mean, tau=1./0.05, observed=data[:,2:])
with model:
mu, sds, elbo = pm.variational.advi(n=50000)
step = pm.NUTS(scaling=model.dict_to_array(sds), is_cov=True)
trace = pm.sample(5000, step=step, start=mu)
We use ADVI here to find a good starting point and scaling for our NUTS sampler. NUTS is a "smarter" MCMC sampling method than Metropolis, so as a result we need fewer total samples for our chains to converge. ADVI follows a completely different methodology to fit a model that we will not get into here. We may cover ADVI, as well as NUTS, in-depth in a later chapter.
Below we plot a "heatmap" of the posterior distribution. (Which is just a scatter plot of the posterior, but we can visualize it as a heatmap.)
t = trace["halo_position"].reshape(5000,2)
fig = draw_sky(data)
plt.title("Galaxy positions and ellipcities of sky %d." % n_sky)
plt.xlabel("x-position")
plt.ylabel("y-position")
plt.scatter(t[:,0], t[:,1], alpha = 0.015, c = "r")
plt.xlim(0, 4200)
plt.ylim(0, 4200);
The most probable position reveals itself like a lethal wound.
Associated with each sky is another data point, located in ./data/Training_halos.csv
that holds the locations of up to three dark matter halos contained in the sky. For example, the night sky we trained on has halo locations:
halo_data = np.genfromtxt("data/Training_halos.csv",
delimiter = ",",
usecols = [1, 2,3, 4,5,6,7,8,9],
skip_header = 1)
print(halo_data[n_sky])
The third and fourth column represent the true $x$ and $y$ position of the halo. It appears that the Bayesian method has located the halo within a tight vicinity.
fig = draw_sky(data)
plt.title("Galaxy positions and ellipcities of sky %d." % n_sky)
plt.xlabel("x-position")
plt.ylabel("y-position")
plt.scatter(t[:,0], t[:,1], alpha = 0.015, c = "r")
plt.scatter(halo_data[n_sky-1][3], halo_data[n_sky-1][4],
label = "True halo position",
c = "k", s = 70)
plt.legend(scatterpoints = 1, loc = "lower left")
plt.xlim(0, 4200)
plt.ylim(0, 4200);
print("True halo location:", halo_data[n_sky][3], halo_data[n_sky][4])
Perfect. Our next step is to use the loss function to optimize our location. A naive strategy would be to simply choose the mean:
mean_posterior = t.mean(axis=0).reshape(1,2)
print(mean_posterior)
from DarkWorldsMetric import main_score
_halo_data = halo_data[n_sky-1]
nhalo_all = _halo_data[0].reshape(1,1)
x_true_all = _halo_data[3].reshape(1,1)
y_true_all = _halo_data[4].reshape(1,1)
x_ref_all = _halo_data[1].reshape(1,1)
y_ref_all = _halo_data[2].reshape(1,1)
sky_prediction = mean_posterior
print("Using the mean:")
main_score(nhalo_all, x_true_all, y_true_all, \
x_ref_all, y_ref_all, sky_prediction)
#what's a bad score?
random_guess = np.random.randint(0, 4200, size=(1,2))
print("Using a random location:", random_guess)
main_score(nhalo_all, x_true_all, y_true_all, \
x_ref_all, y_ref_all, random_guess)
This is a good guess, it is not very far from the true location, but it ignores the loss function that was provided to us. We also need to extend our code to allow for up to two additional, smaller halos: Let's create a function for automatizing our PyMC3.
def halo_posteriors(n_halos_in_sky, galaxy_data,samples = 5e5, burn_in = 500):
#set the size of the halo's mass
with pm.Model() as model:
mass_large = pm.Uniform("mass_large", 40, 180)
mass_small_1 = 20
mass_small_2 = 20
masses = np.array([mass_large,mass_small_1, mass_small_2], dtype=object)
#set the initial prior positions of the halos, it's a 2-d Uniform dist.
halo_positions = pm.Uniform("halo_positions", 0, 4200, shape=(n_halos_in_sky,2)) #notice this size
fdist_constants = np.array([240, 70, 70])
_sum = 0
for i in range(n_halos_in_sky):
_sum += masses[i]/f_distance(data[:,:2], halo_positions[i, :], fdist_constants[i])*\
tangential_distance(data[:,:2], halo_positions[i, :])
mean = pm.Deterministic("mean", _sum)
ellpty = pm.Normal("ellipcity", mu=mean, tau=1./0.05, observed=data[:,2:])
mu, sds, elbo = pm.variational.advi(n=50000)
step = pm.NUTS(scaling=model.dict_to_array(sds), is_cov=True)
trace = pm.sample(samples, step=step, start=mu)
burned_trace = trace[burn_in:]
return burned_trace["halo_positions"]
n_sky = 215
data = np.genfromtxt("data/Train_Skies/Train_Skies/\
Training_Sky%d.csv" % (n_sky),
dtype = None,
skip_header = 1,
delimiter = ",",
usecols = [1,2,3,4])
#there are 3 halos in this file.
samples = 5000
traces = halo_posteriors(3, data, samples = samples, burn_in=500)
fig = draw_sky(data)
plt.title("Galaxy positions and ellipcities of sky %d." % n_sky)
plt.xlabel("x-position")
plt.ylabel("y-position")
colors = ["#467821", "#A60628", "#7A68A6"]
for i in range(traces.shape[1]):
plt.scatter(traces[:, i, 0], traces[:, i, 1], c = colors[i], alpha = 0.02)
for i in range(traces.shape[1]):
plt.scatter(halo_data[n_sky-1][3 + 2*i], halo_data[n_sky-1][4 + 2*i],
label = "True halo position", c = "k", s = 90)
#plt.legend(scatterpoints = 1)
plt.xlim(0, 4200)
plt.ylim(0, 4200);
This looks pretty good, though it took a long time for the system to (sort of) converge. Our optimization step would look something like this:
_halo_data = halo_data[n_sky-1]
print(traces.shape)
mean_posterior = traces.mean(axis=0).reshape(1,6)
print(mean_posterior)
nhalo_all = _halo_data[0].reshape(1,1)
x_true_all = _halo_data[3].reshape(1,1)
y_true_all = _halo_data[4].reshape(1,1)
x_ref_all = _halo_data[1].reshape(1,1)
y_ref_all = _halo_data[2].reshape(1,1)
sky_prediction = mean_posterior
print("Using the mean:")
main_score([1], x_true_all, y_true_all, \
x_ref_all, y_ref_all, sky_prediction)
#what's a bad score?
random_guess = np.random.randint(0, 4200, size=(1,2))
print("Using a random location:", random_guess)
main_score([1], x_true_all, y_true_all, \
x_ref_all, y_ref_all, random_guess)
from IPython.core.display import HTML
def css_styling():
styles = open("../styles/custom.css", "r").read()
return HTML(styles)
css_styling()


Yaya Toure names Man Utd outcast Nemanja Matic as his toughest opponent
Yaya Toure has surprisingly named Manchester United midfielder Nemanja Matic as his toughest opponent.
Ivory Coast legend Toure would regularly come up against Matic during his eight-year spell in the Premier League with Manchester City.
Toure, who left English football last year, helped City win three Premier League titles and the FA Cup during his stint at the Etihad.
Serbian midfielder Matic enjoyed two spells at Chelsea while Toure was at City and then joined Manchester rivals United in 2017.
Matic emerged as a key player for former manager Jose Mourinho but has fallen out of favour under Ole Gunnar Solskjaer, although he will hope to revive his career once he returns from injury.
Asked to name the most difficult opponent he came up against during a brilliant career which also included spells at Barcelona and Monaco, Toure said: ‘Nemanja Matic was complicated.
Advertisement Advertisement
‘He’s not quick but he’s so strong, clever.’
The 36-year-old added to The Times: ‘All the rest of the opponents, because I always looked at them carefully before games, I get their weakness.’
Toure also revealed how his move from Barcelona to Manchester City materialised and how he was determined to help turn the Premier League club into champions.
‘I was on the phone with [chief executive] Garry Cook. He promised me he was going to bring players to help me to do great things at City,’ Toure said.
‘I said, ‘Sign David Silva first, and I will come.’ And Silva was saying, ‘Sign Yaya first and I will come!’ I said to Silva, ‘Sign! I am not going to run off!’
‘He didn’t believe me because I was at Barcelona, one of the top teams in the world. But it was time for change. Kolo told me to come. I have to listen to him.
Advertisement Advertisement
‘When I come to City, I said, ‘I come here to win and make City one of the greatest teams in the Premier League.’ People were laughing at me in the beginning.
‘I make my team-mates realise what we can become by starting with one trophy, the FA Cup.’
Toure finished his Manchester City career with 79 goals from 316 appearances.


The preprocessor can be quite a powerful tool: it allows you to declare variables and evaluate expressions. It also possesses some programming language capability, with branching control to skip or loop over a selected block of lines.
Lines which have the first character containing one of the following are treated specially:
Lines beginning with `#' are comment lines and are ignored. (More generally, text after a `#' in any line is ignored) Lines beginning with `%' may be interpreted as directives to the preprocessor. They are not part of the the post-processed input.
talk {4/2} mebecomes
talk 2 me`{...}' can contain constructs other than algebraic expressions (e.g. some string manipulation functions), as described below.
*Caution The substitution {...}→string may increase the length of the line. If the modified line exceeds the maximum allowed size it is truncated. This maximum length is controlled by variable recln0 in the main program. Source codes are distributed with recln0=120.
*Note As rdfiln parses a file, it may create new variables through a preprocessor directive such as
%const var=val ...and accordingly the symbols table is enlarged. The variables allocated this way are temporary, however. When rdfiln has finished with whatever file it is reading, it destroys variables created in the course of reading the file. You can preserve variables for future use (e.g. in parsing expressions after the preprocessor has returned the transformed input) with the `% save' directive.
const cconst cvar udef var vec char char0 cchar getenv vfind ← allocate variables and assigns values if ifdef ifndef iffile else elseif elseifd endif ← branching constructs for conditional reading of lines while repeat end ← looping constructs for repeated looping of lines echo exit include includo macro save show stop trace udef ← miscellaneous other constructsSuch lines interpreted not as part of the input, but as a directive to do something, such as assign a value to a variable.
1a. strn is the name of a character variable, say `myvar' rdfiln replaces `{myvar}' with contents of `myvar'. This rule takes precedence if a character variable `myvar' exists 1b. Similar to (1a), but strn is followed by a qualifier (...), which must be one of the following: *(integer1,integer2) returns a substring of strn. {myvar(n1,n2)} is replaced by the (n1:n2) substring of `myvar'. Example: If myvar="foo bar", "{myvar(2,3)}" → "oo". *('chrlst',n) marks a position in contents of `myvar.' 'chrlst' is a sequence of characters, equivalent to regular expression [chrlst]. {myvar('chrlst',n)} causes rdfiln to search the contents of myvar for any character in 'chrlst'. For definiteness let myvar="foo bar" and chrlst='abc'. Note that "foo bar" contains characters 'b' and 'a' and {myvar('abc',n)} will return the index position in "foo bar" that contains the nth occurrence of 'a' or 'b'. Example: If myvar="foo bar", {myvar('abc',2)} → 6. because myvar(6:6) is the second occurrence of a character in 'abc'. n is optional: if omitted, the preprocessor uses n=1. *(:e) returns an integer marking last nonblank character. Example: If myvar='foo bar', {myvar(:e)} → 7. *(/'strn1'/'strn2'/,n1,n2) substitutes strn2 for strn1. Example: If myvar="foo boor", {myvar(/'oo'/a/,2,2)} → "foo bar" Substitutions are made for the n1th to n2th occurrence of strn1. n1 and n2 are optional, as are the quotation marks. 1c. The following format returns either strn1 or strn2, depending on the result of expr: {?~expr~strn1~strn2} ← the '~' can be any character. expr is an algebraic expression; strn1 and strn2 are strings. If expr evaluates to nonzero, {...} is replaced by strn1. If expr evaluates to zero, {...} is replaced by strn2. 2. strn is name of a vector variable, say `myvec'. rdfiln replaces {myvec} with a sequence of numbers separated by one space, which are the contents of `myvec'. Example : suppose a `myvec' has been declared as a 5-element quantity: % vec myvec[5] 6-1 6-2 5-2 5-3 4-3 Then {myvec} is turned into 5 4 3 2 1 You can also substitute a single element. Thus {myvec(2)} is transformed into 4 3a. strn is an algebraic expression composed of, numbers, scalar variables, elements of vector variables, and macros, combined with unary and binary operators. The syntax is very similar to C. rdfiln parses strn to obtain a binary number, renders the result in ASCII form, and substitutes the result in place of strn. 3b. is an extension of 3a. strn may consist of a sequence of assignments of variables to expressions. The assignment may be a simple one (`=') or involve an arithmetic operation. Members of the sequence separated by commas. For each member a variable is assigned to an expression. rdfiln returns the value of the last expression. Examples: {x=3} ← assigns x to 3 and returns '3' {x=3,y=4} ← assigns x to 3 and y to 4, and returns '4' {x=3,y=4,x*=y} ← assigns x to 3*4 and y to 4, and returns '4' The last expression need not have an assignment operator. Thus {x=3,y=4,x*=y,x*2} ← assigns x to 3*4 and y to 4, and returns '24'
{my{foo}bar}will be transformed into
{my2bar}and finally the result of {my2bar} evaluated. If rdfiln cannot evaluate {my2bar} it will abort with a message similar to this one:
rdfile: bad expression in line { ... my2bar}
*Note the syntactical difference between {..} and (..). The latter applies to only algebraic expressions, while the former offers other possibilities as we have noted. But even when {..} contains an algebraic expression its effect can be a little different from (..). Curly brackets put rdfiln in a special mode where it replaces {..} with another string. Thus {pi-3} is replaced by .14159265 , whereas (pi-3) is kept in a binary representation of π-3, with about 16 decimal digits precision. Note moreover that you can use expressions (..) either inside curly brackets, in which case they form part of an expression that will be rendered in ASCII form as a modification of the input, or outside curly brackets. The input system (which reads whatever the preprocessor returns) can also parse algebraic expressions.
{var assignment-op expr [, ... ]}.Commas separate expressions in the sequence. The final may (and typically does) consist of expr only, omitting the var assignment-op part.
expr is a algebraic expression,
with a syntax very similar to C.
*Note expr may not contain any blanks or tabs.
It is composed of numbers, scalar variables,
elements of vector variables, and macros, combined with unary and binary operators.
Unary operators take first precedence: 1. - arithmetic negative ~ logical negative (.not.) functions abs(), exp(), log(), sin(), asin(), sinh(), cos(), acos() cosh(), tan(), atan(), tanh(), flor(), ceil(), erfc(), sqrt() (flor() rounds to the next lowest integer; ceil() rounds up) The remaining operators are binary, listed here in order of precedence with associativity 2. ^ (exponentiation) 3. * (times), / (divide), % (modulus) 4. + (add), - (subtract) 5. < (.lt.); > (.gt.); = (.eq.); <> (.ne.); <= (.le.); >= (.ge.) 6. & (.and.) 7. | (.or.) 8&9 ?: conditional operators, used as: test?expr1:expr2 10&11 () parentheses
The `?:' pair of operators follow a C-like syntax.
test, expr1, and expr2,
are all algebraic expressions.
If test is nonzero,
expr1 is evaluated and becomes the result.
Otherwise expr2 is evaluated and becomes the result.
assignment-op function '=' simple assignment '*=' replace 'var' by var*expr '/=' replace 'var' by var/expr '+=' replace 'var' by var+expr '-=' replace 'var' by var-expr '^-' replace 'var' by var^expr
Var Name Val 1 t 1.0000 2 f 0.00000 3 pi 3.1416 4 a 2.0000 ... Vec Name Size Val[1..n] 1 firstnums 5 1.0000 5.0000 2 nextnums 5 6.0000 10.000 ... char symbol value 1 c half 2 a whole 3 blank
You can print out the tables of current variables with the `show' directive. As described in more detail below, such a variables table can be created with the following directives:
% const a=2 % char c half a whole blank " " % vec firstnums[5] 1 2 3 4 5 % vec nextnums[5] 6 7 8 9 10Then the line
{c} of the {a} {pi} is {pi/2}is turned into the following;
half of the whole 3.14159265 is 1.57079633whereas the line
one quarter is {1/(nextnums(4)-5)}becomes
one quarter is .25The following illustrates substitution of character substrings:
% char c half a whole To {c(1,3)}ve a cave is to make a {a(2,5)}!becomes
To halve a cave is to make a hole!The following line illustrates substitution of vector name
{firstnums}, I caught a hare alive, {nextnums} I let him go again ...becomes
1 2 3 4 5, I caught a hare alive, 6 7 8 9 10 I let him go again ...The following illustrates nesting of {...}. The innermost block s substituted first, as the following illustrates.
% const xx{1{2+{3+4}1}} = 2undergoes substitution in three passes
% const xx{1{2+71}} = 2 % const xx{173} = 2 % const xx173 = 2The example below combines nesting and '{?~expr~strn1~strn2}' syntax:
MODE={?~k~B~C}3evaluates to, if k is nonzero:
MODE=B3or, if k is zero:
MODE=C3
*Note the scalar variables table is always initialized with predefined variables t=1, f=0 and pi=π. It is STRONGLY ADVISED that you never alter any of these variables.
const cconst cvar udef var vec char char0 cchar getenv vfind ← allocate variables and assigns values if ifdef ifndef iffile else elseif elseifd endif ← branching constructs for conditional reading of lines while repeat end ← looping constructs for repeated looping of lines echo exit include includo macro save show stop trace udef ← miscellaneous other constructs
Example % const myvar=exprdoes two things:
(1) add `myvar' to the scalar variables symbols table if it is not there already. `const' and `var' are equivalent in this respect. (2) assign the result of expr to it, if either * you use the `var' directive or * you use the `const' directive and the variable had not yet been created.In other words, if myvar already exists prior to the directive, const will not alter its value but var will. Thus the lines
% const a=2 % const a=3incorporate a into the symbols table with value 2, while
% const a=2 % var a=3does the same but assigns 3 to a.
*Note expr may be multiplied into, divided into, added into, subtracted from or exponentiated into an already-declared variable using one of the following C-like syntax:
myvar*=expr myvar/=expr myvar+=expr myvar-=expr myvar^=exprThese operators modify myvar for both `const' and `var' directives.
Example: % cconst test-expr myvar=exprtest-expr is an algebraic expression (e.g., i==3) that evaluates to zero or nonzero.
% const a = 2 b=3 c=4 d=5 A={a} B={b} C={c} D={d} % const a=3 % var d=-1 % const b*=2 c+=3 A={a} B={b} C={c} D={d} % cconst b==6 b+=3 c-=3 A={a} B={b} C={c} D={d} % cconst b==6 b+=3 c-=3 A={a} B={b} C={c} D={d}generates four lines:
A=2 B=3 C=4 D=5 A=2 B=6 C=7 D=-1 A=2 B=9 C=4 D=-1 A=2 B=9 C=4 D=-1a is unchanged from its initial assignment while d changes.
Compare the two cconst directives. b and c are altered in the first instance, since the condition b==6 evaluates to 1, while they do not change in the second instance, since now b==6 evaluates to zero.
% char c half a whole blankloads the character table as follows:
char symbol value 1 c half 2 a whole 3 blankThe last declaration can omit an associated string, in which case its value is a blank, as blank is in this case.
% cchar nam expr1 str1 expr2 str2 ...`nam' is the name of the character variable; expr1 expr2 etc are algebraic expressions.
% getenv myhome HOMEputs the string of your home directory into variable `myhome.'
% vec v[n] ← creates a vector variable of length n % vec v[n] n1 n2 n3 ... ← does the same, also setting the first elementsOnce `v' has been declared, individual elements of v may be set with the following syntax
% vec v(i) n ← assigns n to v(i) % vec v(i1:in) n1 n2 ... nn ← assigns range of elements i1..in to n1 n2 ... nnThere must be exactly in−i1+1 elements n1 ... nn.
% vfind v(i1:i2) svar match-value`svar' is a scalar variable and `match-value' a number or expression. Elements v(i1:i2) are parsed. svar is assigned to the the first instance i for which v(i)=match-value. If no match is found, `svar' is set to zero.
% vec a[3] 101 2002 30003 % vfind a(1:3) k 2002 ← sets k=2 % vfind a(1:3) k 10 ← sets k=0
These branching constructs have a function similar to the C constructs
if {text ;} else if {text ;} else {text ;}
or Fortran constructs
if (expr) then; ... elseif (expr) then; ... else; ... endif
% if Quartz is clear % elseif Ag is bright % else neither is right % endifgenerate the line
% ifdef expr1 | expr2 | expr3 ...If any of expr1 , expr2 , ... evaluate to nonzero, the result is nonzero, whether or not preceding expressions are valid.
char-variable ← T if char-variable exists, otherwise F char-variable=='string' ← T ifchar-variable has the value stringExample:
% ifdef x1==2 & atom=='Mg' | x1===1is nonzero if scalar x1 is 2 and if character variable `atom' is equal to "Mg", or if scalar x1 is 1.
% while [expr1 expr2 ...] exprn ← skip to `% end' if exprn is 0 ... ← these lines become part of the input while exprn is nonzero % end ← return to the `% while' directive unless exprn is 0The (optional) expressions `[expr1 expr2 ...]' follow the rules of the `const' directive. That is,
% udef -f db ← removes db from symbols table, if it already exists % while db=-1 db+=2 db<=3 ← db is initialized to -1 only once this is db={db} ← the body of the loop that becomes the input % end ← return file pointer to %while until test db<=3 is 0generates
this is db=1 this is db=3On the first pass, `db' is created and assigned the value −1; then `db+=2' increments db to 1. Condition db<=3 evaluates to 1 and the loop proceeds.
% repeat varnam list ... ← lines parsed for each element in list % endAs with the `while' construct, multiple passes are made through the input lines. list generates a sequence of integers (see this page for the syntax), For each member of the sequence `varnam' takes its value and the body of the loop passed through. list can be just an integer (e.g. `7') or define a more complex sequence, e.g. `1:3,6,2' generates the sequence `1 2 3 6 2'.
% const nm=-3 nn=4 % while db=-1 db+=2 db<=3 % repeat k= 2,7 this is k={k} and db={db} {db+k+nn+nm} is db + k + nn+nm, where nn+nm={nn+nm} % end (loop over k) % end (loop over db)The nested loops are expanded into:
this is k=2 and db=1 4 is db + k + nn+nm, where nn+nm=1 this is k=7 and db=1 9 is db + k + nn+nm, where nn+nm=1 this is k=2 and db=3 6 is db + k + nn+nm, where nn+nm=1 this is k=7 and db=3 11 is db + k + nn+nm, where nn+nm=1
% echo hello worldprints
#rf ##: hello worldwhere ## is the current line number.
% macro xp(x1,x2,x3,x4) x1+2*x2+3*x3+4*x4 The result of xp(1,2,3,4) is {xp(1,2,3,4)}generates
The result of xp(1,2,3,4) is 30
*Caution macros are not quite identical to function declarations. The following lines illustrate this:
% macro xp(x1,x2,x3,x4) x1+2*x2+3*x3+4*x4 The result of xp(1,2,3,4) is {xp(1,2,3,4)} The result of xp(1,2,3,3+1) is {xp(1,2,3,3+1)} The result of xp(1,2,3,(3+1)) is {xp(1,2,3,(3+1))}generates
The result of xp(1,2,3,4) is 30 The result of xp(1,2,3,3+1) is 27 The result of xp(1,2,3,(3+1)) is 30`macro' merely substitutes 1,2,3,.. for x1,x2,x3,x4 in `expr' as follows:
1+2*2+3*3+4*4 &larr xp(1,2,3,4) 1+2*2+3*3+4*3+1 &larr xp(1,2,3,3+1) 1+2*2+3*3+4*(3+1) &larr xp(1,2,3,(3+1))Because operator order matters, `4' and `3+1' behave differently. By using `(3+1)' in the fourth argument, operator precedence is maintained.
% save ← preserves all variables defined to this point % save name [name2 ...] ← saves only variables namedOnly variables in the scalar symbols table are saved.
% show vars prints out the state of the variables table % show lines echos each line generated to the screen until: % show stop is encountered*Note because the vector variables can have arbitrary length, `show' prints only the size of the vector and the first and last entries.
'trace 0' turns the tracing off 'trace 1' turns the tracing on at the lowest level. rdfiln traces directives having to do with execution flow (if-else-endif, repeat/while-end). 'trace 2' prints some information about most directives. 'trace 4' is the most verbose 'trace ' (no argument) toggles whether it is on or off.
Source codes the preprocessor uses are found in the slatsm directory:
rdfiln.f The source code for the preprocessor. Subroutine rdfile parses an entire file and returns a preprocessed one, can be found in rdfiln.f The key subroutine is rdfiln, which parses one line of a file. symvar.f maintains the table of variables for floating point scalars. symvec.f maintains the table of vector variables. a2bin.f evaluates ASCII representations of algebraic expressions using a C-like syntax, converting the result into a binary number. Expressions may include variables and vector elements. bin2a.f converts a binary number into a character string (inverse function to a2bin.f). mkilst.f generates a list of integers for looping constructs, as described below. This page describes the syntax of integer lists.The reader also maintains a table of character variables. It is kept in the character array ctbl, and is passed as an argument to rdfiln.
*Note The ASCII representation of an expression
is represented to 8 to 9 decimal places; thus ASCII representation of a floating point number has
less precision than the binary form. Thus '{1.2345678987654e-8}'
is turned into 1.2345679e-8.


This links from this page require that JavaScript be enabled.
FCKeditor
http://www.fckeditor.net/
(Click the "submit" button to see the HTML code produced by FCKeditor)
It can be styled, skinned, customized - including adding plug-ins.


object-fit: fill;
object-fit: contain;
object-fit: cover;
object-fit: none;
object-fit: scale-down;
original image
object-fit: fill
object-fit: contain
object-fit: cover
object-fit: none
object-fit: scale-down


Feel free to share your thoughts about this website! Please also note that the comments will be posted under your username. If you have not changed your username yet, then the default username is your email username (without the domain).