MII/mai/lab2.ipynb

112 KiB
Raw Blame History

Лабораторная работа 2

Вариант - 9

Датасеты - магазины

  1. Цены на кофе https://www.kaggle.com/datasets/mayankanand2701/starbucks-stock-price-dataset
  2. Цены на акции https://www.kaggle.com/datasets/nancyalaswad90/yamana-gold-inc-stock-price
  3. Цены на золото https://www.kaggle.com/datasets/sid321axn/gold-price-prediction-dataset
In [26]:
import numpy as np
import pandas as pd
from sklearn.feature_selection import mutual_info_regression
from sklearn.model_selection import train_test_split
from imblearn.over_sampling import ADASYN

df = pd.read_csv("data/Diamonds.csv")
print(df.columns)

# Оценка зашумленности
noisy_features = []
for col in df.columns:
  if df[col].isnull().sum() / len(df) > 0.1:  # Если более 10% пропусков
    noisy_features.append(col)
      
print(f"Зашумленные столбцы: {noisy_features}")

cut_mapping = {'Fair': 0, 'Good': 1, 'Very Good': 2, 'Premium': 3, 'Ideal': 4}
df['cut'] = df['cut'].map(cut_mapping)

color_mapping = {'J': 0, 'I': 1, 'H': 2, 'G': 3, 'F': 4, 'E': 5, 'D': 6} 
df['color'] = df['color'].map(color_mapping)

clarity_mapping = {'I1': 0, 'SI2': 1, 'SI1': 2, 'VS2': 3, 'VS1': 4, 'VVS2': 5, 'VVS1': 6, 'IF': 7} 
df['clarity'] = df['clarity'].map(clarity_mapping)

skewness = df.skew()
print(f"Смещение: {skewness}")

skewed_features = skewness[abs(skewness) > 1].index.tolist()
print(f"Сильно смещенные столбцы: {skewed_features}")

# Оценка актуальности данных
print(f"Данные 2022 года, возможна неактуальность")

for col in df.select_dtypes(include=['number']).columns:
    Q1 = df[col].quantile(0.25)
    Q3 = df[col].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    outliers = df[col][(df[col] < lower_bound) | (df[col] > upper_bound)]
    print(f"Выбросы в столбце '{col}':\n{outliers}\n")

if len(df.columns) >= 2:
    for col1 in df.columns:
        for col2 in df.columns:
            if col1 != col2:
                correlation = df[col1].corr(df[col2])
                if abs(correlation) > 0.9:
                    print(f"Просачивание данных: Высокая корреляция ({correlation:.2f}) между столбцами '{col1}' и '{col2}'")

df.hist(figsize=(10, 10))

# решение смещения
df['log_price'] = np.log(df['price'] + 1)
df['log_carat'] = np.log(df['carat'] + 1)

# решение выбросов
Q1 = df['carat'].quantile(0.25)
Q3 = df['carat'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df['carat'] = np.where(df['carat'] > upper_bound, upper_bound, df['carat'])

df.drop(columns=['z'], inplace=True)  # Если z сильно коррелирует с y и x

# Пример оценки информативности для целевой переменной 'price'
X = df.drop(columns=['price'])
y = df['price']
mi_scores = mutual_info_regression(X, y)
print(pd.Series(mi_scores, index=X.columns).sort_values(ascending=False))

if df['carat'].max() > 5:
    print("Ошибка: Обнаружены значения массы, не соответствующие реальным бриллиантам.")
else:
    print("Данные по массе достоверны")

print("Уникальные значения 'cut':", df['cut'].unique())
print("Уникальные значения 'clarity':", df['clarity'].unique())

df['cut'] = df['cut'].fillna('unknown')

df['carat'] = df['carat'].fillna(df['carat'].mean())


print(df.carat.value_counts())

def split_stratified_into_train_val_test(
    df_input,
    stratify_colname="y",
    frac_train=0.6,
    frac_val=0.15,
    frac_test=0.25,
    random_state=None,
):


    if frac_train + frac_val + frac_test != 1.0:
        raise ValueError(
            "fractions %f, %f, %f do not add up to 1.0"
            % (frac_train, frac_val, frac_test)
        )

    if stratify_colname not in df_input.columns:
        raise ValueError("%s is not a column in the dataframe" % (stratify_colname))

    X = df_input  # Contains all columns.
    y = df_input[
        [stratify_colname]
    ]  # Dataframe of just the column on which to stratify.

    # Split original dataframe into train and temp dataframes.
    df_train, df_temp, y_train, y_temp = train_test_split(
        X, y, stratify=y, test_size=(1.0 - frac_train), random_state=random_state
    )

    # Split the temp dataframe into val and test dataframes.
    relative_frac_test = frac_test / (frac_val + frac_test)
    df_val, df_test, y_val, y_test = train_test_split(
        df_temp,
        y_temp,
        stratify=y_temp,
        test_size=relative_frac_test,
        random_state=random_state,
    )

    assert len(df_input) == len(df_train) + len(df_val) + len(df_test)

    return df_train, df_val, df_test

data = df[["carat", "price", "cut"]].copy()

df_train, df_val, df_test = split_stratified_into_train_val_test(
    data, stratify_colname="cut", frac_train=0.60, frac_val=0.20, frac_test=0.20
)
   

print(df_train.columns) 
   

print("Обучающая выборка: ", df_train.shape)
print(df_train.carat.value_counts()) 

print("Контрольная выборка: ", df_val.shape)
print(df_val.carat.value_counts())

print("Тестовая выборка: ", df_test.shape)
print(df_test.carat.value_counts())

ada = ADASYN()

print("Обучающая выборка: ", df_train.shape)
print(df_train.carat.value_counts())

X_resampled, y_resampled = ada.fit_resample(df_train, df_train["carat"])
df_train_adasyn = pd.DataFrame(X_resampled)

print("Обучающая выборка после oversampling: ", df_train_adasyn.shape)
print(df_train_adasyn.carat.value_counts())

df_train_adasyn
Index(['id', 'carat', 'cut', 'color', 'clarity', 'depth', 'table', 'price',
       'x', 'y', 'z'],
      dtype='object')
Зашумленные столбцы: []
Смещение: id         0.000000
carat      1.116705
cut       -0.717161
color     -0.189454
clarity    0.551503
depth     -0.082187
table      0.796836
price      1.618476
x          0.378685
y          2.434233
z          1.522481
dtype: float64
Сильно смещенные столбцы: ['carat', 'price', 'y', 'z']
Данные 2022 года, возможна неактуальность
Выбросы в столбце 'id':
Series([], Name: id, dtype: int64)

Выбросы в столбце 'carat':
12246    2.06
13002    2.14
13118    2.15
13757    2.22
13991    2.01
         ... 
27741    2.15
27742    2.04
27744    2.29
27746    2.07
27749    2.29
Name: carat, Length: 1889, dtype: float64

Выбросы в столбце 'cut':
Series([], Name: cut, dtype: int64)

Выбросы в столбце 'color':
Series([], Name: color, dtype: int64)

Выбросы в столбце 'clarity':
Series([], Name: clarity, dtype: int64)

Выбросы в столбце 'depth':
2        56.9
8        65.1
24       58.1
35       58.2
42       65.2
         ... 
53882    65.4
53886    58.0
53890    57.9
53895    57.8
53927    58.1
Name: depth, Length: 2545, dtype: float64

Выбросы в столбце 'table':
2        65.0
91       69.0
145      64.0
219      64.0
227      67.0
         ... 
53695    65.0
53697    65.0
53756    64.0
53757    64.0
53785    65.0
Name: table, Length: 605, dtype: float64

Выбросы в столбце 'price':
23820    11886
23821    11886
23822    11888
23823    11888
23824    11888
         ...  
27745    18803
27746    18804
27747    18806
27748    18818
27749    18823
Name: price, Length: 3540, dtype: int64

Выбросы в столбце 'x':
11182     0.00
11963     0.00
15951     0.00
22741     9.54
22831     9.38
23644     9.53
24131     9.44
24297     9.49
24328     9.65
24520     0.00
24816     9.42
25460     9.44
25850     9.32
25998    10.14
25999    10.02
26243     0.00
26431     9.42
26444    10.01
26534     9.86
26932     9.30
27130    10.00
27415    10.74
27429     0.00
27514     9.36
27630    10.23
27638     9.51
27649     9.44
27679     9.66
27684     9.35
27685     9.41
49556     0.00
49557     0.00
Name: x, dtype: float64

Выбросы в столбце 'y':
11963     0.00
15951     0.00
22741     9.38
22831     9.31
23644     9.48
24067    58.90
24131     9.40
24297     9.42
24328     9.59
24520     0.00
25460     9.37
25998    10.10
25999     9.94
26243     0.00
26431     9.34
26444     9.94
26534     9.81
27130     9.85
27415    10.54
27429     0.00
27514     9.31
27630    10.16
27638     9.46
27649     9.38
27679     9.63
27685     9.32
49189    31.80
49556     0.00
49557     0.00
Name: y, dtype: float64

Выбросы в столбце 'z':
2207      0.00
2314      0.00
4791      0.00
5471      0.00
10167     0.00
11182     0.00
11963     0.00
13601     0.00
14635     1.07
15951     0.00
16283     5.77
17196     5.76
19346     5.97
21758     5.98
22540     5.91
23539     5.79
23644     6.38
24067     8.06
24131     5.85
24297     5.92
24328     6.03
24394     0.00
24520     0.00
25998     6.17
25999     6.24
26100     5.75
26123     0.00
26194     6.16
26243     0.00
26431     6.27
26444     6.31
26534     6.13
26744     5.86
27112     0.00
27130     6.43
27415     6.98
27429     0.00
27503     0.00
27515     5.90
27516     5.90
27517     5.77
27518     5.77
27630     6.72
27679     6.03
27739     0.00
48410    31.80
49556     0.00
49557     0.00
51506     0.00
Name: z, dtype: float64

Просачивание данных: Высокая корреляция (0.92) между столбцами 'carat' и 'price'
Просачивание данных: Высокая корреляция (0.98) между столбцами 'carat' и 'x'
Просачивание данных: Высокая корреляция (0.95) между столбцами 'carat' и 'y'
Просачивание данных: Высокая корреляция (0.95) между столбцами 'carat' и 'z'
Просачивание данных: Высокая корреляция (0.92) между столбцами 'price' и 'carat'
Просачивание данных: Высокая корреляция (0.98) между столбцами 'x' и 'carat'
Просачивание данных: Высокая корреляция (0.97) между столбцами 'x' и 'y'
Просачивание данных: Высокая корреляция (0.97) между столбцами 'x' и 'z'
Просачивание данных: Высокая корреляция (0.95) между столбцами 'y' и 'carat'
Просачивание данных: Высокая корреляция (0.97) между столбцами 'y' и 'x'
Просачивание данных: Высокая корреляция (0.95) между столбцами 'y' и 'z'
Просачивание данных: Высокая корреляция (0.95) между столбцами 'z' и 'carat'
Просачивание данных: Высокая корреляция (0.97) между столбцами 'z' и 'x'
Просачивание данных: Высокая корреляция (0.95) между столбцами 'z' и 'y'
log_price    8.319386
id           8.135995
log_carat    1.963082
carat        1.961620
y            1.491815
x            1.481414
clarity      0.359837
color        0.288875
cut          0.104551
table        0.057094
depth        0.037126
dtype: float64
Данные по массе достоверны
Уникальные значения 'cut': [4 3 1 2 0]
Уникальные значения 'clarity': [1 2 4 3 5 6 0 7]
carat
0.30    2604
0.31    2249
1.01    2242
2.00    2154
0.70    1982
        ... 
1.95       3
1.85       3
1.94       3
1.99       3
1.92       2
Name: count, Length: 181, dtype: int64
Index(['carat', 'price', 'cut'], dtype='object')
Обучающая выборка:  (32365, 3)
carat
0.30    1562
1.01    1355
0.31    1338
2.00    1269
0.70    1156
        ... 
1.85       2
1.89       2
1.97       1
1.88       1
1.92       1
Name: count, Length: 181, dtype: int64
Контрольная выборка:  (10789, 3)
carat
0.30    500
0.31    474
2.00    441
1.01    435
0.70    425
       ... 
1.84      1
0.88      1
1.83      1
0.20      1
1.85      1
Name: count, Length: 173, dtype: int64
Тестовая выборка:  (10789, 3)
carat
0.30    542
1.01    452
2.00    444
0.31    437
0.70    401
       ... 
1.68      1
1.98      1
1.87      1
1.48      1
1.99      1
Name: count, Length: 175, dtype: int64
Обучающая выборка:  (32365, 3)
carat
0.30    1562
1.01    1355
0.31    1338
2.00    1269
0.70    1156
        ... 
1.85       2
1.89       2
1.97       1
1.88       1
1.92       1
Name: count, Length: 181, dtype: int64
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[26], line 157
    154 print("Обучающая выборка: ", df_train.shape)
    155 print(df_train.carat.value_counts())
--> 157 X_resampled, y_resampled = ada.fit_resample(df_train, df_train["carat"])
    158 df_train_adasyn = pd.DataFrame(X_resampled)
    160 print("Обучающая выборка после oversampling: ", df_train_adasyn.shape)

File c:\Python312\Lib\site-packages\imblearn\base.py:208, in BaseSampler.fit_resample(self, X, y)
    187 """Resample the dataset.
    188 
    189 Parameters
   (...)
    205     The corresponding label of `X_resampled`.
    206 """
    207 self._validate_params()
--> 208 return super().fit_resample(X, y)

File c:\Python312\Lib\site-packages\imblearn\base.py:104, in SamplerMixin.fit_resample(self, X, y)
     83 def fit_resample(self, X, y):
     84     """Resample the dataset.
     85 
     86     Parameters
   (...)
    102         The corresponding label of `X_resampled`.
    103     """
--> 104     check_classification_targets(y)
    105     arrays_transformer = ArraysTransformer(X, y)
    106     X, y, binarize_y = self._check_X_y(X, y)

File c:\Python312\Lib\site-packages\sklearn\utils\multiclass.py:219, in check_classification_targets(y)
    211 y_type = type_of_target(y, input_name="y")
    212 if y_type not in [
    213     "binary",
    214     "multiclass",
   (...)
    217     "multilabel-sequences",
    218 ]:
--> 219     raise ValueError(
    220         f"Unknown label type: {y_type}. Maybe you are trying to fit a "
    221         "classifier, which expects discrete classes on a "
    222         "regression target with continuous values."
    223     )

ValueError: Unknown label type: continuous. Maybe you are trying to fit a classifier, which expects discrete classes on a regression target with continuous values.
No description has been provided for this image

Датасет 1. Цены бриллиантов

  1. carat: Вес бриллианта в каратах
  2. cut: Качество огранки.
  3. color: Цвет бриллианта
  4. clarity: Чистота бриллианта
  5. depth: Процент глубины бриллианта
  6. table: Процент ширины бриллианта
  7. price: Цена бриллианта в долларах США
  8. x: Длина бриллианта в миллиметрах
  9. y: Ширина бриллианта в миллиметрах
  10. z: Глубина бриллианта в миллиметрах

Объект наблюдения: Каждый объект представляет собой отдельный бриллиант.
Связи между объектами: Внутри одного объекта есть взаимосвязь между характеристиками и его ценой. Например, вес, цвет, чистота и огранка могут влиять на цену.
Бизнес-цель: Оптимизация продаж бриллиантов, оценка цен в зависимости от характеристик.
Эффект для бизнеса: Более точная оценка стоимости бриллиантов может помочь ювелирам предлагать конкурентоспособные цены и максимизировать прибыль.
Техническая цель: Построение модели машинного обучения для прогнозирования цены бриллианта на основе его характеристик.\

  • Вход: Характеристики бриллианта (вес, огранка, цвет, чистота, размеры).\
  • Целевой признак: Цена бриллианта.

Информативность: Высокая. Набор данных содержит важные характеристики бриллиантов, которые влияют на их цену: карат, огранка, цвет, чистота, размеры.
Степень покрытия: Высокая. В наборе данных представлено 53 940 бриллиантов, что является достаточно большим объемом для анализа.
Соответствие реальным данным: Высокая. Характеристики бриллиантов в наборе данных соответствуют реальным характеристикам бриллиантов, определяемым геммологами.
Согласованность меток: Высокая. В данном наборе данных нет проблем с несогласованностью меток, так как все данные соответствуют описанию в заголовках столбцов.

Датасет 2. Цены акций Starbucks

  1. Date: Дата торгов
  2. Open: Цена открытия торгов
  3. High: Максимальная цена акции за день
  4. Low: Минимальная цена акции за день
  5. Close: Цена закрытия торгов в данный день
  6. Adj Close: Скоректированная цена закрытия.
  7. Volume: Объем торгов акциями в данный день.

Объект наблюдения: Объектом наблюдения является торговый день на рынке акций компании Starbucks.
Связи между объектами: Временная связь между днями торгов. Важна динамика изменений цен и объемов торгов в зависимости от времени.
Бизнес-цель: Прогнозирование цен акций для управления портфелем акций.
Эффект для бизнеса: Прогнозирование позволит трейдерам принимать более информированные решения, оптимизировать инвестиции и минимизировать риски.
Техническая цель: Прогнозирование цены закрытия акций на основе временных рядов.\

  • Вход: Временные ряды с историческими данными по ценам открытия, закрытия, объёмам.\
  • Целевой признак: Цена закрытия на следующий день.

Датасет 3. Цены на золото

  1. Date: Дата
  2. Open: Цена открытия торгов
  3. High: Максимальная цена за день
  4. Low: Минимальная цена за день
  5. Close: Цена закрытия торгов
  6. Adjusted Close: Скоректированная цена закрытия
  7. Volume: Объем торгов за день

Дополнительные столбцы (факторы, влияющие на цену золота):

  1. SP_open, SP_high, SP_low, SP_close, SP_Ajclose, SP_volume: Данные индекса S&P 500.
  2. DJ_open, DJ_high, DJ_low, DJ_close, DJ_Ajclose, DJ_volume: Данные индекса Dow Jones.
  3. EG_open, EG_high, EG_low, EG_close, EG_Ajclose, EG_volume: Данные компании Eldorado Gold Corporation (EGO).
  4. EU_Price, EU_open, EU_high, EU_low, EU_Trend: Курс валютной пары EUR/USD.
  5. OF_Price, OF_Open, OF_High, OF_Low, OF_Volume, OF_Trend: Цена фьючерсов на нефть Brent.
  6. OS_Price, OS_Open, OS_High, OS_Low, OS_Trend: Цена нефти WTI.
  7. SF_Price, SF_Open, SF_High, SF_Low, SF_Volume, SF_Trend: Цена фьючерсов на серебро.
  8. USB_Price, USB_Open, USB_High, USB_Low, USB_Trend: Ставка по облигациям США.
  9. PLT_Price, PLT_Open, PLT_High, PLT_Low, PLT_Trend: Цена платины.
  10. PLD_Price, PLD_Open, PLD_High, PLD_Low, PLD_Trend: Цена палладия.
  11. RHO_PRICE: Цена родия.
  12. USDI_Price, USDI_Open, USDI_High, USDI_Low, USDI_Volume, USDI_Trend: Индекс доллара США.
  13. GDX_Open, GDX_High, GDX_Low, GDX_Close, GDX_Adj Close, GDX_Volume: Данные ETF на золотые шахты.
  14. USO_Open, USO_High, USO_Low, USO_Close, USO_Adj Close, USO_Volume: Данные ETF на нефть USO.

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

  • Вход: Данные по ценам на золото и дополнительным факторам (нефть, индексы, валюты).\
  • Целевой признак: Цена закрытия золота.