En grundläggande förståelse av en klassificeringsmodells prestanda kan uppnås genom att titta på flera mätvärden, där en av de mest centrala är förvirringsmatrisen. Förvirringsmatrisen ger en detaljerad översikt över en modells förmåga att korrekt förutsäga varje klass i en given uppsättning. Varje rad i matrisen representerar de verkliga klassvärdena, medan varje kolumn representerar de förutsagda klassvärdena. Genom att analysera dessa värden kan vi identifiera fyra huvudsakliga kategorier:

  • True Positive (TP): Antalet korrekt förutsagda positiva exempel.

  • False Negative (FN): Antalet exempel som är verkligt positiva men felaktigt förutsagts som negativa.

  • False Positive (FP): Antalet exempel som är verkligt negativa men felaktigt förutsagts som positiva.

  • True Negative (TN): Antalet korrekt förutsagda negativa exempel.

För att verkligen förstå hur väl en modell presterar behöver man inte bara titta på dess noggrannhet, utan också överväga andra mätvärden som precision och återkallelse. Precision mäter hur många av de förutsagda positiva exemplen som verkligen är positiva. Höga värden innebär att modellen har få falska positiva, men precisionen tar inte hänsyn till de exempel som inte identifierades korrekt (dvs. falska negativa). Å andra sidan fokuserar återkallelse på att mäta hur många av de verkligt positiva exemplen som modellen korrekt förutspår. En hög återkallelse innebär att modellen fångar fler positiva exempel, men kan leda till fler falska positiva.

Det är inte ovanligt att precision och återkallelse är i en slags trade-off: genom att förbättra en aspekt kan den andra försämras. Till exempel kan en modell som klassificerar alla exempel som positiva uppnå en hög återkallelse, men till priset av mycket låg precision. För att väga dessa två metoder samman används ofta F1-poäng, som är ett harmoniskt medelvärde mellan precision och återkallelse, och ger en enskild indikator på hur väl modellen presterar på båda dessa viktiga mått.

När vi dessutom analyserar en modells prestanda genom korskontroll (cross-validation) kan vi få en bättre uppfattning om hur väl den generaliserar till nya, osedda data. Vi bör vara medvetna om att det finns en risk att modellen överanpassar sig till träningsdata och därmed inte fungerar bra på testdata. För att minska denna generaliseringsfel (den skillnad som kan uppstå mellan prestanda på träningsdata och testdata) är det avgörande att använda tekniker som t.ex. regularisering.

Regularisering är en metod för att motverka överanpassning genom att införa en straffterm för stora koefficientvärden under träningen. Detta gör att modellen lär sig att finna lösningar med mindre vikt, vilket kan bidra till att förbättra modellens generaliseringsegenskaper. Ett vanligt sätt att visualisera effekten av regularisering är att undersöka koefficienternas fördelning i en modell. Om koefficienterna är mycket stora innebär det att modellen troligtvis anpassar sig för mycket till träningsdata och lär sig brus i stället för relevanta mönster. Detta leder till dålig prestanda på osedda data.

Det är också viktigt att förstå att överanpassning (overfitting) är en vanlig fallgrop i modellträning, särskilt när man har ett begränsat dataset. Om modellen är för komplex, med alltför många parametrar i förhållande till mängden data, kommer den att försöka "lära sig" mönster som inte existerar, vilket leder till att modellen fungerar bra på träningsdata men inte generaliserar bra på nya data. Genom att använda regularisering kan vi effektivt minska risken för överanpassning.

För att identifiera om modellen överanpassar sig till träningsdata och för att hitta lösningar på detta problem, kan man analysera skillnaderna mellan prestanda på träningsdata och testdata. Om prestandan på träningsdata är mycket bättre än på testdata är detta en indikator på att överanpassning kan ha inträffat. För att åtgärda detta kan man minska modellens komplexitet, öka mängden träningsdata eller tillämpa tekniker som korskontroll och regularisering.

I praktiken, för att förbättra en modell, kan det vara nödvändigt att iterera och testa olika metoder, inklusive justering av parametrar, tillämpning av olika regulariseringstekniker eller användning av mer sofistikerade modeller. Regelbundet testande och justering kan hjälpa till att hitta den optimala balanspunkten mellan att passa träningsdata och att kunna generalisera till nya, osedda data.

Det är också viktigt att vara medveten om att även om man når en hög prestanda på träningsdata och testdata, betyder det inte alltid att modellen är den bästa möjliga. Genom att noggrant utvärdera modellen med hjälp av flera olika mätvärden och genom att testa på nya uppsättningar av data, kan vi vara säkra på att modellen är robust och pålitlig för framtida användning.

Hur kan små molekylers bindning till RNA-mål användas för att utveckla nya läkemedel?

I läkemedelsutveckling har små molekyler som binder till RNA-mål blivit en lovande strategi för att skapa innovativa terapeutiska medel. RNA är en mångsidig molekyl som spelar en central roll i cellens reglering, genom att bära genetisk information. Genom att binda till RNA kan små molekyler förändra en rad biologiska processer, som att hämma specifika RNA-proteininteraktioner, förändra RNA-splitsningsmönster eller till och med främja RNA-nedbrytning. Små molekyler som påverkar RNA-strukturer associerade med cancerprogression har till exempel undersökts som potentiella antikancerbehandlingar.

Att designa små molekyler som selektivt binder till RNA-mål är en utmaning av flera skäl. RNA-molekyler har ofta inga tydliga bindningssidor, och deras strukturer är dynamiska och kan anta flera olika konformationer. Denna flexibilitet gör det svårt att bestämma RNA:s högupplösta strukturer, inklusive de som involverar RNA-molekyler som binder små molekyler. Detta gör att experimentell karakterisering av bindningsegenskaper och affiniteter mellan RNA-mål och små molekyler är begränsad. Därmed blir utvecklingen av prediktiva modeller som kan förutspå denna bindning svårare.

I arbetet av Cai et al. utvecklades en QSAR-modell (kvanitativ struktur-aktivitetrelation) som beskriver förhållandet mellan en molekyls struktur och dess experimentellt observerade bindningsprofil mot ett specifikt RNA-mål. Målet med denna modell är att kunna härleda vilka egenskaper hos en kemisk förening som är avgörande för att uppnå optimal bindning till RNA-målet.

Denna typ av modell kan ha stor betydelse, inte bara för att skapa bättre läkemedel mot virusinfektioner som HIV, utan också för att belysa hur man kan angripa RNA-mål som tidigare varit svåra att behandla. RNA är en lovande, men svår, terapeutisk målstruktur – och genom att förstå de strukturella och kemiska förhållandena som styr bindningen mellan små molekyler och RNA kan vi komma ett steg närmare nya behandlingsstrategier för en rad sjukdomar, från virusinfektioner till neurodegenerativa sjukdomar och cancer.

Det första steget i denna process är att beräkna molekylens egenskaper genom att skapa så kallade "deskriptorer", som kvantifierar de strukturella och elektroniska egenskaperna hos molekyler. Dessa deskriptorer används sedan för att skapa modeller som kan förutspå hur starkt en viss molekyl binder till RNA-målet. Genom att använda avancerade algoritmer som gradient boosting och genom att förstå modellens tolkbarhet kan forskare och läkemedelsutvecklare på ett mer effektivt sätt förutse vilka molekyler som kan vara de mest lovande för vidare utveckling.

Det är dock viktigt att förstå att den största utmaningen ligger i de dynamiska och komplexa strukturerna hos RNA, som innebär att vi inte alltid har tillgång till fullständig information om deras interaktioner med små molekyler. Det krävs en finjustering av modeller för att kunna ta hänsyn till dessa osäkerheter och ändå utveckla tillförlitliga förutsägelser. Modeller som bygger på data från experimentella tester av RNA-molekyler och deras interaktion med små molekyler ger oss en värdefull möjlighet att förstå och förutsäga dessa interaktioner.

Färdiga prediktiva modeller gör det möjligt för forskare att skapa riktade läkemedel mot RNA och att utforska de mekanismer som styr dessa interaktioner på en djupare nivå. Dessutom kan de metodologiska ramverken, som utvecklats i samband med arbetet med HIV-relaterade RNA-strukturer, tillämpas på andra RNA-mål som är inblandade i olika sjukdomar. Den här teknologin och forskningen innebär en potential för att utveckla effektiva behandlingar för tidigare svårbehandlade sjukdomar och infektioner.

Det som också är av stor vikt är att förstå att även om kvantitativa modeller kan förutsäga hur en molekyl binder till sitt RNA-mål, är det inte alltid den enda faktorn som avgör effektiviteten i läkemedelsutveckling. Molekylernas farmakokinetik, deras förmåga att nå det önskade målet i kroppen, samt eventuella biverkningar är faktorer som måste beaktas parallellt för att en behandling ska kunna vara framgångsrik i kliniska studier.

Hur man använder tensorer i PyTorch för djupinlärning

Tensorer är den grundläggande byggstenen i PyTorch, precis som matriser i linjär algebra. De är flerdimensionella arrayer, påminnande om NumPy-arrayer, men har flera tilläggsfunktioner som gör dem särskilt lämpliga för djupinlärning. En av de viktigaste fördelarna med tensorer är att de kan bearbetas både på CPU och GPU, vilket gör det möjligt att accelerera beräkningar vid behov. För att skapa en tensor i PyTorch kan vi använda funktionen torch.tensor() som tar en indata i form av en Python-lista eller annan datakälla. Låt oss säga att vi vill skapa en tvådimensionell tensor från en inbäddad lista:

python
tensor_2d = torch.tensor([[1, 2], [3, 4]])
print(f"Tvådimensionell tensor: {tensor_2d}")

Detta skapar en tensor med två rader och två kolumner. När vi jobbar med tensorer, är det viktigt att hålla koll på deras form och vilken enhet de lagras på, eftersom dessa egenskaper påverkar beräkningarna. PyTorch erbjuder enkla metoder för att hämta denna information:

python
print(f"Formen på tensor: {tensor_2d.shape}") print(f"Datatyp för tensor: {tensor_2d.dtype}") print(f"Enhet som tensoren lagras på: {tensor_2d.device}")

För att ändra precisionen på tensorerna kan vi ange en specifik datatyp. Exempelvis kan vi skapa en tensor med flyttal i stället för heltal genom att ange dtype=torch.float32:

python
tensor_2d_float = torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=torch.float32)
print(f"Datatyp för tensor: {tensor_2d_float.dtype}")

Att välja rätt datatyp är avgörande för prestanda och precision. Högre precision (t.ex. 32-bitars flyttal) ger mer noggrannhet men kan öka minnesanvändningen och sänka hastigheten på beräkningarna. PyTorch erbjuder ett brett urval av datatyper, inklusive 16-bitars, 32-bitars och 64-bitars flyttal samt olika heltalsstorlekar.

Tensorer är inte bara för lagring av data – de används för att utföra matematiska operationer. PyTorch gör det möjligt att snabbt utföra operationer på tensorer som addition, subtraktion, multiplikation och division. Exempelvis kan vi lägga till ett konstant värde till alla element i en tensor:

python
tensor_df_mod = tensor_2d + 2 print(f"Modifierad tvådimensionell tensor: {tensor_df_mod}")

Därmed får vi en ny tensor där varje element har ökat med 2. För att skapa mer komplexa beräkningar används vanligen en kombination av tensoroperationer för att härleda representationer av mönster i indata. Ett exempel på detta kan vara att skapa en ny form av tensor genom att ändra dess dimensioner med metoder som .reshape():

python
tensor_2d = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(f"Omformad tensor: {tensor_2d.reshape(3, 2)}")

Här omvandlas en 2x3 tensor till en 3x2 tensor. Observera att .reshape() inte förändrar originaltensorn om vi inte tilldelar resultatet till en ny variabel.

En annan användbar metod för att ändra form är .view(), som ofta används för att skapa en ny vy av tensorer:

python
tensor_2d = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(f"Omformad tensor: {tensor_2d.view(3, 2)}")

För att omarrangera tensorer används också metoden .T, som transponerar tensorerna – ett viktigt steg när man arbetar med matrismultiplikation:

python
print(tensor_2d.T)

För att kombinera flera tensorer längs en viss dimension kan man använda metoden torch.cat(), som tillåter att sammanfoga olika bitar av data till en enda tensor:

python
tensor = torch.ones(3, 3)
t1 = torch.cat([tensor, tensor], dim=1) print(f"Radvis sammanfogning av två tensorer: {t1}")

Vid arbete med tensorer kan även funktioner som torch.squeeze() och torch.unsqueeze() vara användbara. torch.squeeze() tar bort dimensioner med storleken 1, medan torch.unsqueeze() lägger till en dimension med storleken 1 på en specifik plats.

Matrixmultiplikation är en annan grundläggande operation inom djupinlärning, och i PyTorch gör vi detta antingen med metoden torch.matmul() eller med den enklare "@"-symbolen:

python
print(tensor_2d.matmul(tensor_2d.T))
print(tensor_2d @ tensor_2d.T)

Det är viktigt att komma ihåg att vid matrismultiplikation måste de inre dimensionerna på de två tensorerna matcha – alltså att antalet kolumner i den första tensorn måste vara lika med antalet rader i den andra tensorn.

Det som också är viktigt att notera är att man ofta stöter på problem relaterade till form och datatyper när man bygger djupinlärningsmodeller. Därför är det avgörande att ha en god förståelse för tensorers struktur och vilka operationer som kan utföras på dem. För att lösa sådana problem under utvecklingsfasen är det användbart att ofta inspektera form och datatype för tensorerna, vilket gör det lättare att identifiera eventuella misstag tidigt.

För ytterligare fördjupning rekommenderas att läsa den officiella PyTorch-guiden om tensorer och deras dokumentation för mer detaljerad information om funktioner och användningsområden.

Hur man bedömer effektiviteten hos en poängmodell vid tidig identifiering av aktiva föreningar

Vid rankning eller screening av föreningar, till exempel vid virtuell screening, är ett vanligt mål att prioritera identifiering av de mest relevanta (aktiva) föreningarna så snabbt som möjligt, snarare än att behöva screena hela datamängden. För att uppnå detta använder vi modeller för att ge varje förening ett poäng, där de mest aktiva föreningarna helst hamnar högst upp på rankningslistan. Detta för att underlätta tidig igenkänning av aktiva föreningar, vilket kan påskynda upptäckten av hits.

En central mätmetod för att utvärdera hur väl en metod uppfyller denna tidiga igenkänningsproblem är berikningsfaktorn (EF). EF jämför antalet aktiva föreningar som hittas vid en viss procentandel av de screenade föreningarna med vad som skulle förväntas om föreningarna valdes slumpmässigt. EF beräknas med en formel där resultatet ger en indikator på hur mycket bättre en modell presterar jämfört med en slumpmässig urvalsmetod. Ett EF-värde större än 1 indikerar en bättre än slumpmässig prestation, och ju högre EF-värde, desto bättre koncentreras de aktiva föreningarna högst upp i rankningslistan.

För att förklara, anta att vi har en datamängd med 1 000 föreningar och att 100 av dessa är kända för att vara aktiva (10 % aktiva). Om vår poängmodell identifierar 5 aktiva föreningar i de första 1 % (5 av 10) av rankningen, så skulle EF vid 1 % vara 5, vilket betyder att vår modell är fem gånger mer effektiv än slumpmässig urval i att identifiera aktiva föreningar tidigt.

EF beräknas vid olika procentandelar, ofta vid 0,5 %, 1 %, 2 % och 5 %, beroende på användningsfallet. Om urvalet är helt slumpmässigt skulle EF vara exakt 1 vid varje procentandel. För att få ett mer visuellt perspektiv på modellen kan en berikningsgraf konstrueras, där x-axeln representerar den procentandel av biblioteket som screenats, medan y-axeln representerar andelen aktiva föreningar som hittats. Ju närmare modellens kurva är den optimala berikningslinjen, desto bättre är modellens prestation.

För att förstå berikningsfaktorns effektivitet och relevans är det också viktigt att definiera aktivitetströskeln, i detta fall ett pIC50-värde på 6,3, där föreningar med ett högre värde anses vara aktiva. Detta tröskelvärde kan variera beroende på det specifika fallet, men för EGFR finns det rekommendationer som sträcker sig från 5 till 7.

Det är också viktigt att notera att optimalt berikning representerar det bästa möjliga scenariot där alla aktiva föreningar rankas högst upp i listan. För att räkna ut detta finns två huvudfall att beakta: om det finns fler aktiva föreningar än antalet föreningar i den procentandel som undersöks, kommer EF att begränsas av procenten. Om det finns färre aktiva föreningar än den procentandel som granskas, kommer EF att begränsas av förhållandet mellan totala föreningar och aktiva föreningar.

För att effektivt kunna jämföra olika modeller är det också nödvändigt att förstå hur EF-värdena förändras över olika procentandelar av data. Ett exempel är att om vår modell har ett EF-värde på 1,53 vid 5 %, medan den slumpmässiga urvalsmetoden har ett värde på 1, då innebär det att vi hittar 7,64 % av de aktiva föreningarna i de första 5 % av datamängden. En sådan berikningsanalys gör det möjligt att konkret bedöma och jämföra hur väl olika poängmodeller presterar, och om modellen faktiskt förbättrar identifieringen av aktiva föreningar i jämförelse med en ren slumpmässig urvalsmetod.

En ytterligare aspekt att förstå när man arbetar med berikningsmetoder och deras tillämpning är att dessa tekniker ofta används i samband med större programvaruverktyg och ramverk som PyTorch, som vi kommer att gå in på senare i boken. Det är där dessa matematiska koncept, som berikning, blir applicerbara på riktiga datamängder i form av djupa inlärningsmodeller och maskininlärning. Men innan vi dyker ner i den tekniska aspekten av att bygga och träna modeller, är det avgörande att först förstå den grundläggande teorin och metodiken som gör det möjligt att tillämpa dessa tekniker för att optimera upptäckten av aktiva föreningar.