Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Узнайте, как использовать Apache Spark MLlib для создания приложения машинного обучения. Приложение выполняет прогнозный анализ открытого набора данных. В встроенных библиотеках машинного обучения Spark в этом примере используется классификация с помощью логистической регрессии.
MLlib — это базовая библиотека Spark, которая предоставляет множество служебных программ, полезных для задач машинного обучения, таких как:
- Классификация
- Регрессия
- Кластеризация
- Моделирование
- Сингулярное разложение (SVD) и анализ главных компонентов (PCA)
- Тестирование гипотез и вычисление выборки статистики
Общие сведения о классификации и логистической регрессии
Классификация, популярная задача машинного обучения, — это процесс сортировки входных данных в категории. Это задание алгоритма классификации, чтобы выяснить, как назначать "метки" входным данным, которые вы предоставляете. Например, можно подумать о алгоритме машинного обучения, который принимает данные акций в качестве входных данных. Затем делит акции на две категории: акции, которые следует продавать и акции, которые вы должны сохранить.
Логистическая регрессия — это алгоритм, используемый для классификации. API логистической регрессии Spark полезен для двоичной классификации или классификации входных данных в одну из двух групп. Дополнительные сведения о логистической регрессии см. в Википедии.
В итоге процесс логистической регрессии создает логистическую функцию. Используйте функцию для прогнозирования вероятности того, что входной вектор принадлежит одной группе или другой.
Пример прогнозного анализа данных проверки продуктов питания
В этом примере с помощью Spark выполняется некоторый прогнозный анализ данных проверки продуктов питания (Food_Inspections1.csv). Данные, полученные через портал данных Города Чикаго. Этот набор данных содержит информацию об инспекциях пищевых заведений, проведенных в Чикаго. Включая сведения о каждом учреждении, обнаруженные нарушения (если таковые есть) и результаты проверки. CSV-файл данных уже доступен в учетной записи хранения, связанной с кластером в /HdiSamples/HdiSamples/FoodInspectionData/Food_Inspections1.csv.
В следующих шагах вы разрабатываете модель, чтобы узнать, что требуется для прохождения или непрохождения санитарной проверки.
Создание приложения машинного обучения Apache Spark MLlib
Создайте записную книжку Jupyter Notebook с помощью ядра PySpark. Инструкции см. в разделе Создание файла записной книжки Jupyter Notebook.
Импортируйте типы, необходимые для этого приложения. Скопируйте и вставьте следующий код в пустую ячейку, а затем нажмите клавиши SHIFT+ВВОД.
from pyspark.ml import Pipeline from pyspark.ml.classification import LogisticRegression from pyspark.ml.feature import HashingTF, Tokenizer from pyspark.sql import Row from pyspark.sql.functions import UserDefinedFunction from pyspark.sql.types import *
Ядро PySpark позволяет не задавать контексты явным образом. Контексты Spark и Hive автоматически создаются при запуске первой ячейки кода.
Создание входного кадра данных
Используйте контекст Spark для извлечения необработанных CSV-данных в память в виде неструктурированного текста. Затем используйте библиотеку CSV Python для анализа каждой строки данных.
Выполните следующие строки, чтобы создать устойчивый распределенный набор данных (RDD), импортируя и анализируя входные данные.
def csvParse(s): import csv from io import StringIO sio = StringIO(s) value = next(csv.reader(sio)) sio.close() return value inspections = sc.textFile('/HdiSamples/HdiSamples/FoodInspectionData/Food_Inspections1.csv')\ .map(csvParse)
Выполните следующий код, чтобы получить одну строку из RDD, чтобы просмотреть схему данных:
inspections.take(1)
Выходные данные:
[['413707', 'LUNA PARK INC', 'LUNA PARK DAY CARE', '2049789', "Children's Services Facility", 'Risk 1 (High)', '3250 W FOSTER AVE ', 'CHICAGO', 'IL', '60625', '09/21/2010', 'License-Task Force', 'Fail', '24. DISH WASHING FACILITIES: PROPERLY DESIGNED, CONSTRUCTED, MAINTAINED, INSTALLED, LOCATED AND OPERATED - Comments: All dishwashing machines must be of a type that complies with all requirements of the plumbing section of the Municipal Code of Chicago and Rules and Regulation of the Board of Health. OBSEVERD THE 3 COMPARTMENT SINK BACKING UP INTO THE 1ST AND 2ND COMPARTMENT WITH CLEAR WATER AND SLOWLY DRAINING OUT. INST NEED HAVE IT REPAIR. CITATION ISSUED, SERIOUS VIOLATION 7-38-030 H000062369-10 COURT DATE 10-28-10 TIME 1 P.M. ROOM 107 400 W. SURPERIOR. | 36. LIGHTING: REQUIRED MINIMUM FOOT-CANDLES OF LIGHT PROVIDED, FIXTURES SHIELDED - Comments: Shielding to protect against broken glass falling into food shall be provided for all artificial lighting sources in preparation, service, and display facilities. LIGHT SHIELD ARE MISSING UNDER HOOD OF COOKING EQUIPMENT AND NEED TO REPLACE LIGHT UNDER UNIT. 4 LIGHTS ARE OUT IN THE REAR CHILDREN AREA,IN THE KINDERGARDEN CLASS ROOM. 2 LIGHT ARE OUT EAST REAR, LIGHT FRONT WEST ROOM. NEED TO REPLACE ALL LIGHT THAT ARE NOT WORKING. | 35. WALLS, CEILINGS, ATTACHED EQUIPMENT CONSTRUCTED PER CODE: GOOD REPAIR, SURFACES CLEAN AND DUST-LESS CLEANING METHODS - Comments: The walls and ceilings shall be in good repair and easily cleaned. MISSING CEILING TILES WITH STAINS IN WEST,EAST, IN FRONT AREA WEST, AND BY THE 15MOS AREA. NEED TO BE REPLACED. | 32. FOOD AND NON-FOOD CONTACT SURFACES PROPERLY DESIGNED, CONSTRUCTED AND MAINTAINED - Comments: All food and non-food contact equipment and utensils shall be smooth, easily cleanable, and durable, and shall be in good repair. SPLASH GUARDED ARE NEEDED BY THE EXPOSED HAND SINK IN THE KITCHEN AREA | 34. FLOORS: CONSTRUCTED PER CODE, CLEANED, GOOD REPAIR, COVING INSTALLED, DUST-LESS CLEANING METHODS USED - Comments: The floors shall be constructed per code, be smooth and easily cleaned, and be kept clean and in good repair. INST NEED TO ELEVATE ALL FOOD ITEMS 6INCH OFF THE FLOOR 6 INCH AWAY FORM WALL. ', '41.97583445690982', '-87.7107455232781', '(41.97583445690982, -87.7107455232781)']]
Выходные данные дают представление о схеме входного файла. Он включает в себя имя каждого учреждения и тип учреждения. Кроме того, адрес, данные инспекций и местоположение, помимо прочего.
Выполните следующий код, чтобы создать кадр данных (df) и временную таблицу (CountResults) с несколькими столбцами, полезными для прогнозного анализа.
sqlContext
используется для преобразования структурированных данных.schema = StructType([ StructField("id", IntegerType(), False), StructField("name", StringType(), False), StructField("results", StringType(), False), StructField("violations", StringType(), True)]) df = spark.createDataFrame(inspections.map(lambda l: (int(l[0]), l[1], l[12], l[13])) , schema) df.registerTempTable('CountResults')
В таблице нас интересуют четыре столбца: ID, имя, результаты и нарушения.
Выполните следующий код, чтобы получить небольшой пример данных:
df.show(5)
Выходные данные:
+------+--------------------+-------+--------------------+ | id| name|results| violations| +------+--------------------+-------+--------------------+ |413707| LUNA PARK INC| Fail|24. DISH WASHING ...| |391234| CAFE SELMARIE| Fail|2. FACILITIES TO ...| |413751| MANCHU WOK| Pass|33. FOOD AND NON-...| |413708|BENCHMARK HOSPITA...| Pass| | |413722| JJ BURGER| Pass| | +------+--------------------+-------+--------------------+
Общие сведения о данных
Начнем с того, что содержит набор данных.
Выполните следующий код, чтобы отобразить уникальные значения в столбце результатов :
df.select('results').distinct().show()
Выходные данные:
+--------------------+ | results| +--------------------+ | Fail| |Business Not Located| | Pass| | Pass w/ Conditions| | Out of Business| +--------------------+
Выполните следующий код, чтобы визуализировать распределение этих результатов:
%%sql -o countResultsdf SELECT COUNT(results) AS cnt, results FROM CountResults GROUP BY results
Магия
%%sql
, которая идет за-o countResultsdf
, гарантирует, что выходные данные запроса сохраняются локально на сервере Jupyter (обычно это головной узел кластера). Выходные данные сохраняются в виде фрейма данных Pandas с указанным именем countResultsdf. Дополнительные сведения о%%sql
магии и других магиях, доступных в ядре PySpark, см. в разделе "Ядра", доступные в Jupyter Notebook с кластерами Apache Spark HDInsight.Выходные данные:
Вы также можете использовать Matplotlib, библиотеку, используемую для создания визуализации данных, для создания диаграммы. Так как диаграмма должна быть создана из локально сохранённого кадра данных countResultsdf, фрагмент кода должен начинаться с магической команды
%%local
. Это действие гарантирует локальное выполнение кода на сервере Jupyter.%%local %matplotlib inline import matplotlib.pyplot as plt labels = countResultsdf['results'] sizes = countResultsdf['cnt'] colors = ['turquoise', 'seagreen', 'mediumslateblue', 'palegreen', 'coral'] plt.pie(sizes, labels=labels, autopct='%1.1f%%', colors=colors) plt.axis('equal')
Чтобы предсказать результат проверки продуктов питания, необходимо разработать модель на основе нарушений. Так как логистическая регрессия является двоичным методом классификации, имеет смысл сгруппировать данные результатов на две категории: Fail и Pass:
Пропуск
- Пропуск
- Пас с условиями
Сбой
- Сбой
Удалить
- Бизнес не найден
- Вне бизнеса
Данные с другими результатами ("Бизнес не найден" или "Бизнес закрыт") не полезны, и они составляют небольшой процент результатов все равно.
Выполните следующий код, чтобы преобразовать существующий кадр данных(
df
) в новый кадр данных, где каждая проверка представлена как пара нарушений меток. В этом случае метка0.0
представляет сбой, метку1.0
представляет успех, а метка-1.0
представляет некоторые результаты, помимо этих двух результатов.def labelForResults(s): if s == 'Fail': return 0.0 elif s == 'Pass w/ Conditions' or s == 'Pass': return 1.0 else: return -1.0 label = UserDefinedFunction(labelForResults, DoubleType()) labeledData = df.select(label(df.results).alias('label'), df.violations).where('label >= 0')
Выполните следующий код, чтобы отобразить одну строку помеченных данных:
labeledData.take(1)
Выходные данные:
[Row(label=0.0, violations=u"41. PREMISES MAINTAINED FREE OF LITTER, UNNECESSARY ARTICLES, CLEANING EQUIPMENT PROPERLY STORED - Comments: All parts of the food establishment and all parts of the property used in connection with the operation of the establishment shall be kept neat and clean and should not produce any offensive odors. REMOVE MATTRESS FROM SMALL DUMPSTER. | 35. WALLS, CEILINGS, ATTACHED EQUIPMENT CONSTRUCTED PER CODE: GOOD REPAIR, SURFACES CLEAN AND DUST-LESS CLEANING METHODS - Comments: The walls and ceilings shall be in good repair and easily cleaned. REPAIR MISALIGNED DOORS AND DOOR NEAR ELEVATOR. DETAIL CLEAN BLACK MOLD LIKE SUBSTANCE FROM WALLS BY BOTH DISH MACHINES. REPAIR OR REMOVE BASEBOARD UNDER DISH MACHINE (LEFT REAR KITCHEN). SEAL ALL GAPS. REPLACE MILK CRATES USED IN WALK IN COOLERS AND STORAGE AREAS WITH PROPER SHELVING AT LEAST 6' OFF THE FLOOR. | 38. VENTILATION: ROOMS AND EQUIPMENT VENTED AS REQUIRED: PLUMBING: INSTALLED AND MAINTAINED - Comments: The flow of air discharged from kitchen fans shall always be through a duct to a point above the roofline. REPAIR BROKEN VENTILATION IN MEN'S AND WOMEN'S WASHROOMS NEXT TO DINING AREA. | 32. FOOD AND NON-FOOD CONTACT SURFACES PROPERLY DESIGNED, CONSTRUCTED AND MAINTAINED - Comments: All food and non-food contact equipment and utensils shall be smooth, easily cleanable, and durable, and shall be in good repair. REPAIR DAMAGED PLUG ON LEFT SIDE OF 2 COMPARTMENT SINK. REPAIR SELF CLOSER ON BOTTOM LEFT DOOR OF 4 DOOR PREP UNIT NEXT TO OFFICE.")]
Создание модели логистической регрессии из входного кадра данных
Последняя задача — преобразовать помеченные данные. Преобразуйте данные в формат, анализируемый логистической регрессией. Входные данные для алгоритма логистической регрессии требуют набора пар векторов метка-признак. Где "вектор признаков" является вектором чисел, представляющих входную точку. Таким образом, необходимо преобразовать столбец "нарушения", который является полуструктурирован и содержит много комментариев в свободном тексте. Преобразуйте столбец в массив реальных чисел, которые компьютер может легко понять.
Одним из стандартных подходов машинного обучения для обработки естественного языка является назначение каждого отдельного слова индексом. Затем передайте вектор алгоритму машинного обучения. Таким образом, значение каждого индекса содержит относительную частоту этого слова в текстовой строке.
MLlib предоставляет простой способ выполнения этой операции. Во-первых, "токенизировать" каждую строку нарушений, чтобы получить отдельные слова в каждой строке. Затем используйте алгоритм HashingTF
логистической регрессии для преобразования каждого набора маркеров в вектор признаков, который затем можно передать в алгоритм логистической регрессии для создания модели. Все эти шаги выполняются в последовательности с помощью конвейера.
tokenizer = Tokenizer(inputCol="violations", outputCol="words")
hashingTF = HashingTF(inputCol=tokenizer.getOutputCol(), outputCol="features")
lr = LogisticRegression(maxIter=10, regParam=0.01)
pipeline = Pipeline(stages=[tokenizer, hashingTF, lr])
model = pipeline.fit(labeledData)
Оценка модели с помощью другого набора данных
Вы можете использовать созданную ранее модель для прогнозирования результатов новых проверок. Прогнозы основаны на наблюдаемых нарушениях. Вы обучили эту модель на наборе данных Food_Inspections1.csv. Для оценки силы этой модели на новых данных можно использовать второй набор данных Food_Inspections2.csv. Этот второй набор данных (Food_Inspections2.csv) находится в контейнере хранилища по умолчанию, связанном с кластером.
Выполните следующий код, чтобы создать новый кадр данных, прогнозыDf , содержащие прогноз, созданный моделью. Фрагмент кода также создает временную таблицу с именем "Прогнозы " на основе кадра данных.
testData = sc.textFile('wasbs:///HdiSamples/HdiSamples/FoodInspectionData/Food_Inspections2.csv')\ .map(csvParse) \ .map(lambda l: (int(l[0]), l[1], l[12], l[13])) testDf = spark.createDataFrame(testData, schema).where("results = 'Fail' OR results = 'Pass' OR results = 'Pass w/ Conditions'") predictionsDf = model.transform(testDf) predictionsDf.registerTempTable('Predictions') predictionsDf.columns
Выходные данные должны отображаться следующим образом:
['id', 'name', 'results', 'violations', 'words', 'features', 'rawPrediction', 'probability', 'prediction']
Посмотрите на один из прогнозов. Запустите этот фрагмент кода:
predictionsDf.take(1)
Существует прогноз для первой записи в тестовом наборе данных.
Метод
model.transform()
применяет то же преобразование к любым новым данным с той же схемой и возвращает прогноз классификации данных. Вы можете сделать некоторые статистические данные, чтобы получить представление о том, как были прогнозы:numSuccesses = predictionsDf.where("""(prediction = 0 AND results = 'Fail') OR (prediction = 1 AND (results = 'Pass' OR results = 'Pass w/ Conditions'))""").count() numInspections = predictionsDf.count() print ("There were", numInspections, "inspections and there were", numSuccesses, "successful predictions") print ("This is a", str((float(numSuccesses) / float(numInspections)) * 100) + "%", "success rate")
Выходные данные выглядят так:
There were 9315 inspections and there were 8087 successful predictions This is a 86.8169618894% success rate
Использование логистической регрессии с Spark дает модель связи между описаниями нарушений на английском языке. Сможет ли данный бизнес пройти или провалить проверку безопасности пищевых продуктов.
Создание визуального представления прогноза
Теперь можно создать окончательную визуализацию, чтобы помочь вам подумать о результатах этого теста.
Сначала вы извлекаете различные прогнозы и результаты из временной таблицы прогнозов , созданной ранее. Следующие запросы разделяют выходные данные как true_positive, false_positive, true_negative и false_negative. В приведенных ниже запросах вы отключите визуализацию с помощью
-q
и также сохраните выходные данные (используя-o
) в качестве кадров данных, которые затем можно использовать с магией%%local
.%%sql -q -o true_positive SELECT count(*) AS cnt FROM Predictions WHERE prediction = 0 AND results = 'Fail'
%%sql -q -o false_positive SELECT count(*) AS cnt FROM Predictions WHERE prediction = 0 AND (results = 'Pass' OR results = 'Pass w/ Conditions')
%%sql -q -o true_negative SELECT count(*) AS cnt FROM Predictions WHERE prediction = 1 AND results = 'Fail'
%%sql -q -o false_negative SELECT count(*) AS cnt FROM Predictions WHERE prediction = 1 AND (results = 'Pass' OR results = 'Pass w/ Conditions')
Наконец, используйте следующий фрагмент кода, чтобы создать график с помощью Matplotlib.
%%local %matplotlib inline import matplotlib.pyplot as plt labels = ['True positive', 'False positive', 'True negative', 'False negative'] sizes = [true_positive['cnt'], false_positive['cnt'], false_negative['cnt'], true_negative['cnt']] colors = ['turquoise', 'seagreen', 'mediumslateblue', 'palegreen', 'coral'] plt.pie(sizes, labels=labels, autopct='%1.1f%%', colors=colors) plt.axis('equal')
Вы увидите следующие выходные данные:
На этой диаграмме положительный результат относится к неуспешной проверке пищевых продуктов, а отрицательный результат относится к успешной проверке.
Выключить ноутбук
После запуска приложения необходимо завершить работу записной книжки, чтобы освободить ресурсы. Для этого в меню File (Файл) записной книжки выберите пункт Close and Halt (Закрыть и остановить). Это действие завершает работу и закрывает записную книжку.