Реальный бой — базовый процесс машинного обучения и многомерной линейной регрессии.

машинное обучение

Сквозной проект машинного обучения

Контент взят из проектов с открытым исходным кодом:hands1ml.apachecn.org/#/docs/2

Набор данных доступен из вышеуказанного проекта.

Основные этапы решения проблемы с помощью методов машинного обучения:

  1. Обзор проекта.
  2. получить данные.
  3. Находите и визуализируйте данные, чтобы обнаруживать закономерности.
  4. Подготовьте данные для алгоритмов машинного обучения.
  5. Выберите модель для обучения.
  6. Настройте модель.
  7. Дайте решение.
  8. Развертывание, мониторинг и обслуживание систем.

Обзор проекта

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

Блочная группа — это наименьшая географическая единица (обычно от 600 до 3000 человек в блоке), для которой Бюро расследований США публикует выборочные данные. Мы просто назовем его «блок».

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

проблема разграничения

сборочная линия

Ряд компонентов обработки данных называется конвейером данных. Конвейерная обработка распространена в системах машинного обучения, поскольку необходимо обрабатывать и преобразовывать большое количество данных.

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

С другой стороны, без мониторинга неисправный компонент может какое-то время работать незаметно. Данные будут загрязнены, а производительность всей системы снизится.

image.png

определить проблему

Проблема определения машинного обучения очень важна. Построение модели может не быть конечной целью. Как использовать и извлечь выгоду из модели? Это важно, потому что от этого зависит, как очерчена проблема, какой алгоритм выбрать, по каким показателям оценивать производительность модели и сколько усилий потребуется для тонкой настройки.

Посмотрим, как работает текущее решение. Босс обычно дает эталонную производительность и то, как решить проблему. Владелец сказал, что цены на дома в кварталах теперь оцениваются экспертами вручную, а группы экспертов собирают самую свежую информацию о квартале (исключая медианные цены на жилье) и используют сложные правила для оценки. Этот метод является дорогостоящим и трудоемким, а предполагаемые результаты не являются идеальными с частотой ошибок около 15%.

Хорошо, с этой информацией вы можете приступить к проектированию системы. Во-первых, вам нужно обозначить проблему: контролируемое или неконтролируемое обучение или обучение с подкреплением? Это задача классификации, задача регрессии или что-то еще? Использовать пакетное обучение или онлайн-обучение?

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

Выберите метрику производительности/функцию потерь

Выберите показатели эффективности.Типичным показателем для задач регрессии является среднеквадратическая ошибка (RMSE).. Среднеквадратическая ошибка измеряет стандартное отклонение систематической ошибки прогноза. Например, RMSE, равный 50 000, означает, что 68 % прогнозируемых значений системы находятся в пределах 50 000 долларов США от фактического значения, а 95 % прогнозируемых значений находятся в пределах 100 000 долларов США от фактического значения (признак обычно соответствует гауссовскому закону). распределение, т.е. правило "68-95"-99,7": около 68% значений попадают в, 95% значений попадают в, 99,7% значений попадают ввнутри, здесьσравно 50000).

image.png

Общие символы машинного обучения:

  • mэто количество экземпляров в наборе данных, где измеряется RMSE. Например, если вы найдете RMSE с проверочным набором из 2000 блоков, тоm = 2000.

  • x^(i)набор данныхiвектор всех собственных значений (исключая метки) каждого экземпляра,y^(i)этоЭтикетка(Выходное значение этого экземпляра).

    Например, если первый район в наборе данных находится на -118,29 ° долготы, 33,91 ° широты, имеет 1416 жителей, средний доход составляет 38 372 доллара США, а средняя цена дома составляет 156 400 долларов США (без учета других характеристик), то есть:

    x(1)=(118.2933.91141638372),y(1)=(156400)x^{(1)}=\begin{pmatrix} -118,29 \\ 33,91 \\ 1416 \\ 38372\end{pmatrix}, y^{(1)}=\begin{pmatrix}156400\end{pmatrix}
  • hфункция предсказания системы, также известная как гипотеза. Когда система получает вектор признаков экземпляраx^(i), выведет предсказанное значение для этого экземпляраy_hat = h(x^(i))(y_hatчитатьy-hat).

    Например, если система прогнозирует, что средняя цена дома в Районе 1 составляет 158 400 долларов, тоy_hat^(1) = h(x^(1)) = 158400. Ошибка предсказанияy_hat^(1) - y^(1) = 2000.

  • RMSE(X,h)заключается в использовании предположенияhФункция потерь, измеренная на наборе образцов.

Мы используем курсив в нижнем регистре для скалярных значений (например,mилиy^(i)) и имена функций (например,h), строчными буквами жирным шрифтом для векторов (например,x^(i)), жирным шрифтом в верхнем регистре обозначены матрицы (например,X).

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

MAE(X,h)=1mi=1mh(xi)yiMAE(X,h)=\frac{1}{m}\sum_{i=1}^m|h(x^i)-y^i|

И RMSE, и MAE являются методами измерения расстояния между двумя векторами прогнозируемых и целевых значений. Существует несколько способов измерения расстояния, или нормы:

  • Вычисляет корень суммы квадратов, соответствующий евклидовой норме (RMSE): это расстояние было введено. это также называетсяℓ2норма, обозначаемая как||·||₂(или просто||·||).
  • Расчет соответствуетℓ1(Отметить как||·||₁) абсолютной суммы нормы (MAE). Ее также иногда называют манхэттенской нормой, потому что она измеряет расстояние, пройденное двумя точками в городе вдоль сторон прямоугольника.
  • В более общем плане содержитnвектор элементовvизℓkнорма (Min Norm порядка K), определяемая как

  • Чем выше показатель нормы, тем больше внимания уделяется большим значениям, а меньшие игнорируются. Вот почему RMSE более чувствителен к выбросам, чем МАЭ. Но когда выбросы экспоненциально распределены (похоже на нормальную кривую), RMSE работает хорошо.

получить данные

На обработку наборов данных приходится более 60% всей работы, загружайте данные из общедоступных наборов данных и используйте pycharm+jupyter для создания проектов машинного обучения.

Загрузить набор данных

Загрузить набор данных с пандами и отобразить

import pandas as pd
HOUSING_PATH="./dataset/housing/housing.csv"
#加载数据集
def load_housing_data(housing_path=HOUSING_PATH):
    return pd.read_csv(housing_path)

housing=load_housing_data()
housing.head()

Анализ функций данных

Каждая строка представляет собой блок. Всего свойств 10 (6 видно на скриншоте):Долгота, широта, средний возраст дома, общее количество комнат, общее количество спален, население, домохозяйства, средний доход, средняя стоимость дома, расстояние до моря.

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

В наборе данных 20 640 экземпляров, что немного по стандартам машинного обучения, но очень подходит для начала работы. Мы замечаем, что для общего количества спален имеется только 20433 ненулевых значения, а это значит, что 207 блоков не имеют этого значения. Это будет рассмотрено позже.

Все свойства числовые, кроме удаленности от моря. Его тип — Object, поэтому он может содержать любой объект Python, но поскольку элемент загружается из CSV-файла, он должен быть текстового типа.Когда вы только что посмотрели на первые пять элементов в данных, вы, возможно, заметили, что значение в этом столбце повторяется, что означает, что это может быть атрибут, представляющий категорию. можно использоватьvalue_counts()метод, чтобы увидеть, какие категории находятся в элементе, и сколько блоков содержится в каждой категории:

>>> housing["ocean_proximity"].value_counts()
<1H OCEAN     9136
INLAND        6551
NEAR OCEAN    2658
NEAR BAY      2290
ISLAND           5
Name: ocean_proximity, dtype: int64

Посмотрим на другие поля.describe()Метод показывает обобщение численных свойств

count,mean,minиmaxСмысл нескольких строк очевиден. Обратите внимание, что нулевые значения игнорируются (таким образом, общее количество спален составляет 20433 вместо 20640).stdстандартное отклонение (показывающее разброс значений). 25%, 50%, 75% показывают соответствующие квантили: каждый квантиль указывает меньшее значение, чем это значение, и указывает процент группировки. Например, в 25% районов средний возраст меньше 18 лет, в 50% — меньше 29 лет, а в 75% — меньше 37 лет. Эти значения часто называют 25-м процентилем (или первым квартилем), медианой и 75-м процентилем (или третьим квартилем).

**Еще один быстрый способ получить представление о типах данных — нарисовать гистограмму каждого числового свойства. Гистограмма (вертикальная ось) показывает количество экземпляров в определенном диапазоне. ** Вы также можете отображать свойства по одному или вызывать полный набор данных.hist()метод, который рисует гистограмму для каждого числового атрибута. Например, вы можете увидеть чуть более 800 блоков.median_house_valueСтоимость почти равна 500 000 долларов.

#绘图
%matplotlib inline
import matplotlib.pyplot as plt
housing.hist(bins=50,figsize=(20,15))
plt.show()

hist()Методы основаны на Matplotlib, который использует указанный пользователем графический сервер для печати на экране. Поэтому перед рисованием вам нужно указать серверную часть, которую будет использовать Matplotlib. Самый простой способ — использовать магические команды Jupyter.%matplotlib inline. Он говорит Jupyter настроить Matplotlib для использования собственного бэкэнда Jupyter. Рисунок будет отображен в блокноте. Обратите внимание на вызов в Jupytershow()Не обязательно, так как Jupyter автоматически отобразит изображение после выполнения кода.

Также следует отметить, что данные могли быть предварительно обработанными и не совсем реальными данными, например, в этом примере медианный доход при высоком доходе станет 15 (фактически 15,0001), а медианный доход станет 5 (фактически 15,0001) 0,4999).

Средний возраст дома и средняя стоимость дома также ограничены. Последнее может стать серьезной проблемой, поскольку это ваш целевой атрибут (ваш тег). Ваш алгоритм машинного обучения может узнать, что цена не выходит за эту границу. Вам нужно уточнить у нижестоящих команд, если это будет проблемой. Если они скажут вам, что им нужен четкий прогноз, даже если это более 500 000 долларов, у вас есть два варианта:

  1. Для закрытых тегов повторно соберите соответствующие теги;
  2. Удалите эти блоки из тренировочного набора (а также из тестового набора, потому что, если цена дома превысит 500 000 долларов, ваша система будет плохо оценена).

Исследование и визуализация данных, обнаружение закономерностей

Если обучающая выборка очень велика, может потребоваться выборка другой исследовательской выборки, чтобы убедиться, что операция удобна и быстра. В нашем случае набор данных небольшой, поэтому работать с ансамблем просто. Создайте копию, чтобы не повредить тренировочный набор:

housing_train_copy=train_set.copy()

Этот шаг можно рассматривать как анализ данных и выполнение извлечения признаков.

визуализация данных

Поскольку имеется географическая информация (широта и долгота), рекомендуется создать диаграмму рассеивания всех окрестностей для визуализации данных иalphaУстановите значение 0,1, чтобы упростить просмотр плотности точек данных.

image.png

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

Теперь посмотрите на цены. Радиус каждого круга представляет население блока (опцияs), цвет обозначает цену (вариантc). Мы используем предопределенное имяjetцветовая карта (вариантыcmap), который варьируется от синего (низкая цена) до красного (высокая цена) (цветовая карта):

image.png

Такая цветовая карта очень полезна при отображении бумаги.

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

Найдите ассоциации

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

corr_matrix=housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)
//-----
median_house_value    1.000000
median_income         0.688075
income_cat            0.643892
total_rooms           0.134153
housing_median_age    0.105623
households            0.065843
total_bedrooms        0.049686
population           -0.024650
longitude            -0.045967
latitude             -0.144160
Name: median_house_value, dtype: float64

То есть показатели корреляции данных, такие как показатели расстояния, косинусные расстояния, поддержка и достоверность...

Коэффициент корреляции колеблется от -1 до 1. Когда он близок к 1, это означает сильную положительную корреляцию: например, по мере увеличения среднего дохода растет и средняя цена дома. Когда коэффициент корреляции близок к -1, это означает сильную отрицательную корреляцию; вы можете видеть, что существует небольшая отрицательная корреляция между широтой и медианной ценой на жилье (т. е. чем севернее, тем вероятнее, что цены на жилье ниже). Наконец, коэффициент корреляции близок к 0, что означает отсутствие линейной корреляции.

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

Другой способ определить коэффициенты корреляции между атрибутами — использовать Pandas.scatter_matrixфункция, которая отображает каждый числовой атрибут по отношению ко всем другим числовым атрибутам. Поскольку теперь имеется 11 числовых свойств, вы можете получить11 ** 2 = 121Картина Чжан. Наиболее многообещающим атрибутом для прогнозирования средней цены дома является средний доход, ориентируйтесь на рисунок.

image.png

Эта картинка иллюстрирует несколько моментов. **Во-первых, корреляция очень высокая, отчетливо виден восходящий тренд и точки данных не сильно разбросаны. Во-вторых, максимум, который мы видели ранее, четко представленный горизонтальной линией на уровне 500 000 долларов. ** На графике также представлены некоторые не столь очевидные линии: линия на уровне 450 000 долларов, линия на уровне 350 000 долларов, линия на уровне 280 000 долларов и несколько ниже. Вы можете удалить соответствующие блоки, чтобы алгоритм не повторял эти совпадения.

Анализ признаков/Извлечение признаков

Экспериментируйте с комбинациями атрибутов, анализируйте исходный набор данных, находите ассоциации, извлекайте признаки и создавайте новые атрибуты.

Попробуйте различные комбинации атрибутов. Например, общее количество комнат в блоке мало что дает, если вы не знаете, сколько домохозяйств в этом блоке. Все, что вам действительно нужно, это несколько комнат на семью. Точно так же общее количество спален не имеет значения: вам может понадобиться сравнить его с количеством комнат. Население на домохозяйство также представляет собой интересное сочетание признаков. Создайте эти новые свойства:

housing["rooms_per_household"] = housing["total_rooms"]/housing["households"]
housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"]
housing["population_per_household"]=housing["population"]/housing["households"]
corr_matrix=housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)
//
median_house_value          1.000000
median_income               0.688075
income_cat                  0.643892
rooms_per_household         0.151948
total_rooms                 0.134153
housing_median_age          0.105623
households                  0.065843
total_bedrooms              0.049686
population_per_household   -0.023737
population                 -0.024650
longitude                  -0.045967
latitude                   -0.144160
bedrooms_per_room          -0.255880
Name: median_house_value, dtype: float64

предварительная обработка данных

Теперь давайте подготовим данные для алгоритма машинного обучения. Не делайте этого вручную, вам нужно написать несколько функций:

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

Однако сначала вернитесь к чистому тренировочному набору (путем повторной репликацииtrain_set),Отдельные предварительные меры и ярлыки, поскольку мы не хотим применять одно и то же преобразование к прогнозируемому и целевому значениям (примечаниеdrop()Создает резервную копию ваших данных, не затрагиваяstrat_train_set):

Очистка данных

Большинство алгоритмов машинного обучения не могут обрабатывать отсутствующие функции, поэтому сначала создайте несколько функций для работы с отсутствующими функциями. Раньше вы должны были заметить свойствоtotal_bedroomsЕсть некоторые пропущенные значения. Есть три варианта разрешения:

  • удалить соответствующий блок;
  • удалить весь атрибут;
  • Значение выполнения (0, среднее, медиана и т. д.).

использоватьDataFrameизdropna(),drop()fillna()метод, который может быть легко реализован:

housing.dropna(subset=["total_bedrooms"])    # 选项 1
housing.drop("total_bedrooms", axis=1)       # 选项 2
median = housing["total_bedrooms"].median()
housing["total_bedrooms"].fillna(median)     # 选项 3复制ErrorOK!

Если вы выберете вариант 3, вам нужно вычислить медиану обучающей выборки, заполнить недостающие значения обучающей выборки медианой и не забыть сохранить медиану. При последующей оценке системы с тестовым набором необходимо заменить отсутствующие значения в тестовом наборе, и его также можно использовать для замены пропущенных значений в новых данных в режиме реального времени.

Scikit-Learn предоставляет удобный класс для обработки пропущенных значений:SimpleImputer. Вот как это использовать:1. Во-первых, вам нужно создатьImputerПример, указывающий заменить все отсутствующие значения атрибута медианой атрибута:

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy="median")

Поскольку медиану можно вычислить только для числовых атрибутов, нам нужно создать копию, не включающую текстовые атрибуты.ocean_proximityКопия данных:

#使用中位数代替,去掉文本属性
housing_num=housing.drop("ocean_proximity",axis=1)

2. Теперь вы можете использоватьfit()метод будетimputerПример подгонки к обучающим данным:

imputer.fit(housing_num)复制ErrorOK!

imputerРассчитал медиану для каждого атрибута и сохранил результат в переменной экземпляра.statistics_середина. Хотя только свойстваtotal_bedroomsЕсть пропущенные значения, но мы не можем быть уверены, будут ли пропущенные значения для других атрибутов в новых данных в будущем, поэтому безопасно использоватьimputerприменяется к каждому значению.

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

3. Теперь вы можете использовать этот «обученный»imputerпреобразовать обучающий набор, заменив пропущенные значения медианой:

X = imputer.transform(housing_num)

В результате получается обычный массив Numpy, содержащий преобразованные функции. Если вы хотите вернуть его в PandasDataFrame, тоже очень просто:

housing_tr = pd.DataFrame(X, columns=housing_num.columns)

image.png

Обработка текстовых данных

Преобразование текстовых данных в категориальные/числовые

Ранее мы отказались от атрибута категорииocean_proximity, так как это текстовый атрибут, медиану вычислить нельзя. Большинство алгоритмов машинного обучения предпочитают работать с числами, поэтому эти текстовые метки необходимо преобразовать в числа. Здесь нет преобразования, а текстовый атрибут удаляется напрямую.

пользовательский конвертер

Хотя Scikit-Learn предоставляет множество полезных преобразователей, вам все же необходимо написать свои собственные преобразователи для выполнения таких задач, как пользовательские операции очистки или составление свойств. Вам нужно, чтобы ваш доморощенный преобразователь работал без проблем с компонентами Scikit-Learn (такими как Pipelines), поскольку Scikit-Learn полагается на утиную типизацию (а не наследование), все, что вам нужно сделать, это создать класс и реализовать три метода:fit()(возвращениеself),transform()fit_transform(). добавлениемTransformerMixinВ качестве базового класса легко получить последний. Кроме того, если вы добавитеBaseEstimatorкак базовый класс (и избегайте его использования в конструкторе*argsи**kargs), вы получаете два дополнительных метода (get_params() иset_params()), оба из которых могут облегчить автоматическую точную настройку гиперпараметров.

Масштабирование функций

Одно из наиболее важных преобразований, которое должны выполнить данные, — это масштабирование признаков. Алгоритмы машинного обучения, за некоторыми исключениями, плохо работают, когда входные числовые показатели атрибутов различаются. Эта закономерность также применима к данным о собственности: общее количество комнат распределяется от 6 до 39 320, а средний доход распределяется только от 0 до 15. Обратите внимание, что обычно нам не нужно масштабировать целевое значение.

Есть два распространенных способа сделать так, чтобы все атрибуты имели одинаковую меру: нормализация линейной функции (Min-Max масштабирование) и стандартизация (стандартизация).

Нормализация линейной функции (многие называют это нормализацией) проста: значения преобразуются, масштабируются, пока диапазон не станет от 0 до 1. Мы нормализуем, вычитая минимальное значение, а затем разделив его на разницу между максимальным и минимальным значениями. Scikit-Learn предоставляет конвертерMinMaxScalerдля достижения этой функции. у него есть гиперпараметрfeature_range, который позволяет вам изменить диапазон, если вы не хотите, чтобы диапазон был от 0 до 1.

Стандартизация совсем другая: сначала вычтите среднее (поэтому среднее стандартизованных значений всегда равно 0), затем разделите на дисперсию, чтобы полученное распределение имело единичную дисперсию. В отличие от нормализации, нормализация не ограничивает значения определенным диапазоном, что может быть проблематичным для некоторых алгоритмов (например, нейронные сети часто требуют входных значений в диапазоне от 0 до 1). Однако стандартизация очень мало страдает от выбросов. Например, предположим, что средний доход района становится равным 100 по какой-то ошибке, нормализация превратит другие значения в диапазоне от 0 до 15 в 0-0,15, но нормализация не пострадает. Scikit-Learn предоставляет конвертерStandardScalerстандартизировать.

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

from sklearn.preprocessing import StandardScaler

std_scaler=StandardScaler()
XX=std_scaler.fit_transform(housing_num)
XX

Создать тестовый набор

Человеческий мозг — это волшебная система открытий, а это значит, что мозг очень легко подогнать: если вы посмотрите на тестовый набор, вы выберете конкретную модель машинного обучения в соответствии с законами концентрации тестов.. И когда вы используете тестовый набор для оценки частоты ошибок, это может привести к чрезмерно оптимистичной оценке, и реальная развернутая система будет работать плохо. Это называется поворотным смещением.

Теоретически создать тестовый набор просто: просто выберите несколько случайных экземпляров, обычно 20% набора данных, и отложите их в сторону:

**Обычным решением является использование идентификатора каждого экземпляра, чтобы определить, следует ли помещать экземпляр в тестовый набор (при условии, что каждый экземпляр имеет уникальный и неизменный идентификатор). Например, вы можете вычислить хэш каждого идентификатора экземпляра, оставить только последний байт и поместить его в тестовый набор, если он меньше или равен 51 (около 20% от 256). **Это гарантирует, что при нескольких запусках набор тестов останется неизменным, даже если набор данных будет обновлен. Новый тестовый набор будет содержать 20% новых экземпляров, но не будет экземпляров, которые ранее были в обучающем наборе.

При использовании индексов строк в качестве уникальных идентификаторов необходимо убедиться, что новые данные помещаются в конец существующих данных, а строки не удаляются. Если это невозможно, для создания уникального идентификатора можно использовать наиболее стабильные характеристики. Например, широта и долгота района постоянны на протяжении миллионов лет, поэтому их можно объединить в один идентификатор.

Scikit-Learn предоставляет функции для разделения набора данных на подмножества различными способами. Самая простая функцияtrain_test_split

# 切分测试集和训练集,测试集比例0.2
from sklearn.model_selection import train_test_split
train_set,test_set=train_test_split(housing,test_size=0.2,random_state=42)

Вышеуказанное использует случайную выборку, которая обычно работает, когда ваш набор данных большой (особенно по сравнению с количеством атрибутов); но если набор данных небольшой, существует риск смещения выборки. Когда опросная компания хочет опросить 1000 человек, они не случайно выбирают 1000 человек в телефонной будке. Обоснованная компания должна обеспечить, чтобы 1000 человек представили населения в целом. Например, 51,3% населения США - женщины и 48,7% мужчин. Таким образом, в Соединенных Штатах, строгие опросы необходимо обеспечить также тот же соотношение: 513 женщин, 487 мужчин. ** Это называется стратифицированной выборкой: разделите население в однородные подгруппы, называемые слоями и принимают соответствующее количество экземпляров из каждого слоя, чтобы гарантировать, что тестовый набор является представителем общей численности населения. ** Если система опроса использовала чистую случайную выборку, было бы 12% вероятность смещения выборки: менее 49% женщин или более 54%. В любом случае, выводы будут серьезно перекошены.

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

Большинство значений среднего дохода сгруппированы вокруг 2-5 (10 000 долларов США), но некоторые средние доходы превышают 6. Важно, чтобы в ваших данных было достаточное количество экземпляров каждой страты в вашем наборе данных. В противном случае оценка важности стратификации будет необъективной. Это означает, что у вас не может быть слишком много слоев, и каждый слой должен быть достаточно большим.Следующий код создает атрибут категории дохода путем деления медианного дохода на 1,5 (чтобы ограничить количество категорий дохода) сceilЗначения округляются (для получения дискретных классов), и все классы больше 5 группируются в класс 5.

Новый атрибут является распространенным методом предварительной обработки данных.Здесь стратифицированная выборка может быть выполнена в соответствии с новым атрибутом, чтобы обеспечить лучший эффект обучения.

import numpy as np
housing['income_cat']=np.ceil(housing['median_income'] / 1.5)
housing['income_cat'].where(housing['income_cat'] < 5,5.0,inplace=True)
housing.head()

Теперь можно провести стратифицированную выборку по классификации доходов. Вы можете использовать Scikit-Learn'sStratifiedShuffleSplitсвоего рода:

from sklearn.model_selection import StratifiedShuffleSplit

split=StratifiedShuffleSplit(n_splits=1,test_size=0.2,random_state=42)
train_set=pd.DataFrame()
test_set=pd.DataFrame()
for train_index,test_index in split.split(housing,housing['income_cat']):
    train_set=housing.loc[train_index]
    test_set=housing.loc[test_index]
# 验证分层抽样比例
print(housing['income_cat'].value_counts()/len(housing))
# 删除自定义属性
for set in (train_set,test_set):
    set.drop(['income_cat'],axis=1,inplace=True)
print(train_set.head())
>>> housing["income_cat"].value_counts() / len(housing)
3.0    0.350581
2.0    0.318847
4.0    0.176308
5.0    0.114438
1.0    0.039826
Name: income_cat, dtype: float64

Теперь доля пропорционального теста на проблем пробоотборника доходной классификации и общий набор данных практически идентичен, но случайное отклонение данных отбора проб, серьезное отклонение.

Причина, по которой создание тестового набора занимает много времени, заключается в том, что тестовый набор часто игнорируется, но на самом деле это очень важная часть машинного обучения. Кроме того, многие идеи в процессе создания тестового набора очень полезны для последующего обсуждения перекрестной проверки.

Выбрать и обучить модель

Тренируйтесь и оценивайте на тренировочном наборе

Поскольку это контролируемое обучение, сначала разделите атрибуты обучения и метки.

train_set_attr=train_set.drop(["median_house_value"],axis=1)
train_set_label=train_set["median_house_value"]
test_set_attr=test_set.drop(["median_house_value"],axis=1)
test_set_label=test_set["median_house_value"]

Давайте сначала обучим модель линейной регрессии:

from sklearn.linear_model import LinearRegression
lin_reg=LinearRegression()
lin_reg.fit(train_set_attr,train_set_label)

Затем используйте модель, чтобы делать прогнозы и вычислять функцию потерь.

from sklearn.metrics import mean_squared_error
housing_predictions=lin_reg.predict(test_set_attr)
lin_mse=mean_squared_error(test_set_label,housing_predictions)
line_rmse=np.sqrt(lin_mse)
line_rmse
# 73368.96605703988

Хорошо, хоть что-то лучше, чем ничего, но, видимо, вышло не очень: большинство кварталовmedian_housing_valuesОн находится между 120 000 и 265 000 долларов, поэтому ошибка прогноза в 73 368 долларов неудовлетворительна.

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

K-кратная перекрестная проверка

Самый простой метод называется,k-кратная перекрестная проверка. k-кратная перекрестная проверка делит обучающий набор на k меньших наборов. КаждыйkСкладывание будет следовать следующему процессу:

  • будетk-1Подмножество обучающего набора используется в качестве обучающих данных для обучения модели,
  • Используйте оставшийся 1 подмножество обучающего набора для проверки модели (то есть используйте его в качестве тестового набора для расчета показателей производительности модели, таких как точность).

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

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
forest_reg=RandomForestRegressor()
scores=cross_val_score(forest_reg,train_set_attr,train_set_label,scoring="neg_mean_squared_error",cv=3)
print(scores)
forest_reg.fit(train_set_attr,train_set_label)

Если эффект хуже исходного, значит, произошло переобучение

Используйте линейную регрессию, дерево решений, предсказание случайного леса соответственно

Суммировать

Наука о данных и анализ данных, применение методов статистического обучения, вообще говоря, шаги примерно одинаковы

Сбор данных, анализ данных, извлечение признаков, выбор признаков, очистка данных, создание тестовых и обучающих наборов, выбор модели, перекрестная проверка, прогнозирование модели

Но вообще говоря, прогнозирующий эффект модели не очень хорош, и необходимо постоянно анализировать данные и корректировать параметры.

Исходный блокнот:

GitHub.com/age Рон/Бин…

GitHub.com/LS lwind/Mac…