2.semesterprojekt

Jyllands-Posten - case abonnementssalg

Author

Nadia Nelander, Nicolaj Petersen, Nawl Hkang og Frederikke Larsen

Published

May 31, 2023

Indledning

Denne opgave fokuserer på Jyllands-Posten, der oplever ændringer i læsevanerne hos deres kunder. Som følge heraf har det været nødvendigt for dem at tilpasse sig de digitale læsevaner og justere deres strategi for at imødekomme deres kunder. Dette kræver dog, at Jyllands-Posten tager beslutningen om at blive en mere datadrevet virksomhed. Det at være en datadreven virksomhed handler om, at indsamle data og bearbejde det på en analytisk måde. En af de afdelinger som Jyllands-Posten gerne vil effektivisere, er deres telemarketingafdeling for digitale produkter. Morten, som er chef for telemarketingafdelingen ved Jyllands-Posten, oplever udfordringer i forbindelse med manglende interesse fra deres kunder i forbindelse med køb af abonnementer. Deres telemarketingteam ringer rundt til de kunder, som har takket ja til deres 1 kr. abonnement, for en måned, for at tilbyde 1 års abonnement til under markedsprisen. Deres kunder får adgang til den digitale avis, hvor de så kan benytte sig af Jyllands-Postens produkter den første måned. Det er så her, der sker dataindsamling omkring kundeadfærd, når en kunde går ind og læser. Dog har Morten ikke kunne benytte sig af deres kundedata, da de ikke har en medarbejder til at arbejde med dataanalyse og som kan analysere og formidle dataene. Vi har fået adgang til Jyllands-Posten kundedata, hvor vi kan afprøve vores kompetencer, som vi har fået gennem vores uddannelse. Forinden fik vi en præsentation af Jyllands-Posten og deres organisationsstruktur samt telemarketingafdelingens arbejdsgang. Her fik vi en god forståelse for Jyllands-Posten som virksomhed, der ønsker at arbejde henimod at blive mere datadreven. Vi har gennemgået deres datasæt for at finde mulige måder at bearbejde det på. Vi startede med at tidy dataen for at rydde op i dataen og tilføje nye variabler, der kunne være relevante. Vi har også været tilbageholdende med at fjerne NA’er, da det stadig er information. Derefter gik vi i gang med at lave de simpleste modeller som logistisk regression. Der er tale om et klassifikations problem, og ikke et regressions problem. Det betyder, at vi skal finde forklarende variabler, for at finde ud af hvem telemarketingafdelingen skal ringe til, for at tilbyde 1 års abonnement. Herefter har vi lavet mere avancerede modeller som Random Forest og Boosting. Derefter har vi brugt nogle metoder, som diskriminant analyse og QDA, til at validere vores modellers performance. Ud fra disse modeller har vi vurderet den mest præsterende model med forklarende variabler. Ved brug af modellerne er vi kommet frem til hvem der har højest sandsynlighed for at købe abonnementet. Derefter har vi også regnet på, hvem der har højest sandsynlighed for at churn. Til sidst har vi beregnet på hvor meget de ville kunne spare hvis de brugte vores model. Alt dette er gjort tilgængeligt for Morten gennem et dashboard, som er lavet med Shiny App. Derved kan Morten få overblik over de nødvendige variabler, som kan give ham et nyt indblik i kundeadfærd. På den måde kan han tage datadrevet beslutninger i telemarketingafdelingen.

Problemformulering

Hvordan kan Jyllands-Posten ved hjælp af statistiske modeller bedst mulig forudsige hvilke kunder der vil ønsker at fortsætte med et nyt abonnement og hvilke der vil churne, med henblik på at optimere deres omkostninger på deres digitale kanaler?

Hvem er Jyllands-Posten? Hvordan bruger de i dag deres kundedata for at forudsige hvilke kunder der kunne være interesseret i at fortsætte deres abonnement, hvilke data indsamles, samt hvilke indsatser benyttes?

Hvordan kan Jyllands-Posten ved hjælp af statistiske modeller og et visualiseringsværktøj forbedre deres salg gennem forudsigelse af abonnementer og hermed fokusere deres salgsindsatser efter de rette kunder?

Hvordan kan implementeringen af en statistisk model, og churnanalyse hjælpe Jyllands-Posten til at få fat i de rette kunder med formål at fastholde disse? Hvordan kan Jyllands-Posten bruge et visualiseringsværktøj til at fremme deres salg?

Afgrænsning

I vores arbejde med projektet omkring Jyllands-Posten, har vi igennem opgaven måtte tage os en række antagelser, for at kunne svare på problemformuleringen og dens underliggende spørgsmål, på bedste vis. Dette har været nødvendigt da vi ikke på alle områder kender det fulde sandhedsbillede af, hvordan Jyllands-Posten arbejder med deres kundedata i dag, samt at vi heller ikke kender alle Jyllands-Postens interne procesgange, når det kommer til salg af abonnementer i det daglige arbejde. Under virksomhedsbesøget hos Jyllands-Posten i Århus, fik vi et indblik i dele af det, men det har været nødvendigt at lave antagelser på flere områder. Først og fremmest vil det komme til udtryk i bearbejdelsen af de kundedata, vi har modtaget fra Jyllands-Posten, i forhold til datarensning og de efterfølgende analyser af prædiktion og churn. Mere specifikt handler det om nogle af variablerne, hvor vi har givet os selv den frihedsgrad, at ændre forudsætningerne for nogle af værdierne. Det drejer sig blandt andet om variablen ‘kontakt’, hvor der i det oprindelige datasæt er flere blanke værdier. Dette kan skyldes, at de enten er på robinsonlisten eller tidligere har været forsøgt kontaktet, men at der ingen respons har været. De blanke er ændret til værdien ‘0’, hvilket vil sige, at det specifikke konto- id ikke er blevet kontaktet endnu. Det betyder også, at vi gør os den antagelse, at der ikke findes nogen på robinsonlisten. Derudover, for at komme udenom komplikationer, og et forsøg på at simplificere modelleringen af vores modeller i opgaven, har vi konverteret ‘NA´s’ til værdien 0, således at en klassifikation kun kan tage værdien 0 eller 1. Dette gør det nemmere, når vi foretager vores prædiktion og senere laver vores churn-analyse. Zoomer vi ind på churn-analysen, vil man i dette afsnit kunne læse om omkostningsberegninger for, hvad det vil koste Jyllands-Posten, hvis en kunde churner. Disse omkostningsberegninger er lavet ud fra værdier, som ikke er de reelle omkostninger, men nogle tal vi har sat ind. Churn-analysen skal ses som et eksempel og et værktøj til, hvordan Jyllands-Posten selv kan gå ind og lave sine egne beregninger med de korrekte tal. Man vil kunne læse mere om dette i afsnittet. Undervejs i opgaven forsøger vi at skrive om, hvad det er for nogle juridiske love samt paragraffer Jyllands-Posten skal overholde eller i det mindste gøre sig overvejelser om, når det kommer til personfølsomme oplysninger. Da vi har et begrænset vidensgrundlag om, hvordan Jyllands-Posten behandler følsomme kundedata i dag, gør vi os den antagelse, at de med selvfølgelighed overholder alle juridiske bindinger. Dette gør sig også gældende for enhver fremtidig anbefaling, samt konkrete tiltag vi giver til Jyllands-Posten, som de måtte vælge at tage i brug.

Metode og videnskabsteori

I dette afsnit vil det fremgå, hvilke metoder og teoretiske fremstillinger, der er valgt til besvarelse af problemformuleringen, samt hvilke overvejelser der er gjort i forbindelse med kildebehandling.

Den overordnede process for den arbejdsgang som er blevet gjort nytte af i denne opgave, kommer fra Crisp DM modellen.Crisp DM

I denne opgave har vi brugt de 6 faser fra Crisp DM. Vi starter med at få en forretningsforståelse for branchen, herunder Jyllands-Posten. Det er gjort gennem eksplorative undersøgelser på nettet, samt virksomhedsbesøg, hvor vi har arbejdet induktivt, da vi ønsker at skaffe ny viden, for at kunne besvare vores problemformulering. Ydermere, har vi arbejdet deduktivt i vores arbejde med at forstå den data, der er blevet stillet til rådighed af Jyllands-Posten. Den deduktive arbejdsmåde ses da vi benytter eksisterende viden, blandt andet fra undervisning og vores egen viden. Da forståelsen af forretningen og dataene var på plads, gik vi i gang med oprensning af datasættene, hvor vi udvalgte relevante variabler og sammensatte datasæt. Det rene datasæt er herefter benyttet til at lave forskellige modeller for at finde de bedst mulige modeller til, at undersøge sandsynligheden for kunder som ønsker at købe et abonnement, samt undersøge sandsynligheden for kunde churn. Herefter har vi udvalgt de bedst mulige modeller, og kommet med et løsningsforslag til hvordan Jyllands-Posten, ved hjælp af modellerne, kan optimere deres salgsomkostninger, og forbedre deres forudsigelse af kundekøb, og kunde churn. (Hotz, Nick. 2023) I denne opgave er der udelukkende benyttet sekundær data, som vi har fået udleveret af Jyllands-Posten med formål om, at kunne anvende dataene til vores analyse, og dermed løse vores problemformulering. Denne data er helt essentielt for projektet, og har i den grad været med til, at vi kunne løse opgaven. Foruden sekundær data, har vi samtidig benyttet forskellige statistiske modeller i vores analyse. De har alle hver deres formål, og er i det samlede billede med til at teste modellerne af, for til sidst at finde den model, som bedst kan forudsige det ønskede. I analysen har vi arbejdet objektivt og realistisk, ved at kigge på fakta og resultater frem for følelser. Vi har benyttet det positivistiske paradigme, da vi tror på at verden er konstruktiv og dens fænomener findes ude i virkeligheden. Dette har hjulpet os med at finde frem til et data og fakta baseret løsningsforslag. (Egholm, L. 2014)

Redegørelse

Hvem er Jyllands-Posten

Jyllands-Posten er en af Danmarks førende aviser, som findes i fysisk form såvel som digitalt. Jyllands-Posten markedsfører sig selv på, at være førende inden for kvalitetsjournalistik, hvor du kan finde det stærkeste og ikke mindst nyeste indhold. Avisen blev grundlagt i 1871, da man var utilfreds med de øvrige avisers indhold. I dag ejes de henholdsvis af Jyllands-Posten Holding A/S (50%) og A/S Politiken Holding (50%). (Jyllands-Posten. (s.d.).) Ønsket om at levere god og gennemtænkt kvalitetsjournalistisk, står fortsat stærkt i dag for avisen, og bliver i den grad bakket op af deres tre løfter til borgerne; “1. Vi vil gøre vores læsere klogere. 2. Vi vil styrke demokratiet. 3.”Vi vil opfinde fremtidens journalistisk.” (Jyllands-Posten. (s.d.).) Derudover er Jyllands-Posten også uafhængig af ydre økonomisk, organisatorisk og politisk indflydelse, som tilsammen er med til at sørge for avisens integritet og troværdighed. (Jyllands-Posten. (s.d.)) Jyllands-Postens vision er “at skabe mere viden og fremskridt gennem det frie ord”, og netop dette formår de at gøre gennem deres mission, som et uafhængigt liberalt mediehus, ved at formidle alle ytringer og holdninger, som kan udfordre og styrke læserens viden. (Jyllands-Posten. (s.d.).)

Jyllands-Postens målgruppe

Ifølge Jyllands-Postens egen udtalelse, skriver de deres avis til den moderne og fritænkende dansker. Ser man på opdelingen af køn, består deres kundesegment på deres fysiske avis af 55% mænd, og 45% kvinder, med en samlet gennemsnitsalder på 56 år. Ser man derimod på deres digitale kanal, jp.dk, er der en kønsfordeling på 58% mænd og 42% kvinder, med en gennemsnitsalder på 46 år (Jyllands-Posten. (s.d.)). Der er generelt, på tværs af de 2 kanaler, tale om en målgruppe som har en videregående uddannelse, og som har en gennemsnitlig højere løn. Der ses et betydeligt fald i gennemsnitsalderen på den målgruppe, der læser Jyllands-Postens digitale avis, mod den målgruppe, der læser den fysiske udgave. Dette kan skyldes flere faktorer, såsom den store tilgang til sociale medier og eksponeringen af ‘Smart-Devices’. Ser man på den overordnede fordeling af læsere af trykte aviser i Danmark, har denne været faldende over en længere årrække. I Kulturministeriets rapport om skrevne nyhedsmedier 2021, ses det, at der fra 2019-2020 var et fald på 15% i Jyllands-Postens læsere af den fysiske avis (Kulturministeriet. (2021)). Dette afspejler sig også, når man kigger på gennemsnitsalderen på henholdsvis den printede og digitale version af Jyllands-Posten. Som nævnt, ses der en forskel på 10 år, på gennemsnitsalderen, hvor den er lavest ved den digitale version. Dette tyder på, at den yngre generation foretrækker den digitale avis frem for den fysiske. Dette stemmer overens med den overordnede viden der er omkring sociale medier, og deres popularitet i dagens Danmark, samt den store nedgang af læsere af fysiske aviser. På baggrund af dette og opgavens omfang, vælger vi derfor blot at se på Jyllands-Postens digitale kanaler, og have vores hovedfokus på hvordan salgsindsatserne kan optimeres her.

Avis markedet, samt konkurrenter

I Danmark er der flere konkurrenter på avismarkedet og det samme gør sig gældende i forhold til Jyllands-Posten. Konkurrenterne er bl.a. Politiken, Berlingske, Ekstra Bladet og B.T. m.fl. Fælles for alle disse aviser er, at de leverer nyheder til danskerne på daglig basis. Dog har de hver især deres position på markedet og det kan også være forskelligt hvilke kanaler de primært kommunikerer igennem. En avis som Jyllands-Posten har traditionelt haft en stærk position for salg af trykte aviser gennem tiderne. Gennemsnittet af trykte avislæsere, er gradvist faldende fra år til år (Törnfelt, C. (2017)). Det hænger højst sandsynligt sammen med, at to ud af tre trykte avislæsere, har en alder på 64 år eller derover. Modsat, har andre digitale nyhedskanaler, såsom nyheder på tv, netaviser/netapps, radio og podcast, opnået en større popularitet blandt befolkningen, viser tal fra 2018 til 2022 (Glavind, L. & Tassy, A. (2022)). Det er dog også muligt at se Jyllands-Postens nyheder i online format, gennem deres hjemmeside eller app. Sammenligner man med deres konkurrenter, har de en blandet markedsposition alt efter, hvem man holder dem op i mod. Før vi gør det, vil vi gerne præcisere, hvad der kan betegnes som de brede og snævre konkurrenter i forhold til Jyllands-Posten. I en bred forstand ligger Jyllands-Posten i konkurrence med alle udbudte nyhedsformidlere i Danmark, hvoraf Ekstra Bladet har den mest dominerende rolle, med over 500 mio. views i april 2023, som er opmålt gennem deres web samt app (Gemius Audience. (2023, april)). I den snævre konkurrence ligger Jyllands-Posten mere tæt med Politiken og Berlingske, der har sammenlignelige kundesegmenter. Her positionerer Jyllands-Posten sig lige i midten af de to konkurrenter, når man kigger på antallet af besøgende for april måned 2023. Berlingske lægger sig i front med 12,5 mio. besøgende, Jyllands-Posten nummer to med 7 mio. og til sidst Politikken, der har ca. 5,4 mio. besøgende. Når man holder nyhedsaviserne op mod hinanden, er det værd at bemærke, hvilke typer aviser, der sammenlignes, da de kan have forskellige kundesegmenter. De kan have forskellige måder at kommunikere nyhederne ud på, og der er forskel på, om det er gratis eller med abonnement. Hvis Jyllands-Posten skal styrke sin tilstedeværelse på de digitale platforme og rangere sig højere på listen i forhold til de målinger, som er nævnt i dette afsnit, kunne en løsning være at arbejde mere datadrevet når det kommer til at konvertere leads til kunder.

Hvad gør Jyllands-Posten i dag ifht. deres salgsaktiviteter, samt hvilke datapunkter indsamles?

Jyllands-Posten er en af de aviser, som står overfor udfordringer i forhold til at følge med på kundernes skiftende læsevaner, fra det traditionelle til det digitale. Det skyldes, at Jyllands-Posten er en traditionel virksomhed, som er over 150 år gammel. De har dog investeret ressourcerne i digitale platforme, som deres hjemmeside og app. Digitalisering kræver ny viden og andre færdigheder end traditionelle aviser er vant til. Dette kræver viden inden for dataanalyse, herunder indsamling og analyse af data. Dette vil give virksomheden ny viden om kunderne og deres online adfærd. Jyllands-Posten er i det stadie, hvor de har indsamlet kundedata, som de har haft liggende i deres database. Dog har de ikke været i gang med at bearbejde deres kundedata, så dataene kunne komme dem til gavn. I denne sammenhæng har de efterspurgt dataanalyse-studerende fra Viborg Erhvervsakademi til at arbejde med deres kundedata og muligvis løse nogle af problemstillingerne, som de står overfor. De udfordringer Jyllands-Posten står overfor er at forstå kundernes online adfærd. Igennem årene har kunderne efterspurgt flere digitale produkter, og det betyder samtidig, at der sker en ændret adfærd. Dette kan have sammenhæng med, at der er adgang til flere medier ad gangen og dermed øget konkurrence. Denne situation har øget risikoen for churn og resulteret i færre loyale kunder blandt Jyllands-Postens digitale abonnenter. Morten, der er chef for salgsafdelingen, arbejder med problemstillingen i virksomheden. Det Morten vil undersøge, er, hvordan hans telemarketingsælgere kan ringe til kunder, der med højest sandsynlighed vil konvertere til 1 års abonnement, fra open-up-abonnement. Det er bekosteligt for afdelingen at ringe rundt, da der er chance for, at de ikke får et salg eller at kunden laver et churn. For at optimere omkostningerne i forbindelse med opringninger er det vigtigt at finde ud af, hvem der har høj sandsynlighed for at købe abonnement og derefter finde ud af, hvem der med højest sandsynlighed vil churn. Jyllands-Posten ønsker at identificere, hvilke af deres digitale abonnenter der har risiko for at afmelde sig (churn) og hvem der vil forblive som loyale kunder. Derfor er det vigtigt for Jyllands-Posten, at forstå, hvem der er tilbøjelige til at trække sig fra deres abonnement. Det kan undersøges ved at analysere deres data og kundernes læsevaner. På den måde kan man identificere de abonnenter, der er af høj kvalitet, og kontakte dem for at øge sandsynligheden for, at de bliver langvarige abonnenter hos Jyllands-Posten. Dette kan være med til at give besparelser i salgsafdelingens budget. På den måde kan sælgerne prioritere at kontakte de mest aktive læsere og dermed optimere ressourceforbruget. I dag har Jyllands-Posten ikke et system, som filtrerer deres kunder. Det betyder, at der bliver ringet til forskellige kunder ud fra ren tilfældighed. Jyllands-Postens leads får de gennem cookies, pop op og derefter social media kampagner. Disse leads bliver så genererede til sælgerne gennem et softwaresystem. De bedste leads bliver fordelt til de bedste sælgere og herefter fordeles de efter dyreste leads. Dermed har de høj sandsynlighed for at konvertere kunden. Eneste fordel er, at hvis en kunde har udfyldt et spørgeskema og angivet, at de ønsker at blive kontaktet, kan det tyde på en vis interesse. Når kundens open-up-abonnement er ved at udløbe, ringer Jyllands-Postens telemarketingafdeling kunden op, for at tilbyde 1 års abonnement til en god pris. Gennem open-up-abonnement, som det også hedder, har kunden nu adgang til den digitale avis. Her har Jyllands-Posten indsamlet kundens online adfærd som sidevisning, startdato og slutdato på abonnementet. Som en del af opgaven har vi fået ansvaret for at udføre dataanalyse på de forskellige variabler og identificere potentielle sammenhænge, som Jyllands-Posten kan opnå ny indsigt fra. På baggrund af denne indsigt vil det give dem oplysninger til at finde ny forståelse af deres kunder. Datene kan bruges til at prædiktere, hvem der vil købe et nyt abonnement. Vi vil analysere mulige variabler til at finde nye kunder, segmenter og mulige kundegrupper, som Morten og sælgerne kan fokusere på. I opgaven vil vi præsentere de data, som Morten har udleveret til os. Vores datasæt består af data fra salgsafdelingen. Vores datasæt er for en periode på 3 måneder i 2022. Datasættet, som arbejdes med, består af datasæt ark 1, 2 og 3. Den første del består af data som startdato for kundens open-up-abonnement. Her kan man se, at de har sagt ja tak til abonnement til open-up-abonnement. for 1 måned. Der er ikke nogen begrænsning på dette tilbud, og det betyder, at en kunde kan have flere ordrer. Variablen abonnement_tidligere handler om, at kunden tidligere har haft et abonnement før open-up-abonnementet. Her antager vi, at det er et andet betalt abonnement og ikke et open-up-abonnement. Vi antager også, at de er abonnenter hos Jyllands-Posten og ikke konkurrenter. Abonnement_nu fortæller, at de har abonnement pr. 04-04-2023. Det vil sige i hele perioden. Disse oplysninger vil vi gerne bruge til at lave en churnanalyse ud fra. Kontakt_variablen fortæller, at sælgerne har kontaktet kunden. Det kan dog være, at kunden er en del af robinsonlisten. Her tager vi udgangspunkt i, at denne gruppe kunder, som ikke er blevet kontaktet, ikke er en del af robinsonlisten. Dermed bliver NA gruppen en del af 0, dvs. ikke kontaktet endnu. Succesfuldt_køb handler om, at kunden har købt et abonnement, hvor et open-up-abonnement ikke tæller med. Købsdato handler om det samme som succesfuldt køb. Ordre_id er kun for open-up-abonnementet. Det gælder for alle, dog er der nogle kunder som kan have flere, da de har mulighed for at benytte tilbuddet om open-up-abonnement. Konto-id er en unik kode for kunder. Dog kan ét kunde-id, godt have flere ordrenumre. For at gøre arbejdet nemmere, og mere overskueligt, lægger vi antallet af ordrenumre sammen og laver en ny variabel og kalder det “antal køb”. Sidevisninger er talt op efter data for pågældende konto-id. Kundernes læsevaner, i forhold til ugedage eller pr. måned, er interessant, da det viser, at der er nogle kunder, der er meget aktive i starten af måneden, men ikke så aktive i længden. På den måde kan vi undersøge kundeadfærd ud fra disse data.

Hvilke juridiske overvejelser/love skal overholdes når der er tale om kundedata?

Når det kommer til behandling af kundedata, skal Jyllands-Posten overholde gældende persondataretlige regler i Danmark, herunder EU’s databeskyttelsesforordning (GDPR), samt andre relevante love og regler i forbindelse med behandling af personoplysninger. Jyllands-Posten skal sikre, at kundedata behandles på en sikker og forsvarlig måde, og at kunderne er informeret om, hvordan deres data behandles. I forbindelse med behandling af kundedata, gennem markedsføring og telefonsalg, er der flere regler og love, der skal overholdes. De love der skal tages højde for, er databeskyttelsesforordningen (GDPR), databeskyttelsesloven, markedsføringsloven samt forbrugeraftaleloven. Ifølge GDPR, er der krav til, hvordan personoplysninger skal behandles, opbevares og beskyttes. Jyllands-Posten kan overholde GDPR ved at sikre, at de kun behandler personoplysninger til det formål, som kunderne har givet samtykke til, og at deres oplysninger opbevares sikkert og i overensstemmelse med GDPR. Kunderne skal informeres om deres rettigheder i forhold til deres personoplysninger, herunder deres ret til at ændre eller få slettet deres data (Nielsen, K.M.S. & Vendelbo, P. (2022). Persondataret). Telefonsalg er i få tilfælde lovligt, selvom forbrugeren ikke har givet samtykke til at blive ringet op. Ifølge forbrugeraftalelovens § 4, stk. 2, er det tilladt at ringe op uden samtykke for at sælge bøger, abonnementer på aviser, ugeblade, tidsskrifter, og forsikringer. Hvis forbrugeren står på Robinsonlisten eller har frabedt sig opkald fra virksomheden, er det ulovligt at ringe personen op (Forbrugerombudsmanden. (s.d.)) (Lov om forbrugeraftaler [Forbrugeraftaleloven]). Markedsføringsloven indeholder regler for markedsføring gennem telefonsalg. Reglerne i Markedsføringsloven finder anvendelse ved siden af GDPR, og man skal derfor forholde sig til begge regelsæt. Personoplysninger der typisk behandles i forbindelse med markedsføring er navn, adresse, e-mail, mobilnummer, hvad der købes, hvad der tidligere er købt, interesser og præferencer, alder, familiestatus, hjemmeside og internet adfærd, som kan indsamles igennem cookies eller andre sporingsteknologier. Derudover er der IP-adresser, brug af apps og lokationsdata. Ifølge Markedsføringsloven kan Jyllands-Posten ringe til kunder der har givet samtykke til at blive kontaktet, dog kan de ifølge forbrugeraftalelovens § 4, stk. 2, ringe til eksisterende kunder uden samtykke, hvis det sker i forbindelse med salg af lignende produkter. Dette betyder, at hvis salgsafdelingen allerede har solgt en vare til en kunde og ønsker at ringe til kunden med tilbud om en lignende vare, er det tilladt at ringe op uden samtykke. Man skal dog være opmærksom på, at selvom det er tilladt at ringe op uden samtykke i visse tilfælde, så skal Markedsføringslovens regler stadig overholdes. Hvilket betyder, at hvis en kunde beder om at blive slettet fra listen over potentielle kunder eller ønsker at modtage færre opkald, så skal Jyllands-Posten respektere dette og ikke ringe til kunden igen med tilbud (Nielsen, K.. & Vendelbo, P.. (3). Markedsføringsret). Markedsføringsloven handler altså om, hvordan en virksomhed må markedsføre sig, mens GDPR handler om, hvordan og i hvilket omfang en virksomhed må opbevare og behandle data om enkeltpersoner. Forbrugeraftaleloven er en lov, der beskytter forbrugeren mod urimelige aftalevilkår. Jyllands-Posten skal sikre, at de tilbud og aftale de giver til deres kunder, er klare og forståelige. Kunderne skal modtage alle relevante oplysninger som; priser, betalingsvilkår, produkt- eller servicebeskrivelser samt vilkår og betingelser. I forbindelse med et salg har forbrugere rettigheder når de indgår en aftale, og de har ret til at fortryde aftalen inden for en vis periode. Hvis Jyllands-Posten ønsker at forbedre sit avissalg, bør de sikre, at de overholder de relevante regler og love, og at de har fokus på god markedsføringsskik. Dette vil opbygge tillid hos forbrugerne og øge sandsynligheden for, at de vælger at tegne et abonnement (Virksomhedsguiden & Justistministeren. (s.d.)).

Analyse

I dette afsnit vil der blive analyseret på to datasæt modtaget fra Jyllands-Posten. Datasæt 1 indeholder informationer om startdato, abonnent tidligere, abonnent nu, kontakt, succesfuld køb, købsdato, ordre-id samt konto-id. Datasæt 2 indeholder dato, sidevisninger og konto-id. Ved hjælp af statistiske metoder vil dataene blive bearbejdet og analyseret, for at kunne opnå en dybere forståelse og drage nogle konklusioner. Koderne i det følgende vil blive dokumenteret for at sikre reproducerbarhed og forståelighed.

Juridiske overvejelser ved databehandling og håndtering

Når man som Jyllands-Posten behandler personoplysninger om andre personer skal man være opmærksom på sin rolle i forbindelse med behandlingen. Kigger man på persondataretten skelnes der mellem om man er dataansvarlig for behandling af personoplysninger eller om man fungerer som databehandler for en dataansvarlig. Kravene hertil er forskellige og man skal derfor være opmærksom på lovgivningen. Efter databeskyttelsesforordningens artikel 4, nr. 7 er en dataansvarlig: “en fysisk eller juridisk person, en offentlig myndighed, en institution eller et andet organ, der alene eller sammen med andre afgør, til hvilke formål og med hvilke hjælpemidler der må foretages behandling af personoplysninger.” Efter databeskyttelsesforordningens artikel 4, nr. 8, er en databehandler: “en fysisk eller juridisk person, en offentlig myndighed, en institution eller et andet organ, der behandler personoplysninger på den dataansvarliges vegne”. (datatilsynet.dk, 2017). Det er som udgangspunkt virksomheden eller organisationen, som i sidste ende anses for at være ansvarlig for behandlingen af personoplysninger, medmindre det er gjort klart at det er en fysisk person, der er den dataansvarlige. Når man vurderer om man er dataansvarlig eller databehandler, tager man hensyn til databeskyttelsesforordningen. Her kan det udledes, at der kun vil være en databehandlerkonstruktion, hvis der eksisterer en aftale mellem Jyllands-Posten og en databehandler, hvor den anden part skal behandle personoplysninger efter instrukser fra den dataansvarlige. Dette kan omfatte indsamling, registrering, opbevaring, videregivelse eller sletning af personoplysninger. Hvis aftalen mellem Jyllands-Posten og en anden part drejer sig om levering af en anden ydelse og ikke behandling af personoplysninger, hvor man ikke har behov for behandling af personoplysninger, vil den anden part ikke være databehandler. Det der er afgørende for om, der er en instruks, og altså en databehandlerkonstruktion, er, om en behandling af personoplysninger behandles af en anden part, mens man som dataansvarlig fortsat bestemmer over formålet og over behandlingen, herunder indsamling, sletning, videregivelse og brug af eventuelle underdatabehandlere. Hvis man som privat virksomhed ved lov er blevet pålagt at behandle (f.eks. indsamle, registrere, videregive, opbevare eller slette) specifikke personoplysninger, vil man skulle sørge for, at oplysningerne behandles efter instruks som dataansvarlig. Grunden er, at man er pålagt et ansvar. Hvis man er dataansvarlig og har vurderet, at der er en databehandlerkonstruktion mellem to parter, skal man efterfølgende sørge for, at der udarbejdes en databehandleraftale. Databehandleraftalen skal indgås mellem den dataansvarlige og databehandleren, derudover skal den leve op til kravene til databehandleraftaler i databeskyttelsesforordningen. I følge databeskyttelsesforordningens artikel 32, fastlægges det at den dataansvarlige er forpligtet til, at sørge for implementering af passende organisatoriske såvel som tekniske sikkerhedsforanstaltninger, for at imødekomme de risici der kan være i forbindelse med behandling af persondata. Dette krav gælder fysisk og elektronisk behandling af persondata (Nielsen, K. & Vendelbo, P. 2022). Et eksempel når vi kigger på vores opgave som databehandler er, at sørge for at data er anonymiseret. I persondataforordningens præambel nr. 26, beskrives anonymiseringen således “oplysninger, der ikke vedrører en identificeret eller identificerbar fysisk person, eller for personoplysninger, som er gjort anonyme på en sådan måde, at den registrerede ikke er, eller ikke længere kan identificeres.” (Nielsen, K. & Vendelbo, P. 2022. Persondataret). Det er derfor yderst vigtigt, at vi som databehandlere sørger for, at det på ingen måde er muligt at finde tilbage til den fysiske person, som “sidder bagved” de registrerede data. Det er vores medansvar, sammen med den dataansvarlige, at sørge for at vores data rent faktisk bliver anonymiseret. I denne opgave har vi en variabel ‘konto_id’ i datasæt, som der arbejdes med i analysen. Det er vores ansvar at sørge for, at konto_id’et i kombination med andre relevante variabler, ikke kan føres tilbage til den fysiske person. I vores tilfælde, er anonymiseringen gjort på forhånd, idet vi får dataene fra Jyllands-Posten, da man gennem datasættet ikke har mulighed for at finde tilbage til den oprindelige ejermand. Når anonymiseringen er gjort tilstrækkeligt, vil dataen ikke længere blive kategoriseret som persondata, og herved vil persondataforordningen ikke længere være gældende (for anonymiserede datapunkter).

Import og datarensning

Som første del bliver datasæt 1 importeret fra en Excel-fil, hvorefter datasættet gemmes i variablen “data1”. Herefter ses der på hvilke data, der er relevante og hvad der skal omorganiseres. Købsdato og ordre-id fjernes fra datasættet, da disse er irrelevante. Konto-id rykkes ind efter startdato, hvorefter de flyttes til de første positioner i datasættet og datasættet grupperes efter konto-id. Til sidst tilføjes en ny variabel på antal køb, som angiver antallet af køb pr. konto-id. Herefter fjernes dubletter baseret på konto-id, som vil sørge for, at der kun bliver vist antal køb én gang og summeret op på antal gange konto-id har foretaget et køb. Der kigges nu på NA, altså de manglende værdier, hvor NA får værdien 0 i kontakt og succesfuldt køb. Det vil sørge for, at erstatte de manglende værdier i disse kolonner. Der bliver herefter tjekket antal observationer og variabler samt typerne af variabler. Variablerne abonnent tidligere, abonnent nu, kontakt og succesfuldt køb, laves om til en faktor. Ved at lave dem om til faktor, viser det, at de repræsenterer kategorier som 0 og 1, i stedet for numeriske værdier. Dato: Variablen laves om til datoformat og der fjernes observationer fra før d. 04.03, da abonnementet nu angiver dem som havde abonnement d. 04.04.23, derved opnås der, at denne variable passer med 1 år tilbage.

Vis koden
data1 <- read_excel("data/data_og_analyse_opgave1.xlsx", 
                                      sheet = "datasæt1")


data1_select <- data1 |>
  dplyr::select(-købsdato, -ordre_id) |>
dplyr::select(startdato, konto_id, everything()) |>
  group_by(konto_id) |>
  mutate(antal_køb = n()) 


data1_select1 <- data1_select[!duplicated(data1_select$konto_id), ] |>
  dplyr::select(startdato, konto_id, antal_køb, everything())



data1_select1 <- data1_select1 |>
  mutate_at(c('kontakt','succesfuldt_køb'), ~replace_na(.,0))


variabelnavne <- c('abonnent_tidligere' ,'abonnent_nu', 'kontakt', 'succesfuldt_køb')
data1_select1[,variabelnavne] <- lapply(data1_select1[,variabelnavne] , factor)


data1_select2 <-  data1_select1 |>
  mutate(startdato = ymd(startdato)) |> 
  filter(startdato > '2022-03-04')

view(data1_select2)

I denne del importeres datasæt 2, her laves dato variablen i datoformat, hvorefter der filtreres på måneden i dato-varianten, således at de får værdien 3, 4 og 5. Dernæst grupperes de ud fra konto-id og der laves en ny variabel for visninger, ud fra månederne. Til sidst laves en summering af sidevisninger i alt pr. konto-id.

Vis koden
data2 <- read_excel("data/data_og_analyse_opgave1.xlsx", sheet = "datasæt2")


data2_1 <- data2 |>
mutate(dt = ymd(dt)) |>
  filter(month(dt) %in% c(3, 4, 5)) |>
  group_by(konto_id) |>
  summarize(visning_marts = sum(ifelse(month(dt) == 3, sidevisninger, 0)),
            visning_april = sum(ifelse(month(dt) == 4, sidevisninger, 0)),
            visning_maj = sum(ifelse(month(dt) == 5, sidevisninger, 0)), 
            sidevisninger_total = sum(sidevisninger, na.rm = FALSE))

Det der sker herefter er, at vi sætter de to datasæt sammen, som vi kalder “datamerge”. Det vil sørge for, at kombinere rækkerne fra begge dataframes, hvor konto-id matcher og besvarer alle rækker fra data1_select2. Vi tjekker herefter for manglende værdier (NA) i sidevisninger totalt.

Vis koden
data_merge <- left_join(data1_select2, data2_1, by = "konto_id")

data_merge <- data_merge %>%
  mutate_at(c('visning_marts', 'visning_april', 'visning_maj', 'sidevisninger_total'),
            ~replace_na(.,0))

Her kigger vi på 2 forskellige korrelationsmatrixer for, at se på multikollineariteten i vores data. I første output ses der blandt andet på sidevisning total og holder man den op imod visninger fra marts, viser det, at der er stor korrelation imellem dem. I andet output gøres det samme sig gældende, ved at der er stor korrelation mellem visninger i marts og sidevisninger totalt. Det at der ses en korrelation mellem vores sidevisning total variabel, og sidevisning marts, giver god mening, da variablen sidevisning total indeholder observationer fra sidevisning marts.

Undersøgelse og prædiktion af andelen af kunder som vil købe et abonnement

Logistisk regression

I dette afsnit vil der blive afprøvet logistisk regression. En logistisk regressionsmodel kan bruges til, at forudsige sandsynligheden for en bestemt begivenhed baseret på værdierne af de forklarende variabler. For eksempel som i salgsafdelingens tilfælde, kan en model, der er trænet på historiske data om kunders adfærd, bruges til at forudsige sandsynligheden for, at en kunde foretager et køb eller ej. I første del forsøges der, at forudsige succesfuldt køb ud fra de variabler der er i data_merge og der findes frem til AIC og BIC. Variablerne ‘startdato’, ‘antal_køb’, ‘abonnent_tidligere’, ‘abonnent_nu’, ‘visning_marts’ og ‘visning_april’ har p-værdier, der er mindre end det typiske signifikansniveau (0.05), som betyder, at de er signifikante, for at forudsige succesfulde køb (Bilag 1, figur 1). Det vil sige, at ændringer i disse variabler har en betydelig påvirkning på sandsynligheden for succesfulde køb. Variablene ‘konto_id’, ‘kontakt’, ‘visning_maj’ og ‘sidevisninger_total’ har p-værdier, der er større end det typiske signifikansniveau (0.05), det betyder, at der ikke er nok bevis for, at de har en signifikant indflydelse på succesfulde køb i denne model. Ændringer i disse variabler er ikke signifikante for at forudsige succesfulde køb. Modellens fit: Residual deviance (4223.9) er mindre end null deviance (5845.9), hvilket indikerer, at modellen er bedre passende til dataene end en model uden nogen uafhængig variabel. Normalt indikerer en lavere deviance og AIC-værdi (4243.9) en mere præcis tilpasning af modellen til dataene, hvilket tyder på, at modellen bedre beskriver den observerede variation. (Bilag 1, figur 1). Den endelige model med de endelige variabler har til formål, at undersøge sammenhænge mellem variablerne; antal_køb, abonnent_tidligere, abonnent_nu, kontakt, sidevisninger_total og sandsynligheden for succesfulde køb. Ved at gøre dette, kan man se hvordan de bidrager til sandsynligheden for succesfulde køb. Herefter kan man se koefficienterne og derefter ser man de første 10 sandsynligheder. Sandsynligheden for succesfuldt køb for observation 1 i datasættet er 18,47%. I næste del kan man se fordelingen er 0 og 1. Der laves herefter en ny prædiktion for ‘Nej’, 9366 gange og næste del viser alle som har en sandsynlighed for køb over 50% for værdien 1 ‘Ja’. Herefter vises en krydstabel, der opdeler observationerne i “nej” og “ja” kategorier. Der er samtidig lavet en krydstabel over ja og nej, de sande værdier og de forudsagte. Dette giver en måling af, hvor godt modellen klarer sig til at forudsige succesfulde køb korrekt. Resultatet er en værdi mellem 0 og 1, hvor 1 viser en perfekt præcision og 0 viser ingen præcision. Dernæst fremkommer modellens præcision, som viser 0.9061499, hvilket betyder, at modellen forudsiger 90.61% af observationerne i forhold til succesfulde køb. Det ses at modellen lige akkurat er bedre til at forudsige hvem der køber og ikke gør, end hvis man ikke brugte den, da vores “no information rate” er 90,5%. Ved at bruge confusionmatrix vil man kunne se hvor godt modellen præsterer i forhold til klassifikationerne af observationer. Ved at kigge på Kappa-værdien ser man et lavt niveau 0,1135 og det skal gerne være højere, da det fortæller hvor godt modellen kan forudsige resultaterne.

Vis koden
glm.fit <- glm(succesfuldt_køb ~., family = binomial, data = data_merge)

#summary(glm.fit)

glm.fit1 <- glm(succesfuldt_køb ~ konto_id + startdato+ antal_køb + abonnent_tidligere
               + abonnent_nu + kontakt + sidevisninger_total, family = binomial(), data = data_merge)


#glm.bic <- BIC(glm.fit)
#glm.aic <- AIC(glm.fit)

#den endelige model

glm.fit2 <- glm(succesfuldt_køb ~  antal_køb + abonnent_tidligere
               + abonnent_nu + kontakt + sidevisninger_total, family = binomial(), data = data_merge)


glm.probs <- predict(glm.fit2, type = "response")
#glm.probs[1:10]

#contrasts(data_merge$succesfuldt_køb)
#table(data_merge$succesfuldt_køb)

glm.pred <- rep("0", 9366)
glm.pred[glm.probs > .5] = "1"


#Her ses en krydstabel over fordellingen af 0 og 1
#table(glm.pred, data_merge$succesfuldt_køb)

#Her får man modellens nøjagtihed
#mean(glm.pred == data_merge$succesfuldt_køb) 

glm_cm <- confusionMatrix(as.factor(glm.pred), data_merge$succesfuldt_køb, mode = "everything")
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 8419  812
         1   65   70
                                          
               Accuracy : 0.9064          
                 95% CI : (0.9003, 0.9122)
    No Information Rate : 0.9058          
    P-Value [Acc > NIR] : 0.4386          
                                          
                  Kappa : 0.1155          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.99234         
            Specificity : 0.07937         
         Pos Pred Value : 0.91204         
         Neg Pred Value : 0.51852         
              Precision : 0.91204         
                 Recall : 0.99234         
                     F1 : 0.95049         
             Prevalence : 0.90583         
         Detection Rate : 0.89889         
   Detection Prevalence : 0.98559         
      Balanced Accuracy : 0.53585         
                                          
       'Positive' Class : 0               
                                          

Der prøves nu med et træningsdatasæt og et testdatasæt for at vurdere modellens præsentation. Accuracy viser 90,61% på baggrund af det, kan man sige at modellen har en relativt høj nøjagtighed i forudsigelsen af både positive og negative tilfælde. Dette er generelt positivt og viser en rimelig god modelpræstation. Ved at køre confusionmatrix viser tallet 2526 i rækken 0 og kolonnen 0, at der var 2526 tilfælde, hvor modellen korrekt forudsagde “0” (negativt) og testdatasættet faktisk var “0”. På samme måde viser tallet 24 i rækken 1 og kolonnen 1, at der var 24 tilfælde, hvor modellen korrekt forudsagde “1” (positivt) og testdatasættet faktisk var “1”. Tallet 240 i rækken 0 og kolonnen 1 viser, at der var 240 tilfælde, hvor modellen fejlagtigt forudsagde 1 (falsk positiv) og testdatasættet faktisk var 0. Tallet 19 i rækken 1 og kolonnen 0 viser, at der var 19 tilfælde, hvor modellen fejlagtigt forudsagde 0 (falsk negativ) og testdatasættet faktisk var 1.

Krydstabellen giver et visuelt overblik over, hvordan modellens forudsigelser matcher de faktiske værdier i testdatasættet. Ud fra tallene kan man sige, at modellen har en høj præcision for at forudsige de negative tilfælde (0), da antallet af TN er højt. Dog har modellen en lavere præcision for at forudsige de positive tilfælde (1), da antallet af TP er lavere, og der er et vis antal FN og FP.

Vis koden
#Nu prøver vi med et test og træningsdatasæt
set.seed(1)
train <- createDataPartition(y=data_merge$succesfuldt_køb, p=0.70, list=FALSE)
#table(data_merge[train, "succesfuldt_køb"])

train_køb <- data_merge[train, ]
test_køb <- data_merge[-train, ]
test_output <- data_merge$succesfuldt_køb[-train]
train_output <- data_merge$succesfuldt_køb[train]

glm.fit <- glm(succesfuldt_køb ~ antal_køb + abonnent_tidligere
               + abonnent_nu + kontakt + sidevisninger_total, family = binomial(), 
               data = data_merge, subset = train)

glm.prob <- predict(glm.fit, data_merge[-train,],
                    type = "response")

glm.pred <- rep("0", length(test_output))
glm.pred[glm.prob > .5] <- "1"
#table(glm.pred, test_output)
#mean(glm.pred == test_output) #Accuracy
#mean(glm.pred != test_output) # Fejlraten overall

glm_cm <- confusionMatrix(as.factor(glm.pred), test_output, mode = "everything")
#Her får vi en krydstabel
#table(glm.pred, test_output)
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 2524  240
         1   21   24
                                          
               Accuracy : 0.9071          
                 95% CI : (0.8957, 0.9176)
    No Information Rate : 0.906           
    P-Value [Acc > NIR] : 0.4392          
                                          
                  Kappa : 0.1316          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.99175         
            Specificity : 0.09091         
         Pos Pred Value : 0.91317         
         Neg Pred Value : 0.53333         
              Precision : 0.91317         
                 Recall : 0.99175         
                     F1 : 0.95084         
             Prevalence : 0.90602         
         Detection Rate : 0.89854         
   Detection Prevalence : 0.98398         
      Balanced Accuracy : 0.54133         
                                          
       'Positive' Class : 0               
                                          

Lineær diskriminant analyse

Vi ønsker udover logistisk regression, at afprøve flere modeller for vores data, for til sidst at finde frem til den model som bedst kan forudsige andelen af kunder som vil fortsætte deres abonnement, det vil sige købe et nyt. For at undersøge dette benytter vi vores variabel succesfuldt_køb som vores y variabel igen, da det er denne vi ønsker at forudsige andelen af. Målet med dette er, at vi til sidst kan finde frem til en model, som kan hjælpe Morten og hans salgsteam med at tilpasse deres salgsindsatser ved at gruppere de kunder, som vil have størst sandsynlighed for at købe nyt abonnement. Samtidig med at gruppere dem der har mindst sandsynlighed for at købe nyt abonnement, for at kunne fokusere og tilpasse deres indsatser de korrekte steder. Nu afprøves en LDA, lineær diskriminantanalyse på baggrund af tidligere model med samme y, og x variabler, samtidig benyttes samme test og træningsdatasæt. LDA modellen har, ud fra træningsdata, en fejlrate på 9,4%, hvilket er noget højt, da træningsfejlraten oftes er lavere end fejlraten på testdata. Modellen testes herefter igennem på vores testdata, og der laves en prædiktionsberegning på baggrund af vores LDA model og vores testdata. Når vi kigger på LDA prædiktionsmodellens nøjagtighed, ses det at denne har en fejlrate på 9,2%, altså en smule lavere end LDA modellen lavet ud fra vores træningsdatasæt. Altså har vores overordnede model en nøjagtighed på 90%, om dette er højt eller lavt, kan vi bedre konkludere på, når vi har kørt vores resterende modeller. Det ses at modellen forudsiger at 224 ikke vil købe, men ifølge de sande værdier fra vores data, vil de faktisk købe et abonnement. Derudover forudsiger modellen at 36 vil købe, på trods af, at det ikke vil købe ifølge de sande værdier.

Vis koden
lda.fit <- lda(succesfuldt_køb ~ antal_køb + abonnent_tidligere
               + abonnent_nu + kontakt + sidevisninger_total, 
               data = data_merge,
               subset = train)

lda.pred <- predict(lda.fit, test_køb)

#sum(lda.pred$posterior[, 1] >= .5)
#sum(lda.pred$posterior[, 1] < .5)

#lda.pred$posterior[1:90, 1]
#lda.pred$class[1:90]

#sum(lda.pred$posterior[, 1] > .8)

#lda.pred$posterior[,1]

pred_lda <- rep("0", length(test_output))
pred_lda[lda.pred$posterior[,1] < .5] <- "1"

#table(pred_lda, test_output)
#mean(pred_lda == test_output)
#mean(pred_lda != test_output)


lda_cm <- confusionMatrix(as.factor(pred_lda), test_output, mode = "everything")
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 2509  224
         1   36   40
                                          
               Accuracy : 0.9074          
                 95% CI : (0.8961, 0.9179)
    No Information Rate : 0.906           
    P-Value [Acc > NIR] : 0.4137          
                                          
                  Kappa : 0.2018          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.9859          
            Specificity : 0.1515          
         Pos Pred Value : 0.9180          
         Neg Pred Value : 0.5263          
              Precision : 0.9180          
                 Recall : 0.9859          
                     F1 : 0.9507          
             Prevalence : 0.9060          
         Detection Rate : 0.8932          
   Detection Prevalence : 0.9729          
      Balanced Accuracy : 0.5687          
                                          
       'Positive' Class : 0               
                                          

Naive Bayes

Nu vil vi afprøve en Naive Bayes model. Vi laver den på samme vis som vores LDA model, med samme y, og x variabler som tidligere, og starter med at lave modellen ud fra vores træningsdata. Vores Naive Bayes prædiktionsmodel har en nøjagtighed på 90%, ligesom vores LDA model. Det vil sige, at på nuværende tidspunkt er LDA og Naive Bayes lige så gode til at forudsige andelen af de kunder som vil/ikke vil købe. Ser vi på vores confusionmatrix, ses det at modellen forudsiger at 208 ikke vil købe, som rent faktisk køber, og at 65 vil købe, som ifølge de sande værdier faktisk ikke vil købe. Sammenligner vi dette med LDA, er antallet af FP (false positiv) faldet fra 224 i LDA, til 208 i Naive Bayes. Dog er antallet af FN (false negative) steget en hel del, fra 36 i LDA, til 65 i Naive Bayes. Vi fortsætter vores test af yderligere modeller for at se om vi kan finde en bedre.

Vis koden
nb.fit <- naiveBayes(succesfuldt_køb ~ antal_køb + abonnent_tidligere
                     + abonnent_nu + kontakt + sidevisninger_total, 
                     data = data_merge,
                     subset = train)


nb.pred <- predict(nb.fit, test_køb, type = "raw")

pred_nb <- rep("0", length(test_output))
pred_nb[nb.pred[,1] < .5] <- "1"


nb_cm <- confusionMatrix(as.factor(pred_nb), test_output, mode = "everything")
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 2480  208
         1   65   56
                                          
               Accuracy : 0.9028          
                 95% CI : (0.8913, 0.9135)
    No Information Rate : 0.906           
    P-Value [Acc > NIR] : 0.7323          
                                          
                  Kappa : 0.2464          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.9745          
            Specificity : 0.2121          
         Pos Pred Value : 0.9226          
         Neg Pred Value : 0.4628          
              Precision : 0.9226          
                 Recall : 0.9745          
                     F1 : 0.9478          
             Prevalence : 0.9060          
         Detection Rate : 0.8829          
   Detection Prevalence : 0.9569          
      Balanced Accuracy : 0.5933          
                                          
       'Positive' Class : 0               
                                          

Random Forest

Random forest er en form for beslutningstræ, som bruges til klassifikation, og til at forudsige kvalitative responsvariabler. For at kunne køre denne model, starter vi igen ud med at lave et test og træningsdatasæt ud fra vores oprindelige datasæt. Når vi har opdelt vores test og træningsdata, starter vi ud med at tune vores model, for at finde mtry som er antallet af variabler man tager med i hver opdeling af træet, disse er udtrukket tilfældigt fra p. Når vi har fundet antallet af mtry, ønsker vi at finde ntree, for at finde ud af, hvor mange grene vi skal have i vores model. Vi finder frem til at mtry skal være 3, og ntree skal være 500. Vores random forest model med mtry = 3, og ntree = 500 har en fejlrate på 9%, hvilket er det samme som LDA og Naive bayes. Nå vores randomforest model er lavet, laver vi herefter en prædiktionsmodel ud fra testdata. Denne model har en fejlrate på 8%, og er altså indtil videre overordnet set mere nøjagtige end forrige modeller. Vores random forest model forudsiger, at 137 ikke køber, hvor de sande data rent faktisk siger at de køber. Dog er antallet af FN (false negativ) faldet, til 28 mod 65 i Naive Bayes, og 35 i LDA modellerne.

Vis koden
set.seed(2)
train1 <- createDataPartition(y = data_merge$succesfuldt_køb, p = 0.80, list = FALSE)
#table(data_merge[train1, "succesfuldt_køb"]) 
train_køb1 <- data_merge[train1, ] 
test_køb1 <- data_merge[-train1, ] 
test_output1 <- data_merge$succesfuldt_køb[-train1] 
train_output1 <- data_merge$succesfuldt_køb[train1]


try_tree <- randomForest(succesfuldt_køb ~ antal_køb + abonnent_tidligere
                         + abonnent_nu + kontakt + sidevisninger_total,
                         data = train_køb1, 
                         importance = TRUE,
                         proximity = TRUE)

#print(try_tree)
#plot(try_tree)


#bestmtry <- tuneRF(train_køb1, train_køb1$succesfuldt_køb,stepFactor = 1.2, 
                   #improve = 0.01, trace=T, plot= T) 





rf_model <- randomForest(succesfuldt_køb ~ antal_køb + abonnent_tidligere
                         + abonnent_nu + kontakt + sidevisninger_total,
                         data = train_køb1, mtry = 3, importance = TRUE, ntree = 500)


#importance(rf_model)
#varImpPlot(rf_model)
rf_pred <- predict(rf_model, test_køb1) 
accuracy <- sum(rf_pred == test_output1) / length(test_output1) 
#print(paste("Model Accuracy:", accuracy)) 
rf_cm <- confusionMatrix(data = rf_pred, reference = test_output1) 
#print(rf_cm)
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 1671  142
         1   25   34
                                         
               Accuracy : 0.9108         
                 95% CI : (0.897, 0.9233)
    No Information Rate : 0.906          
    P-Value [Acc > NIR] : 0.2523         
                                         
                  Kappa : 0.2542         
                                         
 Mcnemar's Test P-Value : <2e-16         
                                         
            Sensitivity : 0.9853         
            Specificity : 0.1932         
         Pos Pred Value : 0.9217         
         Neg Pred Value : 0.5763         
             Prevalence : 0.9060         
         Detection Rate : 0.8926         
   Detection Prevalence : 0.9685         
      Balanced Accuracy : 0.5892         
                                         
       'Positive' Class : 0              
                                         

Boosting

Den sidste model der køres tilhører også decision trees, og er en Boosting model. I denne metode vokser hvert træ med information fra de tidligere træer. Vi ønsker igen at forudsige sandsynligheden og andelen af kunder, som ønsker at købe et nyt abonnement. Vi har valgt at bruge en shrinkage parameter/lamda på 0,01. Oprindeligt ville vi benytte fordelingen bernoulli til vores klassifikationsmodel, men da vi oplevede problemer, er vi derfor gået med fordelingen “multinomial”. Ved brug af denne model, får vi en advarsel ud, som ganske kort skriver “use at your own risk.” For at kunne udføre vores boosting model, har vi valgt at ignorere denne advarsel, og der skal derfor tages højde for at modellens resultater kunne have været anderledes, hvis man havde valgt fordelingen, bernoulli i stedet. Ser vi på krydstabellen der vises, ses det at vores model forudsiger, at 151 vil købe, som rent faktisk ikke køber, altså FN (false negativ) er 151. Derudover forudsiger modellen også, at 17 ikke vil købe, som rent faktisk ville købe, altså at FP (false positive) er 17. Sammenlignes dette med ovenstående modeller, kan vi se at antallet er FP (false positive) er faldet ret væsentligt, hvorimod antallet af FN (false negative) ikke er steget voldsomt. Som tidligere nævnt, mangler vi konkrete oplysninger fra Jyllands-Posten angående omkostningerne ved tab af en kunde, samt at få en ny kunde. Antager man, at FP (false postive) har den højeste omkostning/pris, så er boosting modellen at foretrække.

Vis koden
#Vi starter med at ungroupe by kontoid
test_køb1 <- test_køb1 |> 
  ungroup()

train_køb1 <- train_køb1 |>
  ungroup()


jp.boost <- gbm(succesfuldt_køb ~ antal_køb + abonnent_tidligere
                + abonnent_nu + kontakt + sidevisninger_total,
                data = train_køb1, n.trees = 500, shrinkage = 0.01,
                distribution = "multinomial", interaction.depth = 4)
Warning: Setting `distribution = "multinomial"` is ill-advised as it is
currently broken. It exists only for backwards compatibility. Use at your own
risk.
Vis koden
#summary(jp.boost)

boost.prob <- predict(jp.boost, test_køb1, n.trees = 500, type = "response")


boost.pred <- apply(boost.prob, 1, which.max)

boost.pred <- boost.pred - 1


boost.pred <- factor(boost.pred, levels = c(0, 1))

boost_cm <- confusionMatrix(factor(test_køb1$succesfuldt_køb),factor(boost.pred))
#table(test_køb1$succesfuldt_køb, boost.pred)
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 1681   15
         1  151   25
                                          
               Accuracy : 0.9113          
                 95% CI : (0.8975, 0.9238)
    No Information Rate : 0.9786          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.2038          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.9176          
            Specificity : 0.6250          
         Pos Pred Value : 0.9912          
         Neg Pred Value : 0.1420          
             Prevalence : 0.9786          
         Detection Rate : 0.8980          
   Detection Prevalence : 0.9060          
      Balanced Accuracy : 0.7713          
                                          
       'Positive' Class : 0               
                                          

Roc-Kurve

Ud fra vores roc-kurve, og modellernes AUC (area under the curve) ses det at logistisk regression og Naive Bayes modellerne dominerer. Dette stemmer ikke overens med vores resultater fra tidligere confusionmatrix, hvor boosting modellens nøjagtighed/accuracy var bedst til at forudsige hvem der rent faktisk vil købe. Vi har i løbet af denne opgave oplevet udfordringer med at få vores ROC kurve til at køre korrekt, og fremvise et retvisende billede af hvilke modeller der dominerer. Vi har desværre ikke været i stand til at løse dette problem. Under normale omstændigheder, ville man benytte en ROC kurven til at kigge på hvilke modeller som dominerede, her ville vi blandt andet kigge på modellernes AUC (area under the curve), hvor man udvælger den model med den højeste værdi. Her ville man yderligere undersøge, om nogle af modellerne klarer sig bedre ved forskellige thredsholds, og på baggrund af disse vil det være med til at udvælge den endelige model. På baggrund af ovenstående oplysninger, benyttes vores ROC kurve IKKE til at udvælge den endelige model.

Roc - Kurve

Model udvælgelse

Når vi vælger den model, der giver de bedste resultater i forhold til at forudsige andelen af kunder, der ønsker at købe et nyt Jyllands-Posten-abonnement, så præcist som muligt, tager vi flere parametre i betragtning. Først og fremmest er der blevet testet og gennemgået forskellige statistiske modeller for at tjekke deres evne til at forudsige andelen af køb. Vi har udarbejdet confusionmatrix’s for vores modeller, for at kigge på modellens nøjagtighed, samt fordelingen af de forudsagte værdier holdt op imod de sande. Dette er gjort, for at finde den bedst mulige model. Det er vigtigt at identificere, om man helst vil have en lav FN (false negative), mod en højere FP (false postive) værdi, eller omvendt. Det er derfor vigtigt at se på, hvilken fejl der vil have mest betydning over for det gældende emne. Vi har ikke nogen oplysninger om, hvorvidt det koster Jyllands-Posten flere penge at tabe en kunde, mod at få en kunde. Når man ser på modellernes confusionmatrix er det tydeligt, at vores boosting model er den med højeste accuarcy, og samtidig højest specificity og sensitivity. Vores boosting model har en sensitivity værdi på 92%, og en specificity værdi på 61%. Sammenligner man værdierne med de øvrige modeller, kan man finde modeller med en højere senitivity værdi, altså en højere TP (true postive) rate hvor man mere præcist forudsiger et positivt testresultat, samtidig med at den sande værdi også er positive. Dog er specificity betydeligt lavere i alle de andre modeller, hvor sensitivity raten er højere end ved boosting. Det vil altså sige, at vi kan finde en model med en bedre evne til at ramme rigtigt, når det gælder forudsigelse af TP (true postive). Dette er dog på bekostning af modellens evne til at forudsige TN (true negative) rate, som går fra 21% ved Naive Bayes og helt ned til 9% ved vores logistiske regression. Baseret på sammenligning af modellerne ud fra accuarcy, specificity og sensitivity værdier, er vores boosting-model valgt som den mest egnede til at forudsige sandsynligheden for, at kunder vil købe et nyt abonnement.

Undersøgelse af andelen af kunder som vil churne indenfor 1 år

Churn analyse

I dette afsnit vil der blive foretaget en churn analyse med henblik på, at finde ud af hvilke kunder, der har størst sandsynlighed for churn et år efter de har købt deres abonnement. Churn vil sige, at kunden vælger at stoppe sit abonnement og ikke fortsætter med det efter det løber ud. Generelt set kan man beskrive churn analyse som en metode, hvorpå det er muligt at finde ud af en specifik kundes adfærd. Det kan være om de har en stor eller lille sandsynlighed for at opsige deres abonnement. I dette tilfælde henviser adfærd til variablerne, som skal være med til at beregne vores y-værdi (abonnement_nu). Før vi gør det, vil vi forsøge at beregne den laveste omkostning pr. kunde ud fra det mest optimale threshold. Threshold angiver grænseværdien for hvem modellen forudsiger der vil churn og ikke churn. For at finde frem til det, vil vi forsøge os med fire forskellige modeller, heraf, to forskellige logistiske regressioner, LDA (lineær diskriminant analyse) og QDA (kvadratisk diskriminant analyse).

Før vi går i gang med selve modellerne, opdeler vi ‘data_merge’ i et test og trænings datasæt og placerer dem i nye objekter kaldet ‘train_churn’ og ‘test_churn’

Vis koden
# Træningsdata og testdata ------------------------------------------------
# Vi bruger funktionen set.seed, så vi kan reproducere vores resultater
set.seed(10)
#Denne kode bruger funktionen createDataPartition til at opdele dataene i en #træningssæt og et testsæt med henblik på at forudsige churn (afmelding af #abonnement).
intrain_churn <- createDataPartition(y=data_merge$abonnent_nu, p=0.80, list=FALSE)


#Koden her laver et nyt træningsdatasæt objekt og et testdatasæt objekt baseret på #'intrain_churn'. Dette gør vi for at kunne træne dataene på en del af datasættet #og derefter kunne teste det på nye uafhængige dele af dataene.

train_churn <- data_merge[intrain_churn,]
test_churn <- data_merge[-intrain_churn,]

Omkostninger ved kunde churn

Vurderingerne af den laveste omkostning har betydning for, hvor vi skal placere vores threshold henne. Der vil derfor blive opstillet, hvad de forskellige fejl i forudsigelsen koster, og hvad de betyder hver især. Da vi ikke kender de reelle omkostninger for Jyllands-Posten, er disse tal sat ind for at eksemplificere modellens anvendelse. Dette betyder også, at det endelige resultat ikke repræsenterer den sande virkelighed. Churn analysen skal ses som et redskab Jyllands-Posten kan bruge til, at forudsige hvilke kunder der vil opsige deres abonnement, og heraf udregne en omkostningsbesparelse. FN_omk = 300 kr. Omkostningen for en falsk negativ, hvilket vil sige at vi prædikter kunden fortsætter sit abonnement, men i virkeligheden opsiger de. TP_omk = 60 kr. Omkostningen for en sand positiv, hvilket vil sige vi prædikter kunden opsiger sit abonnement og at de også gør det. FP_omk = TP_omk En falsk positiv vil sige at de opsiger, men i virkeligheden opsiger kunde ikke. TN_omk = 0 kr. Omkostningen for en sand negativ, hvilket vil sige at vi prædikter kunden vil churn og at de også gør det. Da Jyllands-Posten ikke anvender nogen form for churn analyse i dag, af deres kunder, har vi først lavet en omkostningsberegning for, hvis de gætter tilfældigt på hvem der vil churn og hvem der ikke vil. Resultatet af dette kommer ud i ‘omkostninger_mavefornemmelse’, hvilket giver en omkostning på 60,25 kr. pr. kunde. Dette tal vil vi bruge til, at holde op imod de andre modeller, som vil blive gennemgået herefter.

Vis koden
#For at kunne beregne omkostningerne senere laver et fire nye objekter, hvor vi #giver dem hver især en fast værdi. De repræsnterer hvad det vil koste at lave en prædiktionsfejl. Tallene er angivet i kr. 
FN_omk <- 300
TP_omk <- 60
FP_omk <- TP_omk
TN_omk <- 0

#Nedenunder laves en ny variabel kalder no-abonnent. Her sætter vi alle #observationer til "no", hvilket vil sige at ingen churner. FN_Simple bruges til at #lave en omkostnings beregning per kunder ved at gange FN_omk med FN_simple
#antages det at vi gætter tilfædligt hvem der churner og ikke gør. 

test_churn$no_abonnent <- "No"
FN_simple <- table(test_churn$abonnent_nu, test_churn$no_abonnent)[2]/(table(test_churn$abonnent_nu, test_churn$no_abonnent)[1]+
                                                                        table(test_churn$abonnent_nu, test_churn$no_abonnent)[2])

#Giver et resultat på 60.25 per kunde
omkostninger_mavefornemmelse <- FN_omk*FN_simple 
#Vælger no_abonnent fra datasættet igen

test_churn <- dplyr::select(test_churn, -no_abonnent) 

Logistisk regression

I første omgang prøver vi logistisk regression. Hvorpå vi laver vores model ud fra ‘data_merge’ med de relevante variabler. I ‘churn_probs’ udregner vi sandsynligheden for churn for alle observationer i ‘test’churn’. I første del af koden her laver vi en sekvens på længden af 100, der går fra 0,01-1,0. ‘omk’ laver en vektor på samme længde af ‘thresh’ hvor den indsætter nulværdier. Når vi kører vores løkke, vil omk indeholde beregnede omkostninger for hver threshold-værdi. Vi finder den laveste omkostning ved at køre funktionen min(omk), og resultatet er 38,58 kr., hvilket svarer til en threshold-værdi på 18.

Vi forsøger at gentage eksperimentet, men med en fast threshold på 0,50. Med andre ord ønsker vi at beregne omkostningen pr. kunde under antagelse af, at 50% churner og 50% ikke churner. Resultatet gemmes i omk_simple. Omkostningen her er 49,42 kr., så vi kan hurtigt konkludere, at sammenlignet med den første model er omk_simple omkostningen noget højere.

Her ses omkostningerne ved henholdsvis den optimeret, og den simple model.

Besparelsesberegning

Det betyder i kroner og øre at vi kan aflæse besparelsesberegningen ved at køre koden her. Pr. kunde kan Jyllands-Posten spare 10 kr. ved at vælge den optimeret frem for den simple. Alt i alt regnes det ud, at ved alle kunder vil det give en besparelse på 101,465 kr. På samme vis kan vi også sammenligne den optimerede løsning med ‘besparelse_mavefornemmelse’. Pr. kunde vil det koste 21. kr. mindre. Det giver en samlet besparelse på 202,930 kr., hvilket må siges at være noget af en forbedring allerede.

Vis koden
#En beregning af omkostningsbesparelsen per kunde ved at vælge et threshold på 0,18 #fremfor 0,50. Det giver en besparelse på 10 kr. per kunde
besparelse_pr_kunde <- omk_simple - min(omk)

#Her regnes besparelsen ud for alle kunder. Det giver en besparelse på lidt over #100.000 kr. 
#dim(data_merge)
besparelse_allekunder <- besparelse_pr_kunde*9366

#Samme øvelse som før, bare med sammenligningen mellem 'omk' og #'omkostninger_mavefornemmelse'. Det giver en besparelse på 21 kr. per kunde
besparelse_mavefornemmelse <- omkostninger_mavefornemmelse - min(omk)
#Besparelse i alt 
#besparelse_mavefornemmelse*9366

Lineær diskriminant analyse

Vi kan nu forsøge os med LDA for, at se om vi kan finde en større omkostningsbesparelse. Variablerne til modellen er de samme som tidligere, ligesom det er tilfældet med y-variablen. Fremgangsmåden er den samme som ved logistisk regression. I ‘min(omk_lda)’ kan man aflæse, at den lavest fundne omkostning ligger på 38,71 kr. pr. kunde. Selvom det er minimalt, finder logistisk regression stadig den laveste omkostning pr. kunde. Sammenligner man de to modeller vil det være dyrere samlet set at vælge lda fremfor logistisk regression. Dog klarer den sig stadig betydeligt bedre overfor ‘omk_simple’ og mavefornemmelses modellerne.

Kvadratisk diskriminant analyse

Til sidst kan vi prøve QDA. Her viser det sig at den får en endnu lavere omkostning pr. kunde end logistisk, nemlig 38,49 kr. Hvilket er tæt, men kigger man på threshold er det til gengæld den med det højeste, nemlig 0,32. Igen har vi lavet sammenligninger mellem besparelserne ved at vælge forskellige modeller.

Model udvælgelse

Ud fra omkostningsbesparelserne ville QDA modellen være at foretrække til at forudsige kundechurn. Hvis Jyllands-Posten er interesseret i at finde ud af hvilken andel af kunder som vil churn har vi beregnet dette ud for 4 forskellige modeller, samt omkostningerne ved kundechurn, og sammenlignet det med deres nuværende metode, som er baseret på mavefornemmelse. Det eneste Jyllands-Posten skal ændre i denne model, er deres reelle omkostninger i forhold til de forskellige fejl omkostninger. Ved at benytte QDA modellen frem for deres mavefornemmelse i dag, ville de samlet kunne spare 204.731, og dermed optimere deres omkostninger forbundet med deres salg.

Forberedelse til data visualisering

Inden vi kan udarbejde vores shiny applikation, og dashboard, laver vi 2 nye variabler. Vi finder sandysnlighederne for churn ud fra vores QDA model, og laver en ny variabel kaldet churn_sandsynlighed. Det samme gør vi for sandsynlighederne for køb ud fra vores boosting model, og laver en ny variabel vi kaleder køb_sandsynlighed. Til sidst laver vi vores nye variabler, samt vores datasæt data_merge til RDS filer, så vi kan hive dem ind i vores Shiny app.

Data visualisering

I denne del henvises der til vores shiny applikation, som er at finde på dette link, eller i sin egen særskilte fil.

Klik her for at se vores dashboard.

Vores dashboard har en farvekode #186860 som er en af Jyllands-Postens farver de bruger i deres avis. Vi har lavet hele teksten hvid og hele dashboardet til grøn, da det giver god kontrast. Det er en mørkegrøn farve, som repræsenterer den grønne fremtid. Vi har også Jyllands-Postens logo, som vi har valgt at bruge, således at Jyllands-Postens aftryk vil være på dashboardet. Vi har valgt at lave vores dashboard i tabel form, da vi gerne vil vise så mange informationer som muligt. Det betyder at, Morten vil kunne få et overblik over deres kundedatabase og forstå kundeadfærd. Nogle af vores primære variabler, som Morten kan få gavn af, er sandsynligheden for køb, sandsynligheden for churn og sidevisninger totalt. Disse variabler har en høj forklaringsgrad, hvilket betyder, at de giver en hurtig indsigt i, om kunden er en avislæser og om kunden er tilbøjelig til at købe et avisabonnement. Der er også bygget nogle widgets til brug for Morten, således han kan vælge bestemte kundetyper til eller fra. Den første er konto-id, hvor Morten kan søge en bestemt kunde frem eller vælge, at have alle kunder på dashboardet. På sigt vil dette dashboard også kunne benyttes at sælgerne, med få justeringer. Her vil det være muligt at filtrere på kunde_ID, så sælgeren kun ser oplysninger for det lead de snakker med. Dette kan eksempelvis være tidligere historik på kunden, har kunden tidligere haft abonnement, er kunden tidligere blevet kontaktet, hvad er sandsynligheden for køb, sandsynligheden for churn mv. Med dette vil sælgerne kunne tilpasse deres salgsindsatser således, at de bedre kan fange de rigtige kunder. Derudover har vi også select box som Morten kan bruge til, at opdele kunder i grupper, så som tidligere abonnenter, eller kontaktet kunder. Dashboardet har også en slider, hvor Morten kan justere kunder ud fra hvor mange sidevisninger de har haft. Vores slider kan justeres fra 0 til 4000 sidevisninger og kan justeres efter den rækkevidde, der måtte ønskes. Det betyder at Morten for eksempel kan kontakte de kunder, der har haft 1000 til 2000 sidevisninger i alt. Vi har valgt at bruge gestalt principper i vores dashboard, som kontinuitet hvor linjerne i dashboardet deles mellem kunderne. Linjerne har også en længde, der fortæller noget om connection i gestalt-princippet, hvilket viser at dataene har en sammenhæng. Vores datatable præsenterer et exploratory princip, som fortæller at der er meget at opdage i datatable. Datatable giver også mulighed for at opdage forskellige kundeadfærd og grupper med kundetyper, som Morten kan fokusere på for at effektivisere telemarketingafdelingen. Dermed har vi offentliggjort vores Shiny-app, så Morten kan få adgang til vores dashboard, og dagligt drage fordel af funktionerne til ham og hans sælgere.

Test af app

Efter at have udviklet vores Shiny app, er det nu tid til at teste dens performance. Det er afgørende at evaluere dens effektivitet, funktionalitet og brugeroplevelse, før den bliver lanceret til et større publikum. Områder der kan have indflydelse på brugerens oplevelse inkluderer appens hastighed, dens brugervenlighed, samt evnen til at understøtte flere brugere på samme tid. Vi vil nu teste app’en på disse områder. Vi vil gøre brug af R-studio, det samme miljø hvor app’en er udviklet, til at foretage en ‘record test’. Denne proces optager alle brugerens handlinger under testforløbet og genererer et R-script, der giver specifikke anbefalinger til forbedringer. I vores tilfælde, blev vi rådet til at ændre ‘konto_id’ dropdown-menuen for at forbedre appens performance.(bilag 2, figur 2) Vi testede også appens evne til at håndtere flere brugere simultant. Sådan en test kan køres gennem R med udgangspunkt i ‘record test’, hvor man specificerer antallet af brugere, der kører en simulation samtidig, f.eks. 5. Dette bliver uploadet til ens directory og herfra er det muligt at analysere på testen ved, at kigge på ting som; antallet af sessioner gennemført eller fejlet, gennemsnitlig responstid eller hvor lang tid det tager for en bruger at gennemføre hele testen. Da vi oplevede problemer med at gennemføre sådan en test i R, har vi valgt at køre en test med os selv, altså fire person. Her oplevede Ingen af as problemer med belastning eller de andre nævnte KPI’er med forbehold for, at det ikke det samme som at køre en test i R. Til trods for anbefalingen om øget performance ser vi på nuværende tidspunkt ikke behov for at handle, da vores løsning er designet til en enkelt bruger, nemlig Morten. For at opnå yderligere indsigt i appens performance, kan vi anvende Shinyapps.io. Dette er en platform, der tillader offentlig adgang til appen uden at kræve en separat Shiny server. Her kan man overvåge fem forskellige parametre; antallet af forbindelser, hukommelsesforbrug, worker processer, CPU-brug og netværksbrug. Resultaterne kan findes i det vedlagte bilag(bilag 3-7). Ved at analysere disse data, kan vi engagere os i en dialog med organisationens udviklere for at afgøre, om der er behov for at øge ressourcerne til nogen af disse parametre.

Løsningsforslag og implemntering

Vores dashboard er specifikt rettet mod Morten for at hjælpe ham med at forenkle sit arbejde og øge effektiviteten. Vi har derfor lavet et dashboard til ham, med det formål at det skal hjælpe ham med, at tage bedre beslutninger som chef i telemarketingafdelingen. I dag har hans afdeling ikke et filtreringssystem af abonnement kunder. De har altså indtil nu ringet ud til kunder, uden at have viden om deres interesse i at købe eller forlænge deres abonnement. Vi vil gerne hjælpe Morten med at fordele deres kunder ud fra sandsynligheden for om der bliver købt et nyt abonnement, dette har vi beregnet ud fra vores model. Denne model er bygget ud fra udvalgte variabler, som vi mener er afgørende for, at forudsige sandsynligheden for et køb. Dette giver Morten information og overblik over, hvilke kunder der har været mest aktive. Dashboardet gør, at Morten kan filtrere de kunder der har højest sandsynlighed for køb og uddele det til sine salgsmedarbejdere. Han kan give dem med højest sandsynlighed til de bedste sælgere, så der kommer konvertering. Eller omvendt hvor han giver de bedste leads til nye sælgere således de får små succeshistorier. Med det nye dashboard og filtreringssystem, kan Morten og hans afdeling løbende holde øje med nye kunder/leads, som bliver tilføjet systemet. Dette er en klar forbedring, da de tidligere ikke benyttede nogle former for filtrering på deres leads, men derimod blot ringede ud tilfældigt. Dette nye dashboard gør det muligt for dem at kontakte de bedste leads, og hermed spare tid og ressourcer ved at fokusere deres salgsindsatser bedre. Dette vil løse deres primære problem med at optimere brugen af ressourcer til kundekontakt og dermed effektivisere processen med at ringe til kunder. Morten skal altså bruge prædiktionsmodellen fremadrettet for at få identificeret de kunder, som har størst sandsynlighed for at købe et nyt abonnement. Her vil man i kombination med modellen, kunne overveje at indføre RPA(robotic process automation), som ville kunne hjælpe med at automatisere grupperingen af de kunder som vil købe, og dem som ikke vil. Ved at anvende denne model og RPA (Robotic Process Automation) vil Morten og hans salgsafdeling kunne optimere deres salgsaktiviteter og dermed øge deres salgsindsats, samtidig med at de opnår nye salg. Derudover skal Morten også anvende vores churn-analysemodel til at oprette analyser om, hvilke kunder der med høj sandsynlighed vil afmelde deres abonnement inden for det næste år. Her vil Mortens salgsafdeling kunne benytte oplysningerne til at vurdere, om det giver mening at indsætte ekstra indsatser for at forhindre kundens churn. Denne information kan bruges til at designe og implementere en ny kampagne eller lignende tiltag. Samtidig kan oplysningerne om kunder, der ikke forventes at afmelde deres abonnement (ikke-churners), bruges til at pleje og styrke forholdet til disse kunder. Ved at sikre, at de modtager relevante kampagner og tilbud ved forlængelse af deres abonnement, kan man øge chancerne for at fastholde disse kunder.

Konklusion

Jyllands-Posten er en landsdækkende medieplatform, der er tilgængelig både som fysisk avis og som digital avis. De står i dag overfor udfordringer i forbindelse med at antallet af avislæsere er faldende, og de har derfor sat ekstra fokus på deres digitale kanaler, og ønsker at optimere deres omkostninger. Derudover ønsker de at blive bedre til at spore sig ind på, hvem der med højest sandsynlighed er interesseret i at købe et abonnement. På nuværende tidspunkt udnytter Jyllands-Posten kun i begrænset omfang data til at forudsige sandsynligheden for kundekøb og kundechurn. Der indsamles kundedata, men udnyttelsen af den til analytisk brug er sparsom. I denne opgave har der været fokus på at undersøge, hvordan to forskellige statistiske modeller kan hjælpe Jyllands-Posten med at identificere de rette kunder og dermed optimere deres salgsomkostninger. Igennem analysen er der henholdsvis kigget på forskellige prædiktionsmodeller til at forudsige kunders sandsynlighed for at købe et nyt abonnement, og der er her fundet frem til en model som med 91% nøjagtighed kan forudsige om kunden vil købe et nyt abonnement eller ej. Det kan antages, at hvis Jyllands-Posten fremadrettet benytter denne model, vil deres salgsindsats opleve en betydelig forbedring. Dette skyldes, at de i øjeblikket ikke benytter sig af lignende analytiske metoder til at optimere deres salgsaktiviteter. Ved at implementere disse analytiske metoder vil Jyllands-Posten kunne træffe mere præcise og informerede beslutninger i deres salgsstrategi og opnå bedre resultater i forhold til kundetilfredshed og omsætning. Foruden dette, har vi i analysen undersøgt diverse prædiktionsmodeller til at forudsige kunde churn. Her har vi fundet frem til en model, som på årlig basis kan give en samlet besparelse på 203.830 kr., ud fra de omkostningsvariabler vi har lavet. Jyllands-Posten har i øjeblikket ingen form for churn-analyse, hvilket antyder, at de baserer sig primært på mavefornemmelse i forhold til at håndtere kundechurn. Derfor kan det forventes, at vores churn-model vil kunne bidrage til at optimere deres omkostninger og salgsindsatser på dette område. Ved at anvende churn-analysen vil Jyllands-Posten kunne opnå en mere datadrevet tilgang til at forudsige og håndtere kundechurn, hvilket kan føre til mere effektive ressourceallokeringer og øget kundetilfredshed. For at salgsafdelingen og Morten, som er Jyllands-Postens salgschef, kan få udbyttet af de to modeller, har vi udarbejdet et dashboard i en shiny applikation. Dasboardet kan Morten benytte for at få viden om de eksisterende leads, såsom hvilke har størst sandsynlighed for at købe, hvem der har størst sandsynlighed for at churne om 1 år. Gennem dette dashboard kan Morten bringe relevante leads videre til sælgerne og på den måde fokusere deres salgsindsats på de rette leads. Opsummeret, vil Morten og hans salgsafdeling ved brug af vores prædiktionsmodel til at finde sandsynligheden for køb, forbedre deres chance for at få et salg igennem ved de rette leads. Derudover, vil salgsafdelingen ud fra vores omkostningsvariabler, som må antages at være sat lavere end Jyllands-Postens, kunne spare cirka 200.000kr i alt årligt på at benytte churn-analyse.

Bilag

Bilag 1, figur 1

Summary af glm.fit Bilag 2, figur 2

Bilag 3, figur 3

Bilag 4, figur 4

Bilag 5, figur 5

Bilag 6, figur 6

Bilag 7, figur 7

Litteraturliste

Datatilsynet & Jusitstministeret. (2017, november). Vejledning om dataansvarlige og databehandlere. https://www.datatilsynet.dk/media/6560/dataansvarlige-og-databehandlere.pdf?fbclid=IwAR3GlbIQdvYPcdZYlQywtr5kkkADsGndw3Vx3faAFLcOjQc9KXY–2ioOSg

Egholm, L. (2014). Videnskabsteori. : Perspektiver på Organisationer og Samfund. Hans Reitzels Forlag.

Forbrugerombudsmanden. (s.d.). Telefonsalg: Uanmodede henvendelser. Forbrugerombudsmanden.dk. https://www.forbrugerombudsmanden.dk/alle-emner/uanmodede-henvendelser/telefonsalg/

Gemius Audience. (2023, april). Toplisten. gemiusAudience. Lokaliseret den april 2023 på https://e-public.gemius.com/dk/rankings/447

Glavind, L. & Tassy, A. (2022). Især ældre abonnerer på aviser. Danmarks statistik. https://www.dst.dk/da/Statistik/nyheder-analyser-publ/nyt/NytHtml?cid=40266

Hotz, Nick. (2023, 19. januar). What is CRISP DM. Data Science Process Alliance. https://www.datascience-pm.com/crisp-dm-2/

Jyllands-Posten. (s.d.). Jyllands-Postens historie. Jyllands-Posten. http://www.jyllands-posten.org/jps-historie.php

Jyllands-Posten. (s.d.). Jyllands-Postens redaktionelle værdier. Jyllands-Posten. http://www.jyllands-posten.org/vaerdier.php

Jyllands-Posten. (s.d.). Målgrupper. jpannonce. https://www.jpannonce.dk/da/audiences

Jyllands-Posten. (s.d.). Organisation: Jyllands-Posten. Jyllands-Posten. http://jyllands-posten.org/organisation.php

Kultur ministeriet. (2021). Mediernes udvikling i Danmark: Skrevne nyhedsmedier 2021, hovedresultater og konklusioner. https://kum.dk/fileadmin/_mediernesudvikling/2021/Skrevne_nyhedsmedier_2021_hovedkonklusioner.pdf

Lov om forbrugeraftaler [Forbrugeraftaleloven], LOV nr. 1457 af 17/12/2013. Lovtidende A (2013). https://www.retsinformation.dk/eli/lta/2013/1457

Nielsen, K.. & Vendelbo, P.. (3). Markedsføringsret: Jura for kortere videregående uddannelser. Forlaget LawLab ApS. xxx

Nielsen, K.M.S. & Vendelbo, P. (2022). Persondataret: Jura for kortere videregående uddannelser (3. udg.). Forlaget LawLab ApS. xxx

Törnfelt, C. (2017). Færre avislæsere og færre læste aviser. Danmarks statistik. https://www.dst.dk/da/Statistik/nyheder-analyser-publ/nyt/NytHtml?cid=24083

Virksomhedsguiden & Justistministeren. (s.d.). Forbrugeraftaleloven: Det skal du være opmærksom på. Virksomhedsguiden.dk. https://virksomhedsguiden.dk/content/ydelser/forbrugeraftaleloven-det-skal-du-vaere-opmaerksom-paa/31ecc243-a513-434c-a303-ec32eea2f913/