1. ภาพรวม
การประมวลผลภาษาธรรมชาติ (NLP) คือการศึกษาการหาข้อมูลเชิงลึกและการวิเคราะห์ข้อมูลที่เป็นข้อความ เมื่อปริมาณงานเขียนที่สร้างขึ้นบนอินเทอร์เน็ตเพิ่มขึ้นเรื่อยๆ องค์กรต่างๆ จึงต้องการใช้ประโยชน์จากข้อความเพื่อรับข้อมูลที่เกี่ยวข้องกับธุรกิจของตนมากยิ่งขึ้น
NLP สามารถใช้ได้ทุกอย่าง ตั้งแต่การแปลภาษาไปจนถึงการวิเคราะห์ความรู้สึก การสร้างประโยคตั้งแต่ต้น และอื่นๆ อีกมากมาย ซึ่งเป็นประเด็นที่ยังมีการศึกษาวิจัยกันอย่างต่อเนื่องและกำลังเปลี่ยนรูปแบบการทำงานกับข้อความ
เราจะมาดูวิธีใช้ NLP กับข้อมูลข้อความจำนวนมากในวงกว้าง ซึ่งเป็นงานที่ท้าทายอย่างแน่นอน โชคดีที่เราจะใช้ประโยชน์จากไลบรารีอย่าง Spark MLlib และ spark-nlp เพื่อให้การดำเนินการนี้ง่ายขึ้น
2. กรณีการใช้งานของเรา
หัวหน้านักวิทยาศาสตร์ด้านข้อมูลขององค์กร (สมมติ) "FoodCorp" สนใจที่จะเรียนรู้เพิ่มเติมเกี่ยวกับเทรนด์ในอุตสาหกรรมอาหาร เรามีสิทธิ์เข้าถึงคลังข้อมูลข้อความในรูปแบบโพสต์จากฟอรัมย่อย r/food ของ Reddit ซึ่งเราจะใช้เพื่อสำรวจสิ่งที่ผู้คนกำลังพูดถึง
วิธีหนึ่งในการทำเช่นนี้คือผ่านวิธีการ NLP ที่เรียกว่า "การสร้างโมเดลหัวข้อ" การสร้างแบบจำลองหัวข้อเป็นวิธีการทางสถิติที่สามารถระบุแนวโน้มในความหมายเชิงความหมายของกลุ่มเอกสาร กล่าวคือ เราสามารถสร้างโมเดลหัวข้อในคลัง "โพสต์" ของ Reddit ซึ่งจะสร้างรายการ "หัวข้อ" หรือกลุ่มคำที่อธิบายเทรนด์
ในการสร้างโมเดล เราจะใช้อัลกอริทึมที่เรียกว่า Latent Dirichlet Allocation (LDA) ซึ่งมักใช้ในการจัดกลุ่มข้อความ ดูข้อมูลเบื้องต้นเกี่ยวกับ LDA ได้ที่นี่
3. การสร้างโปรเจ็กต์
หากยังไม่มีบัญชี Google (Gmail หรือ Google Apps) คุณต้องสร้างบัญชี ลงชื่อเข้าใช้คอนโซล Google Cloud Platform ( console.cloud.google.com) แล้วสร้างโปรเจ็กต์ใหม่โดยทำดังนี้



จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากรของ Google Cloud
การทำตาม Codelab นี้ไม่ควรมีค่าใช้จ่ายเกิน 2-3 ดอลลาร์ แต่ก็อาจมีค่าใช้จ่ายมากกว่านี้หากคุณตัดสินใจใช้ทรัพยากรเพิ่มเติมหรือปล่อยให้ทรัพยากรทำงานต่อไป Codelab PySpark-BigQuery และ Spark-NLP แต่ละรายการจะอธิบาย "ล้างข้อมูล" ในตอนท้าย
ผู้ใช้ใหม่ของ Google Cloud Platform มีสิทธิ์รับช่วงทดลองใช้ฟรีมูลค่า$300
4. การตั้งค่าสภาพแวดล้อม
ก่อนอื่น เราต้องเปิดใช้ Dataproc และ Compute Engine API
คลิกไอคอนเมนูที่ด้านซ้ายบนของหน้าจอ

เลือก API Manager จากเมนูแบบเลื่อนลง

คลิกเปิดใช้ API และบริการ

ค้นหา "Compute Engine" ในช่องค้นหา คลิก "Google Compute Engine API" ในรายการผลลัพธ์ที่ปรากฏ

ในหน้า Google Compute Engine ให้คลิกเปิดใช้

เมื่อเปิดใช้แล้ว ให้คลิกลูกศรที่ชี้ไปทางซ้ายเพื่อกลับไป
ตอนนี้ให้ค้นหา "Google Dataproc API" แล้วเปิดใช้ด้วย

จากนั้นเปิด Cloud Shell โดยคลิกปุ่มที่มุมขวาบนของ Cloud Console

เราจะตั้งค่าตัวแปรสภาพแวดล้อมบางอย่างที่เราอ้างอิงได้เมื่อทำตาม Codelab ก่อนอื่น ให้เลือกชื่อสำหรับคลัสเตอร์ Dataproc ที่เราจะสร้าง เช่น "my-cluster" แล้วตั้งค่าในสภาพแวดล้อม คุณใช้ชื่อใดก็ได้ตามต้องการ
CLUSTER_NAME=my-cluster
จากนั้นเลือกโซนจากโซนที่มีให้ใช้งานที่นี่ ตัวอย่างเช่น us-east1-b.
REGION=us-east1
สุดท้ายนี้ เราต้องตั้งค่า Bucket ต้นทางที่งานจะอ่านข้อมูลจาก เรามีข้อมูลตัวอย่างในที่เก็บข้อมูล bm_reddit แต่คุณสามารถใช้ข้อมูลที่สร้างจาก PySpark สำหรับการประมวลผลข้อมูล BigQuery เบื้องต้น ได้หากดำเนินการเสร็จก่อนหน้านี้
BUCKET_NAME=bm_reddit
เมื่อกำหนดค่าตัวแปรสภาพแวดล้อมแล้ว ให้เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างคลัสเตอร์ Dataproc
gcloud beta dataproc clusters create ${CLUSTER_NAME} \
--region ${REGION} \
--metadata 'PIP_PACKAGES=google-cloud-storage spark-nlp==2.7.2' \
--worker-machine-type n1-standard-8 \
--num-workers 4 \
--image-version 1.4-debian10 \
--initialization-actions gs://dataproc-initialization-actions/python/pip-install.sh \
--optional-components=JUPYTER,ANACONDA \
--enable-component-gateway
มาดูคำสั่งแต่ละรายการกัน
gcloud beta dataproc clusters create ${CLUSTER_NAME}: จะเริ่มสร้างคลัสเตอร์ Dataproc ที่มีชื่อที่คุณระบุไว้ก่อนหน้านี้ เราใส่ beta ไว้ที่นี่เพื่อเปิดใช้ฟีเจอร์เบต้าของ Dataproc เช่น Component Gateway ซึ่งเราจะพูดถึงด้านล่าง
--zone=${ZONE}: การดำเนินการนี้จะตั้งค่าตำแหน่งของคลัสเตอร์
--worker-machine-type n1-standard-8: นี่คือประเภทเครื่องที่จะใช้สำหรับผู้ปฏิบัติงาน
--num-workers 4: เราจะมี Worker 4 รายในคลัสเตอร์
--image-version 1.4-debian9: ระบุเวอร์ชันอิมเมจของ Dataproc ที่เราจะใช้
--initialization-actions ...: การดำเนินการเริ่มต้นคือสคริปต์ที่กำหนดเองซึ่งจะทำงานเมื่อสร้างคลัสเตอร์และ Worker โดยอาจเป็นไฟล์ที่ผู้ใช้สร้างและจัดเก็บไว้ในที่เก็บข้อมูล GCS หรืออ้างอิงจากที่เก็บข้อมูลสาธารณะ dataproc-initialization-actions การดำเนินการเริ่มต้นที่รวมไว้ที่นี่จะอนุญาตให้ติดตั้งแพ็กเกจ Python โดยใช้ Pip ตามที่ระบุไว้พร้อมกับแฟล็ก --metadata
--metadata 'PIP_PACKAGES=google-cloud-storage spark-nlp': นี่คือรายการแพ็กเกจที่คั่นด้วยช่องว่างเพื่อติดตั้งลงใน Dataproc ในกรณีนี้ เราจะติดตั้งgoogle-cloud-storageไลบรารีของไคลเอ็นต์ Python และ spark-nlp
--optional-components=ANACONDA: คอมโพเนนต์ที่ไม่บังคับคือแพ็กเกจทั่วไปที่ใช้กับ Dataproc ซึ่งจะได้รับการติดตั้งโดยอัตโนมัติในคลัสเตอร์ Dataproc ระหว่างการสร้าง ข้อดีของการใช้คอมโพเนนต์ที่ไม่บังคับแทนการดำเนินการเริ่มต้น ได้แก่ เวลาเริ่มต้นที่เร็วขึ้นและการทดสอบสำหรับ Dataproc บางเวอร์ชัน โดยรวมแล้วมีความน่าเชื่อถือมากกว่า
--enable-component-gateway: แฟล็กนี้ช่วยให้เราใช้ประโยชน์จาก Component Gateway ของ Dataproc เพื่อดู UI ทั่วไป เช่น Zeppelin, Jupyter หรือประวัติ Spark หมายเหตุ: บางรายการต้องใช้คอมโพเนนต์เสริมที่เกี่ยวข้อง
ดูข้อมูลเบื้องต้นเกี่ยวกับ Dataproc แบบเจาะลึกเพิ่มเติมได้ใน Codelab นี้
จากนั้นเรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อโคลนที่เก็บด้วยโค้ดตัวอย่างและเปลี่ยนไดเรกทอรีไปยังไดเรกทอรีที่ถูกต้อง
cd
git clone https://github.com/GoogleCloudPlatform/cloud-dataproc
cd cloud-dataproc/codelabs/spark-nlp
5. Spark MLlib
Spark MLlib เป็นไลบรารีแมชชีนเลิร์นนิงที่ปรับขนาดได้ซึ่งเขียนใน Apache Spark MLlib สามารถวิเคราะห์ข้อมูลจำนวนมากได้โดยใช้ประโยชน์จากประสิทธิภาพของ Spark ร่วมกับชุดอัลกอริทึมแมชชีนเลิร์นนิงที่ได้รับการปรับแต่งอย่างละเอียด โดยมี API ใน Java, Scala, Python และ R ในโค้ดแล็บนี้ เราจะมุ่งเน้นที่ Python โดยเฉพาะ
MLlib มีชุดตัวแปลงและตัวประมาณจำนวนมาก Transformer คือเครื่องมือที่สามารถเปลี่ยนหรือแก้ไขข้อมูลได้ โดยปกติจะใช้ฟังก์ชัน transform() ส่วนตัวประมาณคืออัลกอริทึมที่สร้างไว้ล่วงหน้าซึ่งคุณสามารถฝึกข้อมูลได้ โดยปกติจะใช้ฟังก์ชัน fit()
ตัวอย่างของ Transformer ได้แก่
- การแยกคำ (การสร้างเวกเตอร์ของตัวเลขจากสตริงของคำ)
- การเข้ารหัสแบบ One-hot (การสร้างเวกเตอร์แบบกระจัดกระจายของตัวเลขที่แสดงคำที่มีอยู่ในสตริง)
- เครื่องมือลบคำที่ไม่สำคัญ (ลบคำที่ไม่ได้เพิ่มค่าเชิงความหมายให้กับสตริง)
ตัวอย่างเครื่องมือประมาณการ ได้แก่
- การแยกประเภท (นี่คือแอปเปิ้ลหรือส้ม)
- การถดถอย (แอปเปิลลูกนี้ควรมีราคาเท่าใด)
- การจัดกลุ่ม (แอปเปิลทั้งหมดคล้ายกันมากน้อยเพียงใด)
- แผนผังการตัดสินใจ (หากสีเป็นสีส้ม แสดงว่าเป็นส้ม) มิฉะนั้นจะเป็นแอปเปิล)
- การลดมิติ (เราจะนำฟีเจอร์ออกจากชุดข้อมูลและยังคงแยกความแตกต่างระหว่างแอปเปิ้ลกับส้มได้ไหม)
นอกจากนี้ MLlib ยังมีเครื่องมือสำหรับวิธีการอื่นๆ ที่ใช้กันทั่วไปในแมชชีนเลิร์นนิง เช่น การปรับแต่งและการเลือกไฮเปอร์พารามิเตอร์ รวมถึงการตรวจสอบแบบไขว้
นอกจากนี้ MLlib ยังมี Pipelines API ซึ่งช่วยให้คุณสร้างไปป์ไลน์การเปลี่ยนรูปแบบข้อมูลได้โดยใช้ Transformer ต่างๆ ที่สามารถเรียกใช้ซ้ำได้
6. Spark-NLP
Spark-nlp เป็นไลบรารีที่สร้างโดย John Snow Labs สำหรับการประมวลผลภาษาธรรมชาติอย่างมีประสิทธิภาพโดยใช้ Spark โดยมีเครื่องมือในตัวที่เรียกว่าเครื่องมือประกอบสำหรับงานทั่วไป เช่น
- การแยกคำ (การสร้างเวกเตอร์ของตัวเลขจากสตริงของคำ)
- การสร้างการฝังคำ (การกำหนดความสัมพันธ์ระหว่างคำผ่านเวกเตอร์)
- แท็กประเภทของคำ (คำใดเป็นคำนาม ซึ่งเป็นคำกริยา)
แม้จะอยู่นอกขอบเขตของโค้ดแล็บนี้ แต่ spark-nlp ก็ผสานรวมกับ TensorFlow ได้อย่างดีเช่นกัน
ที่สำคัญที่สุดคือ Spark-NLP ขยายความสามารถของ Spark MLlib โดยการจัดหาคอมโพเนนต์ที่สามารถใส่ลงในไปป์ไลน์ MLlib ได้อย่างง่ายดาย
7. แนวทางปฏิบัติแนะนำสำหรับการประมวลผลภาษาธรรมชาติ
ก่อนที่จะดึงข้อมูลที่เป็นประโยชน์จากข้อมูลได้ เราต้องจัดการข้อมูลบางอย่างก่อน ขั้นตอนการประมวลผลล่วงหน้าที่เราจะดำเนินการมีดังนี้
การแปลงข้อมูลเป็นโทเค็น
สิ่งแรกที่เรามักจะทำคือ "แปลงโทเค็น" ข้อมูล ซึ่งเกี่ยวข้องกับการนำข้อมูลมาแยกตาม "โทเค็น" หรือคำ โดยทั่วไป เราจะนำเครื่องหมายวรรคตอนออกและตั้งค่าคำทั้งหมดเป็นตัวพิมพ์เล็กในขั้นตอนนี้ เช่น สมมติว่าเรามีสตริงต่อไปนี้ What time is it? หลังจากทำการโทเค็นแล้ว ประโยคนี้จะมีโทเค็น 4 รายการ ได้แก่ "what" , "time", "is", "it". เราไม่ต้องการให้โมเดลถือว่าคำว่า what เป็นคำ 2 คำที่แตกต่างกันซึ่งมีตัวพิมพ์ใหญ่แตกต่างกัน นอกจากนี้ เครื่องหมายวรรคตอนมักไม่ได้ช่วยให้เราเรียนรู้การอนุมานจากคำได้ดีขึ้น เราจึงนำเครื่องหมายวรรคตอนออกด้วย
การแปลงเป็นรูปแบบมาตรฐาน
เรามักต้องการ "ปรับ" ข้อมูลให้เป็นมาตรฐาน การดำเนินการนี้จะแทนที่คำที่มีความหมายคล้ายกันด้วยคำเดียวกัน เช่น หากระบบระบุคำว่า "fought" "battled" และ "dueled" ในข้อความ การแปลงเป็นรูปแบบมาตรฐานอาจแทนที่คำว่า "battled" และ "dueled" ด้วยคำว่า "fought"
การตัดคำ
การตัดคำจะแทนที่คำด้วยความหมายรากของคำนั้น เช่น ระบบจะแทนที่คำว่า "car", "cars" และ "car's" ด้วยคำว่า "car" เนื่องจากคำเหล่านี้มีความหมายเดียวกันในระดับราก
การนำคำที่ไม่สำคัญออก
คำหยุดคือคำอย่างเช่น "และ" และ "the" ซึ่งโดยปกติแล้วไม่ได้เพิ่มคุณค่าให้กับความหมายเชิงความหมายของประโยค โดยปกติแล้วเราต้องการนำสิ่งเหล่านี้ออกเพื่อลดสัญญาณรบกวนในชุดข้อมูลข้อความ
8. การเรียกใช้งาน
มาดูงานที่เราจะเรียกใช้กัน คุณดูโค้ดได้ที่ cloud-dataproc/codelabs/spark-nlp/topic_model.py โปรดใช้เวลาอย่างน้อย 2-3 นาทีในการอ่านนโยบายและข้อคิดเห็นที่เกี่ยวข้องเพื่อทำความเข้าใจสิ่งที่เกิดขึ้น นอกจากนี้ เราจะไฮไลต์บางส่วนด้านล่างด้วย
# Python imports
import sys
# spark-nlp components. Each one is incorporated into our pipeline.
from sparknlp.annotator import Lemmatizer, Stemmer, Tokenizer, Normalizer
from sparknlp.base import DocumentAssembler, Finisher
# A Spark Session is how we interact with Spark SQL to create Dataframes
from pyspark.sql import SparkSession
# These allow us to create a schema for our data
from pyspark.sql.types import StructField, StructType, StringType, LongType
# Spark Pipelines allow us to sequentially add components such as transformers
from pyspark.ml import Pipeline
# These are components we will incorporate into our pipeline.
from pyspark.ml.feature import StopWordsRemover, CountVectorizer, IDF
# LDA is our model of choice for topic modeling
from pyspark.ml.clustering import LDA
# Some transformers require the usage of other Spark ML functions. We import them here
from pyspark.sql.functions import col, lit, concat
# This will help catch some PySpark errors
from pyspark.sql.utils import AnalysisException
# Assign bucket where the data lives
try:
bucket = sys.argv[1]
except IndexError:
print("Please provide a bucket name")
sys.exit(1)
# Create a SparkSession under the name "reddit". Viewable via the Spark UI
spark = SparkSession.builder.appName("reddit topic model").getOrCreate()
# Create a three column schema consisting of two strings and a long integer
fields = [StructField("title", StringType(), True),
StructField("body", StringType(), True),
StructField("created_at", LongType(), True)]
schema = StructType(fields)
# We'll attempt to process every year / month combination below.
years = ['2016', '2017', '2018', '2019']
months = ['01', '02', '03', '04', '05', '06',
'07', '08', '09', '10', '11', '12']
# This is the subreddit we're working with.
subreddit = "food"
# Create a base dataframe.
reddit_data = spark.createDataFrame([], schema)
# Keep a running list of all files that will be processed
files_read = []
for year in years:
for month in months:
# In the form of <project-id>.<dataset>.<table>
gs_uri = f"gs://{bucket}/reddit_posts/{year}/{month}/{subreddit}.csv.gz"
# If the table doesn't exist we will simply continue and not
# log it into our "tables_read" list
try:
reddit_data = (
spark.read.format('csv')
.options(codec="org.apache.hadoop.io.compress.GzipCodec")
.load(gs_uri, schema=schema)
.union(reddit_data)
)
files_read.append(gs_uri)
except AnalysisException:
continue
if len(files_read) == 0:
print('No files read')
sys.exit(1)
# Replacing null values with their respective typed-equivalent is usually
# easier to work with. In this case, we'll replace nulls with empty strings.
# Since some of our data doesn't have a body, we can combine all of the text
# for the titles and bodies so that every row has useful data.
df_train = (
reddit_data
# Replace null values with an empty string
.fillna("")
.select(
# Combine columns
concat(
# First column to concatenate. col() is used to specify that we're referencing a column
col("title"),
# Literal character that will be between the concatenated columns.
lit(" "),
# Second column to concatenate.
col("body")
# Change the name of the new column
).alias("text")
)
)
# Now, we begin assembling our pipeline. Each component here is used to some transformation to the data.
# The Document Assembler takes the raw text data and convert it into a format that can
# be tokenized. It becomes one of spark-nlp native object types, the "Document".
document_assembler = DocumentAssembler().setInputCol("text").setOutputCol("document")
# The Tokenizer takes data that is of the "Document" type and tokenizes it.
# While slightly more involved than this, this is effectively taking a string and splitting
# it along ths spaces, so each word is its own string. The data then becomes the
# spark-nlp native type "Token".
tokenizer = Tokenizer().setInputCols(["document"]).setOutputCol("token")
# The Normalizer will group words together based on similar semantic meaning.
normalizer = Normalizer().setInputCols(["token"]).setOutputCol("normalizer")
# The Stemmer takes objects of class "Token" and converts the words into their
# root meaning. For instance, the words "cars", "cars'" and "car's" would all be replaced
# with the word "car".
stemmer = Stemmer().setInputCols(["normalizer"]).setOutputCol("stem")
# The Finisher signals to spark-nlp allows us to access the data outside of spark-nlp
# components. For instance, we can now feed the data into components from Spark MLlib.
finisher = Finisher().setInputCols(["stem"]).setOutputCols(["to_spark"]).setValueSplitSymbol(" ")
# Stopwords are common words that generally don't add much detail to the meaning
# of a body of text. In English, these are mostly "articles" such as the words "the"
# and "of".
stopword_remover = StopWordsRemover(inputCol="to_spark", outputCol="filtered")
# Here we implement TF-IDF as an input to our LDA model. CountVectorizer (TF) keeps track
# of the vocabulary that's being created so we can map our topics back to their
# corresponding words.
# TF (term frequency) creates a matrix that counts how many times each word in the
# vocabulary appears in each body of text. This then gives each word a weight based
# on its frequency.
tf = CountVectorizer(inputCol="filtered", outputCol="raw_features")
# Here we implement the IDF portion. IDF (Inverse document frequency) reduces
# the weights of commonly-appearing words.
idf = IDF(inputCol="raw_features", outputCol="features")
# LDA creates a statistical representation of how frequently words appear
# together in order to create "topics" or groups of commonly appearing words.
lda = LDA(k=10, maxIter=10)
# We add all of the transformers into a Pipeline object. Each transformer
# will execute in the ordered provided to the "stages" parameter
pipeline = Pipeline(
stages = [
document_assembler,
tokenizer,
normalizer,
stemmer,
finisher,
stopword_remover,
tf,
idf,
lda
]
)
# We fit the data to the model.
model = pipeline.fit(df_train)
# Now that we have completed a pipeline, we want to output the topics as human-readable.
# To do this, we need to grab the vocabulary generated from our pipeline, grab the topic
# model and do the appropriate mapping. The output from each individual component lives
# in the model object. We can access them by referring to them by their position in
# the pipeline via model.stages[<ind>]
# Let's create a reference our vocabulary.
vocab = model.stages[-3].vocabulary
# Next, let's grab the topics generated by our LDA model via describeTopics(). Using collect(),
# we load the output into a Python array.
raw_topics = model.stages[-1].describeTopics().collect()
# Lastly, let's get the indices of the vocabulary terms from our topics
topic_inds = [ind.termIndices for ind in raw_topics]
# The indices we just grab directly map to the term at position <ind> from our vocabulary.
# Using the below code, we can generate the mappings from our topic indices to our vocabulary.
topics = []
for topic in topic_inds:
_topic = []
for ind in topic:
_topic.append(vocab[ind])
topics.append(_topic)
# Let's see our topics!
for i, topic in enumerate(topics, start=1):
print(f"topic {i}: {topic}")
การเรียกใช้งาน
ตอนนี้มาเรียกใช้งานกันเลย เรียกใช้คำสั่งต่อไปนี้
gcloud dataproc jobs submit pyspark --cluster ${CLUSTER_NAME}\
--region ${REGION}\
--properties=spark.jars.packages=com.johnsnowlabs.nlp:spark-nlp_2.11:2.7.2\
--driver-log-levels root=FATAL \
topic_model.py \
-- ${BUCKET_NAME}
คำสั่งนี้ช่วยให้เราใช้ประโยชน์จาก Dataproc Jobs API ได้ การใส่คำสั่ง pyspark เป็นการระบุให้คลัสเตอร์ทราบว่านี่คืองาน PySpark เราจะระบุชื่อคลัสเตอร์ พารามิเตอร์ที่ไม่บังคับจากพารามิเตอร์ที่มีให้ที่นี่ และชื่อของไฟล์ที่มีงาน ในกรณีของเรา เราจะระบุพารามิเตอร์ --properties ซึ่งช่วยให้เราเปลี่ยนพร็อพเพอร์ตี้ต่างๆ สำหรับ Spark, Yarn หรือ Dataproc ได้ เรากำลังเปลี่ยนแปลงพร็อพเพอร์ตี้ Spark packages ซึ่งช่วยให้เราแจ้ง Spark ว่าเราต้องการรวม spark-nlp เป็นแพ็กเกจพร้อมกับงานของเรา นอกจากนี้ เรายังระบุพารามิเตอร์ --driver-log-levels root=FATAL ซึ่งจะระงับเอาต์พุตบันทึกส่วนใหญ่จาก PySpark ยกเว้นข้อผิดพลาด โดยทั่วไปแล้ว บันทึกของ Spark มักจะมีข้อมูลที่ไม่เกี่ยวข้อง
สุดท้าย -- ${BUCKET} คืออาร์กิวเมนต์บรรทัดคำสั่งสำหรับสคริปต์ Python เองที่ระบุชื่อ Bucket โปรดสังเกตช่องว่างระหว่าง -- กับ ${BUCKET}
หลังจากเรียกใช้งานเป็นเวลา 2-3 นาที เราควรเห็นเอาต์พุตที่มีโมเดลของเรา

ยอดเยี่ยม!! คุณอนุมานแนวโน้มได้ไหมเมื่อดูเอาต์พุตจากโมเดล แล้วของเราล่ะ
จากเอาต์พุตข้างต้น เราอาจอนุมานแนวโน้มจากหัวข้อ 8 ที่เกี่ยวข้องกับอาหารเช้า และของหวานจากหัวข้อ 9
9. ล้างข้อมูล
โปรดดำเนินการดังนี้เพื่อเลี่ยงไม่ให้เกิดการเรียกเก็บเงินที่ไม่จำเป็นกับบัญชี GCP หลังจากที่ทำตามการเริ่มต้นอย่างรวดเร็วนี้เสร็จแล้ว
- ลบ Bucket ของ Cloud Storage สำหรับสภาพแวดล้อมและที่คุณสร้างไว้
- ลบสภาพแวดล้อม Dataproc
หากสร้างโปรเจ็กต์เพื่อใช้กับ Codelab นี้โดยเฉพาะ คุณจะลบโปรเจ็กต์ได้ด้วย (ไม่บังคับ) โดยทำดังนี้
- ในคอนโซล GCP ให้ไปที่หน้าโปรเจ็กต์
- ในรายการโปรเจ็กต์ ให้เลือกโปรเจ็กต์ที่ต้องการลบ แล้วคลิกลบ
- พิมพ์รหัสโปรเจ็กต์ในช่อง แล้วคลิกปิดเพื่อลบโปรเจ็กต์
ใบอนุญาต
ผลงานนี้ได้รับอนุญาตภายใต้สัญญาอนุญาตครีเอทีฟคอมมอนส์แบบระบุแหล่งที่มา 3.0 ทั่วไป และสัญญาอนุญาต Apache 2.0