How to implement a time interval as an exponential function? - time

I need to implement an event (stock loss error) that occurs between time intervals as a renewal process. With every day of non-occurrence the probability of occurrence at the other day increases based on an exponential distribution: "The time intervals are based on an exponential distribution with a mean time between stock loss events (TBSLE). The frequency of (stock loss-)occurrence is the reciprocal of TBSLE. The expected value for the mean stock loss quantity can be estimated as 2.05."
First try:
def stockLossError(self):
stockLossErrorProbability = 0
inverseLambda =
errors = 0
randomnumber = np.random.exponential(scale=inverseLambda,size=(1,1))
if(randomnumber > stockLossErrorProbability):
self.daysSinceLastError += 1
self.errors += 2.05

Related

How to get the number e (2.718) using a random number sensor?

Is it possible to calculate the number e (2.718) using random numbers?
I'm assuming that when you say "using random numbers" you mean "using some sort of random sampling scheme." If you want the exact answer to an infinite number of decimals, the answer is "no, not unless you have an infinite amount of time." However, we can generate random sequences whose expected value is e, and we can assess the sampling error using basic statistics. By increasing the sample size, we can decrease the sampling error to any precision you want as long as you specify your desired confidence level.
It turns out that if you sum a bunch of random uniform(0,1)'s until the sum exceeds 1, the quantity of uniforms required has an expected value of e. We can turn that into a sampling problem by writing a method/function to return the count, and taking the average of the values obtained by calling that method multiple times.
You didn't specify any particular language, so here it is in Ruby (which is practically like pseudocode):
require 'quickstats' # install from rubygems w/ 'gem install quickstats'
def trial # generate results of one trial
count = 0
sum = 0.0
while sum < 1.0
count += 1
sum += rand # Ruby's rand produces U(0,1) values by default
end
return count # added "return" keyword for non-rubyists' readability
end
stats = QuickStats.new
10_000_000.times { stats.new_obs trial } # more precision? bump up sample size
puts "Average = #{stats.avg}"
half_width = 1.96 * stats.std_err
puts "CI half-width = #{half_width}"
deviation = (stats.avg - Math::E).abs
puts " |E - avg| = #{deviation} (should be ≤ half-width 95% of the time)"
This runs in under 4 seconds on my laptop and produces outputs such as:
Average = 2.7179918000002234
CI half-width = 0.0005421324752620413
|E - avg| = 0.0002900284588216451 (should be ≤ half-width 95% of the time)
Here’s another option. Consider the following probability question: you have a biased coin that comes up heads with probability 1/n. You then flip the coin n times. What is the probability that you never flip heads? Well, that’s the probability that you flip tails n times, which is (1 - 1/n)n, which as n tends towards infinity starts to rapidly approach 1/e. You could therefore estimate e by picking some modest value of n, simulating n tosses of a coin that comes up heads with probability 1/n, and seeing whether you never flip heads. The proportion of trials that don’t yield heads will approach 1/e, and from there you can estimate e.
For example, here's Python code to flip a coin with heads probability 1/n a total of n times (done by sampling a uniformly random number between 0 and 1) and see if all of them are tails:
from random import random
def one_trial(n):
for i in range(n):
if random() < 1 / n:
return False
return True
We can then run a large number of trials and see which fraction of them are all tails. That fraction will be approximately 1/e, so we just take the reciprocal:
def estimate_e(n, num_trials):
successes = 0
for i in range(num_trials):
if one_trial(n):
successes += 1
return num_trials / successes
Doing this with n = 210 and num_trials = 220 gave me the estimate
e ≈ 2.7198016257969466,
which isn't too bad.

Maximum profit earned in Interval

We have to rent our car to customers. We have a list whose each element represent the time at which car will be given, second -> the time at which car will be returned and third -> the profit earned at that lending. So i need to find out the maximum profit that can be earned.
Eg:
( [1,2,20], [3,6,15], [2,8,25], [7,12,18], [13,31,22] )
The maximum profit earned is 75. [1,2] + [3,6] + [7,12] + [13,31].
We can have overlapping intervals. We need to select such case that maximizes our profit.
Assuming you have only one car, then the problem we are solving in Weighted Interval Scheduling
Let us assume we have intervals I0 , I1, I2, ....In-1 and Interval Ii is (si,ti,pi)
Algorithm :
First sort the Intervals on the basis of starting points si.
Create a array for Dynamic Programming, MaxProfit[i] represent the maximum profit you can make from intervals Ii,Ii+1,In-1.Initialise the last value
MaxProfit[n-1] = profit_of_(n-1)
Then using DP we can find the maximum profit as :
a. Either we can ignore the given interval, In this case our maximum profit will be the maximum profit we can gain from the remaining intervals
MaxProfit[i+1]
b. Or we can include this interval, In this case the maximum profit can be written as
profit_of_i + MaxProfit[r]
where r is the next Interval such that sr > ti
So our overall DP becomes
MaxProfit[i] = max{MaxProfit[i+1], profit_of_i + MaxProfit[r] }
Return the value of MaxProfit[0]
use something like dynamic programming.
at first sort with first element.
you have 2 rows, first show most earned if this time is used and another is for most earned if not used.
then you will put each task in the related period of time and see in each time part it is a good choice to have it or not.
take care that if intervals are legal we choose all of them.

Q learning - epsilon greedy update

I am trying to understand the epsilon - greedy method in DQN. I am learning from the code available in https://github.com/karpathy/convnetjs/blob/master/build/deepqlearn.js
Following is the update rule for epsilon which changes with age as below:
$this.epsilon = Math.min(1.0, Math.max(this.epsilon_min, 1.0-(this.age - this.learning_steps_burnin)/(this.learning_steps_total - this.learning_steps_burnin)));
Does this mean the epsilon value starts with min (chosen by user) and then increase with age reaching upto burnin steps and eventually becoming to 1? Or Does the epsilon start around 1 and then decays to epsilon_min ?
Either way, then the learning almost stops after this process. So, do we need to choose the learning_steps_burnin and learning_steps_total carefully enough? Any thoughts on what value needs to be chosen?
Since epsilon denotes the amount of randomness in your policy (action is greedy with probability 1-epsilon and random with probability epsilon), you want to start with a fairly randomized policy and later slowly move towards a deterministic policy. Therefore, you usually start with a large epsilon (like 0.9, or 1.0 in your code) and decay it to a small value (like 0.1). Most common and simple approaches are linear decay and exponential decay. Usually, you have an idea of how many learning steps you will perform (what in your code is called learning_steps_total) and tune the decay factor (your learning_steps_burnin) such that in this interval epsilon goes from 0.9 to 0.1.
Your code is an example of linear decay.
An example of exponential decay is
epsilon = 0.9
decay = 0.9999
min_epsilon = 0.1
for i from 1 to n
epsilon = max(min_epsilon, epsilon*decay)
Personally I recommend an epsilon decay such that after about 50/75% of the training you reach the minimum value of espilon (advice from 0.05 to 0.0025) from which then you have only the improvement of the policy itself.
I created a specific script to set the various parameters and it returns after what the decay stop is reached (at the indicated value)
import matplotlib.pyplot as plt
import numpy as np
eps_start = 1.0
eps_min = 0.05
eps_decay = 0.9994
epochs = 10000
pct = 0
df = np.zeros(epochs)
for i in range(epochs):
if i == 0:
df[i] = eps_start
else:
df[i] = df[i-1] * eps_decay
if df[i] <= eps_min:
print(i)
stop = i
break
print("With this parameter you will stop epsilon decay after {}% of training".format(stop/epochs*100))
plt.plot(df)
plt.show()

Time-decaying sum sketch

At the Data Mining course at school i've received the following question regarding sketching:
Consider a stream of events with timestamps: t1 < t2<...
We are interested
in maintaining a sketch of timestamps that would allow us to estimate the time decaying with the current time
t with CV of ε
Tα=Σα(ti)
for any decay function α
I've tried to use the Morris Counter because it has logarithmic size and the probability of sampling the fist timestamps, which has the largest value in the decay function, is larger.
But the CV of the Morris Counter is a constant and I couldn't figure out how to modify it.
edit:
my solution so far:
initialize: x = 0, result = 0
for each new timestamp t:
- sample it with probability of 2^(-x)
- if it is sampled:
- x++
- result = result + α(t)

How to implement a counter that decays over time?

Requirements of special counter
I want to implement a special counter: all increment operations time out after a fixed period of time (say 30 days).
An example:
Day 0: counter = 0. TTL = 30 days
Day 1: increment counter (+1)
Day 2: increment counter (+1)
Day 3: value of counter == 2
Day 31: value of counter == 1
Day 32: value of counter == 0
Naive solution
A naïve implementation is to maintain a set of timestamps, where each timestamp equals the time of an increment. The value of the counter equals the size of the set after subtracting all timestamps that have timed out.
This naïve counter has O(n) space (size of the set), has O(n) lookup and O(1) inserts. The values are exact.
Better solution (for me)
Trade speed and memory for accuracy.
I want a counter with O(1) lookup and insert, O(1) space. The accuracy < exact.
Alternatively, I would accept O(log n) space and lookup.
The counter representation should be suited for storage in a database field, i.e., I should be able to update and poll the counter rapidly without too much (de)serialization overhead.
I'm essentially looking for a counter that resembles a HyperLogLog counter, but for a different type of approximate count: decaying increments vs. number of distinct elements
How could I implement such a counter?
If you can live with 24 hour granularity then you can bucket your counter into k buckets where k is the number of days in your longest TTL.
Incrementing is an O(1) operation - simply increment the value in the bucket with index (k-TTL), as well as the current sum total.
Reading is another O(1) operation as you simply read the current sum total.
A cronjob pops off the now-expired bucket each night (and adds a bucket with value 0 at the opposite end) and decreases your counter by the sum in that bucket (this is a background task so it would not affect your insert or read operations)
Decaying counter based on annealing
Here is a counter that is based on annealing (implemented in Python).
The counter exponentially decays over time; controlled by the rate alpha
When you read and write the counter, you provide a time index (increment or read the counter at time t)
You can read the counter in the present and future (w.r.t. index of last increment), but not in the past
Time indices of sequential increments must be weakly monotonically increasing
The algorithm is exact w.r.t. the alternative formulation (annealing vs. TTL). It has O(1) increment and read. It consumes O(1) space, in fact just three floating point fields.
class AnnealingCounter():
def __init__(self, alpha=0.9):
self.alpha = alpha # rate of decay
self.last_t = .0 # time of last increment
self.heat = .0 # value of counter at last_t
def increment(self, t=None, amount=1.0):
"""
t is a floating point temporal index.
If t is not provided, the value of last_t is used
"""
if t is None: t = self.last_t
elapsed = t - self.last_t
if elapsed < .0 :
raise ValueError('Cannot increment the counter in the past, i.e. before the last increment')
self.heat = amount + self.heat * (self.alpha ** elapsed)
self.last_t = t
def get_value(self, t=None):
"""
t is a floating point temporal index.
If t is not provided, the value of last_t is used
"""
if t is None: t = self.last_t
elapsed = t - self.last_t
if elapsed < .0 :
raise ValueError('Cannot increment the counter in the past, i.e. before the last increment')
return self.heat * (self.alpha ** elapsed)
def __str__(self):
return str('Counter value at time {}: {}'.format(self.last_t, self.heat))
def __repr__(self):
return self.__str__()
Here is how to use it:
>>> c = AnnealingCounter(alpha=0.9)
Counter has value 0.0 at time 0.0
>>> c.increment() # increment by 1.0, but don't move time forward
Counter has value 1.0 at time 0.0
>>> c.increment(amount=3.2, t=0.5) # increment by 3.2 and move time forward (t=0.5)
Counter has value 4.14868329805 at time 0.5
>>> c.increment() # increment by 1.0, but don't move time forward
Counter has value 5.14868329805 at time 0.5
>>> c.get_value() # get value as after last increment (t=0.5)
5.148683298050514
>>> c.get_value(t=2.0)
4.396022866630942 # get future value (t=2.0)
Since the increments expire in the same order as they happen, the timestamps form a simple queue.
The current value of the counter can be stored separately in O(1) additional memory. At the start of each operation (insert or query), while the front of the queue is expired, it's popped out of the queue, and the counter is decreased.
Note that each of the n timestamps is created and popped out once. Thus you have O(1) amortized time to access the current value, and O(n) memory to store the non-expired timestamps. The actual highest memory usage is also limited by the ratio of TTL / frequency of new timestamp insertions.

Resources