PySpark Opetusohjelma aloittelijoille: Opi ESIMERKKEJÄ

⚡ Älykäs yhteenveto

PySpark on Python API Apachelle Spark, jonka avulla analyytikot voivat suorittaa hajautettua tiedonkäsittelyä, SQL-kyselyitä ja koneoppimista klustereissa. Tämä ohje asentaa sen, selittää SparkContext ja SQLContext muodostavat sitten logistisen regressioluokittimen.

  • 🔘 Moottorin perusasiat: Spark aikatauluttaa, jakaa ja valvoo työtä työkoneiden klusterissa, keeping laskenta muistissa.
  • ☑️ Python silta: PySpark altistaa RDD:t, DataFramet ja MLlibin Python, joten panda-käyttäjät skaalautuvat yhden koneen rajojen ulkopuolelle.
  • ✅ Kaksi asennuspolkua: Docker-kuva AWS-instanssissa tai erillinen Conda-ympäristö Windows ja Mac.
  • 🧪 Sisäänpääsypisteet: SparkKonteksti avaa klusteriyhteyden; SQLContext (SparkSession (nykyaikaisissa versioissa) luo tiedostoista DataFrame-kehyksiä.
  • 🛠️ Putken API: StringIndexer-, OneHotEncoder- ja VectorAssembler-vaiheet kokoavat ominaisuuksia täsmälleen samalla tavalla kuin scikit-learn-putket.
  • 📊 Virityksen hyöty: Regularisointiparametrin ristiinvalidointi nostaa aikuisille tarkoitetun tietojoukon luokittelijan tarkkuuden 82.376 prosentista 85.316 prosenttiin.

PySpark Opetusohjelma aloittelijoille

Ennen kuin opit PySpark, ymmärretään:

Mikä on Apache Spark?

Spark on big data -ratkaisu, joka on osoittautunut helpommaksi ja nopeammaksi kuin Hadoop MapReduce. Spark on avoimen lähdekoodin ohjelmisto, jonka UC Berkeley RAD lab on kehittänyt vuonna 2009. Siitä lähtien, kun se julkaistiin yleisölle vuonna 2010, Spark on kasvattanut suosiotaan ja sitä käytetään alalla ennennäkemättömässä mittakaavassa.

Big datan aikakaudella ammattilaiset tarvitsevat enemmän kuin koskaan nopeita ja luotettavia työkaluja datan suoratoiston käsittelyyn. Aiemmat työkalut, kuten MapReduce, olivat suosittuja, mutta hitaita. Tämän ongelman ratkaisemiseksi Spark tarjoaa ratkaisun, joka on sekä nopea että yleiskäyttöinen. Tärkein ero Spark ja MapReduce on se Spark suorittaa laskelmia muistissa myöhemmin kiintolevyllä. Se mahdollistaa nopean käytön ja tietojenkäsittelyn, mikä lyhentää aikaa tunneista minuutteihin.

Mikä on PySpark?

PySpark on Apachen luoma työkalu Spark Yhteisön käyttöön Python Spark. Se mahdollistaa työskentelyn RDD:n (Resilient Distributed Dataset) kanssa Python. Se tarjoaa myös PySpark Shell linkkiin Python Sovellusliittymät Spark ydin aloittaa Spark Asiayhteys. Spark on klusterilaskentaa toteuttava nimimoottori, kun taas PySpark is Pythonkirjaston käytettäväksi Spark.

Kirjasto toimittaa nimellä pyspark paketti PyPI:ssä, joten yksittäinen pip install pyspark vetää sisään Scala/JVM-moottorin sekä Py4J-sillan, joka mahdollistaa Python objektit kutsuvat sitä. Kaikki alla oleva rakentuu tuon yhden paketin päälle.

Kuinka Spark toimii?

Spark perustuu laskennalliseen moottoriin, mikä tarkoittaa, että se huolehtii sovelluksen aikataulutuksesta, jakelusta ja valvonnasta. Jokainen tehtävä suoritetaan useiden työkoneiden kesken, joita kutsutaan laskentaklusteriksi. Laskentaklusteri viittaa tehtävien jakoon. Yksi kone suorittaa yhden tehtävän, kun taas muut osallistuvat lopulliseen tuotokseen toisen tehtävän kautta. Lopulta kaikki tehtävät yhdistetään tuotoksen tuottamiseksi. The Spark admin antaa 360 asteen yleiskatsauksen erilaisista Spark Jobs.

Alla oleva kaavio näyttää, kuinka ajuriohjelma siirtää työn klusterin muodostaville työkoneille.

Spark laskentaklusteri, joka näyttää kuljettajan aikatauluttavat tehtävät työntekijöiden koneissa

Miten Spark Työskentele

Spark on suunniteltu toimimaan yhdessä

  • Python
  • Java
  • Scala
  • SQL

Merkittävä ominaisuus Spark on valtava määrä sisäänrakennettua kirjastoa, mukaan lukien MLlib koneoppimista varten. Spark on myös suunniteltu toimimaan Hadoop-klusterien kanssa ja pystyy lukemaan laajan tyyppisiä tiedostoja, kuten Hive-dataa, CSV:tä, JSON:ia, Cassandra muun muassa tietoja.

Miksi käyttää Spark?

Tulevana data-alan ammattilaisena sinun tulisi olla perehtynyt Pythonkuuluisat kirjastot: Pandat ja scikit opittavaNämä kaksi kirjastoa ovat loistavia jopa keskikokoisten tietojoukkojen tutkimiseen. Tavalliset koneoppimisprojektit rakennetaan seuraavan metodologian ympärille:

  • Lataa tiedot levylle
  • Tuo tiedot koneen muistiin
  • Käsittele/analysoi tiedot
  • Rakenna koneoppimismalli
  • Tallenna ennuste takaisin levylle

Ongelma syntyy, jos datatieteilijä haluaa käsitellä dataa, joka on liian suurta yhdelle tietokoneelle. Datatieteen aiempina aikoina ammattilaiset ottivat näytteitä, koska koulutusta valtavien datajoukkojen kanssa ei aina tarvittu. Datatieteilijä löysi hyvän tilastollisen otoksen, suoritti ylimääräisen luotettavuustarkistuksen ja kehitti erinomaisen mallin.

Tässä on kuitenkin joitain ongelmia:

  • Kuvaako tietojoukko todellista maailmaa?
  • Sisältääkö data konkreettisen esimerkin?
  • Sopiiko malli näytteenottoon?

Otetaan esimerkiksi käyttäjien suositus. Suosittelijat luottavat siihen, että he vertaavat käyttäjiä muihin käyttäjiin arvioidessaan heidän mieltymyksiään. Jos tietojenkäsittelyn asiantuntija ottaa vain osan tiedoista, ei ole olemassa joukkoa käyttäjiä, jotka ovat hyvin samankaltaisia ​​keskenään. Suosittelijat on suoritettava koko tietojoukossa tai ei ollenkaan.

Mikä on ratkaisu?

Ratkaisu on ollut ilmeinen jo pitkään, jakaa ongelma useisiin tietokoneisiin. Rinnakkaislaskentaan liittyy myös useita ongelmia. Kehittäjillä on usein vaikeuksia kirjoittaa rinnakkaiskoodia, ja heidän on lopulta ratkaistava joukko monimutkaisia ​​​​ongelmia, jotka liittyvät itse monikäsittelyyn.

PySpark antaa datatieteilijälle API:n, jota voidaan käyttää rinnakkaisten datankäsittelyongelmien ratkaisemiseen. PySpark käsittelee moniprosessoinnin monimutkaisuuden, kuten datan jakelun, koodin jakelun ja tulosteen keräämisen työntekijöiltä koneklusterissa.

Spark voi suorittaa itsenäisesti, mutta useimmiten se toimii klusterilaskentakehyksen, kuten Hadoopin, päällä. Testauksessa ja kehityksessä datatieteilijä voi kuitenkin ajaa tehokkaasti Spark kehityslaatikoissaan tai kannettavissa tietokoneissaan ilman klusteria

  • Yksi Spark on rakentaa arkkitehtuuri, joka sisältää tiedon suoratoiston hallinnan, saumattomasti datakyselyt, koneoppimisen ennustamisen ja reaaliaikaisen pääsyn erilaisiin analyyseihin.
  • Spark tekee tiivistä yhteistyötä SQL kieli eli strukturoitu data. Se mahdollistaa datan kyselyn reaaliajassa.
  • Datatieteilijän päätehtävänä on analysoida ja rakentaa ennustavia malleja. Lyhyesti sanottuna datatieteilijän on tiedettävä, miten dataa voidaan kyselyidä SQL:n avulla, miten voidaan tuottaa tilastollinen raportti ja miten koneoppimista hyödynnetään ennusteiden tuottamiseen. Datatieteilijä käyttää merkittävän osan ajastaan ​​datan puhdistamiseen, muuntamiseen ja analysointiin. Kun aineisto tai datan työnkulku on valmis, datatieteilijä käyttää erilaisia ​​tekniikoita löytääkseen oivalluksia ja piileviä malleja. Datan manipuloinnin tulee olla sekä vankkaa että helppokäyttöistä. Spark on oikea työkalu nopeudensa ja monipuolisten API-liittymiensä ansiosta.

Tässä PySpark opetusohjelmassa opit rakentamaan luokitin Py:lläSpark esimerkkejä.

Kuinka asentaa PySpark AWS: n kanssa

Jupyter tiimi rakentaa Docker-imagin käytettäväksi Spark tehokkaasti. Alla on vaiheet, joita voit seurata Py:n asentamisessaSpark esimerkiksi AWS:ssä.

Katso opetusohjelmamme AWS ja TensorFlow

Vaihe 1: Luo ilmentymä

Ensinnäkin sinun on luotava ilmentymä. Siirry AWS-tilillesi ja käynnistä ilmentymä. Voit kasvattaa tallennustilaa 15 grammaan ja käyttää samaa suojausryhmää kuin TensorFlow-opetusohjelmassa.

Vaihe 2: Avaa yhteys

Avaa liitäntä ja asenna telakointisäiliö. Katso lisätietoja TensorFlow with -oppaasta Satamatyöläinen. Huomaa, että sinun on oltava oikeassa työhakemistossa.

Asenna Docker suorittamalla nämä koodit:

sudo yum update -y
sudo yum install -y docker
sudo service docker start
sudo user-mod -a -G docker ec2-user
exit

Vaihe 3: Avaa yhteys uudelleen ja asenna Spark

Kun avaat yhteyden uudelleen, voit asentaa Py:n sisältävän kuvanSpark.

## Spark
docker run -v ~/work:/home/jovyan/work -d -p 8888:8888 jupyter/pyspark-notebook

## Allow preserving Jupyter notebook
sudo chown 1000 ~/work

## Install tree to see our working directory next
sudo yum install -y tree

Vaihe 4: Avoin Jupyter

Tarkista säiliö ja sen nimi

docker ps

Käynnistä telakointiasema telakointilokeilla, joita seuraa telakointiaseman nimi. Esimerkiksi docker kirjaa zealous_goldwasser

Mene selaimeesi ja käynnistä Jupyter. Osoite on http://localhost:8888/. Liitä päätteen antama salasana.

Huomautus: Jos haluat ladata tiedoston AWS-koneellesi, voit käyttää ohjelmistoa Cyberduck.

Kuinka asentaa PySpark on Windows/Mac ja Conda

Seuraavassa on yksityiskohtainen prosessi Py:n asentamisestaSpark on Windows/Mac ja Anaconda:

Voit asentaa Spark Suositeltava käytäntö on luoda uusi conda-ympäristö paikallisella koneellasi. Tämä uusi ympäristö asennetaan Python 3.6, Spark ja kaikki riippuvuudet.

Mac-käyttäjä

cd anaconda3
touch hello-spark.yml
vi hello-spark.yml

Windows käyttäjä

cd C:\Users\Admin\Anaconda3
echo.>hello-spark.yml
notepad hello-spark.yml

Voit muokata .yml-tiedostoa. Ole varovainen sisennyksen kanssa. Kaksi välilyöntiä vaaditaan ennen -

name: hello-spark 
    dependencies:
    
    - python=3.6
    - jupyter
    - ipython
    - numpy
    - numpy-base
    - pandas
    - py4j
    - pyspark
    - pytz

Tallenna se ja luo ympäristö. Se kestää jonkin aikaa

conda env create -f hello-spark.yml

Lisätietoja sijainnista on TensorFlow-asennusohjeessa

Voit tarkistaa kaiken koneellesi asennetun ympäristön

conda env list
Activate hello-spark

Mac-käyttäjä

source activate hello-spark

Windows käyttäjä

activate hello-spark

Huomautus: Olet jo luonut erityisen TensorFlow-ympäristön TensorFlow'n opetusohjelmien suorittamista varten. On kätevämpää luoda uusi ympäristö, joka poikkeaa hello-tf:stä. Ei ole mitään järkeä ylikuormittaa hello-tf:llä Spark tai muita koneoppimiskirjastoja.

Kuvittele, että suurin osa projektistasi sisältää TensorFlow'n, mutta sinun on käytettävä sitä Spark yhdelle tietylle projektille. Voit asettaa TensorFlow-ympäristön kaikille projekteillesi ja luoda erillisen ympäristön Spark. Voit lisätä niin monta kirjastoa Spark ympäristöön haluamallasi tavalla ilman, että se häiritsee TensorFlow-ympäristöä. Kun olet valmis Spark-projektissa, voit poistaa sen vaikuttamatta TensorFlow-ympäristöön.

Jupyter

avoin Jupyter Muistikirja ja kokeile, jos PySpark toimii. Liitä uuteen muistikirjaan seuraava PySpark mallikoodi:

import pyspark
from pyspark import SparkContext
sc =SparkContext()

Onnistunut ajo ei tulosta lainkaan tulosta, kuten alla oleva muistikirjan kuvakaappaus osoittaa.

Jupyter Notebook-solun tuonti pysparkiin ja luonti SparkKontekstiobjekti

Jos virheilmoitus näytetään, se on todennäköistä Java ei ole asennettu koneellesi. Macissa avaa pääte ja kirjoita java -versio, jos on java-versio, varmista että se on 1.8. sisään Windows, siirry Sovellukseen ja tarkista, onko siellä a Java kansio. Jos on a Java kansio, tarkista se Java 1.8 on asennettuna. Tämän kirjoitushetkellä PySpark ei ole yhteensopiva Java 9 ja edellä.

Versiohuomautus: että Java 8 rajoitus koskee Spark 2.x-riviä käytetään koko tässä läpikäynnissä. Nykyinen Spark 3.x- ja 4.x-versiot toimivat Java 8, 11 ja 17, joten uudempi JDK riittää, jos asennat vastaavan Py:nSpark versio.

Jos sinun on asennettava Java, sinun täytyy ajatella linkkiä ja lataa jdk-8u181-windows-x64.exe

Mac-käyttäjille on suositeltavaa käyttää `brew.`

brew tap caskroom/versions
brew cask install java8

Katso tämä vaihe vaiheelta opetusohjelma miten asentaa Java

Huomautus: Käytä poista-komentoa poistaaksesi ympäristön kokonaan.

 conda env remove -n hello-spark -y

Spark Tausta

SparkKonteksti on sisäinen moottori, joka mahdollistaa yhteydet klusterien kanssa. Jos haluat suorittaa leikkauksen, tarvitset a SparkAsiayhteys.

Luo SparkTausta

Ensinnäkin sinun on aloitettava a SparkAsiayhteys.

import pyspark
from pyspark import SparkContext
sc =SparkContext()

Nyt SparkKonteksti on valmis, voit luoda tietokokoelman nimeltä RDD, Resilient Distributed Dataset. RDD:n laskenta rinnastetaan automaattisesti klusterin poikki.

nums= sc.parallelize([1,2,3,4])

Pääset ensimmäiselle riville take-toiminnolla

nums.take(1)
[1]

Voit käyttää muunnoksia dataan lambda-funktiolla. PySpark alla olevassa esimerkissä palautat numeroiden neliön. Se on karttamuunnos

squared = nums.map(lambda x: x*x).collect()
for num in squared:
    print('%i ' % (num))
1 
4 
9 
16

SQLContext

Kätevämpi tapa on käyttää DataFramea. SparkKonteksti on jo asetettu, voit käyttää sitä DataFramen luomiseen. Sinun on myös määriteltävä SQLContext.

SQLContext mahdollistaa moottorin yhdistämisen eri tietolähteisiin. Sitä käytetään toimintojen käynnistämiseen Spark sql.

Versiohuomautus: SQLContext korvattiin funktiolla SparkIstunto Spark 2.0 ja virallisesti vanhentunut vuonna Spark 3.0. Alla olevissa esimerkeissä säilytetään SQLContext, koska alkuperäinen läpikäynti perustuu siihen; nykyaikaisella klusterilla vastaava aloituskohta on SparkSession.builder.getOrCreate(), joka paljastaa samat read- ja createDataFrame-metodit.

from pyspark.sql import Row
from pyspark.sql import SQLContext

sqlContext = SQLContext(sc)

Nyt tässä Spark oppitunti Python, luodaan luettelo monista. Jokainen monikko sisältää ihmisten nimet ja heidän ikänsä. Tarvitaan neljä vaihetta:

Vaihe 1) Luo luettelo tuplesta tiedoilla

[('John',19),('Smith',29),('Adam',35),('Henry',50)]

Vaihe 2) Rakenna RDD

rdd = sc.parallelize(list_p)

Vaihe 3) Muunna ketjut

rdd.map(lambda x: Row(name=x[0], age=int(x[1])))

Vaihe 4) Luo DataFrame-konteksti

sqlContext.createDataFrame(ppl)
list_p = [('John',19),('Smith',29),('Adam',35),('Henry',50)]
rdd = sc.parallelize(list_p)
ppl = rdd.map(lambda x: Row(name=x[0], age=int(x[1])))
DF_ppl = sqlContext.createDataFrame(ppl)

Jos haluat käyttää kunkin ominaisuuden tyyppiä, voit käyttää printSchema()

DF_ppl.printSchema()
root
 |-- age: long (nullable = true)
 |-- name: string (nullable = true)

Koneoppimisen esimerkki Py:n kanssaSpark

Nyt kun sinulla on lyhyt käsitys Spark ja SQLContext, olet valmis rakentamaan ensimmäisen koneoppimisohjelman.

Seuraavassa on vaiheet koneoppimisohjelman luomiseksi Py:n avullaSpark:

  • Vaihe 1) Perustoiminto Py:lläSpark
  • Vaihe 2) Tietojen esikäsittely
  • Vaihe 3) Rakenna tietojenkäsittelyputki
  • Vaihe 4) Luo luokitin: logistiikka
  • Vaihe 5) Kouluta ja arvioi malli
  • Vaihe 6) Viritä hyperparametri

Tässä PySpark Koneoppimisopas, käytämme aikuisille suunnattua aineistoa. Tämän opetusohjelman tarkoituksena on oppia käyttämään Py:tä.SparkLisätietoja tietojoukosta on tässä opetusohjelmassa.

Huomaa, että tietojoukko ei ole merkittävä ja saatat ajatella, että laskenta kestää kauan. Spark on suunniteltu käsittelemään huomattavaa määrää dataa. Spark:n suorituskyky paranee suhteessa muihin koneoppimiskirjastoihin, kun käsiteltävä tietojoukko kasvaa.

Vaihe 1) Perustoiminto Py:lläSpark

Ensinnäkin sinun on alustettava SQLContext, jota ei ole vielä aloitettu.

#from pyspark.sql import SQLContext
url = "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/adult_data.csv"
from pyspark import SparkFiles
sc.addFile(url)
sqlContext = SQLContext(sc)

sitten voit lukea cvs-tiedoston sqlContext.read.csv:llä. Käytät inferSchemaa, jonka arvo on True Spark arvaamaan automaattisesti tiedon tyypin. Oletuksena se on käännetty False.

df = sqlContext.read.csv(SparkFiles.get("adult_data.csv"), header=True, inferSchema= True)

Katsotaanpa tietotyyppiä

df.printSchema()
root
 |-- age: integer (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: integer (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: integer (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: integer (nullable = true)
 |-- capital_loss: integer (nullable = true)
 |-- hours_week: integer (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)

Näet tiedot näytöllä.

df.show(5, truncate = False)
+---+----------------+------+---------+-------------+------------------+-----------------+-------------+-----+------+------------+------------+----------+--------------+-----+
|age|workclass       |fnlwgt|education|education_num|marital           |occupation       |relationship |race |sex   |capital_gain|capital_loss|hours_week|native_country|label|
+---+----------------+------+---------+-------------+------------------+-----------------+-------------+-----+------+------------+------------+----------+--------------+-----+
|39 |State-gov       |77516 |Bachelors|13           |Never-married     |Adm-clerical     |Not-in-family|White|Male  |2174        |0           |40        |United-States |<=50K|
|50 |Self-emp-not-inc|83311 |Bachelors|13           |Married-civ-spouse|Exec-managerial  |Husband      |White|Male  |0           |0           |13        |United-States |<=50K|
|38 |Private         |215646|HS-grad  |9            |Divorced          |Handlers-cleaners|Not-in-family|White|Male  |0           |0           |40        |United-States |<=50K|
|53 |Private         |234721|11th     |7            |Married-civ-spouse|Handlers-cleaners|Husband      |Black|Male  |0           |0           |40        |United-States |<=50K|
|28 |Private         |338409|Bachelors|13           |Married-civ-spouse|Prof-specialty   |Wife         |Black|Female|0           |0           |40        |Cuba          |<=50K|
+---+----------------+------+---------+-------------+------------------+-----------------+-------------+-----+------+------------+------------+----------+--------------+-----+
only showing top 5 rows

Jos et asettanut inferSchema-arvoksi True, tyypille tapahtuu seuraavaa. Ne kaikki ovat merkkijonossa.

df_string = sqlContext.read.csv(SparkFiles.get("adult.csv"), header=True, inferSchema=  False)
df_string.printSchema()
root
 |-- age: string (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: string (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: string (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: string (nullable = true)
 |-- capital_loss: string (nullable = true)
 |-- hours_week: string (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)

Jos haluat muuntaa jatkuvan muuttujan oikeaan muotoon, voit käyttää sarakkeiden uudelleenlaatimista. Voit käyttää Columnilla kertomaan Spark missä sarakkeessa muunnos suoritetaan.

# Import all from `sql.types`
from pyspark.sql.types import *

# Write a custom function to convert the data type of DataFrame columns
def convertColumn(df, names, newType):
    for name in names: 
        df = df.withColumn(name, df[name].cast(newType))
    return df 
# List of continuous features
CONTI_FEATURES  = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']
# Convert the type
df_string = convertColumn(df_string, CONTI_FEATURES, FloatType())
# Check the dataset
df_string.printSchema()
root
 |-- age: float (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: float (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: float (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: float (nullable = true)
 |-- capital_loss: float (nullable = true)
 |-- hours_week: float (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)

from pyspark.ml.feature import StringIndexer
#stringIndexer = StringIndexer(inputCol="label", outputCol="newlabel")
#model = stringIndexer.fit(df)
#df = model.transform(df)
df.printSchema()

Valitse sarakkeet

Voit valita ja näyttää rivit Select- ja ominaisuuksien nimillä. Alla on valittu ikä ja fnlwgt.

df.select('age','fnlwgt').show(5)
+---+------+
|age|fnlwgt|
+---+------+
| 39| 77516|
| 50| 83311|
| 38|215646|
| 53|234721|
| 28|338409|
+---+------+
only showing top 5 rows

Laske ryhmittäin

Jos haluat laskea esiintymien määrän ryhmittäin, voit ketjuttaa:

  • groupBy()
  • Kreivi()

yhdessä. PySpark alla olevassa esimerkissä lasket rivien lukumäärän koulutustason mukaan.

df.groupBy("education").count().sort("count",ascending=True).show()
+------------+-----+
|   education|count|
+------------+-----+
|   Preschool|   51|
|     1st-4th|  168|
|     5th-6th|  333|
|   Doctorate|  413|
|        12th|  433|
|         9th|  514|
| Prof-school|  576|
|     7th-8th|  646|
|        10th|  933|
|  Assoc-acdm| 1067|
|        11th| 1175|
|   Assoc-voc| 1382|
|     Masters| 1723|
|   Bachelors| 5355|
|Some-college| 7291|
|     HS-grad|10501|
+------------+-----+

Kuvaile tiedot

Saadaksesi yhteenvetotilastot tiedoista, voit käyttää description(). Se laskee:

  • laskea
  • tarkoittaa
  • standardipoikkeama
  • minuuttia
  • max
df.describe().show()
+-------+------------------+-----------+------------------+------------+-----------------+--------+----------------+------------+------------------+------+------------------+----------------+------------------+--------------+-----+
|summary|               age|  workclass|            fnlwgt|   education|    education_num| marital|      occupation|relationship|              race|   sex|      capital_gain|    capital_loss|        hours_week|native_country|label|
+-------+------------------+-----------+------------------+------------+-----------------+--------+----------------+------------+------------------+------+------------------+----------------+------------------+--------------+-----+
|  count|             32561|      32561|             32561|       32561|            32561|   32561|           32561|       32561|             32561| 32561|             32561|           32561|             32561|         32561|32561|
|   mean| 38.58164675532078|       null|189778.36651208502|        null| 10.0806793403151|    null|            null|        null|              null|  null|1077.6488437087312| 87.303829734959|40.437455852092995|          null| null|
| stddev|13.640432553581356|       null|105549.97769702227|        null|2.572720332067397|    null|            null|        null|              null|  null| 7385.292084840354|402.960218649002|12.347428681731838|          null| null|
|    min|                17|          ?|             12285|        10th|                1|Divorced|               ?|     Husband|Amer-Indian-Eskimo|Female|                 0|               0|                 1|             ?|<=50K|
|    max|                90|Without-pay|           1484705|Some-college|               16| Widowed|Transport-moving|        Wife|             White|  Male|             99999|            4356|                99|    Yugoslavia| >50K|
+-------+------------------+-----------+------------------+------------+-----------------+--------+----------------+------------+------------------+------+------------------+----------------+------------------+--------------+-----+

Jos haluat yhteenvetotilaston vain yhdestä sarakkeesta, lisää sarakkeen nimi description() -kohtaan.

df.describe('capital_gain').show()
+-------+------------------+
|summary|      capital_gain|
+-------+------------------+
|  count|             32561|
|   mean|1077.6488437087312|
| stddev| 7385.292084840354|
|    min|                 0|
|    max|             99999|
+-------+------------------+

Ristitaulukkolaskenta

Joskus voi olla mielenkiintoista nähdä kuvaavat tilastot kahden parikohtaisen sarakkeen välillä. Voit esimerkiksi laskea niiden ihmisten määrän, joiden tulot ovat alle tai yli 50 XNUMX koulutustason mukaan. Tätä toimintoa kutsutaan ristitaulukoksi.

df.crosstab('age', 'label').sort("age_label").show()
+---------+-----+----+
|age_label|<=50K|>50K|
+---------+-----+----+
|       17|  395|   0|
|       18|  550|   0|
|       19|  710|   2|
|       20|  753|   0|
|       21|  717|   3|
|       22|  752|  13|
|       23|  865|  12|
|       24|  767|  31|
|       25|  788|  53|
|       26|  722|  63|
|       27|  754|  81|
|       28|  748| 119|
|       29|  679| 134|
|       30|  690| 171|
|       31|  705| 183|
|       32|  639| 189|
|       33|  684| 191|
|       34|  643| 243|
|       35|  659| 217|
|       36|  635| 263|
+---------+-----+----+
only showing top 20 rows

Näet, että kenelläkään ei ole nuorina yli 50 XNUMX tuloja.

Pudota sarake

Sarakkeiden pudottamiseksi on kaksi intuitiivista sovellusliittymää:

  • drop(): Pudota sarake
  • dropna(): Pudota NA:t

Pudotat alle sarakkeen koulutus_num

df.drop('education_num').columns

['age',
 'workclass',
 'fnlwgt',
 'education',
 'marital',
 'occupation',
 'relationship',
 'race',
 'sex',
 'capital_gain',
 'capital_loss',
 'hours_week',
 'native_country',
 'label']

Suodata tiedot

Voit käyttää suodatinta () käyttääksesi kuvaavia tilastoja tietojen osajoukossa. Voit esimerkiksi laskea yli 40-vuotiaiden määrän

df.filter(df.age > 40).count()

13443

Descripttilastot ryhmittäin

Lopuksi voit ryhmitellä tiedot ryhmittäin ja laskea tilastollisia operaatioita, kuten keskiarvoa.

df.groupby('marital').agg({'capital_gain': 'mean'}).show()
+--------------------+------------------+
|             marital| avg(capital_gain)|
+--------------------+------------------+
|           Separated| 535.5687804878049|
|       Never-married|376.58831788823363|
|Married-spouse-ab...| 653.9832535885167|
|            Divorced| 728.4148098131893|
|             Widowed| 571.0715005035247|
|   Married-AF-spouse| 432.6521739130435|
|  Married-civ-spouse|1764.8595085470085|
+--------------------+------------------+

Vaihe 2) Tietojen esikäsittely

Tietojenkäsittely on kriittinen vaihe koneoppimisessa. Kun olet poistanut roskatiedot, saat tärkeitä tietoja.

Tiedät esimerkiksi, että ikä ei ole lineaarinen tulojen funktio. Kun ihmiset ovat nuoria, heidän tulonsa ovat yleensä alle keski-iän. Eläkkeelle siirtymisen jälkeen kotitalous käyttää säästönsä eli tulojen pienenemistä. Voit tallentaa tämän kuvion lisäämällä neliön ikäominaisuuteen

Lisää ikäneliö

Voit lisätä uuden ominaisuuden seuraavasti:

  1. Valitse sarake
  2. Ota muunnos käyttöön ja lisää se DataFrame-kehykseen
from pyspark.sql.functions import *

# 1 Select the column
age_square = df.select(col("age")**2)

# 2 Apply the transformation and add it to the DataFrame
df = df.withColumn("age_square", col("age")**2)

df.printSchema()
root
 |-- age: integer (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: integer (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: integer (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: integer (nullable = true)
 |-- capital_loss: integer (nullable = true)
 |-- hours_week: integer (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)
 |-- age_square: double (nullable = true)

Voit nähdä, että age_square on lisätty tietokehykseen onnistuneesti. Voit muuttaa muuttujien järjestystä select-painikkeella. Alla tuot ikäneliön heti iän jälkeen.

COLUMNS = ['age', 'age_square', 'workclass', 'fnlwgt', 'education', 'education_num', 'marital',
           'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
           'hours_week', 'native_country', 'label']
df = df.select(COLUMNS)
df.first()
Row(age=39, age_square=1521.0, workclass='State-gov', fnlwgt=77516, education='Bachelors', education_num=13, marital='Never-married', occupation='Adm-clerical', relationship='Not-in-family', race='White', sex='Male', capital_gain=2174, capital_loss=0, hours_week=40, native_country='United-States', label='<=50K')

Sulje pois Holand-Alankomaat

Kun piirteen ryhmällä on vain yksi havainto, se ei tuo malliin tietoja. Päinvastoin, se voi johtaa virheeseen ristiinvalidoinnin aikana.

Tarkastellaan kotitalouden alkuperää

df.filter(df.native_country == 'Holand-Netherlands').count()
df.groupby('native_country').agg({'native_country': 'count'}).sort(asc("count(native_country)")).show()
+--------------------+---------------------+
|      native_country|count(native_country)|
+--------------------+---------------------+
|  Holand-Netherlands|                    1|
|            Scotland|                   12|
|             Hungary|                   13|
|            Honduras|                   13|
|Outlying-US(Guam-...|                   14|
|          Yugoslavia|                   16|
|            Thailand|                   18|
|                Laos|                   18|
|            Cambodia|                   19|
|     Trinadad&Tobago|                   19|
|                Hong|                   20|
|             Ireland|                   24|
|             Ecuador|                   28|
|              Greece|                   29|
|              France|                   29|
|                Peru|                   31|
|           Nicaragua|                   34|
|            Portugal|                   37|
|                Iran|                   43|
|               Haiti|                   44|
+--------------------+---------------------+
only showing top 20 rows

Ominaisuus native_country on vain yksi kotitalous, joka tulee Hollannista. Suljet sen pois.

df_remove = df.filter(df.native_country !=	'Holand-Netherlands')

Vaihe 3) Rakenna tietojenkäsittelyputki

Samanlainen kuin scikit-learn, PySpark sisältää putkilinjan API:n.

Liukuputki on erittäin kätevä ylläpitää tietojen rakennetta. Työnnät tiedot putkiin. Liukulinjan sisällä tehdään erilaisia ​​​​toimintoja, lähtöä käytetään algoritmin syöttämiseen.

Esimerkiksi yksi koneoppimisen universaali muunnos koostuu merkkijonon muuntamisesta yhdeksi hot-encoderiksi eli yhdeksi sarakkeeksi ryhmässä. Yksi kuuma enkooderi on yleensä matriisi, joka on täynnä nollia.

Tietojen muuntamisen vaiheet ovat hyvin samanlaisia ​​kuin scikit-learn. Sinun täytyy:

  • Indeksoi merkkijono numeerisiksi
  • Luo yksi kuuma enkooderi
  • Muunna tiedot

Kaksi API:ta hoitaa työn: StringIndexer, OneHotEncoder

  1. Ensinnäkin valitset merkkijonosarakkeen indeksoitavaksi. InputCol on tietojoukon sarakkeen nimi. outputCol on muunnetulle sarakkeelle annettu uusi nimi.
StringIndexer(inputCol="workclass", outputCol="workclass_encoded")
  1. Sovita tiedot ja muunna se
model = stringIndexer.fit(df)		
`indexed = model.transform(df)``
  1. Luo uutissarakkeet ryhmän perusteella. Jos ominaisuudessa on esimerkiksi 10 ryhmää, uudessa matriisissa on 10 saraketta, yksi jokaiselle ryhmälle.
OneHotEncoder(dropLast=False, inputCol="workclassencoded", outputCol="workclassvec")
### Example encoder
from pyspark.ml.feature import StringIndexer, OneHotEncoder, VectorAssembler

stringIndexer = StringIndexer(inputCol="workclass", outputCol="workclass_encoded")
model = stringIndexer.fit(df)
indexed = model.transform(df)
encoder = OneHotEncoder(dropLast=False, inputCol="workclass_encoded", outputCol="workclass_vec")
encoded = encoder.transform(indexed)
encoded.show(2)
+---+----------+----------------+------+---------+-------------+------------------+---------------+-------------+-----+----+------------+------------+----------+--------------+-----+-----------------+-------------+
|age|age_square|       workclass|fnlwgt|education|education_num|           marital|     occupation| relationship| race| sex|capital_gain|capital_loss|hours_week|native_country|label|workclass_encoded|workclass_vec|
+---+----------+----------------+------+---------+-------------+------------------+---------------+-------------+-----+----+------------+------------+----------+--------------+-----+-----------------+-------------+
| 39|    1521.0|       State-gov| 77516|Bachelors|           13|     Never-married|   Adm-clerical|Not-in-family|White|Male|        2174|           0|        40| United-States|<=50K|              4.0|(9,[4],[1.0])|
| 50|    2500.0|Self-emp-not-inc| 83311|Bachelors|           13|Married-civ-spouse|Exec-managerial|      Husband|White|Male|           0|           0|        13| United-States|<=50K|              1.0|(9,[1],[1.0])|
+---+----------+----------------+------+---------+-------------+------------------+---------------+-------------+-----+----+------------+------------+----------+--------------+-----+-----------------+-------------+
only showing top 2 rows

Rakenna putki

Rakennat liukuhihnan, jonka avulla voit muuntaa kaikki tarkat ominaisuudet ja lisätä ne lopulliseen tietojoukkoon. Putkilinjassa on neljä toimintoa, mutta voit lisätä niin monta toimintoa kuin haluat.

  1. Koodaa kategoriset tiedot
  2. Indeksoi tarraominaisuus
  3. Lisää jatkuva muuttuja
  4. Kokoa portaat.

Jokainen vaihe on tallennettu vaiheiksi nimettyyn luetteloon. Tämä luettelo kertoo VectorAssemblerille, minkä toiminnon sen tulee suorittaa liukuhihnan sisällä.

1. Koodaa kategoriset tiedot

Tämä vaihe on täsmälleen sama kuin yllä oleva esimerkki, paitsi että käyt läpi kaikki kategoriset ominaisuudet.

from pyspark.ml import Pipeline
from pyspark.ml.feature import OneHotEncoderEstimator
CATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']
stages = [] # stages in our Pipeline
for categoricalCol in CATE_FEATURES:
    stringIndexer = StringIndexer(inputCol=categoricalCol, outputCol=categoricalCol + "Index")
    encoder = OneHotEncoderEstimator(inputCols=[stringIndexer.getOutputCol()],
                                     outputCols=[categoricalCol + "classVec"])
    stages += [stringIndexer, encoder]

API-huomautus: OneHotEncoderEstimator yhdistettiin takaisin OneHotEncoderiin vuonna Spark 3.0. Päällä Spark 3.x:ssä tai uudemmassa versiossa tuo OneHotEncoder ja välitä samat inputCols- ja outputCols-argumentit; loput silmukasta pysyvät muuttumattomina.

2. Indeksoi tarraominaisuus

Spark, kuten monet muut kirjastot, ei hyväksy merkkijonoarvoja. Muunnat tarraominaisuuden StringIndexerillä ja lisäät sen listan vaiheisiin

# Convert label into label indices using the StringIndexer
label_stringIdx =  StringIndexer(inputCol="label", outputCol="newlabel")
stages += [label_stringIdx]

3. Lisää jatkuva muuttuja

VectorAssemblerin inputCols on sarakeluettelo. Voit luoda uuden luettelon, joka sisältää kaikki uudet sarakkeet. Alla oleva koodi täyttää luettelon koodatuilla kategorisilla ominaisuuksilla ja jatkuvilla ominaisuuksilla.

assemblerInputs = [c + "classVec" for c in CATE_FEATURES] + CONTI_FEATURES

4. Kokoa askelmat.

Lopuksi suoritat kaikki vaiheet VectorAssemblerissä

assembler = VectorAssembler(inputCols=assemblerInputs, outputCol="features")stages += [assembler]

Nyt kun kaikki vaiheet ovat valmiit, työnnät tiedot liukuhihnaan.

# Create a Pipeline.
pipeline = Pipeline(stages=stages)
pipelineModel = pipeline.fit(df_remove)
model = pipelineModel.transform(df_remove)

Jos tarkistat uuden tietojoukon, näet, että se sisältää kaikki ominaisuudet muunnetuina ja muuntamattomina. Olet kiinnostunut vain uudesta etiketistä ja ominaisuuksista. Ominaisuudet sisältävät kaikki muunnetut ominaisuudet ja jatkuvat muuttujat.

model.take(1)

[Row(age=39, age_square=1521.0, workclass='State-gov', fnlwgt=77516, education='Bachelors', education_num=13, marital='Never-married', occupation='Adm-clerical', relationship='Not-in-family', race='White', sex='Male', capital_gain=2174, capital_loss=0, hours_week=40, native_country='United-States', label='<=50K', workclassIndex=4.0, workclassclassVec=SparseVector(8, {4: 1.0}), educationIndex=2.0, educationclassVec=SparseVector(15, {2: 1.0}), maritalIndex=1.0, maritalclassVec=SparseVector(6, {1: 1.0}), occupationIndex=3.0, occupationclassVec=SparseVector(14, {3: 1.0}), relationshipIndex=1.0, relationshipclassVec=SparseVector(5, {1: 1.0}), raceIndex=0.0, raceclassVec=SparseVector(4, {0: 1.0}), sexIndex=0.0, sexclassVec=SparseVector(1, {0: 1.0}), native_countryIndex=0.0, native_countryclassVec=SparseVector(40, {0: 1.0}), newlabel=0.0, features=SparseVector(99, {4: 1.0, 10: 1.0, 24: 1.0, 32: 1.0, 44: 1.0, 48: 1.0, 52: 1.0, 53: 1.0, 93: 39.0, 94: 77516.0, 95: 2174.0, 96: 13.0, 98: 40.0}))]

Vaihe 4) Luo luokitin: logistiikka

Laskennan nopeuttamiseksi muunnat mallin DataFrame-kehykseksi.

Sinun on valittava mallista uusi tarra ja ominaisuudet kartan avulla.

from pyspark.ml.linalg import DenseVector
input_data = model.rdd.map(lambda x: (x["newlabel"], DenseVector(x["features"])))

Olet valmis luomaan junatiedot DataFrame-kehyksenä. Käytät sqlContextia

df_train = sqlContext.createDataFrame(input_data, ["label", "features"])

Tarkista toinen rivi

df_train.show(2)
+-----+--------------------+
|label|            features|
+-----+--------------------+
|  0.0|[0.0,0.0,0.0,0.0,...|
|  0.0|[0.0,1.0,0.0,0.0,...|
+-----+--------------------+
only showing top 2 rows

Luo juna/testisarja

Jaat tietojoukon 80/20 randomSplitillä.

# Split the data into train and test sets
train_data, test_data = df_train.randomSplit([.8,.2],seed=1234)

Lasketaan kuinka monella on alle/yli 50k tulot sekä harjoittelussa että kokeessa

train_data.groupby('label').agg({'label': 'count'}).show()
+-----+------------+
|label|count(label)|
+-----+------------+
|  0.0|       19698|
|  1.0|        6263|
+-----+------------+
test_data.groupby('label').agg({'label': 'count'}).show()
+-----+------------+
|label|count(label)|
+-----+------------+
|  0.0|        5021|
|  1.0|        1578|
+-----+------------+

Rakenna logistinen regressori

Viimeisenä muttei vähäisimpänä, voit rakentaa luokittelijan. PySpark sisältää LogisticRegression-nimisen API:n logistisen regression suorittamiseen.

Alustat lr:n ilmoittamalla nimisarakkeen ja ominaisuussarakkeet. Asetat enintään 10 iteraatiota ja lisäät regularisointiparametrin, jonka arvo on 0.3. Huomaa, että seuraavassa osiossa käytät ristiinvalidointia parametriruudukon kanssa mallin virittämiseen

# Import `LinearRegression`
from pyspark.ml.classification import LogisticRegression

# Initialize `lr`
lr = LogisticRegression(labelCol="label",
                        featuresCol="features",
                        maxIter=10,
                        regParam=0.3)

# Fit the data to the model
linearModel = lr.fit(train_data)

#Näet kertoimet regressiosta

# Print the coefficients and intercept for logistic regression
print("Coefficients: " + str(linearModel.coefficients))
print("Intercept: " + str(linearModel.intercept))
Coefficients: [-0.0678914665262,-0.153425526813,-0.0706009536407,-0.164057586562,-0.120655298528,0.162922330862,0.149176870438,-0.626836362611,-0.193483661541,-0.0782269980838,0.222667203836,0.399571096381,-0.0222024341804,-0.311925857859,-0.0434497788688,-0.306007744328,-0.41318209688,0.547937504247,-0.395837350854,-0.23166535958,0.618743906733,-0.344088614546,-0.385266881369,0.317324463006,-0.350518889186,-0.201335923138,-0.232878560088,-0.13349278865,-0.119760542498,0.17500602491,-0.0480968101118,0.288484253943,-0.116314616745,0.0524163478063,-0.300952624551,-0.22046421474,-0.16557996579,-0.114676231939,-0.311966431453,-0.344226119233,0.105530129507,0.152243047814,-0.292774545497,0.263628334433,-0.199951374076,-0.30329422583,-0.231087515178,0.418918551,-0.0565930184279,-0.177818073048,-0.0733236680663,-0.267972912252,0.168491215697,-0.12181255723,-0.385648075442,-0.202101794517,0.0469791640782,-0.00842850210625,-0.00373211448629,-0.259296141281,-0.309896554133,-0.168434409756,-0.11048086026,0.0280647963877,-0.204187030092,-0.414392623536,-0.252806580669,0.143366465705,-0.516359222663,-0.435627370849,-0.301949286524,0.0878249035894,-0.210951740965,-0.621417928742,-0.099445190784,-0.232671473401,-0.1077745606,-0.360429419703,-0.420362959052,-0.379729467809,-0.395186242741,0.0826401853838,-0.280251589972,0.187313505214,-0.20295228799,-0.431177064626,0.149759018379,-0.107114299614,-0.319314858424,0.0028450133235,-0.651220387649,-0.327918792207,-0.143659581445,0.00691075160413,8.38517628783e-08,2.18856717378e-05,0.0266701216268,0.000231075966823,0.00893832698698]
Intercept: -1.9884177974805692

Vaihe 5) Kouluta ja arvioi malli

Voit luoda ennusteen testisarjallesi

Voit käyttää lineaarimallia muunnoksen () kanssa test_datassa

# Make predictions on test data using the transform() method.
predictions = linearModel.transform(test_data)

Voit tulostaa elementit ennusteisiin

predictions.printSchema()
root
 |-- label: double (nullable = true)
 |-- features: vector (nullable = true)
 |-- rawPrediction: vector (nullable = true)
 |-- probability: vector (nullable = true)
 |-- prediction: double (nullable = false)

Olet kiinnostunut etiketistä, ennusteesta ja todennäköisyydestä

selected = predictions.select("label", "prediction", "probability")
selected.show(20)
+-----+----------+--------------------+
|label|prediction|         probability|
+-----+----------+--------------------+
|  0.0|       0.0|[0.91560704124179...|
|  0.0|       0.0|[0.92812140213994...|
|  0.0|       0.0|[0.92161406774159...|
|  0.0|       0.0|[0.96222760777142...|
|  0.0|       0.0|[0.66363283056957...|
|  0.0|       0.0|[0.65571324475477...|
|  0.0|       0.0|[0.73053376932829...|
|  0.0|       1.0|[0.31265053873570...|
|  0.0|       0.0|[0.80005907577390...|
|  0.0|       0.0|[0.76482251301640...|
|  0.0|       0.0|[0.84447301189069...|
|  0.0|       0.0|[0.75691912026619...|
|  0.0|       0.0|[0.60902504096722...|
|  0.0|       0.0|[0.80799228385509...|
|  0.0|       0.0|[0.87704364852567...|
|  0.0|       0.0|[0.83817652582377...|
|  0.0|       0.0|[0.79655423248500...|
|  0.0|       0.0|[0.82712311232246...|
|  0.0|       0.0|[0.81372823882016...|
|  0.0|       0.0|[0.59687710752201...|
+-----+----------+--------------------+
only showing top 20 rows

Arvioi malli

Sinun on tarkasteltava tarkkuusmittaria nähdäksesi kuinka hyvin (tai huonosti) malli toimii. Tällä hetkellä ei ole API:ta tarkkuusmitan laskemiseen Spark. Oletusarvo on ROC, vastaanottimen toimintakäyrä. Se on eri mittari, joka ottaa huomioon väärän positiivisen määrän.

Ennen kuin tarkastelet ROC:ta, rakennetaan tarkkuusmitta. Tämä mittari on sinulle tutumpi. Tarkkuusmitta on oikean ennusteen summa havaintojen kokonaismäärästä.

Luot DataFramen tunnisteella ja ennusteella.

cm = predictions.select("label", "prediction")

Voit tarkistaa luokan lukumäärän tarrasta ja ennusteesta

cm.groupby('label').agg({'label': 'count'}).show()
+-----+------------+
|label|count(label)|
+-----+------------+
|  0.0|        5021|
|  1.0|        1578|
+-----+------------+
cm.groupby('prediction').agg({'prediction': 'count'}).show()
+----------+-----------------+
|prediction|count(prediction)|
+----------+-----------------+
|       0.0|             5982|
|       1.0|              617|
+----------+-----------------+

Esimerkiksi testijoukossa on 1578 kotitaloutta, joiden tulot ovat yli 50 tk ja 5021 alle. Luokitin ennusti kuitenkin 617 kotitaloutta, joiden tulot olivat yli 50 XNUMX.

Voit laskea tarkkuuden laskemalla määrän, kun tarra on luokiteltu oikein rivien kokonaismäärään nähden.

cm.filter(cm.label == cm.prediction).count() / cm.count()

0.8237611759357478

Voit kääriä kaiken yhteen ja kirjoittaa funktion tarkkuuden laskemiseksi.

def accuracy_m(model): 
    predictions = model.transform(test_data)
    cm = predictions.select("label", "prediction")
    acc = cm.filter(cm.label == cm.prediction).count() / cm.count()
    print("Model accuracy: %.3f%%" % (acc * 100)) 
accuracy_m(model = linearModel)
Model accuracy: 82.376%

ROC-mittarit

Moduuli BinaryClassificationEvaluator sisältää ROC-mitat. Vastaanottaja Operating Ominaisuuskäyrä on toinen yleinen työkalu, jota käytetään binääriluokituksessa. Se on hyvin samanlainen kuin tarkkuus/palautuskäyrä, mutta sen sijaan, että piirrettäisiin tarkkuus vs. muistaminen, ROC-käyrä näyttää todellisen positiivisen taajuuden (eli palauttamisen) väärän positiivisen taajuuden suhteen. Väärien positiivisten tapausten osuus on virheellisesti positiivisiksi luokiteltujen negatiivisten tapausten suhde. Se on yhtä suuri kuin yksi miinus todellinen negatiivinen korko. Todellista negatiivista korkoa kutsutaan myös spesifisyydeksi. Tästä syystä ROC-käyrä kuvaa herkkyyden (muistutuksen) vs. 1 – spesifisyys

### Use ROC 
from pyspark.ml.evaluation import BinaryClassificationEvaluator

# Evaluate model
evaluator = BinaryClassificationEvaluator(rawPredictionCol="rawPrediction")
print(evaluator.evaluate(predictions))
print(evaluator.getMetricName())

0.8940481662695192alueROC:n alla

print(evaluator.evaluate(predictions))

0.8940481662695192

Vaihe 6) Viritä hyperparametri

Viimeisenä muttei vähäisimpänä, voit säätää hyperparametreja. Samoin kuin scikit-learnissa, luot parametriruudukon ja lisäät siihen säädettävät parametrit.

Laskennan ajan lyhentämiseksi säädät vain säännöstelyparametria vain kahdella arvolla.

from pyspark.ml.tuning import ParamGridBuilder, CrossValidator

# Create ParamGrid for Cross Validation
paramGrid = (ParamGridBuilder()
             .addGrid(lr.regParam, [0.01, 0.5])
             .build())

Lopuksi arvioit mallia käyttämällä ristivalidointimenetelmää, jossa on 5 taittoa. Koulutus kestää noin 16 minuuttia.

from time import *
start_time = time()

# Create 5-fold CrossValidator
cv = CrossValidator(estimator=lr,
                    estimatorParamMaps=paramGrid,
                    evaluator=evaluator, numFolds=5)

# Run cross validations
cvModel = cv.fit(train_data)
# likely take a fair amount of time
end_time = time()
elapsed_time = end_time - start_time
print("Time to train model: %.3f seconds" % elapsed_time)

Aika mallin kouluttamiseen: 978.807 sekuntia

Paras regularisoinnin hyperparametri on 0.01, jonka tarkkuus on 85.316 prosenttia.

accuracy_m(model = cvModel)
Model accuracy: 85.316%

Voit extracsuositeltu parametri ketjuttamalla cvModel.bestModel esimerkillätractParamMap()

bestModel = cvModel.bestModel
bestModel.extractParamMap()
{Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='aggregationDepth', doc='suggested depth for treeAggregate (>= 2)'): 2,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='elasticNetParam', doc='the ElasticNet mixing parameter, in range [0, 1]. For alpha = 0, the penalty is an L2 penalty. For alpha = 1, it is an L1 penalty'): 0.0,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='family', doc='The name of family which is a description of the label distribution to be used in the model. Supported options: auto, binomial, multinomial.'): 'auto',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='featuresCol', doc='features column name'): 'features',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='fitIntercept', doc='whether to fit an intercept term'): True,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='labelCol', doc='label column name'): 'label',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='maxIter', doc='maximum number of iterations (>= 0)'): 10,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='predictionCol', doc='prediction column name'): 'prediction',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities'): 'probability',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name'): 'rawPrediction',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='regParam', doc='regularization parameter (>= 0)'): 0.01,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='standardization', doc='whether to standardize the training features before fitting the model'): True,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='threshold', doc='threshold in binary classification prediction, in range [0, 1]'): 0.5,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='tol', doc='the convergence tolerance for iterative algorithms (>= 0)'): 1e-06}

UKK

RDD on tyypittämätön hajautettu kokoelma, jota muunnat map- ja filter-komennoilla. DataFrame lisää nimetyn skeeman ja ajaa sen läpi Catalyst-optimoijan, joten strukturoidun datan kysely on yleensä nopeampaa ja helpompaa.

Spark 2.x vaaditaan Java vain 8. Spark 3.x ja 4.x toimivat Java 8, 11 ja 17 sekä tuki Python 3.8 ylöspäin. Sovita JDK aina Spark julkaisu, koska uudempi JDK rikkoo vanhemmat koontiversiot.

Tekoälyavustajat lukevat Spark Käyttöliittymän mittarit ja vaihesuunnitelmat merkitsevät vinoja osioita, leveitä sekoituksia ja muistin vuotamista ja ehdottavat sitten uudelleenosiointia tai liitosten lähettämistä. Ne lyhentävät säätötyötä, joka aiemmin vaati jokaisen suoritusvaiheen manuaalista tarkistusta.

Copilot laatii mallipohjan hyvin: Column-muunnoksilla, groupBy-aggregaatioilla ja pipeline-vaiheilla. Sarakkeiden nimet ja liittymisavaimet on silti tarkistettava varsinaista kaavaa vasten, koska luotu koodi kääntyy ongelmitta, vaikka se valitsisi hiljaa väärän kentän.

Valitse pandat, kun data mahtuu mukavasti yhden koneen muistiin. Siirry Py:hen.Spark kun tiedostot ylittävät käytettävissä olevan RAM-muistin, kun työ on suoritettava klusterissa tai kun sama työ syöttää tietoja tuotantoputkeen tutkimusmuistion sijaan.

Py4JJavaVirhe paljastaa JVM-poikkeuksen Python silta. Yleisiä laukaisimia ovat puuttuva tai yhteensopimaton JDK, asettamaton JAVA_HOME tai PySpark versio, joka on rakennettu eri Spark vapautus kuin polulla oleva.

Tallenna skripti .py-tiedostona ja käynnistä se spark-submit-komennolla lisäämällä –master valitaksesi paikallisen tai klusteritilan. Sama koodi, joka suoritetaan tiedoston sisällä Jupyter toimii muuttumattomana kerran SparkIstunto luodaan eksplisiittisesti.

Transformaatiot, kuten map, filter ja withColumn, rakentavat vain suunnitelman. Mitään ei suoriteta ennen kuin jokin toiminto, kuten count, collect tai show, on suoritettu. Spark optimoi sitten koko ketjun kerralla, mikä välttää tarpeettomien välitulosten kirjoittamisen.

Tiivistä tämä viesti seuraavasti: