WE LIVE OUR LIVES INCREASINGLY ONLINE

WE LIVE OUR LIVES INCREASINGLY ONLINE

BUT THE ONLY CONSTANT IS CHANGE.

CONSUMENTENBOND - ENERGIE VERGELIJKER

– SAFIA NOBLE, PHD,
AUTHOR OF ALGORITHMS OF OPPRESSION “People are using search engines rather than libraries or teachers to make sense of the world we’re inhabiting .”

TECH CAN BE MAGICAL

SARAH DRASNER @SARAH_EDO

LIVE &
MACHINE LEARN

The good, the bad, 
 and the intriguing

"MACHINE LEARNING GIVES COMPUTERS ABILITY TO LEARN WITHOUT BEING EXPLICITLY PROGRAMMED ” ARTHUR SAMUEL, 1959

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo SUPERVISED Pug Pug Pug Kitten Kitten Kitten

@sarah_edo UNSUPERVISED ?

SUPERVISED

@sarah_edo Naive Bayes Nearest Neighbor Linear Regression Support Vector Machines Genetic Convolutional Neural Networks Back Propagation Neural Network

@sarah_edo Pug? Pug? Pug?

@sarah_edo

@sarah_edo +

@sarah_edo +

@sarah_edo Pug? Accuracy: 90% Accuracy: 100%

@sarah_edo

THE ROAD TO HELL IS PAVED WITH GOOD INTENTIONS

@sarah_edo PredPol SOURCE: WEAPONS OF MATH DESTRUCTION

ONCE A CRIMINAL,
ALWAYS A CRIMINAL • 68 % become re-offenders within 3 years, 
 77% in 5 years • People report to finding it hard to fit back into “normal” life once being in prison for a while • Employment becomes more difficult SOURCE: US DEPARTMENT OF JUSTICE

COMPAS RISK ASSESSMENT Recidivism Score is used to determine whether someone will commit another crime within two years. SOURCE: PRACTITIONER’S GUIDE TO COMPAS SCORES

@sarah_edo SOURCE: MACHINE BIAS, RISK ASSESSMENT IN CRIMINAL SENTENCING

@sarah_edo Blacks are almost twice as likely as whites to be labeled a higher risk but not actually re-offend

@sarah_edo

@sarah_edo

@sarah_edo ZILLY, 48, CONSTRUCTION WORKER

WHAT MAKES COMPAS FAIL? • No transparency • It doesn’t adapt over time • People use it without asking questions • Including whether this is the right place 
 for an algorithm at all. CAN ONLY EVALUATE THE PAST SOURCE: WEAPONS OF MATH DESTRUCTION

@sarah_edo “I don’t like the idea myself of COMPAS being the sole

evidence that a decision would be based upon.”

-Brennan, co-creator of COMPAS

PEOPLE WILL SAY ALGORITHMS CAN’T BE BIASED. BUT ALGORITHMS ARE WRITTEN BY PEOPLE.

ACXIOM, A DATA BROKERAGE • Had an average of 1500 data points for 500 million consumers, including the entire adult population of the United States • That was in 2012. • That’s just one company. SOURCE: TECHNICALLY WRONG

WHAT DOES FACEBOOK THINK ABOUT ME? Science Wine Do it yourself Toys Software Developer Animated Movies Cloud computing The Oatmeal Neuroscience Dogs 3d computer graphics Trench Coats Mermaid Navy James Patterson Knitting Shoes Sports

• Facebook uses these tags to drive directed ads • You can use it to target on demographics, including race • Buying a house- limited to races
• Illegal under the Fair Housing Act of 1968 • Once pointed out, Facebook fixed it SOURCE: TECHNICALLY WRONG

@sarah_edo

–SARA WACHTER-BOETTCHER , AUTHOR OF DESIGN FOR REAL LIFE “It’s not that digitizing the world is inherently bad. But the more technology becomes embedded in all aspects of life, the more it matters whether that technology is biased, alienating, or harmful ”

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo < input

type

" file "

name

" file "

id

" file "

class

" inputfile " @ change

" fileUpload " />

< label

for

" file "

aria-label

" upload image "

< svg

xmlns

" http://www.w3.org/2000/svg "

width

" 45 "

height

" 45 "

viewBox

" 0 0 32 32 "

aria-labelledby

" plus "

role

" presentation "

< title

id

" plus "

Plus Sign </ title

< circle cx

" 15 "

cy

" 15 "

r

" 15 "

fill

" #bf310b " />

< line x1

" 15 "

x2

" 15 "

y1

" 10 "

y2

" 20 "

fill

" none "

stroke-weight

" 2 "

stroke

" #fff " />

< line x1

" 10 "

x2

" 20 "

y1

" 15 "

y2

" 15 "

fill

" none "

stroke-weight

" 2 "

stroke

" #fff " />

</ svg

</ label

@sarah_edo fileUpload (e) {

var files

e . target . files

|| e . dataTransfer . files ;

if ( ! files . length ) return ;

this . image

= files[ 0 ];

this . createImage ();

this . visionReq (); }, createImage () {

var image

new

Image ();

var reader

new

FileReader (); reader . onload

=

e

=> {

this . image

= e . target . result ; }; reader . readAsDataURL ( this . image ); },

@sarah_edo apiReq (params, urlPath) {

let uribase

https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/ ${ urlPath };

...

return

axios ({

method : " post " ,

url : uribase,

data : data,

params : params,

headers : {

" Content-Type " : contentType,

" Ocp-Apim-Subscription-Key " : “ xxxxxxxxxxxxxxx "

}, 

validateStatus ( status ) {

return status <

500 ; } }); },

@sarah_edo visionReq () {

let param1

{

language : " unk " ,

" detectOrientation " : " true "

};

let param2

{

visualFeatures : " Categories,Description,Color " ,

details : "" ,

language : " en "

};

...

this . apiReq (param2, " analyze " ) . then ( response

=> {

if (response . status

===

200 ) {

this . desc

= response . data . description . captions [ 0 ] . text ; } else {

this . noText

=

true ; } }); },

@sarah_edo

LUIS WHAT ELSE CAN COGNITIVE SERVICES DO?

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo

@sarah_edo SLOW DOWN

BIOFEEDBACK

@sarah_edo

@sarah_edo

@sarah_edo getUnderstanding ( {

commit

},

utterance ) {

commit ( ' setUiState ' , ' fetching ' )

const url

` https://westus.api.cognitive.microsoft.com/luis/v2.0/apps

               /4aba2274-c5df-4b0d-8ff7-57658254d042

` https: axios ({

method : ' get ' , url,

params : {

verbose : true ,

timezoneOffset : 0 ,

q : utterance },

headers : {

' Content-Type ' : ' application/json ' ,

' Ocp-Apim-Subscription-Key ' : ‘ XXXXXXXXXXXXXXXXXXX '

    } 
  })

In store.js (Vuex)

@sarah_edo

. then ( ( {

data

} )

=> {

console . log ( ' axios result ' , data)

if (altMaps . hasOwnProperty (data . query )) {

commit ( ' newIntent ' , {

intent : altMaps[data . query ],

score : 1

        }) 
      } 

else {

commit ( ' newIntent ' , data . topScoringIntent ) }

commit ( ' setUiState ' , ' idle ' )

commit ( ' setZoom ' ) })

. catch ( err

=> {

console . error ( ' axios error ' , err) }) In store.js (Vuex)

@sarah_edo export

default

new

Vuex . Store ({

state : {

counter : 0 ,

intent : ' None ' ,

intensity : ' None ' ,

score : 0 ,

// idle - awaiting user input

// listening - listening to user input

// fetching - fetching user data from the API

uiState : ' idle ' ,

zoom : 3

},

getters : {

intentStr : state

=> {

var str

state . intent

  str 

= str . replace ( / \b ( App . ) \b / gi , '' )

return str },

In store.js (Vuex)

@sarah_edo actions : {

getSpeech ( {

dispatch ,

commit ,

state

} ) {

commit ( ' setUiState ' , ' listening ' )

// keep recording speech all the time or activate it-

  //for the first screen no, press a button. second screen yes.

  state

. intent

===

' None '

? (recognition . continuous

=

true )

: (recognition . continuous

=

false ) recognition . start () recognition . onresult

=

function ( event ) {

const last

event . results . length

1

const phrase

event . results [last][ 0 ] . transcript

dispatch ( ' getUnderstanding ' , phrase) } },

…

In store.js (Vuex)

@sarah_edo

@sarah_edo

@sarah_edo mutations : {

newIntent : ( state ,

{ intent ,

score } )

=> {

if (intent . includes ( ' Intensity ' )) { state . intensity

= intent

if (intent . includes ( ' More ' )) { state . counter++

    } 

else

if (intent . includes ( ' Less ' )) { state . counter

    } 
  } 

else { state . intent

= intent } state . score

= score },

… 

} In store.js (Vuex)

@sarah_edo In Base.vue (Components) createShapes () {

this . bufferCamera . position . z

=

this . shapeZoom

if ( this . torusKnot

!==

null ) {

this . torusKnot . material . dispose ()

this . torusKnot . geometry . dispose ()

this . bufferScene . remove ( this . torusKnot ) }

var shape

new

THREE . TorusKnotGeometry (

this . tConfig . a ,

this . tConfig . b ,

this . tConfig . c ,

this . tConfig . d

    ), 
    material 
 …

  

this . torusKnot

=

new

THREE . Mesh (shape, material)

this . torusKnot . material . needsUpdate

=

true

this . bufferScene . add ( this . torusKnot ) },

@sarah_edo animate () {

this . storeRAF

=

requestAnimationFrame ( this . animate )

this . bufferScene . rotation . x

+=

0.01

this . bufferScene . rotation . y

+=

0.02

this . renderer . render (

this . bufferScene ,

this . bufferCamera ,

this . bufferTexture

  ) 
  

this . renderer . render ( this . scene , this . camera ) },

In Base.vue (Components)

@sarah_edo In Base.vue (Components) watch : {

shapeZoom () {

this . createShapes ()

cancelAnimationFrame ( this . storeRAF )

this . animate () } },

Repo: github.com/sdras/three-vue-pattern

@sarah_edo

ML IN MEDICINE • Sophia Genetics is training algorithms to diagnose diseases through DNA analysis • All4Cure is a social network for cancer patients where patients can enter diagnosis and treatment so that it can be analyzed • HealthMap algorithm spotted an ebola outbreak 9 days before the World Health Organization SOURCES: SILICON ANGLE , GEEKWIRE , AND NEWSWEEK

WHAT CAN YOU DO?

APPLICATIONS FOR GOOD ✨ ✨

CURRENT APPLICATION

WHAT HAPPENS WHEN 
 THEY’RE OFFLINE? BUT…

@sarah_edo backgroundSync && Service Workers • Alert them when they are offline • When they’re offline, queue the messages • When it’s back up, send them out 
 (even if the browser tab is closed)

@sarah_edo

@sarah_edo window . addEventListener ( ' online ' , vm . isOnline ); window . addEventListener ( ' offline ' , vm . isOnline );

isOnline () {

if ( navigator . onLine ) {

this . status

= Online. Clear to send.

this . offline

=

false

}

else {

this . status

= Offline. But don't worry, your requests 
 will still be processed soon as you are 
 connected.

this . offline

=

true

} }, Alert them when they’re offline

@sarah_edo Register the service worker when a request is made requestButton (type) {

if ( ' serviceWorker '

in

navigator ) {

navigator . serviceWorker . register ( ' ./service-worker.js ' ) . then ( ( registration )

=> {

return

navigator . serviceWorker . ready ; }) . then ( ( registration )

=> { registration . sync . register (request- ${ type }) . then ( ()

=> {

console . log ( ' %c sync registered ' , ' font-size: 16px; … ’ ); }) . catch ( function

( error ) {

console . log ( ' Unable to fetch resources. ' ); });

...

}

@sarah_edo Create the sync event self . addEventListener ( ' sync ' , event

=> {

let type

event . tag . split ( '

' )[ 1 ]

console . log ( %c sync event fired: request ${ type }, ${ styles } background: #00449e; color: #cdecff; )

event . waitUntil ( fetchResource (type)) })

@sarah_edo Fetch the URL, and postMessage back to the client const

fetchResource

=

resource

=> {

fetch ( ' //jsonplaceholder.typicode.com/users ' )

. then ( response

=> {

return response })

. then ( text

=> {

const message

{

response : text . status ,

resource : resource } self . clients

. matchAll ()

. then ( all

=> all . map ( client

=> client . postMessage (message))) }) ...

}

@sarah_edo updateRequest (response, type) {

if (response

200 ) {

this . responseSuccess

=

true

this . messageQueue . push (

  `

You successfully sent a message: <span> ${ type } </span> `

) } }, Let them know when it’s successful

ASK QUESTIONS MOST IMPORTANT…

City Buildings Your house

@sarah_edo THANK YOU! @sarah_edo