Для чего используется Тест-и-набор?

К сожалению, эта функция недоступна в старшей версии Spark MLlib 1.5.1.

Однако вы можете найти ее в недавнем API Pipeline в Spark MLlib 2.x как RandomForestClassifier:

import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.classification.RandomForestClassifier
import org.apache.spark.ml.feature.{IndexToString, StringIndexer, VectorIndexer}
import org.apache.spark.mllib.util.MLUtils

// Load and parse the data file, converting it to a DataFrame.
val data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt").toDF

// Index labels, adding metadata to the label column.
// Fit on whole dataset to include all labels in index.
val labelIndexer = new StringIndexer()
  .setInputCol("label")
  .setOutputCol("indexedLabel").fit(data)

// Automatically identify categorical features, and index them.
// Set maxCategories so features with > 4 distinct values are treated as continuous.
val featureIndexer = new VectorIndexer()
  .setInputCol("features")
  .setOutputCol("indexedFeatures")
  .setMaxCategories(4).fit(data)

// Split the data into training and test sets (30% held out for testing)
val Array(trainingData, testData) = data.randomSplit(Array(0.7, 0.3))

// Train a RandomForest model.
val rf = new RandomForestClassifier()
  .setLabelCol(labelIndexer.getOutputCol)
  .setFeaturesCol(featureIndexer.getOutputCol)
  .setNumTrees(10)

// Convert indexed labels back to original labels.
val labelConverter = new IndexToString()
  .setInputCol("prediction")
  .setOutputCol("predictedLabel")
  .setLabels(labelIndexer.labels)

// Chain indexers and forest in a Pipeline
val pipeline = new Pipeline()
  .setStages(Array(labelIndexer, featureIndexer, rf, labelConverter))

// Fit model. This also runs the indexers.
val model = pipeline.fit(trainingData)

// Make predictions.
val predictions = model.transform(testData)
// predictions: org.apache.spark.sql.DataFrame = [label: double, features: vector, indexedLabel: double, indexedFeatures: vector, rawPrediction: vector, probability: vector, prediction: double, predictedLabel: string]

predictions.show(10)
// +-----+--------------------+------------+--------------------+-------------+-----------+----------+--------------+
// |label|            features|indexedLabel|     indexedFeatures|rawPrediction|probability|prediction|predictedLabel|
// +-----+--------------------+------------+--------------------+-------------+-----------+----------+--------------+
// |  0.0|(692,[124,125,126...|         1.0|(692,[124,125,126...|   [0.0,10.0]|  [0.0,1.0]|       1.0|           0.0|
// |  0.0|(692,[124,125,126...|         1.0|(692,[124,125,126...|    [1.0,9.0]|  [0.1,0.9]|       1.0|           0.0|
// |  0.0|(692,[129,130,131...|         1.0|(692,[129,130,131...|    [1.0,9.0]|  [0.1,0.9]|       1.0|           0.0|
// |  0.0|(692,[154,155,156...|         1.0|(692,[154,155,156...|    [1.0,9.0]|  [0.1,0.9]|       1.0|           0.0|
// |  0.0|(692,[154,155,156...|         1.0|(692,[154,155,156...|    [1.0,9.0]|  [0.1,0.9]|       1.0|           0.0|
// |  0.0|(692,[181,182,183...|         1.0|(692,[181,182,183...|    [1.0,9.0]|  [0.1,0.9]|       1.0|           0.0|
// |  1.0|(692,[99,100,101,...|         0.0|(692,[99,100,101,...|    [4.0,6.0]|  [0.4,0.6]|       1.0|           0.0|
// |  1.0|(692,[123,124,125...|         0.0|(692,[123,124,125...|   [10.0,0.0]|  [1.0,0.0]|       0.0|           1.0|
// |  1.0|(692,[124,125,126...|         0.0|(692,[124,125,126...|   [10.0,0.0]|  [1.0,0.0]|       0.0|           1.0|
// |  1.0|(692,[125,126,127...|         0.0|(692,[125,126,127...|   [10.0,0.0]|  [1.0,0.0]|       0.0|           1.0|
// +-----+--------------------+------------+--------------------+-------------+-----------+----------+--------------+
// only showing top 10 rows

Примечание. Этот пример приведен в официальной документации по ML-Random классификатору леса Spark MLlib.

И вот некоторые объяснения в некоторых выходных столбцах:

  • predictionCol представляет предсказанную метку.
  • rawPredictionCol представляет вектор длины # классов с подсчетами ярлыков обучающих экземпляров на узле дерева, который делает предсказание (доступно только для классификации).
  • probabilityCol представляет вероятность вектора длины # классов, равную rawPrediction, нормированную на многокомпонентное распределение (доступно только с классификацией).

11
задан Gilles 'SO- stop being evil' 23 October 2012 в 21:08
поделиться

5 ответов

Вы используете его любое время, которое Вы хотите записать данным в память после выполнения некоторой работы и удостовериться, что другой поток не перезаписал место назначения, так как Вы запустили. Много lock/mutex-free алгоритмов принимает эту форму.

8
ответ дан 3 December 2019 в 03:19
поделиться

Хорошим примером является "инкремент".

Скажите, что два потока выполняются a = a + 1. Сказать a запускается со значения 100. Если бы оба потока работают одновременно (многоядерный), оба загрузились бы a как 100, инкремент к 101, и хранилище, которые въезжают задним ходом a. Неправильно!

С тестом-и-набором Вы говорите "Набор a кому: 101, но только если это в настоящее время имеет значение 100." В этом случае один поток пройдет тот тест, но другой перестанет работать. В случае возникновения отказов поток может повторить весь оператор, на этот раз загрузившись a как 101. Успех.

Это обычно быстрее, чем использование взаимного исключения потому что:

  1. Большую часть времени нет состояния состязания, таким образом, обновление происходит, не имея необходимость получать своего рода взаимное исключение.
  2. Даже во время коллизии, один поток не заблокирован вообще, и это быстрее для другого потока, чтобы просто вращать и повторить, чем это должно было бы приостановить себя в строке для некоторого взаимного исключения.
14
ответ дан 3 December 2019 в 03:19
поделиться

Предположите запись банковского приложения, и приложение имело запрос для удаления десяти фунтов (да, я англичанин ;)) из учетной записи. Таким образом, необходимо считать баланс текущего счета в локальную переменную, вычесть отказ и затем записать баланс обратно к памяти.

Однако, что, если другой, параллельный запрос происходит между Вами читающий значение и Вас выписывающий его? Существует возможность, что результат того запроса будет полностью перезаписан первым, и остаток на счете будет неправильным.

Тест-и-набор помогает нам решить ту проблему путем проверки, что значение перезапись - то, что Вы думаете, что это должно быть. В этом случае можно проверить, что баланс был исходным значением, которое Вы читаете. Так как это является атомарным, это непрерываемо, таким образом, никто не может вытянуть коврик из-под Вас между чтением и записью.

Другой способ решить ту же проблему состоит в том, чтобы вынуть блокировку на ячейке памяти. К сожалению, в блокировках чрезвычайно трудно разобраться, трудно рассуждать о, иметь проблемы масштабируемости и вести себя плохо перед лицом отказов, таким образом, они не идеал (но определенно практичный) решение. Подходы теста-и-набора формируют основание некоторого программного обеспечения Транзакционные Памяти, которые оптимистично позволяют каждой транзакции выполняться одновременно, за счет прокрутки их всех спина, если они конфликтуют.

5
ответ дан 3 December 2019 в 03:19
поделиться

В основном его использование точно для взаимных исключений, учитывая огромную важность атомарности.Именно.

Тест-и-набор является операцией, которая может быть выполнена с двумя другими инструкциями, неатомарный и быстрее (атомарность переносит аппаратные средства наверху, когда в многопроцессорных системах), так обычно Вы не использовали бы его по другим причинам.

1
ответ дан 3 December 2019 в 03:19
поделиться

Это используется, когда необходимо получить общее значение, сделать что-то с ним и изменить значение, предположив, что другой поток уже не изменил его.

Что касается практических применений, в прошлый раз, когда я видел, это было в реализациях параллельных очередей (очереди, которые могут быть продвинуты/вытолканы несколькими потоками, не нуждаясь в семафорах или взаимных исключениях).

Почему Вы использовали бы TestAndSet, а не взаимное исключение? Поскольку это обычно требует меньше служебного, чем взаимное исключение. Где взаимное исключение требует вмешательства ОС, TestAndSet может быть реализован как единственная атомарная инструкция относительно ЦП. При выполнении в параллельных средах с 100's потоков, единственное взаимное исключение в критическом разделе кода может вызвать серьезные узкие места.

0
ответ дан 3 December 2019 в 03:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: