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

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

Очистка данных: это процесс удаления неточных, противоречивых и неправильных данных.

Интеграция данных: это процесс объединения данных, полученных из нескольких разных источников.

Сокращение данных: это процесс удаления избыточных или избыточных данных из огромного объема для упрощения анализа.

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

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

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

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

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

Дерево решений: использует древовидную структуру для принятия решений на основе входных данных.

Эти алгоритмы сравниваются по различным основаниям, таким как оценка точности, оценка f1, точность, полнота и т. д.

Теперь давайте начнем с процесса прогнозирования цен на жилье.

Важные библиотеки:

Pandas: Pandas используется для быстрой обработки и анализа данных.

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

Matplotlib: Matplotlib — это расширение NumPy, которое в основном используется для построения различных типов графиков.

импортировать панд как pd

импортировать numpy как np

из matplotlib импортировать pyplot как plt

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

df1 = pd.read_csv («Бенгалуру_House_Data.csv»)

df1.head()

df1 — это объект фрейма данных, который хранит данные в табличном формате. Мы можем получить его разные атрибуты, используя разные свойства, например…

df1.shape

df1.columns

df1['тип_области'].unique()

df1['тип_области'].value_counts()

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

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

Мы можем проверить количество строк с пропущенными значениями с помощью функции isnull().

df2.isnull().сумма()

Чтобы удалить эти строки, мы можем вызвать функцию dropna().

df3=df2.dropna()

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

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

Здесь мы видим, что такие атрибуты, как BHK, могут принимать различные формы в ответах, таких как 2, 2BHK, 2 Bedroom и т. д. Чтобы удалить эти полиморфизмы, мы воспользуемся лямбда-функцией и преобразуем их в единый формат.

df3['bhk']=df3['size'].apply(лямбда x: int(x.split('')[0]))

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

def convert_sqft_to_num(x):

токены=x.split('-')

если len(токены)==2:

вернуть (с плавающей запятой (токены [0]) + с плавающей запятой (токены [1]))/2

пытаться:

возврат с плавающей запятой (х)

кроме:

возврат Нет

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

df4=df3.copy()

df4.total_sqft=df4.total_sqft.apply(convert_sqft_to_num)

df4=df4[df4.total_sqft.notnull()]

Чтобы упростить наши дальнейшие расчеты, мы добавим новый атрибут с именем price_per_sqft, который представляет собой разделение цены и общей доступной площади в квадратных футах. Цена, указанная в данных, указана в лакхах, которые будут преобразованы в единицы путем умножения на 100 000 для нормализации данных.

df5=df4.copy()

df5[‘price_per_sqft’]=df5[‘price’]*100000/df5[‘total_sqft’]

Уменьшение размерности:

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

location_stats_less_than_10=location_stats[location_stats‹=10]

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

df5.location=df5.location.apply(лямбда x: «другое», если x в location_stats_less_than_10, иначе x)

Удаление выбросов:

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

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

df6=df5[~(df5.total_sqft/df5.bhk❤00)]

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

защита remove_pps_outliers (df):

df_out = pd.DataFrame()

для ключа, subdf в df.groupby('location'):

m = np.mean (subdf.price_per_sqft)

st = np.std (subdf.price_per_sqft)

reduce_df = subdf[(subdf.price_per_sqft›(m-st)) & (subdf.price_per_sqft‹=(m+st))]

df_out = pd.concat([df_out,reduced_df],ignore_index=True)

вернуть df_out

df7 = удалить_pps_выбросы (df6)

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

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

def plot_scatter_chart (df, местоположение):

bhk2 = df[(df.location==местоположение) & (df.bhk==2)]

bhk3 = df[(df.location==местоположение) & (df.bhk==3)]

matplotlib.rcParams[‘figure.figsize’] = (15,10)

plt.scatter(bhk2.total_sqft,bhk2.price,color='blue',label='2 BHK', s=50)

plt.scatter(bhk3.total_sqft,bhk3.price,marker='+', color='green', label='3 BHK', s=50)

plt.xlabel («Общая площадь в квадратных футах»)

plt.ylabel («Цена (в лакхских индийских рупиях)»)

plt.title(местоположение)

plt.legend()

plot_scatter_chart(df7,"Раджаджи Нагар")

plot_scatter_chart(df7,"Hebbal")

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

защита remove_bhk_outliers (df):

exclude_indices = np.array([])

для местоположения, location_df в df.groupby(‘location’):

bhk_stats = {}

для bhk, bhk_df в location_df.groupby('bhk'):

bhk_stats[bhk] = {

«среднее»: np.mean (bhk_df.price_per_sqft),

«стандарт»: np.std (bhk_df.price_per_sqft),

«количество»: bhk_df.shape[0]

}

для bhk, bhk_df в location_df.groupby('bhk'):

статистика = bhk_stats.get(bhk-1)

if stats и stats[‘count’]›5:

exclude_indices = np.append(exclude_indices, bhk_df[bhk_df.price_per_sqft‹(stats[‘mean’])].index.values)

вернуть df.drop (exclude_indices, ось = 'индекс')

df8 = удалить_bhk_выбросы (df7)

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

df9 = df8[df8.ванна‹df8.bhk+2]

Кодировка:

Большинство наших данных являются категориальными, что означает, что они имеют дискретные значения. Чтобы упростить задачу, мы можем использовать для этого одну горячую кодировку. Одно горячее кодирование преобразует категориальные данные в двоичные данные, создавая лишние столбцы. Столбец добавляется для каждого категориального значения и ставит значения 0 или 1 в зависимости от данных.

манекены = pd.get_dummies(df10.location)

df11 = pd.concat([df10,dummies.drop('другое', ось = 'столбцы')], ось = 'столбцы')

df12 = df11.drop («местоположение», ось = «столбцы»)

Обучение модели:

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

Три лучшие линейные модели для регрессии — это линейная регрессия, регрессия Лассо и дерево решений.

Такие библиотеки, как sklearn, обеспечивают широкую поддержку многих операций, связанных с машинным обучением, от train_test_split до gridsearchCV. Здесь мы не будем подробно обсуждать часть машинного обучения.

из sklearn.model_selection импортировать GridSearchCV

из sklearn.linear_model импортировать лассо

из sklearn.tree импортировать DecisionTreeRegressor

def find_best_model_using_gridsearchcv (X, y):

алгоритмы = {

'линейная регрессия' : {

«модель»: LinearRegression(),

«параметры»: {

«нормализовать»: [Истина, Ложь]

}

},

«лассо»: {

«модель»: Лассо(),

«параметры»: {

«альфа»: [1,2],

«выбор»: [«случайный», «циклический»]

}

},

'Древо решений': {

«модель»: DecisionTreeRegressor(),

«параметры»: {

«критерий»: [‘mse’,’friedman_mse’],

'разделитель': ['лучший','случайный']

}

}

}

баллы = []

cv = ShuffleSplit (n_splits = 5, test_size = 0,2, random_state = 0)

для algo_name конфиг в algos.items():

gs = GridSearchCV(config[‘model’], config[‘params’], cv=cv, return_train_score=False)

gs.fit(X,y)

баллы.append({

«модель»: algo_name,

‘best_score’: gs.best_score_,

«best_params»: gs.best_params_

})

вернуть pd.DataFrame (оценки, столбцы = ['модель','best_score','best_params'])

find_best_model_using_gridsearchcv(X,y)

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

def predict_price (местоположение, квадратный фут, ванна, кв. м):

loc_index = np.where(X.columns==местоположение)[0][0]

х = np.zeros(len(X.columns))

х[0] = квадратный фут

х[1] = ванна

х[2] = чк

если loc_index ›= 0:

х[loc_index] = 1

вернуть lr_clf.predict([x])[0]

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

предсказать_цену («Индира Нагар», 1000, 3, 3)

Рекомендуемое руководство: https://www.youtube.com/playlist?list=PLeo1K3hjS3uu7clOTtwsp94PcHbzqpAdg