In [1]:
from crosscorrelate import test_against_real_data
import numpy as np
import random
import time
import csv
import os
import math
import statistics
from multiprocessing import Pool

In [2]:
def create_new_set(setlength):
    new_set = []
    for i in range(setlength):
        new_set.append(round(random.random(),4))
    count = 0
    for k in new_set:
        i = round(k, 4)
        new_set[count] = i
        count += 1

        return new_set

In [3]:
from PyTCI.weights import leanbodymass
from PyTCI.models import propofol
from patient_solver import solve_for_patient

class New_model(propofol.Propofol):
    def __init__(self, age, weight, height, sex, params):
        
        lean_body_mass = leanbodymass.hume66(height, weight, sex)
        
        self.v1 = ((params[1] * 50) - params[2]*(age - (params[3] * 100))) * (params[4] * (lean_body_mass - (params[5] * 100)))
        self.v2 = params[6] * lean_body_mass * 2
        self.v3 = params[7] * weight * 5
        
        self.Q1 = ((params[8] * self.v1) * (params[9] * age)) ** 0.75
        self.Q2 = (params[9] * self.v2)** 0.75
        self.Q3 = (params[0] * self.v3) ** 0.75
        
        self.keo = 0
        
        propofol.Propofol.from_clearances(self)
        propofol.Propofol.setup(self)
        
class SIVA_model(propofol.Propofol):
    def __init__(self, age, weight, height, sex, params):
        
        lean_body_mass = leanbodymass.hume71(height, weight, sex)
        
        self.v1 = (params[1] * lean_body_mass) * (age **(-params[2]))
        self.v2 = params[3] * lean_body_mass * 2
        self.v3 = params[4] * weight * 5
        
        self.Q1 = (params[5] * (weight ** 0.75) ) * (age ** (-params[6]))
        self.Q2 = params[7] * (self.v2 ** 0.75)
        self.Q3 = params[8] * (self.v3 ** 0.75)
        
        self.keo = 0
        
        propofol.Propofol.from_clearances(self)
        propofol.Propofol.setup(self)        
                                                         
                   
                   
                   
def solve_for_custom(patient, params):
    patient_model = SIVA_model(patient["age"], patient["weight"], patient["height"], patient["sex"], params )
    return solve_for_patient(patient_model, patient["events"])

In [4]:
def create_new_population(size, setlength):
    pop_size = size
    pop_list = []
    for i in range(pop_size):
        newparam = create_new_set(setlength)
        pop_list.append(newparam)
    return pop_list

In [5]:
def mutate_population(children, fittest, second, mutants):
    pop_list = []
    
    #keep fittest set in so we don't go backwards
    pop_list.append(fittest)
    def mutate_chromosome(chrome):
        b = random.random()
        c = len(fittest)
        c = 1 / c
        if b < (c/2):
            chrome = chrome * np.random.normal(1, 0.3)
        elif b < c:
            chrome = chrome * np.random.normal(1, 0.1)
        else:
            chrome = chrome * 1
        return round(chrome, 6)

    # breed parents to create children
    def breed(sprogs, p1, p2):
        for i in range(sprogs):
            child = []
            count = 0
            for k in p1:
                a = random.random()
                if a < 0.5:
                    k = p2[count]
                    k = mutate_chromosome(k)
                    child.append(k)
                else:
                    k = mutate_chromosome(k)
                    child.append(k)

                count += 1
            pop_list.append(child)

    breed(children, fittest, second)

    # immigration to escape local minima
    rand1 = create_new_set(len(fittest))
    rand2 = create_new_set(len(fittest))

    pop_list.append(rand1)
    pop_list.append(rand2)

    breed(2, fittest, rand1)
    breed(2, fittest, rand2)

    # create mutants of fittest
    for i in range(mutants):
        mutant = []
        for k in fittest:
            b = random.random()
            if b < 0.2:
                mut_factor = 0.3
            else:
                mut_factor = 0.1
            k = k * np.random.normal(1, mut_factor)
            k = round(k, 4)
            mutant.append(k)
        pop_list.append(mutant)

    return pop_list

In [6]:
def multi_core_test(cores, maxpt, params):
    # TODO change this so params can be any size

    step_size = round(maxpt / cores)

    jobs = []

    for idx in range(cores):
        a = step_size * idx + 1
        b = step_size * (idx + 1)
        if idx == (cores-1):
            b = maxpt
        thing = (a, b, params)
        jobs.append(thing)

    
    results = pool.map(test_against_real_data, jobs)

    # make this dynamic, cast to float?
    #rms = sum([thing[0] for thing in results]) / cores
    meds = sum([thing[1] for thing in results]) / cores
    bias = sum([thing[2] for thing in results]) / cores
    hypot = math.hypot(meds, bias)

    # "%-15s %-15s" % (rms, meds)
    data = (hypot, meds, bias)

    # return meds
    return data

In [7]:
from csvreader import read_patient_csv

def test_against_real_data(stuff):
    pmin = stuff[0]
    pmax = stuff[1]
    params = stuff[2]
    patients = read_patient_csv()

    medians = []
    bias = []

    for patient in patients[pmin:pmax]:
        res = solve_for_custom(patient, params)
        medians.append(res["median"])
        bias.append(res["bias"])


    MDAPE = statistics.mean(medians)
    MDPE = statistics.mean(bias)
    
    #use pythagorus to calculate score to optimise both performance error and bias
    b = 1

    data = (b, MDAPE, MDPE)
    return data

In [8]:
import time
from IPython import display
from multiprocessing import Pool
import matplotlib.pyplot as plt


print("creating population")
pop = create_new_population(10, 9)
pool = Pool(10)


def test_population(pop):

    pop_list = []
    for i in pop:
        try:
            result = multi_core_test(10, 250, i)
            fitness = result[0]
            pop_list.append([fitness, i, result])

        except:
            result = (99, 99, 99)
            fitness = result[0]
            pop_list.append([fitness, i, result])
    
    pop_list.sort()
    output = (pop_list[0][1], pop_list[0][2], pop_list[1][1], pop_list[1][2])

    return output

print("beginning test")
fit_results = test_population(pop)

fittest_set = fit_results[0]
best_fitness = fit_results[1][1]
second_set = fit_results[2]
second_fitness = fit_results[3][1]

max_tries = 0
while best_fitness > 9.9:
    fit_results = test_population(pop)
    best_fitness = fit_results[1][1]
    
    print ("trying again")    

pltB = []
pltS = []


print("starting")
# 
for i in range(40):
    
   
    new_pop = mutate_population(10, fittest_set, second_set, 10)
    fit_results = test_population(new_pop) 
    
    if fit_results[1][0] < 99:
        fittest_set = fit_results[0]
        best_fitness = fit_results[1][0]
        second_set = fit_results[2]
        second_fitness = fit_results[3][0]

        print(i, fit_results[1])
        
        pltB.append(fit_results[1][1])
        pltS.append(fit_results[1][2])

print(fittest_set)
print ("finished!!")


creating population
beginning test
starting
0 (0.7922297230354145, 0.7904909569351246, 0.05245932771738967)
1 (0.7169438056350594, 0.7163906700707054, -0.0281572064333031)
2 (0.5168791486734332, 0.4036857381320493, 0.3228031585380719)
3 (0.43367760959786933, 0.4336462494186962, -0.005215307432925026)
4 (0.43367760959786933, 0.4336462494186962, -0.005215307432925026)
5 (0.39394279074239896, 0.3907540751872101, 0.05002174629596303)
6 (0.3872791964777525, 0.38628134712423323, 0.027783032382035437)
7 (0.3792858759174065, 0.37299327795554127, 0.06880254552278298)
8 (0.3792858759174065, 0.37299327795554127, 0.06880254552278298)
9 (0.3764816123074747, 0.36772790873822536, -0.08071300725810593)
10 (0.35001861043779353, 0.34698379350722486, 0.0459921155866895)
11 (0.35001861043779353, 0.34698379350722486, 0.0459921155866895)
12 (0.35001861043779353, 0.34698379350722486, 0.0459921155866895)
13 (0.3474544540061567, 0.3471063888137857, 0.015548390700310244)
14 (0.3462592557513559, 0.3430565141324007, 0.046986171421056225)
15 (0.3414103905449353, 0.3391363578691771, 0.03933936378838254)
16 (0.3408192993321838, 0.3388342105438866, 0.0367310844160884)
17 (0.3408192993321838, 0.3388342105438866, 0.0367310844160884)
18 (0.34080147799287697, 0.33882972621052815, 0.0366068851205338)
19 (0.3388730445564218, 0.3387985511631911, 0.007105072600701529)
20 (0.3354284650109968, 0.3343652987592626, 0.02668524171265064)
21 (0.3331536883822084, 0.3188325843464706, 0.09662899793343784)
22 (0.3319418582215868, 0.3192616726008501, 0.09087013617084345)
23 (0.3319418582215868, 0.3192616726008501, 0.09087013617084345)
24 (0.3319418582215868, 0.3192616726008501, 0.09087013617084345)
25 (0.3319418582215868, 0.3192616726008501, 0.09087013617084345)
26 (0.32570921284418847, 0.3193617535367495, 0.06398876236897626)
27 (0.32522387868746244, 0.3159268117094346, 0.07720635279320431)
28 (0.3213054750132856, 0.31896257355515184, 0.038730930076457504)
29 (0.3213054750132856, 0.31896257355515184, 0.038730930076457504)
30 (0.32125701948258956, 0.3184205799848413, 0.04259585436347301)
31 (0.321206527927479, 0.3185441809328914, 0.04127030866155127)
32 (0.321206527927479, 0.3185441809328914, 0.04127030866155127)
33 (0.31914268732256434, 0.3182737046787699, 0.023535160537358102)
34 (0.31914268732256434, 0.3182737046787699, 0.023535160537358102)
35 (0.31914268732256434, 0.3182737046787699, 0.023535160537358102)
36 (0.318920295396768, 0.31825488450083, 0.020590854944007066)
37 (0.318920295396768, 0.31825488450083, 0.020590854944007066)
38 (0.318920295396768, 0.31825488450083, 0.020590854944007066)
39 (0.318920295396768, 0.31825488450083, 0.020590854944007066)
[0.1455, 0.094332, 0.0643, 0.626, 0.0609, 0.7895, 0.6413, 0.0181, 0.2004]
finished!!

In [12]:
from crosscorrelate import test_with_schnider
params = []
stuff = [1, 250, params]

rms, mdpe, bias = test_with_schnider(stuff)

print(mdpe, bias)


0.3957175094766276 0.35897282397993197

In [24]:
%matplotlib notebook

fig, ax1 = plt.subplots()

color = 'tab:red'
ax1.set_xlabel('Generations')
ax1.set_ylabel('MDAPE', color=color)
ax1.set_ylim(ymin=0)
ax1.plot(pltB,  color=color)
ax1.axhline(y=mdpe,color=color, linestyle='--', alpha=0.5)
ax1.tick_params(axis='y', labelcolor=color)

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('MDPE', color=color)  # we already handled the x-label with ax1
ax2.plot(pltS, color=color, alpha=0.5)
ax2.axhline(y=bias, color=color, linestyle='--', alpha=0.5)
#ax2.set_ylim(ymin=0)
ax2.tick_params(axis='y', labelcolor=color)

fig.tight_layout()  # otherwise the right y-label is slightly clipped
plt.show()



In [11]:
x = []
y = range(40,80)
for i in range(40, 80):
    x.append((70 * 0.8)*(i**(-0.6)))
    
fig4 = plt.figure()
plt.plot(y, x)
plt.show()



In [ ]: