924 KiB
Raw Permalink Blame History

Определение бизнес-целей для анализа на основе набора данных Diamonds Prices2022

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

Подготовка данных

In [1]:
import pandas as pd

# Загружаем данные
data = pd.read_csv('data/Diamonds Prices2022.csv')

# Преобразуем столбец 'price' в числовой формат
data['price'] = pd.to_numeric(data['price'], errors='coerce')

# Преобразуем 'carat' в числовой формат
data['carat'] = pd.to_numeric(data['carat'], errors='coerce')

# Преобразуем 'depth' в числовой формат
data['depth'] = pd.to_numeric(data['depth'], errors='coerce')

# Преобразуем 'table' в числовой формат
data['table'] = pd.to_numeric(data['table'], errors='coerce')

# Преобразуем 'x', 'y', 'z' в числовой формат
data['x'] = pd.to_numeric(data['x'], errors='coerce')
data['y'] = pd.to_numeric(data['y'], errors='coerce')
data['z'] = pd.to_numeric(data['z'], errors='coerce')

# Преобразуем 'cut', 'color', 'clarity' в категориальные данные
data['cut'] = data['cut'].astype('category')
data['color'] = data['color'].astype('category')
data['clarity'] = data['clarity'].astype('category')

# Проверяем изменённые данные
print(data.head())
   Unnamed: 0  carat      cut color clarity  depth  table  price     x     y  \
0           1   0.23    Ideal     E     SI2   61.5   55.0    326  3.95  3.98   
1           2   0.21  Premium     E     SI1   59.8   61.0    326  3.89  3.84   
2           3   0.23     Good     E     VS1   56.9   65.0    327  4.05  4.07   
3           4   0.29  Premium     I     VS2   62.4   58.0    334  4.20  4.23   
4           5   0.31     Good     J     SI2   63.3   58.0    335  4.34  4.35   

      z  
0  2.43  
1  2.31  
2  2.31  
3  2.63  
4  2.75  

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

In [3]:
import pandas as pd
from sklearn.model_selection import train_test_split

# Загружаем данные
data = pd.read_csv('data/Diamonds Prices2022.csv')

# Целевая переменная для регрессии - 'price'
X_regression = data.drop(columns=['price', 'carat', 'cut', 'color', 'clarity'])
y_regression = data['price']

# Разделяем на обучающую, валидационную и тестовую выборки
X_reg_train, X_reg_temp, y_reg_train, y_reg_temp = train_test_split(
    X_regression, y_regression, test_size=0.3, random_state=42
)
X_reg_val, X_reg_test, y_reg_val, y_reg_test = train_test_split(
    X_reg_temp, y_reg_temp, test_size=0.5, random_state=42
)

# Проверка размеров выборок
print("Regression datasets sizes:")
print("Train:", X_reg_train.shape, "Validation:", X_reg_val.shape, "Test:", X_reg_test.shape)
Regression datasets sizes:
Train: (37760, 6) Validation: (8091, 6) Test: (8092, 6)

Оценим

In [4]:
import matplotlib.pyplot as plt

# Визуализация распределения целевой переменной для регрессии
plt.figure(figsize=(12, 6))
plt.hist(y_reg_train, bins=50, alpha=0.6, label='Train', color='blue', edgecolor='black')
plt.hist(y_reg_val, bins=50, alpha=0.6, label='Validation', color='green', edgecolor='black')
plt.hist(y_reg_test, bins=50, alpha=0.6, label='Test', color='red', edgecolor='black')
plt.xlabel('Цена бриллиантов')
plt.ylabel('Количество')
plt.legend()
plt.show()

# График с нормированными частотами (барплот)
plt.figure(figsize=(12, 6))
bar_width = 0.25

# Нормированные частоты для каждой выборки
train_counts = y_reg_train.value_counts(normalize=True).sort_index()
val_counts = y_reg_val.value_counts(normalize=True).sort_index()
test_counts = y_reg_test.value_counts(normalize=True).sort_index()

# Все уникальные значения цены, чтобы синхронизировать данные
all_values = sorted(set(train_counts.index).union(val_counts.index).union(test_counts.index))

# Заполнение недостающих значений нулями
train_counts = train_counts.reindex(all_values).fillna(0)
val_counts = val_counts.reindex(all_values).fillna(0)
test_counts = test_counts.reindex(all_values).fillna(0)

# Позиции для баров
positions = range(len(all_values))

# Строим барплот
plt.bar(positions, train_counts, width=bar_width, label='Train', color='blue', edgecolor='black', align='center')
plt.bar([p + bar_width for p in positions], val_counts, width=bar_width, label='Validation', color='green', edgecolor='black', align='center')
plt.bar([p + 2 * bar_width for p in positions], test_counts, width=bar_width, label='Test', color='red', edgecolor='black', align='center')

plt.xlabel('Цена бриллиантов')
plt.ylabel('Нормированное количество')
plt.legend()
plt.show()
No description has been provided for this image
No description has been provided for this image

Создадим дополнительные признаки для решения целей

In [6]:
import pandas as pd

# Загрузка данных
file_path = 'data/Diamonds Prices2022.csv'
data = pd.read_csv(file_path)

# Проверим, есть ли столбец с годом продажи, и если его нет, выберем другой столбец
if 'year' in data.columns:
    year_column = 'year'
else:
    print("Столбец с годом продажи отсутствует в данных, возможно его нужно заменить или добавить.")

# Убедимся, что столбцы 'price' и 'carat' содержат только числовые значения
data['price'] = pd.to_numeric(data['price'], errors='coerce')
data['carat'] = pd.to_numeric(data['carat'], errors='coerce')

# 1. Конструирование признаков для цели "Оптимизация ценовой политики"
# Создаем признак "Вес бриллианта" (Carat)
data['Diamond_Weight'] = data['carat']

# Нормализуем цену бриллианта
data['Normalized_Price'] = (data['price'] - data['price'].mean()) / data['price'].std()

# 2. Конструирование признаков для цели "Увеличение конкурентоспособности"
# Генерация бинарного признака: "Дорогостоящие бриллианты" (цена > 5000)
data['Expensive_Diamond'] = (data['price'] > 5000).astype(int)

# Генерация категориального признака на основе веса
data['Carat_Category'] = pd.cut(data['carat'], bins=[0, 0.5, 1.0, 1.5, 2.0, 5.0],
                                 labels=['<0.5', '0.5-1.0', '1.0-1.5', '1.5-2.0', '2.0+'])

# Сохраняем результат в новый файл
data.to_csv('Diamonds_Prices2022_with_features.csv', index=False)

# Выводим первые строки нового датасета для проверки
print(data.head())
Столбец с годом продажи отсутствует в данных, возможно его нужно заменить или добавить.
   Unnamed: 0  carat      cut color clarity  depth  table  price     x     y  \
0           1   0.23    Ideal     E     SI2   61.5   55.0    326  3.95  3.98   
1           2   0.21  Premium     E     SI1   59.8   61.0    326  3.89  3.84   
2           3   0.23     Good     E     VS1   56.9   65.0    327  4.05  4.07   
3           4   0.29  Premium     I     VS2   62.4   58.0    334  4.20  4.23   
4           5   0.31     Good     J     SI2   63.3   58.0    335  4.34  4.35   

      z  Diamond_Weight  Normalized_Price  Expensive_Diamond Carat_Category  
0  2.43            0.23         -0.904093                  0           <0.5  
1  2.31            0.21         -0.904093                  0           <0.5  
2  2.31            0.23         -0.903843                  0           <0.5  
3  2.63            0.29         -0.902088                  0           <0.5  
4  2.75            0.31         -0.901837                  0           <0.5  

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

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

Корреляция измеряет степень линейной зависимости между двумя переменными.

Если корреляция между признаком и целевой переменной высока (близка к +1 или -1), это означает, что признак хорошо объясняет вариации price. Например, такие признаки, как carat или Diamond_Weight, могут иметь сильную корреляцию с ценой, поскольку вес бриллианта напрямую влияет на его стоимость. В то время как признаки, такие как cut или color, могут показывать менее выраженную связь, но все равно вносят вклад в определение цены. Если корреляция близка к 0, признак почти не влияет на price.

In [10]:
import seaborn as sns
import matplotlib.pyplot as plt
import time
import pandas as pd

# Загрузка данных
file_path = 'data/Diamonds Prices2022.csv'
data = pd.read_csv(file_path)

# Предсказательная способность (корреляция с целевыми переменными)
target_columns = ['price', 'carat']
feature_columns = ['carat', 'cut', 'color', 'clarity', 'depth', 'table', 'x', 'y', 'z']

# Преобразуем категориальные столбцы в числовые (one-hot encoding)
data_encoded = pd.get_dummies(data[feature_columns], drop_first=True)

# Объединяем с целевыми переменными
data_combined = pd.concat([data[target_columns], data_encoded], axis=1)

# Выбираем только числовые столбцы для вычисления корреляции
numerical_data = data_combined.select_dtypes(include=['float64', 'int64'])

# Корреляционная матрица
correlation_matrix = numerical_data.corr()

plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, fmt=".2f", cmap='coolwarm')
plt.title('Корреляция признаков и целевых переменных')
plt.show()

# Скорость вычисления
calc_times = {}

# Так как столбца 'year' нет, можно исключить его из расчета или заменить на другую логику
# Пример вычислений без года:
start = time.time()
data['Price_per_Carat'] = data['price'] / data['carat']
calc_times['Price_per_Carat'] = time.time() - start

start = time.time()
data['Normalized_Price'] = (data['price'] - data['price'].mean()) / data['price'].std()
calc_times['Normalized_Price'] = time.time() - start

# График времени вычисления
plt.barh(list(calc_times.keys()), list(calc_times.values()))
plt.xlabel('Время вычисления (в секундах)')
plt.ylabel('Признаки')
plt.title('Время вычисления признаков')
plt.show()

# Надежность
missing_values = data[feature_columns].isnull().sum()

plt.barh(feature_columns, missing_values)
plt.xlabel('Количество пропусков')
plt.ylabel('Признаки')
plt.title('Пропущенные значения по признакам (надежность)')
plt.show()
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

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

  • Не содержит пропущенных значений (NaN или пустых значений).
  • Не имеет ошибок или некорректных значений (например, отрицательная зарплата, некорректные значения для типа занятости или уровня опыта).
  • Содержит логически правильное распределение значений (например, для признаков, таких как experience_level, employment_type, job_title или company_size, присутствуют только допустимые категории, а значения не противоречат ожидаемым).

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

In [15]:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

# Загрузка данных
file_path = 'data/Diamonds Prices2022.csv'
data = pd.read_csv(file_path)

# Проверка названий столбцов
print(data.columns)

# Признаки для анализа (используем только те, которые есть в датасете)
feature_columns = ['carat', 'cut', 'color', 'clarity', 'depth', 'table', 'price', 'x', 'y', 'z']

# Заполним пропущенные значения для категориальных признаков
data[['cut', 'color', 'clarity']] = data[['cut', 'color', 'clarity']].fillna('Unknown')

# Цельность
for feature in feature_columns:
    plt.figure(figsize=(6, 4))
    if data[feature].dtype == 'object':  # Если категориальный признак
        sns.histplot(data[feature], kde=False, bins=30)
    else:  # Если числовой признак
        sns.histplot(data[feature], kde=True, bins=30)

    plt.title(f'Цельность: {feature}')
    plt.xlabel(feature)
    plt.ylabel('Частота')
    plt.show()
Index(['Unnamed: 0', 'carat', 'cut', 'color', 'clarity', 'depth', 'table',
       'price', 'x', 'y', 'z'],
      dtype='object')
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

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

In [16]:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

# Загрузка данных
file_path = 'data/Diamonds Prices2022.csv'
data = pd.read_csv(file_path)

# Признаки для анализа (изменено под ваш датасет)
feature_columns = ['carat', 'cut', 'color', 'clarity', 'depth', 'table', 'price', 'x', 'y', 'z']

# Преобразование категориальных признаков в числовые с использованием one-hot кодирования
data_encoded = pd.get_dummies(data[feature_columns], drop_first=True)

# Рассчитаем корреляционную матрицу
corr_matrix = data_encoded.corr()

# Убедимся, что корреляция имеет смысл (например, все ли признаки числовые)
print(corr_matrix)

# Избыточность: построение корреляционной матрицы
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, fmt=".2f", cmap='coolwarm')
plt.title('Избыточность')
plt.show()
                  carat     depth     table     price         x         y  \
carat          1.000000  0.028234  0.181602  0.921591  0.975093  0.951721   
depth          0.028234  1.000000 -0.295798 -0.010630 -0.025289 -0.029340   
table          0.181602 -0.295798  1.000000  0.127118  0.195333  0.183750   
price          0.921591 -0.010630  0.127118  1.000000  0.884433  0.865419   
x              0.975093 -0.025289  0.195333  0.884433  1.000000  0.974701   
y              0.951721 -0.029340  0.183750  0.865419  0.974701  1.000000   
z              0.953387  0.094927  0.150915  0.861249  0.970771  0.952005   
cut_Good       0.034200  0.136127  0.175155 -0.000307  0.030349  0.032186   
cut_Ideal     -0.163648 -0.022730 -0.549584 -0.097160 -0.162671 -0.153156   
cut_Premium    0.116229 -0.198349  0.338056  0.095685  0.126815  0.107937   
cut_Very Good  0.009564  0.025818  0.119975  0.006589  0.004567  0.016699   
color_E       -0.139217 -0.028766  0.007137 -0.101101 -0.134200 -0.130124   
color_F       -0.060054 -0.017779 -0.004821 -0.024166 -0.048019 -0.046706   
color_G       -0.029032  0.002797 -0.038828  0.008564 -0.024594 -0.024479   
color_H        0.102469  0.026061  0.011560  0.059229  0.095895  0.093479   
color_I        0.161497  0.022648  0.017956  0.097130  0.146522  0.142894   
color_J        0.180057  0.022555  0.037244  0.081714  0.164657  0.160776   
clarity_IF    -0.114446 -0.030869 -0.078767 -0.049593 -0.125976 -0.120800   
clarity_SI1    0.062655  0.040831  0.051976  0.008940  0.079239  0.076093   
clarity_SI2    0.267486  0.007228  0.095325  0.128427  0.270825  0.263250   
clarity_VS1   -0.063089 -0.024144 -0.026869 -0.009879 -0.059882 -0.056490   
clarity_VS2   -0.038906 -0.009466 -0.009640 -0.001066 -0.035507 -0.035926   
clarity_VVS1  -0.167568 -0.023461 -0.069107 -0.095261 -0.185253 -0.179271   
clarity_VVS2  -0.137020 -0.019224 -0.062279 -0.052375 -0.147151 -0.141624   

                      z  cut_Good  cut_Ideal  cut_Premium  ...   color_H  \
carat          0.953387  0.034200  -0.163648     0.116229  ...  0.102469   
depth          0.094927  0.136127  -0.022730    -0.198349  ...  0.026061   
table          0.150915  0.175155  -0.549584     0.338056  ...  0.011560   
price          0.861249 -0.000307  -0.097160     0.095685  ...  0.059229   
x              0.970771  0.030349  -0.162671     0.126815  ...  0.095895   
y              0.952005  0.032186  -0.153156     0.107937  ...  0.093479   
z              1.000000  0.045171  -0.158680     0.090008  ...  0.095043   
cut_Good       0.045171  1.000000  -0.257998    -0.185391  ... -0.009510   
cut_Ideal     -0.158680 -0.257998   1.000000    -0.478081  ... -0.021244   
cut_Premium    0.090008 -0.185391  -0.478081     1.000000  ...  0.027871   
cut_Very Good  0.016037 -0.169938  -0.438231    -0.314901  ... -0.004443   
color_E       -0.132204  0.006990  -0.001162    -0.018468  ... -0.200970   
color_F       -0.048805  0.006942   0.001333    -0.012039  ... -0.197755   
color_G       -0.024578 -0.024719   0.034672     0.003832  ... -0.219481   
color_H        0.095043 -0.009510  -0.021244     0.027871  ...  1.000000   
color_I        0.145278  0.006193  -0.009210     0.005882  ... -0.142590   
color_J        0.164218  0.014982  -0.038479     0.017218  ... -0.099957   
clarity_IF    -0.125247 -0.033042   0.104993    -0.054020  ...  0.006724   
clarity_SI1    0.080994  0.055917  -0.082904     0.023390  ...  0.031588   
clarity_SI2    0.263193  0.041978  -0.108218     0.067595  ...  0.020173   
clarity_VS1   -0.058510 -0.017108   0.034265    -0.011887  ... -0.012730   
clarity_VS2   -0.036314 -0.021067   0.015657     0.022555  ... -0.029928   
clarity_VVS1  -0.182399 -0.037559   0.088365    -0.053863  ...  0.004568   
clarity_VVS2  -0.144743 -0.038621   0.075521    -0.061963  ... -0.030263   

                color_I   color_J  clarity_IF  clarity_SI1  clarity_SI2  \
carat          0.161497  0.180057   -0.114446     0.062655     0.267486   
depth          0.022648  0.022555   -0.030869     0.040831     0.007228   
table          0.017956  0.037244   -0.078767     0.051976     0.095325   
price          0.097130  0.081714   -0.049593     0.008940     0.128427   
x              0.146522  0.164657   -0.125976     0.079239     0.270825   
y              0.142894  0.160776   -0.120800     0.076093     0.263250   
z              0.145278  0.164218   -0.125247     0.080994     0.263193   
cut_Good       0.006193  0.014982   -0.033042     0.055917     0.041978   
cut_Ideal     -0.009210 -0.038479    0.104993    -0.082904    -0.108218   
cut_Premium    0.005882  0.017218   -0.054020     0.023390     0.067595   
cut_Very Good -0.001553  0.009812   -0.033005     0.032489     0.004799   
color_E       -0.157496 -0.110406   -0.044872     0.005984     0.005481   
color_F       -0.154977 -0.108640    0.018534    -0.020373    -0.002261   
color_G       -0.172003 -0.120576    0.077922    -0.080761    -0.045637   
color_H       -0.142590 -0.099957    0.006724     0.031588     0.020173   
color_I        1.000000 -0.078335   -0.012708     0.015914    -0.001987   
color_J       -0.078335  1.000000   -0.019652     0.013596     0.000090   
clarity_IF    -0.012708 -0.019652    1.000000    -0.104747    -0.083975   
clarity_SI1    0.015914  0.013596   -0.104747     1.000000    -0.256280   
clarity_SI2   -0.001987  0.000090   -0.083975    -0.256280     1.000000   
clarity_VS1    0.024197  0.027156   -0.078275    -0.238886    -0.191513   
clarity_VS2   -0.009297  0.018492   -0.100468    -0.306617    -0.245812   
clarity_VVS1  -0.003036 -0.038604   -0.049946    -0.152428    -0.122200   
clarity_VVS2  -0.030477 -0.037966   -0.059644    -0.182026    -0.145929   

               clarity_VS1  clarity_VS2  clarity_VVS1  clarity_VVS2  
carat            -0.063089    -0.038906     -0.167568     -0.137020  
depth            -0.024144    -0.009466     -0.023461     -0.019224  
table            -0.026869    -0.009640     -0.069107     -0.062279  
price            -0.009879    -0.001066     -0.095261     -0.052375  
x                -0.059882    -0.035507     -0.185253     -0.147151  
y                -0.056490    -0.035926     -0.179271     -0.141624  
z                -0.058510    -0.036314     -0.182399     -0.144743  
cut_Good         -0.017108    -0.021067     -0.037559     -0.038621  
cut_Ideal         0.034265     0.015657      0.088365      0.075521  
cut_Premium      -0.011887     0.022555     -0.053863     -0.061963  
cut_Very Good    -0.006855    -0.016336     -0.005255      0.015279  
color_E          -0.027265     0.028006     -0.001521      0.011659  
color_F          -0.011047     0.003741      0.016894      0.013120  
color_G           0.055613    -0.023835      0.042406      0.059753  
color_H          -0.012730    -0.029928      0.004568     -0.030263  
color_I           0.024197    -0.009297     -0.003036     -0.030477  
color_J           0.027156     0.018492     -0.038604     -0.037966  
clarity_IF       -0.078275    -0.100468     -0.049946     -0.059644  
clarity_SI1      -0.238886    -0.306617     -0.152428     -0.182026  
clarity_SI2      -0.191513    -0.245812     -0.122200     -0.145929  
clarity_VS1       1.000000    -0.229129     -0.113907     -0.136025  
clarity_VS2      -0.229129     1.000000     -0.146202     -0.174592  
clarity_VVS1     -0.113907    -0.146202      1.000000     -0.086794  
clarity_VVS2     -0.136025    -0.174592     -0.086794      1.000000  

[24 rows x 24 columns]
No description has been provided for this image