Thuật tốn NạveBayes thực hiện trên mơi trƣờng Spark

Một phần của tài liệu (LUẬN văn THẠC sĩ) ứng dụng mô hình học máy naivebayes trong môi trường spark cho bài toán dự báo khả năng hỏng của đĩa cứng máy tính (Trang 50 - 64)

Việc triển khai Spark cĩ hai giai đoạn:

Giai đoạn 1: Xây dựng trình phân loại Nạve Bayes bằng dữ liệu training để thực hiện điều này sử dụng lớp BuildNạveBayesClassifier. Lớp này đọc dữ liệu huấn luyện và xây dựng trình phân loại Nạve Bayes. Đặt C = {C1, C2, ..., Ck} là một tập hợp các phân loại và dữ liệu đào tạo đƣợc xác định nhƣ sau:

Đặt X = {X1, X2, ..., Xn} là dữ liệu thơ.

Mỗi Xi cĩ m thuộc tính và đƣợc phân loại là: X1 = {X11, X12, ..., X1m} → c1∊ C

X2 = {X21, X22, ..., X2m} → c2∊ C ...

Xn = {Xn1, Xn2, ..., Xnm} → cn∊ C

Mục tiêu của Tơi là tạo ra các hàm bảng xác suất (Xác suất) sau đây: Xác suất (Ci) = pValue

Xác suất (Aj, Ci) = pValue

Trong đĩ Aj là một thuộc tính của X và 0,00 ≤ pValue ≤ 1,00.[5]

Giai đoạn 2: Sử dụng Nạve Bayes Classifier mới đƣợc xây dựng để

phân loại dữ liệu mới

Khi đã xây dựng trình phân loại Nạve Bayes, sẽ sử dụng các hàm ProbabilityTable () để phân loại dữ liệu mới. Thực hiện điều này bằng cách sử dụng lớp sifier NaiveBayesClass. Lớp này đọc trình phân loại (đƣợc biểu thị

42

dƣới dạng các hàm Bleability ()) dữ liệu mới bằng cách sử dụng dữ liệu cĩ sẵn [5].

Hình 2.9 Giai đoạn phân loại [5].

Giai đoạn 1: Xây dựng Trình phân loại bằng Dữ liệu training

Giai đoạn này đƣợc thực hiện bởi lớp Build Nạve Bayes Classifier, chấp nhận dữ liệu đào tạo (đã đƣợc phân loại) và xây dựng trình phân loại Nạve Bayes. Trình phân loại Nạve Bayes là một tập hợp các bảng xác suất (PT). Đầu tiên, Ví dụ 2.1 trình bày lớp Build NaiveBayes Classifierdƣới dạng tập hợp các bƣớc cấp cao, sau đĩ tơi sẽ giải thích chi tiết từng bƣớc.[11]

Ví dụ 2.1. Xây dựng bộ phân loại.

Bƣớc 1: Thêm vào các thƣ viện lớp và giao diện Bƣớc 2: Xử lý thơng số đầu vào

Bƣớc 3: Tạo một đối tƣợng mới trên Spark. Bƣớc 4: Đọc dữ liệu huấn luyện

Bƣớc 5: Tiến hành thực hiện hàm map () cho tất cả các biến của dữ liệu huấn luyện.

43

Bƣớc 6: Tiến hành thực hiện hàm reduce () cho tất cả các biến của dữ liệu huấn luyện.

Bƣớc 7: Tiến hành reduce dữ liệu từ Map Bƣớc 8: Xây dựng trình phân loại

Bƣớc 9: Lƣu trữ trình phân loại

Phƣơng thức toWritableList (), đƣợc định nghĩa trong Ví dụ 2.2, chuẩn bị bộ phân loại sẽ đƣợc lƣu trong HDFS. Để hoạt động đƣợc, dữ liệu đầu vào sẽ sử dụng phƣơng thức Writablecủa Hadoop để lƣu bộ phân loại vào HDFS

Ví dụ 2.2: phƣơng thức toWritableList ()

static List<Tuple2<PairOfStrings, DoubleWritable>> toWritableList(Map<Tuple2<String,String>, Double> PT) {

List<Tuple2<PairOfStrings, DoubleWritable>> list = new ArrayList<Tuple2<PairOfStrings, DoubleWritable>();

for (Map.Entry<Tuple2<String,String>, Double> entry : PT.entrySet()) {

list.add(new Tuple2<PairOfStrings, DoubleWritable>( new PairOfStrings(entry.getKey()._1, entry.getKey()._2), new DoubleWritable(entry.getValue())

}

return list; }

Bước 1: Nhập các lớp và giao diện pyspark cần thiết (Ví dụ 2.3).

Ví dụ 2.3. Bƣớc 1: nhập các lớp và giao diện cần thiết

import java.util.Map; import java.util.HashMap; import java.util.List;

44 import java.util.ArrayList; import scala.Tuple2; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaSparkContext; import org.apache.spark.api.java.function.PairFunction; import org.apache.spark.api.java.function.PairFlatMapFunction; import org.apache.spark.api.java.function.FlatMapFunction; import org.apache.spark.api.java.function.Function; import org.apache.spark.api.java.function.Function2; import org.apache.spark.broadcast.Broadcast; import edu.umd.cloud9.io.pair.PairOfStrings; import org.apache.hadoop.mapred.SequenceFileOutputFormat; import org.apache.hadoop.io.DoubleWritable;

Bước 2: Xử lý các tham số đầu vào

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.4, đọc một tham số đầu vào, <tên tập tin dữ liệu>, là tệp HDFS đại diện cho dữ liệu đào tạo đƣợc sử dụng để xây dựng trình phân loại Nạve Bayes.

Ví dụ 2.4. Bƣớc 2: xử lý các tham số đầu vào

if (args.length < 1) {

System.err.println("Usage: BuildNaiveBayesClassifier <training-data-filename>");

System.exit(1); }

final String trainingDataFilename = args[0];

45

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.5, tạo một đối tƣợng SparkContext và khởi tạo RDD mới. Lớp SparkUtil cĩ các phƣơng thức tĩnh đƣợc tạo tức thì, các trƣờng hợp của pySparkContext sử dụng trình quản lý tài nguyên của YARN hoặc bằng cách sử dụng URL chính Spark.

Ví dụ 2.5. Bƣớc 3: tạo một đối tƣợng bối cảnh Spark

JavaSparkContext ctx = SparkUtil.createJavaSparkContext("naive- bayes");

Bước 4: Đọc dữ liệu đào tạo

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.6, sử dụng một thể hiện của JavaSparkContext để đọc dữ liệu đào tạo của chúng tơi và tạo một JavaRDD <String>, trong đĩ mỗi phần tử là một bản ghi của tập dữ liệu huấn luyện theo định dạng sau:

<attribute_1><,><attribute_2><,>...<,><attribute_m><,><classification Ví dụ 2.6. Bƣớc 4: đọc dữ liệu đào tạo

JavaRDD<String> training = ctx.textFile(trainingDataFilename, 1); training.saveAsTextFile("/output/1");

long trainingDataSize = training.count();

Bước 5: Thực hiện chức năng map () cho tất cả các yếu tố của dữ liệu đào tạo

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.7, ánh xạ tất cả các yếu tố của dữ liệu đào tạo để cĩ thể tạo ra một số lƣợng các thuộc tính liên quan đến phân loại. Sau đĩ, sử dụng các số đếm này để tính xác suất cĩ điều kiện.

Ví dụ 2.7. Bƣớc 5: thực hiện hàm map ()

JavaPairRDD<Tuple2<String,String>,Integer> pairs = training.flatMapToPair(new PairFlatMapFunction< String, Tuple2<String,String>,Integer

46

public Iterable<Tuple2<Tuple2<String,String>,Integer>> call(String

rec) {

List<Tuple2<Tuple2<String,String>,Integer>> result =

new ArrayList<Tuple2<Tuple2<String,String>,Integer>>();

String[] tokens = rec.split(",");

int classificationIndex = tokens.length -1;

String theClassification = tokens[classificationIndex];

for(int i=0; i < (classificationIndex-1); i++) {

Tuple2<String,String> K = new Tuple2<String,String>("CLASS", theClassification); result.add(new Tuple2<Tuple2<String,String>,Integer>(K, 1)); return resultt; } }); pairs.saveAsTextFile("/output/2");

Bước 6: Thực hiện hàm less()

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.8, làm giảm số lƣợng để chuẩn bị tính tốn các xác suất cĩ điều kiện sẽ đƣợc phân loại sử dụng.

Ví dụ 2.8. Bƣớc 6: thực hiện hàm less ()

JavaPairRDD<Tuple2<String,String>, Integer> counts =

pairs.reduceByKey(new Function2<Integer, Integer, Integer>() {

public Integer call(Integer i1, Integer i2) { return i1 + i2;

} });

counts.saveAsTextFile("/output/3");

47

Nhƣ đã trình bày trong Ví dụ 2.9, bƣớc này sử dụng một tính năng mạnh mẽ của API Spark là nhĩm một JavaPairRDD <K,V> nhƣ một Map <K,V> . Tơi sẽ sử dụng Map <K,V> đƣợc tạo để xây dựng trình phân loại.

Ví dụ 2.9. Bƣớc 7: Tiến hành reduce dữ liệu từ hàm Map Map<Tuple2<String,String>, Integer> countsAsMap = counts.collectAsMap();

Bước 8: Xây dựng cấu trúc dữ liệu phân loại

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.10, xây dựng trình phân loại, bao gồm:

Bảng xác suất (PT)

Danh sách phân loại (PHÂN LOẠI)

Ví dụ 2.10. Bƣớc 8: xây dựng cấu trúc dữ liệu phân loại Map<Tuple2<String,String>, Double> PT = new

HashMap<Tuple2<String,String>,Double>();

List<String> CLASSIFICATIONS = new ArrayList<String>();

for (Map.Entry<Tuple2<String,String>, Integer> entry :

countsAsMap.entrySet()) {

Tuple2<String,String> k = entry.getKey(); String classification = k._2;

if (k._1.equals("CLASS")) {

PT.put(k, ((double) entry.getValue())/ ((double) trainingDatasize)); CLASSIFICATION.add(k._2); } else{ Tuple2<String,String>k2=new Tuple2<String,String>("CLASS",classification);

48 Integer count = countsAsMap.get(k2); If (count == null){ PT.put(k, 0.0); } else { PT.put(k,((double)entry.getValue())/ ((double) count.intValue()));}}} System.out.println("PT="+PT);

Bước 9: Lưu cấu trúc dữ liệu phân loại

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.11, lƣu bộ phân loại, bao gồm: Bảng xác suất (PT)

Danh sách phân loại (PHÂN LOẠI)

Để lƣu bất kỳ dữ liệu nào trong Hadoop, lớp dữ liệu đƣợc duy trì của bạn phải triển khai trên Hadoop

Giao diện org.apache.hadoop.io.Writable 1. Trong đoạn mã, tơi đã sử dụng PairOfStrings và DoubleWritable cho các lớp, mà cả hai thực hiện trên giao diện Writable của Hadoop.

Ví dụ 2.11. Bƣớc 9: Lƣu cấu trúc dữ liệu phân loại

// Bước 9.1: Lưu lại PT

List<Tuple2<PairOfStrings, DoubleWritable>> list = toWritableList(PT); JavaPairRDD<PairOfStrings, DoubleWritable> ptRDD = ctx.parallelizePairs(list); ptRDD.saveAsHadoopFile("/naivebayes/pt", PairOfStrings.class, DoubleWritable.class, SequenceFileOutputFormat.class

49 );

// Bước 9.2: Lưu danh sách phân loại

JavaRDD<String> classificationsRDD = ctx.parallelize(CLASSIFICATIONS);

classificationsRDD.saveAsTextFile("/naivebayes/classes");

Tập lệnh YARN để xây dựng một Nạve Bayes Classifier.

Kịch bản shell hiển thị ở đây chạy chƣơng trình Spark để xây dựng Nạve Bayes Classifier trong mơi trƣờng YARN:[11]

# cat run_build_naive_bayes_classifier.sh #!/bin/bash

#... set the CLASSPATH(s) accordingly... BOOK_HOME=/mp/data-algorithms-book

APP_JAR=$BOOK_HOME/dist/data_algorithms_book.jar THE_JARS=$BOOK_HOME/lib/cloud9-1.3.2.jar

INPUT=/naivebayes/training_data.txt

prog=org.dataalgorithms.chap14.spark.BuildNaiveBayesClassifier $SPARK_HOME/bin/spark-submit --class $prog

--master yarn-cluster --num-executors --driver-memory --executor-memory --executor-cores --jars $THE_JARS $APP_JAR $INPUT

Giai đoạn 2: Sử dụng Trình phân loại để phân loại dữ liệu mới.[11]

Trong giai đoạn 1, chúng tơi đã xây dựng một trình phân loại Nạve Bayes bằng cách sử dụng dữ liệu đào tạo đƣợc cung cấp. Mục tiêu của giai

50

đoạn 2 là phân loại dữ liệu mới bằng cách sử dụng trình phân loại đĩ. Trong giai đoạn 2, chúng tơi đọc trình phân loại từ HDFS và sau đĩ phân loại dữ liệu đầu vào của chúng tơi cho phù hợp. Chúng tơi sẽ sử dụng cách sau đây để phân loại dữ liệu mới của Nạve Bayes:

Cpredict=argcmaxP(C=c) ∏P(Xj= uj|C=c)

m

j=1

Việc phân loại đƣợc thực hiện bởi một lớp trình điều khiển duy nhất (Nạve Bayes Classifier) bằng API Spark. Một lần nữa, sẽ trình bày các bƣớc cấp cao (Ví dụ 2.12), sau đĩ thảo luận chi tiết từng bƣớc.

Ví dụ 2.12. Các bƣớc cấp cao cho giải pháp Spark Nạve Bayes Classifier

Bƣớc 1: Thêm thƣ viện các lớp và giao diện

public class NaiveBayesClassifier implements java.io.Serializable { public static void main(String[] args) throws Exception {

Bƣớc 2: Xử lý các tham số đầu vào

Bƣớc 3: Tạo một đối tƣợng mới trên Spark. Bƣớc 4: Đọc dữ liệu mới để phân loại Bƣớc 5: Đọc trình phân loại từ Hadoop

Bƣớc 6: Bộ nhớ đệm các thành phần trình phân loại, cĩ thể đƣợc sử dụng từ bất kỳ nút nào trong cụm.

Bƣớc 7: Phân loại dữ liệu mới Kết thúc

ctx.close(); System.exit(0); }

Bước 1: Nhập các lớp và giao diện cần thiết

Đối với bƣớc đầu tiên, đƣợc hiển thị trong Ví dụ 2.13, tiến hành nhập các lớp và giao diện cần thiết cho giải pháp này.

51

Ví dụ 2.13. Bƣớc 1: Nhập các lớp và giao diện cần thiết

import java.util.Map; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import scala.Tuple2; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaSparkContext; import org.apache.spark.api.java.function.PairFunction; import org.apache.spark.api.java.function.PairFlatMapFunction; import org.apache.spark.api.java.function.FlatMapFunction; import org.apache.spark.api.java.function.Function; import org.apache.spark.api.java.function.Function2; import org.apache.spark.broadcast.Broadcast; import edu.umd.cloud9.io.pair.PairOfStrings; import org.apache.hadoop.mapred.SequenceFileInputFormat; import org.apache.hadoop.io.DoubleWritable;

Bước 2: Xử lý các tham số đầu vào

Bƣớc hiển thị trong Ví dụ 2.14 xử lý các tham số đầu vào cho giải pháp Ví dụ 2.14. Bƣớc 2: xử lý các tham số đầu vào

if (args.length != 2) {

System.err.println("Usage: NaiveBayesClassifier +

<input-data-filename> <NB-PT-path>");

System.exit(1);

}

52

final String nbProbabilityTablePath = args[1];// một phần của phân

loại

Bước 3: Tạo một đối tượng bối cảnh Spark

Sử dụng lớp SparkUtil, trong ví dụ 2.15, tạo một đối tƣợng của Spark và lƣu trữ trên RDD mới.

Ví dụ 2.15. Bƣớc 3: Tạo một đối tƣợng bối cảnh Spark

JavaSparkContext ctx =

SparkUtil.createJavaSparkContext("naive-bayes");

Bước 4: Đọc dữ liệu mới để được phân loại

Dữ liệu thơ đƣợc phân loại (xem ví dụ 2.16 ) cĩ định dạng bản ghi sau: <attribute_1><,><attribute_2><,>...<,><attribute_m>

Ví dụ 2.16. Bƣớc 4: đọc dữ liệu mới để đƣợc phân loại

JavaRDD<String> newdata = ctx.textFile(inputDataFilename, 1);

Bước 5: Đọc trình phân loại từ Hadoop

Bƣớc này, thể hiện trong ví dụ 2.17, đọc các thành phần phân loại và struc dữ liệu - tures xây dựng bởi BuildNaiveBayesClassifier lớp (trong giai đoạn 1). Khi các thành phần phân loại đƣợc đọc, chúng tơi sẵn sàng phân loại dữ liệu mới.

Ví dụ 2.17. Bƣớc 5: đọc trình phân loại từ Hadoop

JavaPairRDD<PairOfStrings, DoubleWritable> ptRDD = ctx.hadoopFile( nbProbabilityTablePath, SequenceFileInputFormat.class, PairOfStrings.class, DoubleWritable.class );

53

JavaPairRDD<Tuple2<String,String>, Double> classifierRDD = ptRDD.mapToPair( new PairFunction< Tuple2<PairOfStrings,DoubleWritable>, // T Tuple2<String,String>, Double >() { public Tuple2<Tuple2<String,String>,Double> call(Tuple2<PairOfStrings,DoubleWritable> rec) { PairOfStrings pair = rec._1;

Tuple2<String,String> K2 =

Double V2 = new Double(rec._2.get());

new Tuple2<String,String>(pair.getLeftElement(), pair.getRightElement());

return new Tuple2<Tuple2<String,String>,Double>(K2, V2); }

});

Bước 6: Cache các thành phần phân loại

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.18, lƣu trữ các thành phần phân loại (sử dụng lớp Phát sĩng của Spark) để chúng cĩ thể đƣợc truy cập và sử dụng từ bất kỳ nút cụm nào.

Ví dụ 2.18. Bƣớc 6: lƣu trữ các thành phần phân loại Map<Tuple2<String,String>, Double> classifier = classifierRDD.collectAsMap();

final Broadcast<Map<Tuple2<String,String>, Double>>

broadcastClassifier =

ctx.broadcast(classifier);

JavaRDD<String> classesRDD = ctx.textFile("/naivebayes/classes", 1); List<String> CLASSES = classesRDD.collect();

54

final Broadcast<List<String>> broadcastClasses =

ctx.broadcast(CLASSEDS);

Bước 7: Phân loại dữ liệu mới

Bƣớc này, đƣợc hiển thị trong Ví dụ 2.19, sử dụng các thành phần phân loại để phân loại dữ liệu mới.

Ví dụ 2.19. Bƣớc 7: phân loại dữ liệu mới

JavaPairRDD<String,String> classified = newdata.mapToPair(new PairFunction<String, String, String>() {

public Tuple2<String,String> call(String rec) {

Map<Tuple2<String,String>, Double> CLASSIFIER = broadcastClassifier.value();

List<String> CLASSES = broadcastClasses.value(); String[] attributes = rec.split(",");

String selectedClass = null; double maxPosterior = 0.0; for (String aClass : CLASSES) {

double posterior = CLASSIFIER.get(new Tuple2<String,String>("CLASS",

aClass));

for (int i=0; i < attributes.length; i++) {

Double probability = CLASSIFIER.get(new Tuple2<String,String>( attributes[i], aClass)); if (probability == null) { posterior = 0.0; break; } else { if posterior > maxPosterior){

55 selectedClass = aClass; maxPosterior = posterior; } } }

return new Tuple2<String,String>(rec, selectedClass); }

});

classified.saveAsTextFile(“/output/classified”);

Một phần của tài liệu (LUẬN văn THẠC sĩ) ứng dụng mô hình học máy naivebayes trong môi trường spark cho bài toán dự báo khả năng hỏng của đĩa cứng máy tính (Trang 50 - 64)

Tải bản đầy đủ (PDF)

(88 trang)