В этой статье мы рассмотрим весь процесс создания модели машинного обучения на основе набора данных для прогнозирования цен на алмазы. Затем мы также сравним результаты, используя различные метрики регрессии.
Вы также можете скачать набор данных из этого репозитория. Он содержит информацию о размере, цвете, чистоте, весе и огранке бриллиантов по сравнению с ценой.
1. Бриллианты
Алмаз образуется в условиях высокой температуры и давления, которые существуют всего в 100 милях от поверхности земли. Атомы углерода алмаза связаны практически одинаковым образом во всех направлениях. Другой минерал, графит, также содержит только углерод, но процесс его образования и кристаллическая структура сильно отличаются. Бриллианты издревле использовались в качестве декоративных элементов; некоторые из самых ранних упоминаний относятся к 25–30 000 годам до нашей эры.
Факты
- Минерал: алмаз
- Химия: C
- Цвет: бесцветный
- Показатель преломления: 2,42
- Двулучепреломление: нет
- Удельный вес: 3,52 (+/- 0,01)
- Твердость по Моосу: 10
В настоящее время производство драгоценных камней составляет около 30 миллионов каратов (6,0 тонны; 6,6 коротких тонн) ограненных и полированных камней ежегодно, и более 100 млн каратов (20 тонн; 22 короткие тонны) добытых алмазов продаются для промышленного использования каждый год, как и около 100 тонн (110 коротких тонн) синтезированного алмаза. Алмазы являются настолько продаваемым товаром, что было создано множество организаций для их оценки и сертификации на основе четырех C, а именно цвета, огранки, чистоты и карата. О четырех до можно прочитать по этой ссылке.
2. Набор данных
Как хорошо сказано: «Хороший мастер всегда знает свой инструмент», точно так же и хороший разработчик машинного обучения всегда должен правильно знать свой набор данных, прежде чем начинать код. Приятно следовать этой привычке, потому что модель машинного обучения - это изображение набора данных, используемого для его обучения. Таким образом, вполне вероятно, что любая тенденция или набор данных, которым следует придерживаться, отразятся в модели машинного обучения. По моему опыту, 80% работы уже сделано, когда у вас есть хороший предварительно обработанный набор данных.
Итак, давайте исследуем неизведанное!
Примечание: я бы посоветовал использовать google colab, поскольку он облегчил мне жизнь, обрабатывая все зависимости и библиотеки, кроме того, он также предоставляет такие утилиты, как GPU и TPU для вычислений, а также легко напрямую связать диск Google с вашим код.
Прежде всего, давайте создадим фрейм данных и визуализируем набор данных.
# import necessities import pandas as pd import numpy as np from sklearn import preprocessing df = pd.read_csv("/content/..../diamonds.csv") df
Теперь давайте посмотрим всю необходимую информацию.
df.info()
Вывод:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 53940 entries, 0 to 53939 Data columns (total 10 columns): carat 53940 non-null float64 cut 53940 non-null object color 53940 non-null object clarity 53940 non-null object depth 53940 non-null float64 table 53940 non-null float64 price 53940 non-null int64 x 53940 non-null float64 y 53940 non-null float64 z 53940 non-null float64 dtypes: float64(6), int64(1), object(3) memory usage: 4.1+ MB
Хммм, выглядит нормально!
Теперь давайте посмотрим на записи, типом данных которых является объект.
print("Cut: ",set(df["cut"])) print("Color: ",set(df["color"])) print("Clarity: ",set(df["clarity"]))
Вывод:
Cut: {'Fair', 'Good', 'Ideal', 'Premium', 'Very Good'} Color: {'D', 'E', 'F', 'G', 'H', 'I', 'J'} Clarity: {'I1', 'IF', 'SI1', 'SI2', 'VS1', 'VS2', 'VVS1', 'VVS2'}
Хммм, у нас ограниченное количество категориальных значений, нам нужно как-то их обработать, поскольку наша модель не понимает нечисловые данные!
3. Предварительная обработка
После понимания данных пришло время обработать данные таким образом, чтобы машина могла понять их, как в отличие от людей, машина могла просто понимать числа, поскольку модели машинного обучения - это не что иное, как сложные уравнения вероятности.
3.1. Кодировка
Как я уже упоминал выше, существует необходимость преобразовать нечисловые данные в числовые, и три из наших характеристик нечисловые, а именно вырезка, цвет и четкость. Мы можем легко применить горячее кодирование к этой проблеме, но это просто увеличит количество функций и, следовательно, требуемую вычислительную мощность. Вместо этого давайте попробуем вывести связь и сопоставить эти категории.
Примечание. Чтобы сформулировать взаимосвязь с ценой на бриллиант, у нас должен быть стандартный справочник, в котором мы можем сравнивать значения, поэтому здесь я сравнил цены за единицу карата.
df['price/wt']=df['price']/df['carat'] print(df.groupby('cut')['price/wt'].mean().sort_values()) print(df.groupby('color')['price/wt'].mean().sort_values()) print(df.groupby('clarity')['price/wt'].mean().sort_values()) df = df.drop(['price/wt','table'], axis=1)
Вывод:
cut Fair 3767.255681 Good 3860.027680 Ideal 3919.699825 Very Good 4014.128366 Premium 4222.905374 Name: price/wt, dtype: float64 color E 3804.611475 J 3825.649192 D 3952.564280 I 3996.402051 H 4008.026941 F 4134.730684 G 4163.411524 Name: price/wt, dtype: float64 clarity I1 2796.296437 SI1 3849.078018 VVS1 3851.410558 SI2 4010.853865 VS2 4080.526787 VS1 4155.816808 VVS2 4204.166013 IF 4259.931736 Name: price/wt, dtype: float64
Хороший! Мы можем легко заметить тенденцию изменения значений по всем трем характеристикам. Это дает нам возможность отображать категориальные значения с числами.
df['cut']=df['cut'].map({'Ideal':1,'Good':2,'Very Good':3,'Fair':4,'Premium':5}) df['color']=df['color'].map({'E':1,'D':2,'F':3,'G':4,'H':5,'I':6,'J':7}) df['clarity']=df['clarity'].map({'VVS1':1,'IF':2,'VVS2':3,'VS1':4,'I1':5,'VS2':6,'SI1':7,'SI2':8})
3.2. Выбор характеристик с помощью корреляционной матрицы
И последнее, давайте посмотрим на корреляционную матрицу наших данных. Матрица корреляции - это таблица, показывающая коэффициенты корреляции между переменными. Каждая ячейка в таблице показывает корреляцию между двумя переменными. Чем выше значение, тем больше вероятность корреляции данных! Поскольку эта проблема, поскольку мы хотим предсказать цену алмаза, мы сосредоточимся на корреляции между ценой и всеми другими столбцами.
df.corr()
Браво!!!
Теперь, основываясь на этой информации, мы можем применить к данным выбор функции. Понятно, что следующие характеристики имеют низкую оценку, это означает, что они меньше всего коррелируют с ценой бриллианта:
- резать
- цвет
- ясность
- глубина
- Таблица
Хотя у этих функций низкий показатель корреляции, мы не можем их удалить. Для геммолога такие характеристики, как «огранка», «цвет» и «чистота», играют решающую роль в определении цены на бриллиант.
С другой стороны, если мы изучим корреляционную матрицу, станет ясно, что цена и карат, то есть вес алмаза, имеют очень хорошие показатели корреляции. Таким образом, мы можем добавить новые функции, такие как обрезка по весу, и отказаться от таких функций, как «обрезка», «цвет» и «четкость». Точно так же мы можем интерпретировать «таблицу», умножив ее на «y», а затем опустить «глубину» из-за низкой оценки.
df['cut/wt']=df['cut']/df['carat'] df['color/wt']=df['color']/df['carat'] df['clarity/wt']=df['clarity']/df['carat'] df = df.drop(['cut','color','clarity','table','depth'], axis=1)
Поразительнй!!!
4. Разделение на тренировку и тест
Теперь, после предварительной обработки набора данных, нам необходимо разделить его на набор для обучения и тестирования, чтобы избежать проблем с переоснащением или недостаточным подбором, поскольку он позволяет нам оценивать прогноз с помощью различных матриц регрессии.
X=df.drop(['price'],axis=1) Y=df['price'] from sklearn.model_selection import train_test_split X_train,X_test,Y_train,Y_test=train_test_split(X,Y,test_size=0.3,random_state=42)
Примечание. Используя
random_state=some_number
, мы гарантируем, что разделение всегда будет одинаковым. Кроме того,random_state=42
часто используется по этой причине 😉.
6. Метрики регрессии
Шаг 6 перед шагом 5? Нет, я не шучу, но давайте проясним, как мы будем оценивать и сравнивать разные модели. Я бы использовал следующие метрики регрессии:
1. Средняя абсолютная ошибка: средняя абсолютная ошибка относится к среднему абсолютному значению каждой ошибки прогнозирования для всех экземпляров набора тестовых данных. Ошибка предсказания - это разница между фактическим значением и предсказанным значением для этого экземпляра.
mae = mean_absolute_error(Y_test,y_pred) print("mae: %f" %(mae))
2. Оценка R-квадрат : R-квадрат - это статистическая мера, которая указывает, насколько близки данные к подобранной линии регрессии. Он также известен как коэффициент детерминации или коэффициент множественной детерминации для множественной регрессии.
Rsquare=regressor.score(X_test,Y_test) print("Rsquare: %f" %(Rsquare))
3. Среднеквадратичная ошибка: это квадратный корень из суммы квадрата разницы между прогнозируемыми и фактическими целевыми переменными, деленной на количество точек данных.
rmse=np.sqrt(mean_squared_error(Y_test,y_pred)) print("rmse: %f" %(rmse))
5. Заставим машину учиться!
После сбора и обработки всех ингредиентов пора попробовать разные рецепты и посмотреть, какой из них самый вкусный.
5.1. Линейная регрессия
Линейная регрессия используется для поиска линейной связи между целью и одним или несколькими предикторами.
from sklearn import linear_model reg_all=linear_model.LinearRegression() reg_all.fit(X_train,Y_train) y_pred=reg_all.predict(X_test) Rsquare=reg_all.score(X_test,Y_test) print("Rsquare: %f" %(Rsquare)) coeff_df = pd.DataFrame(X_train.columns) coeff_df.columns = ['Variable'] coeff_df["Coeff"] = pd.Series(reg_all.coef_) coeff_df.sort_values(by='Coeff', ascending=True) print(coeff_df) print("Intercept: %f" %(reg_all.intercept_)) mae = mean_absolute_error(Y_test,y_pred) print("mae: %f" %(mae)) rmse=np.sqrt(mean_squared_error(Y_test,y_pred)) print("rmse: %f" %(rmse))
Вывод:
Rsquare: 0.861508 Variable Coeff 0 carat 10675.558686 1 x -1192.078847 2 y 957.349861 3 z -615.526175 4 width_top -15.053996 5 cut/wt 30.065902 6 color/wt -48.086153 7 clarity/wt -64.338733 Intercept: 4625.114040 mae: 895.345484 rmse: 1469.665116
5.2. Полиномиальная регрессия
Полиномиальная регрессия - это форма регрессионного анализа, в котором связь между независимой переменной x и зависимой переменной y моделируется как n степени многочлен от x. Полиномиальная регрессия соответствует нелинейной зависимости между значением x и соответствующим условным средним y и используется для описания нелинейных явлений.
from sklearn.preprocessing import PolynomialFeatures poly = PolynomialFeatures(degree = 2) X_train = poly.fit_transform(X_train) X_test = poly.fit_transform(X_test) reg_all = linear_model.LinearRegression() reg_all.fit(X_train,Y_train) y_pred=reg_all.predict(X_test) mae = mean_absolute_error(Y_test,y_pred) print("mae: %f" %(mae)) Rsquare=reg_all.score(X_test,Y_test) print("Rsquare: %f" %(Rsquare)) rmse=np.sqrt(mean_squared_error(Y_test,y_pred)) print("rmse: %f" %(rmse))
Вывод:
mae: 549.500225 Rsquare: 0.933456 rmse: 1018.734087
А для степени = 3 мы получили следующий результат:
mae: 912.372488 Rsquare: -188.653181 rmse: 54385.881154
5.3. Дерево решений Регрессия
Дерево решений - это модель машинного обучения с учителем, используемая для прогнозирования цели путем изучения правил принятия решений на основе функций. Как следует из названия, мы можем думать об этой модели как о разбивке наших данных путем принятия решения, основанного на серии вопросов.
Дерево решений создается с помощью рекурсивного разбиения - начиная с корневого узла (известного как первый родитель), каждый узел можно разделить на левый и правый дочерний узлы. Затем эти узлы можно разделить и превратить в родительские узлы для своих результирующих дочерних узлов.
from sklearn.tree import DecisionTreeRegressor regressor = DecisionTreeRegressor(random_state = 0) regressor.fit(X_train, Y_train) y_pred = regressor.predict(X_test) mae = mean_absolute_error(Y_test,y_pred) print("mae: %f" %(mae)) Rsquare=regressor.score(X_test,Y_test) print("Rsquare: %f" %(Rsquare)) rmse=np.sqrt(mean_squared_error(Y_test,y_pred)) print("rmse: %f" %(rmse))
Вывод:
mae: 373.421487 Rsquare: 0.961235 rmse: 777.550255
5.4. Поддержка векторной регрессии
Машина опорных векторов также может использоваться как метод регрессии, сохраняя все основные характеристики, характеризующие алгоритм (максимальный запас). Регрессия опорных векторов (SVR) использует те же принципы, что и SVM для классификации, с небольшими отличиями. Прежде всего, поскольку выходными данными являются действительные числа, становится очень трудно предсказать имеющуюся информацию, которая имеет бесконечные возможности. В случае регрессии предел допуска (эпсилон) устанавливается в приближении к SVM, который уже был бы запрошен из проблемы. Но, помимо этого факта, есть еще более сложная причина, алгоритм более сложный, поэтому это необходимо учитывать. Однако основная идея всегда одна и та же: минимизировать ошибку, индивидуализировать гиперплоскость, которая максимизирует запас, имея в виду, что часть ошибки допустима.
from sklearn.svm import SVR regressor = SVR(kernel='rbf') regressor.fit(X_train,Y_train) y_pred = regressor.predict(X_test) mae = mean_absolute_error(Y_test,y_pred) print("mae: %f" %(mae)) Rsquare=regressor.score(X_test,Y_test) print("Rsquare: %f" %(Rsquare)) rmse=np.sqrt(mean_squared_error(Y_test,y_pred)) print("rmse: %f" %(rmse))
Примечание. Для запуска кода может потребоваться немного больше времени.
Вывод:
mae: 2672.065590 Rsquare: -0.097922 rmse: 4138.012816
5.5. Случайный лес
Случайный лес - это алгоритм контролируемого обучения, который использует метод ансамблевого обучения для классификации и регрессии.
Случайный лес - это техника бэггинга, а не бустинга. Деревья в случайных лесах запускаются параллельно. Эти деревья не взаимодействуют друг с другом при построении деревьев.
Он работает путем построения множества деревьев решений во время обучения и вывода класса, который является режимом из классов (классификация) или среднего прогноза (регрессия) отдельных деревьев.
Случайный лес - это метаоценка (т. Е. Она объединяет результаты нескольких прогнозов), которая объединяет множество деревьев решений.
from sklearn.ensemble import RandomForestClassifier rf = RandomForestClassifier(n_estimators = 6) rf.fit(X_train,Y_train) y_pred = rf.predict(X_test) mae = mean_absolute_error(Y_test,y_pred) print("mae: %f" %(mae)) Rsquare=rf.score(X_test,Y_test) print("Rsquare: %f" %(Rsquare)) rmse=np.sqrt(mean_squared_error(Y_test,y_pred)) print("rmse: %f" %(rmse))
Примечание. Выполнение следующего кода займет много времени, так как он требует больших вычислений.
Вывод:
mae: 662.102892 Rsquare: 0.119454 rmse: 1423.369221
5.6. Логистическая регрессия
Логистическая регрессия - это алгоритм классификации машинного обучения, который используется для прогнозирования вероятности категориальной зависимой переменной. В логистической регрессии зависимая переменная - это двоичная переменная, которая содержит данные с кодом 1 (да, успех и т. Д.) Или 0 (нет, неудача и т. Д.). Другими словами, модель логистической регрессии предсказывает P (Y = 1) как функцию от X.
Логистическая регрессия - один из самых популярных способов подбора моделей для категориальных данных, особенно для данных двоичного ответа в моделировании данных. Следовательно, в нашем случае это не сработает.
from sklearn.linear_model import LogisticRegression logreg = LogisticRegression(random_state = 0) logreg.fit(X_train,Y_train) y_pred=logreg.predict(X_test) mae = mean_absolute_error(Y_test,y_pred) print("mae: %f" %(mae)) Rsquare=logreg.score(X_test,Y_test) print("Rsquare: %f" %(Rsquare)) rmse=np.sqrt(mean_squared_error(Y_test,y_pred)) print("rmse: %f" %(rmse))
Вывод:
mae: 1294.865468 Rsquare: 0.011185 rmse: 2107.933862
5.6. Нейронная сеть
По мере увеличения объема данных производительность традиционных алгоритмов обучения, таких как SVM и логистическая регрессия, существенно не улучшается. Фактически, он имеет тенденцию к стабилизации после определенного момента. В случае нейронных сетей производительность модели увеличивается с увеличением данных, которые вы вводите в модель.
Если сеть используется для регрессии, то функция потерь при обучении обычно не представляет собой ничего, обычно в качестве показателя в функции потерь используется среднеквадратичная ошибка (MSE) или среднеквадратичная ошибка (RMSE).
import warnings warnings.filterwarnings('ignore') from keras.models import Sequential,model_from_json from keras.layers import Dense from keras.optimizers import RMSprop model = Sequential() model.add(Dense(256, activation='relu', input_shape=(8,))) model.add(Dense(256, activation='relu')) model.add(Dense(256, activation='relu')) model.add(Dense(256, activation='relu')) model.add(Dense(1, activation='relu')) model.summary() model.compile(loss='mean_absolute_error', optimizer='adam', metrics=['mean_absolute_error','mean_squared_error'])history = model.fit(X_train,Y_train,batch_size=64,epochs=100,verbose=2) test=model.evaluate(X_test, Y_test, verbose=1)
Примечание: модель обучалась за 100 эпох.
Вывод:
Using TensorFlow backend. Model: "sequential_1" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_1 (Dense) (None, 256) 2304 _________________________________________________________________ dense_2 (Dense) (None, 256) 65792 _________________________________________________________________ dense_3 (Dense) (None, 256) 65792 _________________________________________________________________ dense_4 (Dense) (None, 256) 65792 _________________________________________________________________ dense_5 (Dense) (None, 1) 257 ================================================================= Total params: 199,937 Trainable params: 199,937 Non-trainable params: 0 - 2s - loss: 1525.3224 - mean_absolute_error: 1525.3224 - mean_squared_error: 8729575.7525 Epoch 2/100 - 2s - loss: 684.7146 - mean_absolute_error: 684.7146 - mean_squared_error: 1974301.8159 Epoch 3/100 - 2s - loss: 672.9809 - mean_absolute_error: 672.9809 - mean_squared_error: 1829558.6347 Epoch 4/100 . . . - 2s - loss: 395.8742 - mean_absolute_error: 395.8742 - mean_squared_error: 793110.1403 Epoch 99/100 - 2s - loss: 403.3112 - mean_absolute_error: 403.3112 - mean_squared_error: 796024.6950 Epoch 100/100 - 2s - loss: 406.1216 - mean_absolute_error: 406.1216 - mean_squared_error: 809139.8724 16182/16182 [==============================] - 0s 21us/step
Примечание: мы можем извлечь квадратный корень из среднеквадратичной ошибки (mse), чтобы получить среднеквадратичную ошибку (rmse), что составляет
rmse=899.522024
.
5.7. Регуляризация
Один из основных аспектов обучения вашей модели машинного обучения - избегать переобучения. Модель будет иметь низкую точность при переобучении. Это происходит потому, что ваша модель слишком сильно пытается уловить шум в вашем наборе обучающих данных. Под шумом мы понимаем точки данных, которые отражают не истинные свойства ваших данных, а случайную случайность. Изучение таких точек данных делает вашу модель более гибкой, с риском переобучения. Регуляризация - это форма регрессии, которая ограничивает / регулирует или сужает оценки коэффициентов до нуля. Другими словами, этот метод препятствует изучению более сложной или гибкой модели, чтобы избежать риска переобучения .
Для регуляризации используются методы Ridge и Lasso. Как правило, регуляризация сочетается с методами регрессии, чтобы избежать переобучения.
regressor1 = Ridge() regressor2 = Lasso()
7. Резюме
Теперь давайте сравним все рецепты, чтобы увидеть, какой из них лучше всего подходит для решения этой проблемы.
Регрессия дерева решений оказалась лучшим рецептом для прогнозирования цены на бриллиант, за которым вскоре последовали нейронные сети и полиномиальная регрессия степени 2.
Спасибо, что прочитали мой блог, рада поделиться своими знаниями 😃.