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

  • Прогноз цены дома
  • Классификация доходов
  • Прогноз оттока клиентов
  • Повторить прогноз покупателя

Введение

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

О данных

Этот набор данных взят из Kaggle. Источник: https://www.kaggle.com/anthonypino/melbourne-housing-market. Он также доступен по ссылке на GitHub в конце блога вместе с полным блокнотом. Имеется 21 столбец и 340009 экземпляров с различными факторами, влияющими на столбец Price . Из 20 независимых переменных 10 являются категориальными/порядковыми.

Исследовательский анализ данных (EDA)

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

  1. Обработка пропущенных значений:

Отсутствующие значения должны быть обработаны с использованием одного из доступных методов до построения модели.

а. Определить отсутствующие значения. Определить отсутствующие значения в pandas довольно просто. Мы использовали это для расчета процента отсутствующего значения.

percent_missing = df_house_price.isnull().sum() * 100 / len(df_house_price)
percent_missing

В 9 столбцах набора данных имеется от 20 до 60 процентов пропущенных значений.

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

df_house_price[‘Bathroom’].fillna(df_house_price[‘Bathroom’].mode()[0], inplace = True)

Для столбцов с числовыми значениями для вменения можно использовать либо среднее значение, либо медиану. Идеально использовать медианное значение распределения с перекосом. Вы можете проверить распределение всех столбцов, используя метод описания в кадре данных pandas. df_house_price.describe()

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

df_house_price['Landsize'].fillna(df_house_price['Landsize'].median(), inplace = True)

в. Отбрасывание отсутствующих значений. Если в столбце всего несколько отсутствующих значений (‹2–3%), можно полностью удалить эти строки, если набор данных достаточно велик. Итак, мы отбросим пропущенные значения Distance , Postcode , Regionname , Propertycount и Councilarea , потому что все эти столбцы имеют только 1 или 2 пропущенных значения, что составляет менее 0,000001% от общего количества значений.

df_house_price.dropna(subset=['Distance','Postcode', 'Regionname','Propertycount'], inplace=True)

2. Удаление ненужных столбцов:

Вы можете удалить столбцы, которые не содержат никакой важной информации для построения модели. Address, Longtitude, Lattitude, Suburb, SellerG и CouncilArea не содержат никакой полезной информации для модели машинного обучения, поэтому они удаляются перед дальнейшей обработкой.

df_house_price = df_house_price.drop(['Address','Longtitude', 'Lattitude','Suburb', 'SellerG', 'CouncilArea'], axis=1)

3. Обработка выбросов

Очень важно обрабатывать выбросы, поскольку они могут привести к необъективным результатам как в модели, так и в анализе.

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

В записной книжке на GitHub показано много блочных диаграмм. Ниже показана блочная диаграмма для столбца Bathroom.

Вы можете заметить, что в большинстве домов есть 1–2 ванные комнаты, но в некоторых домах даже больше 6 ванных комнат. Это могут быть как огромные особняки, так и ошибки ввода данных. Мы будем рассматривать их как выбросы и обрабатывать их на следующем шаге.

б. Вменение выбросов. После выявления выбросов их можно либо вменить, либо удалить. Здесь можно использовать тот же метод вменения. Например, мы вычисляем все строки, в которых количество ванных комнат превышает 6, как показано ниже:

df_house_price.loc[df_house_price['Bathroom'] >  6] = df_house_price['Bathroom'].mode()[0]

Разработка функций

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

  1. Одно горячее кодирование

Мы можем использовать однократное кодирование для преобразования категориальных столбцов в числовые признаки, как показано ниже:

cols = pd.get_dummies(df_house_price['Type'], prefix= 'Type')
df_house_price[cols.columns] = cols
df_house_price.drop('Type', axis = 1, inplace = True)

Это преобразует столбец Type (тип дома) в однократный вектор длины 6. Однократное кодирование будет применено ко всем категориальным столбцам, а полный код доступен на GitHub.

2. Создание новых функций

Вы должны изучить все столбцы в наборе данных и придумать идеи для преобразования ваших столбцов в значимые функции. Например, в этом наборе данных мы создаем признак age_house из двух столбцов, вычитая YearBuilt из Date, чтобы определить, сколько лет дому, что может быть важным признаком в модели машинного обучения.

df_house_price['Date'] =  pd.to_datetime(df_house_price['Date'])
df_house_price['YearBuilt'] =  pd.to_datetime(df_house_price['YearBuilt'])
df_house_price['age_house'] = df_house_price['Date'].dt.year - df_house_price['YearBuilt'].dt.year

3. Разделение объектов и целевая переменная

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

from sklearn.model_selection import train_test_split
y = df_house_price["Price"]
X = df_house_price.drop('Price', axis = 1)
X_train_orig, X_test_orig, y_train, y_test = train_test_split(X, y, random_state = 0)

Целевая переменная Price (цена дома) сохраняется как y, а все остальные переменные, кроме Price, сохраняются как X из кадра данных df_house_price. Затем набор функций X далее делится на Xtrain_orig для обучения и X_test_orig для тестирования. Точно так же y далее делится на y_train для обучения модели машинного обучения и y_test для оценки модели.

4. Масштабирование/нормализация функций

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

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train_orig)
X_test = scaler.transform(X_test_orig)

Экземпляр StandardScaler определяется как scaler, и метод fit_transform() применяется к X_train_orig для получения масштабированных объектов, которые затем сохраняются как X_train. Масштабатор не обязательно должен соответствовать данным тестирования. Вы можете напрямую применить метод масштабирования transform() (который соответствовал обучающим данным) к данным тестирования, чтобы получить масштабированные функции для набора тестовых данных.

5. Анализ главных компонентов (PCA)

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

from sklearn.decomposition import PCA
pca = PCA(n_components= 0.95, svd_solver = 'full')
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.transform(X_test)

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

Эти 17 основных компонентов объясняют 95% дисперсии, что даже больше, чем количество столбцов в исходном наборе данных, поэтому с помощью PCA невозможно уменьшить размерность набора данных.

Построение модели

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

  1. Подгонка модели:

Однако сама по себе подгонка модели — это самый маленький шаг в проекте по науке о данных. Мы можем начать с простейшей модели линейной регрессии, как показано ниже:

from sklearn.linear_model import LinearRegression
lreg = LinearRegression()
lreg.fit(X_train, y_train)
print('Train Score for Linear Regression:', lreg.score(X_train, y_train))
print('Test Score for Linear Regression:', lreg.score(X_test, y_test))

Модель LinearRegression импортируется из библиотеки sklearn.linear_model. Затем он помещается в обучающий набор данных с использованием метода fit(). Наконец, метод score() используется для оценки производительности модели (R²) в наборе данных для обучения и тестирования.

Как видно из приведенного выше вывода, значение R² в тестовом наборе данных равно 0,627, поэтому модель работает нормально, но если вы хотите улучшить ее, вам придется копнуть глубже, чтобы понять взаимосвязь между предикторами и зависимыми. переменные. Мы перепробовали множество моделей на этом наборе данных, и полный код можно найти на GitHub. Однако здесь мы покажем только несколько моделей.

Здесь можно заметить, что регрессия дерева решений с параметром по умолчанию работает хуже по сравнению с моделью линейной регрессии с R² 0,40. Мы рассмотрим возможность улучшения этой модели на следующем этапе.

2. Оптимизация гиперпараметров:

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

from sklearn.model_selection import GridSearchCV
tree = DecisionTreeRegressor()
param_grid = {'max_depth': [1, 5, 10, 25, 50]}
print("Parameter grid:\n{}".format(param_grid))
grid_search_dr = GridSearchCV(tree, param_grid, cv=5,scoring="r2", return_train_score=True )
grid_search_dr.fit(X_train, y_train)

В приведенном выше блоке кода мы передаем список значений для max_depth как 1,5,10,25,50 и метрику оценки как R², поэтому он найдет значение max_depth, при котором R² является максимальным.

Вы можете распечатать значения гиперпараметров после завершения поиска в сетке. Вы можете заметить в выходных данных выше, что max_depth=10 является оптимальным параметром, где R² максимально. Вы также можете отобразить значение R² на разных уровнях глубины, чтобы получить четкое представление о настройке, как показано ниже:

3. Методы ансамбля:

Ансамбль — это метод машинного обучения, объединяющий несколько базовых моделей для создания одной оптимальной прогностической модели. Существует несколько методов ансамбля, таких как бэггинг, вставка, адабустирование, усиление градиента и т. д. Здесь мы покажем несколько примеров, а остальные вы можете найти в нашем репозитории GitHub.

Бэггинг — это тип метода усреднения, при котором выборки выбираются случайным образом с заменой, и несколько независимых оценок строятся на выборках, которые затем усредняются позже, чтобы делать прогнозы. В предыдущем разделе вы заметили, что лучшая модель дерева решений имеет R² 0,71, тогда как использование метода ансамбля пакетов в дереве решений помогает улучшить R² до 0,76.

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

4. Модели уменьшенных размеров

Уменьшение размерности — важный и полезный метод, особенно когда у вас много независимых переменных. Однако в этом случае у нас не так много предикторов, поэтому уменьшение размерности на самом деле не требуется. Но мы все равно показали это в учебных целях. После того, как вы извлекли основные компоненты, как описано на этапе «Разработка функций», вы можете легко использовать их в качестве функций в любой из моделей, как показано ниже:

Как и ожидалось, производительность модели дерева решений не улучшилась при использовании основных компонентов, поскольку для объяснения 95% дисперсии требуется 17 основных компонентов, что даже больше, чем количество столбцов в обработанном наборе данных.

Другой метод уменьшения размерности — использование важности признаков для получения наиболее важных признаков. 10 самых важных функций Adaboost на RandomForestRegressor показаны ниже:

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

5. Модели глубокого обучения

Наконец, вы можете использовать модель глубокого обучения для построения модели прогнозирования дома. Существует множество фреймворков глубокого обучения, таких как Keras, Tensorflow, PyTorch, PyTorch Lightning и т. д. Здесь мы будем использовать фреймворк Keras для построения последовательной модели, как показано ниже:

from keras.models import Sequential
from keras.layers import Dense
import tensorflow as tf
# step 1: build the model
model = Sequential()
model.add(Dense(32, input_dim = 35, activation='relu', kernel_initializer = 'zero', name = 'input_layer'))
model.add(Dense(1, activation = 'softmax', name = 'output_layer'))
# step 2: Compile the model
model.compile(optimizer = 'adam', loss='mse', metrics=['mae','mse'])
# Step 3: Model training
model.fit(X_train, y_train, batch_size=128, epochs=20)

В приведенном выше блоке кода есть 3 этапа обучения модели глубокого обучения. Первым шагом является определение архитектуры модели, которая в данном случае представляет собой последовательную модель с 32 плотными слоями. Мы также добавляем финальное уплотнение с активацией softmax в финальном выходном слое. Второй шаг — это компиляция модели, в которой вы должны определить оптимизатор, потери и показатели, которые равны adam, mse (среднеквадратическая ошибка) и [mae,mse] соответственно. Последним шагом является обучение модели глубокого обучения, которую можно выполнить с помощью метода fit() на определенной модели. Результат обучающей ячейки показан ниже.

Заключение

Мы рассмотрели все шаги, необходимые в проекте по науке о данных, начиная со сбора данных, EDA, разработки функций, построения модели и оценки набора данных на тестовых данных. Мы узнали, что расстояние от центра города, количество комнат, городской район и площадь земли являются наиболее важными факторами при прогнозировании цены дома. Компания по недвижимости должна иметь возможность использовать наилучшую модель для точного прогнозирования цен на жилье со значением R² 0,82 и перечислять свои объекты по справедливым ценам, чтобы они могли быть конкурентоспособными, не ставя под угрозу прибыль.

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

Ссылка на Github: https://github.com/Laxmisankritya/House-price-prediction

Благодарим Шивама Соланки за соавторство в этой серии блогов.

Пожалуйста, не стесняйтесь оставлять свои комментарии и предложения ниже и связаться с нами на LinkedIn.

https://www.linkedin.com/in/shivam-solanki-2b288319/