Prestaties afstemmen en gegevensoptimalisatie voor R

Van toepassing op: SQL Server 2016 (13.x) en latere versies

In dit artikel worden prestatieoptimalisaties besproken voor R- of Python-scripts die worden uitgevoerd in SQL Server. U kunt deze methoden gebruiken om uw R-code bij te werken, zowel om de prestaties te verbeteren als bekende problemen te voorkomen.

Een compute-context kiezen

In SQL Server kunt u de local of SQL compute-context gebruiken bij het uitvoeren van R- of Python script.

Wanneer u de lokale rekencontext gebruikt, wordt een analyse uitgevoerd op uw computer en niet op de server. Als u daarom gegevens ophaalt uit SQL Server die u in uw code wilt gebruiken, moeten de gegevens via het netwerk worden opgehaald. De prestatietreffer die voor deze netwerkoverdracht wordt gemaakt, is afhankelijk van de grootte van de overgedragen gegevens, de snelheid van het netwerk en andere netwerkoverdrachten die tegelijkertijd plaatsvinden.

Wanneer u de SQL Server compute-context gebruikt, wordt de code uitgevoerd op de server. Als u gegevens ophaalt uit SQL Server, moeten de gegevens lokaal zijn voor de server waarop de analyse wordt uitgevoerd en worden er dus geen netwerkoverhead geïntroduceerd. Als u gegevens uit andere bronnen wilt importeren, overweeg dan vooraf ETL te plannen.

Wanneer u met grote gegevenssets werkt, moet u altijd de SQL-rekencontext gebruiken.

Factoren

De R-taal heeft het concept van factoren, die een speciale variabele zijn voor categorische gegevens. Gegevenswetenschappers gebruiken vaak factorvariabelen in hun formule, omdat het afhandelen van categorische variabelen als factoren ervoor zorgt dat de gegevens correct worden verwerkt door machine learning-functies.

Standaard kunnen factorvariabelen worden geconverteerd van tekenreeksen naar gehele getallen en weer terug voor opslag of verwerking. De functie R data.frame verwerkt alle tekenreeksen als factorvariabelen, tenzij de argumenttekenreeksenAsFactors is ingesteld op False. Dit betekent dat tekenreeksen automatisch worden geconverteerd naar een geheel getal voor verwerking en vervolgens worden toegewezen aan de oorspronkelijke tekenreeks.

Als de brongegevens voor factoren worden opgeslagen als een geheel getal, kunnen de prestaties lijden, omdat R de factor gehele getallen tijdens runtime converteert naar tekenreeksen en vervolgens een eigen interne conversie van tekenreeks naar geheel getal uitvoert.

Als u dergelijke runtimeconversies wilt voorkomen, kunt u de waarden opslaan als gehele getallen in de SQL Server tabel en het argument colInfo gebruiken om de niveaus op te geven voor de kolom die als factor wordt gebruikt. De meeste gegevensbronobjecten in RevoScaleR nemen de parameter colInfo. U gebruikt deze parameter om de variabelen die door de gegevensbron worden gebruikt een naam te geven, het type op te geven en de variabelenniveaus of transformaties voor de kolomwaarden te definiëren.

Met de volgende R-functieaanroep worden bijvoorbeeld de gehele getallen 1, 2 en 3 uit een tabel opgehaald, maar worden de waarden toegewezen aan een factor met de niveaus 'appel', 'oranje' en 'banaan'.

c("fruit" = c(type = "factor", levels=as.character(c(1:3)), newLevels=c("apple", "orange", "banana")))

Wanneer de bronkolom tekenreeksen bevat, is het altijd efficiënter om de niveaus van tevoren op te geven met behulp van de parameter colInfo . De volgende R-code behandelt de tekenreeksen bijvoorbeeld als factoren terwijl ze worden gelezen.

c("fruit" = c(type = "factor", levels= c("apple", "orange", "banana")))

Als er geen semantisch verschil is in het genereren van het model, kan de laatste benadering leiden tot betere prestaties.

Gegevenstransformaties

Gegevenswetenschappers gebruiken vaak transformatiefuncties die in R zijn geschreven als onderdeel van de analyse. De transformatiefunctie wordt toegepast op elke rij die uit de tabel is opgehaald. In SQL Server worden dergelijke transformaties toegepast op alle rijen die in een batch zijn opgehaald. Hiervoor is communicatie tussen de R-interpreter en de analyse-engine vereist. Als u de transformatie wilt uitvoeren, worden de gegevens verplaatst van SQL naar de analyse-engine en vervolgens naar het R-interpreterproces en terug.

Daarom kan het gebruik van transformaties als onderdeel van uw R-code een aanzienlijk nadelig effect hebben op de prestaties van het algoritme, afhankelijk van de hoeveelheid betrokken gegevens.

Het is efficiënter om alle benodigde kolommen in de tabel of weergave te hebben voordat u een analyse uitvoert en transformaties tijdens de berekening te voorkomen. Als het niet mogelijk is om extra kolommen toe te voegen aan bestaande tabellen, kunt u een andere tabel of weergave maken met de getransformeerde kolommen en een geschikte query gebruiken om de gegevens op te halen.

Leesbewerkingen in batchrijen

Als u een SQL Server gegevensbron (RxSqlServerData) in uw code gebruikt, raden we u aan om de parameter rowsPerRead te gebruiken om de batchgrootte op te geven. Deze parameter definieert het aantal rijen waarop een query wordt uitgevoerd en vervolgens naar het externe script wordt verzonden voor verwerking. Tijdens de uitvoering ziet het algoritme alleen het opgegeven aantal rijen in elke batch.

De mogelijkheid om de hoeveelheid gegevens te beheren die tegelijk wordt verwerkt, kan u helpen bij het oplossen of voorkomen van problemen. Als uw invoergegevensset bijvoorbeeld zeer breed is (veel kolommen bevat) of als de gegevensset een paar grote kolommen (zoals vrije tekst) heeft, kunt u de batchgrootte verkleinen om te voorkomen dat gegevens uit het geheugen worden gepaged.

Standaard is de waarde van deze parameter ingesteld op 50000, om goede prestaties te garanderen, zelfs op computers met weinig geheugen. Als de server voldoende geheugen heeft, kan het verhogen van deze waarde tot 500.000 of zelfs een miljoen betere prestaties opleveren, met name voor grote tabellen.

De voordelen van het vergroten van de batchgrootte worden zichtbaar in een grote gegevensset en in een taak die kan worden uitgevoerd op meerdere processen. Het verhogen van deze waarde levert echter niet altijd de beste resultaten op. U wordt aangeraden te experimenteren met uw gegevens en algoritme om de optimale waarde te bepalen.

Parallelle verwerking

Als u de prestaties van rx analysefuncties wilt verbeteren, kunt u gebruikmaken van de mogelijkheid van SQL Server om taken parallel uit te voeren met behulp van beschikbare kernen op de servercomputer.

Er zijn twee manieren om parallellisatie met R in SQL Server te bereiken:

  • Gebruik @parallel. Wanneer u de sp_execute_external_script opgeslagen procedure gebruikt om een R-script uit te voeren, stelt u de @parallel parameter in op 1. Dit is de beste methode als uw R-script geen RevoScaleR-functies gebruikt, met andere mechanismen voor verwerking. Als uw script gebruikmaakt van RevoScaleR-functies (meestal voorafgegaan door 'rx'), wordt parallelle verwerking automatisch uitgevoerd en hoeft u niet expliciet in te stellen @parallel op 1.

    Als het R-script kan worden geparallelliseerd en als de SQL-query kan worden geparallelliseerd, maakt de database-engine meerdere parallelle processen. Het maximum aantal processen dat kan worden gemaakt, is gelijk aan de maximale mate van parallelle uitvoering (MAXDOP) voor het exemplaar. Alle processen voeren vervolgens hetzelfde script uit, maar ontvangen slechts een deel van de gegevens.

    Deze methode is dus niet nuttig voor scripts die alle gegevens moeten zien, zoals bij het trainen van een model. Het is echter handig bij het parallel uitvoeren van taken zoals batchvoorspelling. Voor meer informatie over het gebruik van parallelle uitvoering met sp_execute_external_script, zie de sectie Geavanceerde tips: parallelle verwerking van Using R Code in Transact-SQL.

  • Gebruik numTasks =1. Wanneer u rx-functies gebruikt in een SQL Server rekencontext, stelt u de waarde van de parameter numTasks in op het aantal processen dat u wilt maken. Het aantal gemaakte processen kan nooit meer zijn dan MAXDOP; het werkelijke aantal gemaakte processen wordt echter bepaald door de database-engine en kan kleiner zijn dan u hebt aangevraagd.

    Als het R-script kan worden geparallelliseerd en als de SQL-query kan worden geparallelliseerd, SQL Server meerdere parallelle processen maakt bij het uitvoeren van de rx-functies. Het werkelijke aantal processen dat wordt gemaakt, is afhankelijk van verschillende factoren. Dit zijn onder andere resourcebeheer, huidig gebruik van resources, andere sessies en het queryuitvoeringsplan voor de query die wordt gebruikt met het R-script.

Query-parallelisatie

In Microsoft R kunt u met SQL Server gegevensbronnen werken door uw gegevens te definiëren als een RxSqlServerData-gegevensbronobject.

Hiermee maakt u een gegevensbron op basis van een hele tabel of weergave:

RxSqlServerData(table= "airline", connectionString = sqlConnString)

Hiermee maakt u een gegevensbron op basis van een SQL-query:

RxSqlServerData(sqlQuery= "SELECT [ArrDelay],[CRSDepTime],[DayOfWeek] FROM  airlineWithIndex WHERE rowNum <= 100000", connectionString = sqlConnString)

Note

Als een tabel is opgegeven in de gegevensbron in plaats van een query, gebruikt R Services interne heuristieken om de benodigde kolommen te bepalen die uit de tabel moeten worden opgehaald; Deze aanpak leidt echter waarschijnlijk niet tot parallelle uitvoering.

Om ervoor te zorgen dat de gegevens parallel kunnen worden geanalyseerd, moet de query die wordt gebruikt om de gegevens op te halen zodanig worden ingekaderd dat de database-engine een parallel queryplan kan maken. Als de code of het algoritme grote hoeveelheden gegevens gebruikt, moet u ervoor zorgen dat de opgegeven RxSqlServerData query is geoptimaliseerd voor parallelle uitvoering. Een query die niet resulteert in een parallel uitvoeringsplan, kan leiden tot één proces voor berekening.

Als u met grote gegevenssets moet werken, gebruikt u Management Studio of een andere SQL-queryanalyse voordat u uw R-code uitvoert, om het uitvoeringsplan te analyseren. Voer vervolgens aanbevolen stappen uit om de prestaties van de query te verbeteren. Een ontbrekende index in een tabel kan bijvoorbeeld van invloed zijn op de tijd die nodig is om een query uit te voeren. Zie Bewaken en afstemmen op prestatiesvoor meer informatie.

Een andere veelvoorkomende fout die van invloed kan zijn op de prestaties, is dat een query meer kolommen ophaalt dan vereist is. Als een formule bijvoorbeeld is gebaseerd op slechts drie kolommen, maar uw brontabel 30 kolommen bevat, verplaatst u gegevens onnodig.

  • Vermijd het gebruik van SELECT *!
  • Neem even de tijd om de kolommen in de gegevensset te bekijken en alleen de kolommen te identificeren die nodig zijn voor analyse
  • Verwijder uit uw query's kolommen die gegevenstypen bevatten die niet compatibel zijn met R-code, zoals GUIDS en rowguids
  • Controleren op niet-ondersteunde datum- en tijdformaten
  • In plaats van een tabel te laden, maakt u een weergave die bepaalde waarden selecteert of kolommen cast om conversiefouten te voorkomen

Het machine learning-algoritme optimaliseren

Deze sectie bevat diverse tips en resources die specifiek zijn voor RevoScaleR en andere opties in Microsoft R.

Tip

Een algemene bespreking van R-optimalisatie valt buiten het bereik van dit artikel. Als u uw code echter sneller wilt maken, raden we het populaire artikel The R Inferno aan. Het behandelt programmeerconstructies in R en veelvoorkomende valkuilen in levendige taal en detail, en biedt veel specifieke voorbeelden van R-programmeertechnieken.

Optimalisaties voor RevoScaleR

Veel RevoScaleR-algoritmen ondersteunen parameters om te bepalen hoe het getrainde model wordt gegenereerd. Hoewel de nauwkeurigheid en juistheid van het model belangrijk zijn, zijn de prestaties van het algoritme mogelijk even belangrijk. Om de juiste balans te krijgen tussen nauwkeurigheid en trainingstijd, kunt u parameters wijzigen om de snelheid van de berekening te verhogen en in veel gevallen de prestaties te verbeteren zonder de nauwkeurigheid of juistheid te verminderen.

  • rxDTree

    rxDTree ondersteunt de maxDepth parameter, waarmee de diepte van de beslissingsstructuur wordt bepaald. Naarmate maxDepth toeneemt, kunnen de prestaties afnemen. Daarom is het belangrijk om de voordelen van het vergroten van de diepte tegen het mogelijke verlies aan prestaties af te wegen.

    U kunt ook de balans tussen tijdcomplexiteit en voorspellingsnauwkeurigheid regelen door parameters zoals maxNumBins, maxDepth, maxCompleteen maxSurrogate. Het verhogen van de diepte tot meer dan 10 of 15 kan de berekening erg duur maken.

  • rxLinMod

    Gebruik het cube argument als de eerste afhankelijke variabele in de formule een factorvariabele is.

    Wanneer cube is ingesteld op TRUE, wordt de regressie uitgevoerd met behulp van een gepartitioneerde inverse, wat sneller kan zijn en minder geheugen kan gebruiken dan standaard regressieberekening. Als de formule een groot aantal variabelen heeft, kan de prestatiewinst aanzienlijk zijn.

  • rxLogit

    Gebruik het cube argument als de eerste afhankelijke variabele een factorvariabele is.

    Wanneer cube is ingesteld op TRUE, maakt het algoritme gebruik van een gepartitioneerde inverse, wat mogelijk sneller is en minder geheugen gebruikt. Als de formule een groot aantal variabelen heeft, kan de prestatiewinst aanzienlijk zijn.

Zie de volgende artikelen voor meer informatie over optimalisatie van RevoScaleR:

MicrosoftML gebruiken

We raden u ook aan om naar het nieuwe MicrosoftML-pakket te kijken, dat schaalbare machine learning-algoritmen biedt die de rekencontexten en transformaties van RevoScaleR kunnen gebruiken.

Volgende stappen