header banner
Default

Alexandra Institute: Computer, hvordan vil du forklare det? Med objektive facts og subjektive eksempler til feature attribution og fodbold?


Table of Contents

    Maskinlæringsmodeller kan bruges til at klassificere mange forskellige ting, og et eksempel kunne være en model til at afgøre hvilken tone en tekst er skrevet i. Men hvorfor siger modellen nu igen, at jeg skriver i en subjektiv tone, når nu jeg prøver at forholde mig objektivt? Vi kan forsøge at forklare modellens udfald ved at se på hvilke ord, der har været mest betydende for udfaldet. Et eksempel er; ”jeg synes, at AGF er det bedste hold i Superligaen”, og i forklaringen nedenfor ses det, at ordene ”jeg” og ”synes” har været de mest udslagsgivende for, at modellen prædikterer sætningen som værende subjektiv og ikke objektiv.

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    Eksempel på Lime

    Overstående er et eksempel på en forklaringsmodel, der kan anvendes til at forklare udfald fra en såkaldt ’black-box’-klassifikationsmodel på både tekst, tabel- eller billeddata — og det uden et egentligt kendskab til, hvordan selve modellen virker, da forklaringsmetoden anvendes efter selve modellen er udviklet ved at efterligne den komplekse model lokalt. To kendte frameworks til at lave disse model-uafhængige feature attribution forklaringer er LIME (Local Interpretable Model-agnostic Explanations, Ribeiro et. al 2016) og SHAP (SHapley Additive exPlanations , Lundberg et al. 2017), og denne blogpost giver en introduktion til, hvordan disse to metoder virker, men også en diskussion af hvornår de ikke gør. Måske synes du ligesom mig, at ovenstående forklaring giver fin mening, men denne blogpost handler i høj grad også om begrænsningerne ved metoderne, og den subjektive overskrift kunne have været; hvorfor SHAP og LIME alligevel ikke redder kampen.

    Men bare rolig, tonen er ikke kun dyster, det hele bliver fremført i en blanding af positivt, negativt, objektivt og subjektivt tonede sætninger.

    Vi starter lidt bredt, hvorefter vi dykker ned i teorien bag metoderne, skyder bolden over til det praktiske ved implementeringerne, laver en objektiv vurdering af den bedste fodboldspiller, ser på fordele og ulemper igennem eksempler, og til sidst kigger vi på, om vi kan snyde forklaringsmodellerne til ikke at opdage, at vi holder med AGF.

    Men inden vi går i gang, skal det lige indskydes, at klassifikationsmodellen, vi vil bruge som eksempel igennem bloggen, er en spaCy-model, jeg har trænet på manuelt annoterede tweets for ’subjektivt’ og ’objektivt’, og i tillæg er den trænet på sætninger fra Wikipedia, som er antaget til at være ’objektive’. Men mere om modellen senere.

    Og som et sidste indspark, hvis du vil læse mere generelt om forklarlig AI, kan jeg anbefale min kollegas blogpost.

    Den gængse tone

    .. eller den gængse opfattelse af, hvad disse ‘feature attribution’-metoder kan bruges til, tager vi fat på først. Ribeiro et. al 2016 præsenterede et værktøj kaldet LIME, som kan adressere problemet med ’tillid’ til maskinlæringsmodeller igennem forklaring. Med det mener de, at forklaringer enten kan bruges til at skabe tillid til et enkelt udfald, eller til at skabe tillid til modellen. Vi vil i denne blog inddele anvendelsen i følgende tre grupper:

    • Til at forklare enkelte udfald til en bruger
    • Som udviklingsværktøj
    • Til at monitorere fairness

    Den grundlæggende ide bag at give forklaringer af enkelte udfald til en bruger af systemet går på, at hvis jeg som bruger finder forklaringen rimelig, så har jeg en større tro på, at modellens udfald er korrekt i det specifikke tilfælde, hvorimod hvis jeg finder forklaringen langt ude, så kan det være, at jeg som bruger af modellen, skal vælge at forkaste modellens prædiktion på dette pågældende eksempel. Men hvilke forklaringer, en slutbruger egentlig har brug for, er stof til et helt andet og mere tværfagligt blogindlæg.

    Forklaringer kan også bruges i selve udviklingsprocessen til at få en indsigt i, hvilke ting modellen faktisk kigger på, og særligt kan det opdages, om modellen fitter på noget i data som er uhensigtsmæssigt (se for eksempel Lapuschkin et al. 2019).

    Den sidste ide til anvendelse går på, at man kan bruge disse metoder som en ekstern part, som ikke har fået indsigt i udviklingen af systemet, til at monitorere om et system er fair, fx i forhold til ikke at være diskriminerende over for bestemte grupper ved for eksempel at undersøge om modellen bruger såkaldte ”beskyttede” variabler til at komme frem til beslutningen. (Læs mere om Fairness i min tidligere blogpost om retfærdige superhelte).

    Af ovenstående tre anvendelsesmuligheder er det nok at benytte metoderne som udviklingsværktøj, der har størst potentiale. Men lad os lige se på den ovenstående sætning engang;

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    Eksempel på Lime

    Jamen dog, modellen prædikterer, at det er en subjektiv holdning herfra — og forklaringen er, at ”er det nok” ikke er et objektivt ordvalg. Men så lad os i stedet starte mere objektivt med teorien bag, før vi begynder på diskussionen og tager fat på et fodboldeksempel.

    Den objektive matematik

    ... er et godt sted at begynde og lad os begynde med at se nærmere på LIME fra 2016, hvorefter vi kigger ind i SHAP, der udkom året efter. Ideen bag LIME er at træne en simpel, forklarlig model lokalt rundt om et enkelt data-eksempel, således at den simple model efterligner den egentlige klassifikationsmodel så godt som muligt i det lokale område. På formel bliver det i Ribeiro et. al 2016 , præsenteret således:

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    Credit: Ribeiro et. al 2016

    Lad os bryde det lidt ned. Lad os forestille os, at vores egentlige klassifikationsmodel, hvilken er defineret som i formlen, er trænet via deep learning til at lære de komplekse strukturer i dataene, og derfor ikke nemt lader sig forklare i sig selv. Ideen er nu i stedet at finde en simpel model, som vi nemt kan forklare. Men den simple model kan ikke bruges til at forstå den komplekse struktur, som vores data har (hvis den kan det, behøves den komplekse model jo slet ikke). Men det antages, at en simpel model godt kan bruges på et lille, specifikt område af data. Her er opstillingen; tag udgangspunkt i et enkelt datapoint, det er x, og find da såkaldte naboer til dette datapoint, dvs. datapunkter der ligger tæt på x, defineret her som området π_x. På disse datapunkter findes en simpel forklarlig model, g, som kommer så tæt på at lave de samme prædiktioner som på de lokale nabo-datapunkter som muligt, målt ved fx ‘mean squared error’ ved termet L(f,g,π_x). Det sidste term Ω(g) måler kompleksiteten på vores lokale approksimationsmodel g. Desuden skal g være forklarlig, og det betyder, at g skal tage en forklarlig repræsentation af data som input. g kunne være en lineær model, og kompleksiteten for en sådan lineær model kan måles på antallet af features. I praksis optimerer LIME kun på at minimere L, og selve modelkompleksiteten vælges på forhånd.

    To af de praktiske spørgsmål, vi vil vende tilbage til senere, er, hvordan vi vælger vores ’forståelige’ datarepræsentationer, samt hvordan vi vælger vores ’nabo’-eksempler. Men nu vil vi lige blive i matematikken og se på teorien bag SHAP.

    En smukkere, objektiv matematik

    .. fås i SHAP-artiklen (Lundberg et al. 2017). Her fremlægges en generel og mere teoretisk funderet formulering af ‘additive feature attribution’-metoder, som LIME er et eksempel på. Artiklen viser, at LIME, og en række andre ‘feature attribution’-metoder kan beskrives på samme, følgende måde. Problemstillingen er den samme, vi vil gerne forklare enkelte udfald fra en kompleks model ved hjælp af en simpel forklaringsmodel. Denne simple forklaringsmodel, g, bliver præsenteret som en lineær model på binære features z, altså hvorvidt en feature er til stede eller ej. Vi arbejder altså stadig med forklarlige repræsentationer af input-features. Det er nu vægtene ϕ, vi skal finde, da de udtrykker, hvor vigtig hver feature i er på g’s prædiktion.

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    Credit: Lundberg et al. 2017

    Problemet består i at finde vægtene ϕog det på en måde som gør, at vægtene overholder følgende tre kriterier: Lokal Accuracy; at faktisk approksimerer lokalt, Missingness; hvis en feature i ikke er til stede, bør vægten være nul, Consistency; selvom vi havde forskellige modeller, skal bidraget for hver feature gerne være det samme. Lundberg et al. 2017 viser nu, at den eneste definition, som opfylder dette, er at finde vægtene ved hjælp af ‘Shapley Values’.

    Shapley values giver os nu (endelig) en anledning til at tale om fodbold, og så starter vi en ophedet, subjektiv diskussion om, hvilken fodboldspiller der gør det bedst.

    Den bedste fodboldspiller er

    … noget vi teoretisk kan udregne med shapley values. Det giver en metode til at udregne, hvor meget hver spiller bidrager til holdindsatsen. Eller i vores tilfælde kan vi bruge shapley values til at udregne, hvor meget hver feature bidrager til udfaldet af modellen. Formlen ser således ud:

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    credit: Lundberg et al. 2017

    Og måske kan den virke lidt skræmmende. Men princippet bag skal bare deles lidt op. ϕ_i er den pågældende spiller i’s bidrag, som vi gerne vil undersøge, og er antallet af spillere på holdet. For at finde ud af hvor meget spiller bidrager til sejren, summerer vi over alle mulige kombinationer af delmængder af holdet og ekskluderer spiller i og udregner derpå, hvad det marginale bidrage er af at tilføje den ene spiller i til holdet igen. Det marginale bidrag af at tilføje spiller i til delholdet bliver udregnet i termet (v((S {i}-v(s)), hvor er det payoff/den værdi, teamet genererer. (Vi kunne fx måle det i antal mål.) Det sidste term er en faktor, vi ganger på det marginale bidrag for at justere for, hvordan delholdet er sammensat, altså vi vil gerne have det gennemstilige bidrag af spiller i, uanset hvilke andre spillere der er på delholdet. Til slut ganger vi også med 1 over antal spillere, da vi gerne vil have spiller i’s bidrag uanset størrelsen på delholdet.

    Dette er det teoretiske fundament bag SHAP, men praktisk er det alt for omkostningstungt at udregne disse shapley values med alle de kombinationer, der skal opstilles, og derfor approksimeres disse værdier (oftest) i praksis.

    Det praktiske i haven og problemer med at spille med naboen

    … er nogle af de ting, man skal overveje som ’køber’ af LIME og SHAP. I praktisk er både LIME og SHAP implementeret med open source GitHub og pip-pakker lige til at installere og med fine tutorials . Dog er der lidt ting, der skal tages højde for. Der findes forskellige implementationer af SHAP, alt efter hvilken model man vil forklare — dog er kernel SHAP model-uafhængig og minder om LIME, men den er også langsom og den mest grove approksimation af Shapley values.

    I teorien virker metoderne både på tekst, billede og tabeldata, men i praksis understøtter SHAP-implementationerne ikke en direkte behandling af tekst fra alle typer modeller, da det ikke er defineret, hvordan teksten skal behandles som features.

    Der er generelt en udfordring med at vælge ’den forklarlige repræsentation’, fordi der kan være et gab mellem den, og det input som modellen rigtig fitter på. I tilfældet med tekstdata kan den simple lineære model måske tage enkelte ord som input, selvom klassifikationsmodellen ikke nødvendigvis fitter på enkelte ord. Ved billedata kunne den forklarlige repræsentation være et område i billedet i stedet for de egentlige pixels som input — vi snakker om segmentering eller superpixels. Der er altså en forskydning i, hvad modellen egentlig fitter på, og hvad den kan forklares med. Det vil i praksis sige, at vi ikke kan bruge LIME eller SHAP til noget, hvis ikke forklaringen af et udfald kan indfanges i den simple repræsentation, som vi lader LIME og SHAP fitte på. Lad os tage et eksempel med sætningen ”denne blog handler om ansvarlig AI”;

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    Eksempel på Lime

    Modellen afgør, at sætningen er ’objektiv’, men med forklaringen ’denne blog’. Men det er som om, at disse ord i sig selv ikke forklarer, hvorfor modellen siger ’objektiv’, eller hvorfor vi selv vil sige ’objektiv’. Måske er forklaringen nærmere, at der ikke er noget, der gør sætningen subjektiv, eller med andre ord; forklaringen kan ikke fanges ved at pege på enkelte ord.

    Med hensyn til at genere naboer, ligger der en udfordring med afsæt i SHAP i, at da modellen afprøver kombinationer af, hvilke features der er med ’på holdet’ eller ej, så skal vi have en måde at definere på, hvad det vil sige ikke at være med, altså at være bænket. Vi er nødt til at afklare, når vi fjerner en feature, hvad er der så? Altså, hvis vi fjerner et område i et billede, hvad skal ”baggrunden” så være, skal de pixels i området sættes til at være hvide, eller sorte, eller hvad med en gennemsnitlig værdi af hvad pixels ”normalt” tager i det område? Det sidste kræver, at vi har adgang til en lille smule træningsdata for at kunne udregne fx gennemsnitsværdier. Læs mere om udfordringer med baggrundsdata i denne interaktive Distil-publikation.

    Det gode, subjektive eksempel

    … indledes på træningsbanen. Indledningsvis listede vi tre anvendelsesområder for ‘feature attribution’ metoder, og indtil videre har vi sparket lidt tvivl op om deres egentlige anvendelse til at forklare enkelte prædiktioner. Men lad os se på metodernes anvendelse som udviklingsværktøj. Subjektiv/objektiv-klassifikationsmodellen er trænet på manuelt annoterede tweets, hvor vi har gemt 400 til valideringssættet og 1716 eksempler til træning af modellen. Træningssættet fordeler sig mellem de to klasser således:

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    Da dette ikke er særligt balanceret, er der tilføjet 1500 sætninger fra Wikipedia, som vi bare uden videre har antaget er ’objektive’. På valideringsættet opnås en accuracy på 87% og en macro-f1 på 73%. Men lad os lige se på et eksempel, hvor vi prøver at forklare følgende sætning med modellen:

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    I modellens forklaring ser vi, at tilstedeværelse af ”#” trækker prædiktionen mod at være ’subjektiv’. Men vi synes måske egentlig ikke, at “hasttags” bør tale for det ene eller det andet. Vi bliver opmærksomme på, at der netop er en skævhed i vores data, da langt de fleste subjektive eksempler kommer fra tweets, som netop bruger ”#” i modsætning til sætninger fra Wikipedia. Vi renser nu data for ”#” og ”@” og træner modellen igen. Nu opnås en højre accuracy på valideringsættet på 88% (0.74 macro-f1). Og forklaringen på overstående sætning bliver nu:

    Forklaringsmetoderne kan altså gøre os opmærksomme på ting, modellen fitter på, som kan skyldes en skævhed i data. I LIME-artiklen (Ribeiro et. al 2016) vises denne anvendelse på en billedeklassificerings-task med ”husky hund eller ulv”, hvor vi igennem forklaringen kan spotte, at modellen i tilfælde af ’ulv’ fitter på sne i billedet i stedet for på selve dyret. Dette datasæt er dog konstrueret, og skal tages som et legeeksempel. Andre eksempler findes i denne artikel Lapuschkin et al. 2019, hvor der i stedet bruges LRP-metoden.

    Hey dommer, de snyder…

    … forklaringsmodellerne til ikke at se, hvor unfair modellen virkelig er. Slack et al. 2020 viser i deres artikel, hvor nemt LIME og SHAP kan snydes. Med dette argumenterer de imod, at en tredjepart, uden adgang til informationer om selve udviklingen af modellen, kan bruge forklaringsmodellerne til at monitore fairness, hvilket var den tredje mulige anvendelse listet indledningsvis.

    Svagheden ved SHAP og LIME, viser Slack et al. 2020, er, at det er forholdsvist nemt at se forskel på de originale eksempler og de generede naboeksempler. Tricket er derfor at træne en model, der kan kende forskel mellem et original- og et naboeksempel, og ud fra dette kan det sorteres, så eksempler, der bliver brugt til at generere forklaringer af LIME og SHAP, bliver sendt til en anden klassifikationsmodel end den klassifikationsmodel, som anvendes ved originale eksempler.

    Lad os lege lidt med et eksempel. Legefortællingen er følgende: Den Nationale Boldunion Investeringsfond har lavet et udbud på et system, der kan måle på social medie-kommentarer, om fodboldspillere bliver omtalt positivt eller negativ med det formål at investere i de mest positivt omtalte klubber. Men de ved, at fans rundt om i landet vil gøre alt for at levere et system, der fremstiller deres egen klub så positivt omtalt som muligt, og derfor vil de tjekke de indleverede systemer for, om de er favoriserende og diskriminerende.

    Vi er sådan en fan! Og vi holder meget af AGF og knap så meget af Brøndby. Derfor har vi lavet et system, der hver gang, den ser navnet på en AGF-spiller, prædikterer positivt, og hver gang den ser en Brøndby-spiller prædikterer negativt. Hvis ingen navne indgår, benytter systemet Afinn ordlistebaserede sentimentværktøj. Så systemet er helt gennemskueligt og ikke nogen sort boks, men det leger vi, at Den Nationale Boldunion Investeringsfond jo ikke ved. De vil nu benytte SHAP og bruge et “summary-plot” til at opsummere hvilke features, der har været mest betydende i et testsæt, som de har genereret for at teste modellens fairness. De har lavet testsættet til at undersøge diskriminering/favorisering ved at skrive otte sætninger;

    [‘UNK er den bedste fodboldspiller’,
    ‘Den var en sjovt at se UNK scorede et fantastisk mål’,
    ‘unk er en succes’,
    ‘Altid dejlig at se UNK spille’,
    ‘Det var dårligt sparket af UNK’,
    ‘UNK er jo direkte en skændsel for holdet’,
    ‘UNK har sammen med dommeren gjort kampen til en grim katastrofe’,
    ‘Ringere spiller er ikke set end forfærdelige UNK’]

    Samt en liste med spillernavne, som hver kan udskiftes på UNK-pladserne i de ovenstående sætninger:

    AGF = [‘Duncan’, ‘Helenius’, ‘Eskelinen’, ‘Gersbach’ ]

    Brøndby= [‘Gammelby’, ‘Mensah’, ‘Lindstrøm’, ‘Bruus’]

    Hvis SHAP-modellen blev anvendt på ovenstående syntetiske ’testsæt’ og med det ovenstående diskriminerende system, ville vi blive afsløret i, at systemet har AGF-fodboldspillernes navne som features, der trækker modellens output mod ’positiv’, og Brøndbyspillernes mod ’negativ’:

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    SHAP summary plot

    Derfor vil vi nu, som de inkarnerede fans vi er, snyde dette tjek ved i stedet at levere et system, hvor det ikke bliver opdaget, at modellen holder med AGF.

    Ovenstående anvendelse af SHAP er et legeeksempel, hvor inputfeature-repræsentationen er en simpel ”countvector”, og baggrundsdataene UNK er en token. I praksis ville vi nok fitte baggrundsdata på egentlig træningsdata (som vi i så fald bør kende), og i tilfælde af en countvector nok egentlig bare sætte baggrundsværdien til 0, men dette er blot for at vise ideen. Så, med UNK som baggrundsdata, har vi gjort det nemt for os selv at kende forskel på originale eksempler og generede eksempler, så vi behøver blot at indbygge i vores system, at hvis vi ser UNK, skal eksemplet sendes til en ikke-diskriminerede model, og når vi ikke ser UNK, så kan vi anvende vores AGF-elskende model. Som vores ikke-diskriminerende model vil vi blot anvende Afinn-modellen. På den måde viser forklaringerne, hvordan Affin-modellen virker, og ikke hvordan modellen virker in real life. Lad os se hvad SHAP nu siger:

    For at se dette indhold fra miro.medium.com, så skal du give din accept på .

    SHAP summary plot

    Det ses, at SHAP nu tror, at de mest betydende features er hhv. positivt og negativt ladede ord, og ikke længere fodboldspillernavnene som modellen rigtigt bruger.

    Positive og negative takter

    … eller i hvert fald en subjektiv opsummering over fordele og ulemper ved værktøjerne.

    Fordelene ved LIME er, at det er rigtig nemt at bruge, og at værktøjet virker både for tabel-, billede- og tekstdata, og værktøjet kan endda bruges uanset typen af den originale model, og i tillæg kan den originale model være trænet på en ikke-fortolkelig repræsentation. Dette er dog også samtidig en af ulemperne, da der derved kan ske et skred imellem forklaringen, og hvad den originale model bruger af input. Af andre ulemper ved LIME kan nævnes problemet med at genere naboeksemplerne. LIME ignorer sammenhæng mellem features, når naboeksempler genereres, og det kan resultere i usandsynlige datapunkter. Der er i særdeleshed et problem med, hvordan tabeldata skal håndteres. Desuden er det uklart, i hvilket område forklaringerne holder, og om hvorvidt forklaringerne generaliser til andre eksempler, da det lokale områder måske ikke kan beskrives lineært. Til at adresse dette problem er forfatteren bag LIME kommet med en metode, der benytter ’if-then’ regler (Ribeiro et. al. 2018). LIME kritiseres i Alvarez-Melis et. al 2018 for at være ustabil i sine forklaringer.

    SHAP har den fordel, at den med sine shapley values er teoretisk velfunderet, og bør derfor teoretisk anvendes over LIME. Ligeledes giver dens afsæt i shapely values en sammenhæng mellem enkelte forklaringer og forklaringer for fx hele validerings-datasættet. SHAP Kernel implementation er også model-uafhængig, men desværre meget langsomt, og beror på en approksimation af shapley values. Desuden ignoreres feature dependency også her, og udvælgelsen af baggrundsdata er ikke givet. Til gengæld ses der lovende takter med Treebased SHAP, som kan bruges til at forklare ” træ baserede”-modeller. Det er dog ikke noget, der er blevet plads til i dette indlæg, men der kan læses mere om det i Lundberg et al. 2020.

    I den samlede subjektive vurdering af hvad disse feature attribution-metoder kan bruges til, vil jeg lægge vægt på, at metoderne kun er anvendelige, hvis man selv kan pege på, hvad det egentlig er, man forventer, modellerne fortæller en. Forstået på den måde at man kun kan få en forklaring med den simple repræsentation, man nu engang har givet forklaringsmodellen at fitte på. Desuden skal man huske at spørge sig selv, om forklaringen egentlig er særlig forståelig for folk, der ikke kender til værktøjet, eller måske til maskinlæring i det hele taget. Alt i alt er det subjektive lyspunkt nok, at modellen kan bruges til at spotte uhensigtsmæssighed i selve udviklingsprocessen.

    Tak fordi du læste med, selvom det hele blev lidt langt.

    / Amalie Pauli 

    Referencer

    Alvarez-Melis, David, and Tommi S. Jaakkola. “On the robustness of interpretability methods.” arXiv preprint arXiv:1806.08049 (2018).

    Lapuschkin, Sebastian, et al. “Unmasking clever hans predictors and assessing what machines really learn.” Nature communications 10.1 (2019): 1–8.

    Lundberg, Scott M., and Su-In Lee. “A unified approach to interpreting model predictions.” Advances in neural information processing systems. 2017.

    Lundberg, Scott M., et al. “From local explanations to global understanding with explainable AI for trees.” Nature machine intelligence 2.1 (2020): 2522–5839.

    Ribeiro, Marco Tulio, Sameer Singh, and Carlos Guestrin. “” Why should i trust you?” Explaining the predictions of any classifier.” Proceedings of the 22nd ACM SIGKDD international conference on knowledge discovery and data mining. 2016.

    Ribeiro, Marco Tulio, Sameer Singh, and Carlos Guestrin. “Anchors: High-precision model-agnostic explanations.” Thirty-Second AAAI Conference on Artificial Intelligence. 2018.

    Slack, Dylan, et al. “Fooling lime and shap: Adversarial attacks on post hoc explanation methods.” Proceedings of the AAAI/ACM Conference on AI, Ethics, and Society. 2020.

    Sources


    Article information

    Author: Janice Scott

    Last Updated: 1700146081

    Views: 1205

    Rating: 4.2 / 5 (111 voted)

    Reviews: 80% of readers found this page helpful

    Author information

    Name: Janice Scott

    Birthday: 2013-01-27

    Address: 18998 Wolfe Club, Ramirezstad, CO 84660

    Phone: +4673107546601903

    Job: Construction Manager

    Hobby: Skydiving, Golf, Basketball, Dancing, Yoga, Table Tennis, Pottery

    Introduction: My name is Janice Scott, I am a esteemed, rich, bold, vibrant, apt, unwavering, clever person who loves writing and wants to share my knowledge and understanding with you.