2024-10-19 20:31:08 +04:00

22 KiB
Raw Blame History

Lab2 Pibd-31 Sagirov M M

Загрузка трёх датасетов

In [2]:
import pandas as pd
df = pd.read_csv("..//datasets//Lab_2//world-population-by-country-2020.csv", sep=",")
df2 = pd.read_csv("..//datasets//Lab_2//Starbucks Dataset.csv", sep=",")
df3 = pd.read_csv("..//datasets//Lab_2//students_adaptability_level_online_education.csv", sep=",")

Пункты 2-8 представленны далее в виде Markdown:

Пункт 2 - Проблемные области:

df - Население планеты

df2 - Акции Starbucks

df3 - Эффективность онлайн обучения

Пункт 3 - Объекты, их аттрибуты и связи:

df - Объектом наблюдения является Страна. Имеет в себе аттрибуты такие как: место в списке, название, население на 2020 год, изменение за год, процентное изменение, плотность населения, а так же процент мигрантов и рождаемость.

df2 - Объектом наблюдения является Акция. Имеет в себе аттрибуты такие как: дата торговли, цена на открытие биржи, высшая и низшая цена за день, цена на закрытии и объем торговли.

df3 - Объектом наблюдения является Студент. Имеет в себе аттрибуты такие как: Уровень образования, тип обучения (платно/бесплатно), пол, возраст, расположение, финансовое состояние и уровень адаптируемости к онлайн обучению.

Связей между объектами нет.

Пункт 4 - Бизнес-цели:

df - Для составления списка приоритетных стран для показа рекламы для миграции.

df2 - Для выявления тенденций Акций Starbucks.

df3 - Для решения о целесообразности введения онлайн обучения в учереждении.

Пункт 5 - Цели проектов:

df - Поступает нужны процент мигрантов, а на выходе страны с подходящим числом мигрантов.

df2 - Поступает высшая стоимость сегодняшней акции, а на выходе предполагаемый процент завтра.

df3 - Поступает список студентов с их состояниями, а на выходе вердикт оправдает ли себя ввод онлайн обучения.

Пункт 6 - Проблемы наборов:

Проверка на пропущенные значения:

In [3]:
print(df.isnull().sum())
print(df2.isnull().sum())
print(df3.isnull().sum())
no                          0
Country (or dependency)     0
Population 2020             0
Yearly Change               0
Net Change                  0
Density  (P/Km²)            0
Land Area (Km²)             0
Migrants (net)             34
Fert. Rate                  0
Med. Age                    0
Urban Pop %                 0
World Share                 0
dtype: int64
Date         0
Open         0
High         0
Low          0
Close        0
Adj Close    0
Volume       0
dtype: int64
Education Level        0
Institution Type       0
Gender                 0
Age                    0
Device                 0
IT Student             0
Location               0
Financial Condition    0
Internet Type          0
Network Type           0
Flexibility Level      0
dtype: int64

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

df и df2 - неактуальные, так как в первом используется информация 4-х летней давности, а во втором - с 1992.

Пункт 7 - Примеры решений:

Для обоих датасетов решением будет полное обновление данных.

Пункт 8 - Оценка качества:

Информативность лучше всего у df и df3, так же как и степень покрытия. Реальным данным соответствует очень хорошо df2. Во всех датасетах метки хорошо согласованны.

Пункт 9 - Устранение пустых данных:

Устраним пустые данные в df путем удаления строк, в которых они присутствуют

In [5]:
df['Migrants (net)'] = df['Migrants (net)'].replace('', pd.NA)
df_cleaned = df.dropna(subset=['Migrants (net)'])
df_cleaned.to_csv("..//datasets//Lab_2//World_population_cleaned.csv", index=False)

А теперь просто проведем действия с оставшимися наборами данных:

В df2 поставим у всех записей цену при открытии на 12

In [6]:
df2['Open'] = 12
print(df2)
            Date  Open       High        Low      Close  Adj Close     Volume
0     1992-06-26    12   0.347656   0.320313   0.335938   0.260703  224358400
1     1992-06-29    12   0.367188   0.332031   0.359375   0.278891   58732800
2     1992-06-30    12   0.371094   0.343750   0.347656   0.269797   34777600
3     1992-07-01    12   0.359375   0.339844   0.355469   0.275860   18316800
4     1992-07-02    12   0.359375   0.347656   0.355469   0.275860   13996800
...          ...   ...        ...        ...        ...        ...        ...
8031  2024-05-17    12  78.000000  74.919998  77.849998  77.849998   14436500
8032  2024-05-20    12  78.320000  76.709999  77.540001  77.540001   11183800
8033  2024-05-21    12  78.220001  77.500000  77.720001  77.720001    8916600
8034  2024-05-22    12  81.019997  77.440002  80.720001  80.720001   22063400
8035  2024-05-23    12  80.699997  79.169998  79.260002  79.260002    4651418

[8036 rows x 7 columns]

В df3 установим у всех средний по столбцу возраст

In [7]:
Age_mean = df3['Age'].mean()
df3['Age'] = Age_mean
print(df3[['Age']])
           Age
0     17.06556
1     17.06556
2     17.06556
3     17.06556
4     17.06556
...        ...
1200  17.06556
1201  17.06556
1202  17.06556
1203  17.06556
1204  17.06556

[1205 rows x 1 columns]

Пункт 10 - Разбиение

In [12]:
from sklearn.model_selection import train_test_split

train_df, temp_df = train_test_split(df_cleaned, test_size=0.3, random_state=22)
val_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=22) 

train_df2, temp_df2 = train_test_split(df2, test_size=0.3, random_state=22)
val_df2, test_df2 = train_test_split(temp_df2, test_size=0.5, random_state=22)

train_df3, temp_df3 = train_test_split(df3, test_size=0.3, random_state=22)
val_df3, test_df3 = train_test_split(temp_df3, test_size=0.5, random_state=22)
print(f"Train df: {train_df.shape}, Validation df: {val_df.shape}, Test df: {test_df.shape}")
print(f"Train df2: {train_df2.shape}, Validation df2: {val_df2.shape}, Test df2: {test_df2.shape}")
print(f"Train df3: {train_df3.shape}, Validation df3: {val_df3.shape}, Test df3: {test_df3.shape}")
Train df: (140, 12), Validation df: (30, 12), Test df: (31, 12)
Train df2: (5625, 7), Validation df2: (1205, 7), Test df2: (1206, 7)
Train df3: (843, 11), Validation df3: (181, 11), Test df3: (181, 11)

Пункт 11 - Проверка на сбалансированность

In [13]:
#Проверка на сбалансированность
def check_balance(df, target_column):
    distribution = df[target_column].value_counts(normalize=True) * 100
    print(f"Распределение по столбцу '{target_column}':\n", distribution)

# Для датасета 1
print("Баланс Train df:")
check_balance(train_df, 'Migrants (net)')  
print("\nБаланс Validation df:")
check_balance(val_df, 'Migrants (net)')
print("\nБаланс Test df:")
check_balance(test_df, 'Migrants (net)')

# Для датасета 2
print("\nБаланс Train df2:")
check_balance(train_df2, 'High')
print("\nБаланс Validation df2:")
check_balance(val_df2, 'High')
print("\nБаланс Test df2:")
check_balance(test_df2, 'High')

# Для датасета 3
print("\nБаланс Train df3:")
check_balance(train_df3, 'Flexibility Level')
print("\nБаланс Validation df3:")
check_balance(val_df3, 'Flexibility Level')
print("\nБаланс Test df3:")
check_balance(test_df3, 'Flexibility Level')
Баланс Train df:
Распределение по столбцу 'Migrants (net)':
 Migrants (net)
-800       2.857143
0          2.857143
-4,000     2.142857
40,000     2.142857
-5,000     2.142857
             ...   
52,000     0.714286
515        0.714286
50,000     0.714286
-39,858    0.714286
1,485      0.714286
Name: proportion, Length: 115, dtype: float64

Баланс Validation df:
Распределение по столбцу 'Migrants (net)':
 Migrants (net)
900         6.666667
-40,000     6.666667
36,400      3.333333
-67,152     3.333333
87,400      3.333333
-62,920     3.333333
16,000      3.333333
-451        3.333333
-2,803      3.333333
-4,000      3.333333
380         3.333333
11,370      3.333333
-163,313    3.333333
-1,500      3.333333
-1,000      3.333333
10,220      3.333333
-852        3.333333
168,694     3.333333
2,000       3.333333
-98,955     3.333333
-200        3.333333
47,800      3.333333
-60,000     3.333333
10,000      3.333333
3,000       3.333333
-14,837     3.333333
320         3.333333
-20,000     3.333333
Name: proportion, dtype: float64

Баланс Test df:
Распределение по столбцу 'Migrants (net)':
 Migrants (net)
-10,000     6.451613
1,000       3.225806
204,796     3.225806
-14,704     3.225806
-6,800      3.225806
3,911       3.225806
-16,053     3.225806
145,405     3.225806
4,800       3.225806
39,520      3.225806
71,560      3.225806
-4,806      3.225806
0           3.225806
-14,400     3.225806
4,000       3.225806
6,413       3.225806
120         3.225806
-8,353      3.225806
-116,858    3.225806
40,000      3.225806
260,650     3.225806
1,200       3.225806
-9,000      3.225806
1,351       3.225806
2,001       3.225806
-1,256      3.225806
-8,863      3.225806
-38,033     3.225806
-1,342      3.225806
5,000       3.225806
Name: proportion, dtype: float64

Баланс Train df2:
Распределение по столбцу 'High':
 High
0.804688     0.248889
0.742188     0.231111
0.765625     0.231111
0.789063     0.213333
0.757813     0.195556
               ...   
29.485001    0.017778
38.290001    0.017778
97.580002    0.017778
74.769997    0.017778
64.040001    0.017778
Name: proportion, Length: 4071, dtype: float64

Баланс Validation df2:
Распределение по столбцу 'High':
 High
0.851563     0.414938
0.757813     0.414938
0.726563     0.331950
0.812500     0.331950
0.914063     0.331950
               ...   
13.000000    0.082988
10.452500    0.082988
2.492188     0.082988
61.720001    0.082988
3.800781     0.082988
Name: proportion, Length: 1078, dtype: float64

Баланс Test df2:
Распределение по столбцу 'High':
 High
0.796875     0.414594
0.765625     0.414594
1.640625     0.331675
0.882813     0.331675
0.757813     0.331675
               ...   
8.085000     0.082919
10.595000    0.082919
7.540000     0.082919
99.470001    0.082919
88.540001    0.082919
Name: proportion, Length: 1088, dtype: float64

Баланс Train df3:
Распределение по столбцу 'Flexibility Level':
 Flexibility Level
Moderate    52.669039
Low         38.552788
High         8.778173
Name: proportion, dtype: float64

Баланс Validation df3:
Распределение по столбцу 'Flexibility Level':
 Flexibility Level
Moderate    50.276243
Low         44.198895
High         5.524862
Name: proportion, dtype: float64

Баланс Test df3:
Распределение по столбцу 'Flexibility Level':
 Flexibility Level
Moderate    49.723757
Low         41.436464
High         8.839779
Name: proportion, dtype: float64

Наши выборки сбалансированно распределены.

Пункт 12 - Приращение данных:

In [15]:
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler

# Функция для выполнения oversampling
def apply_oversampling(X, y):
    oversampler = RandomOverSampler(random_state=22)
    X_resampled, y_resampled = oversampler.fit_resample(X, y)
    print(f"Размер выборки после oversampling: {X_resampled.shape}")
    return X_resampled, y_resampled

# Функция для выполнения undersampling
def apply_undersampling(X, y):
    undersampler = RandomUnderSampler(random_state=22)
    X_resampled, y_resampled = undersampler.fit_resample(X, y)
    print(f"Размер выборки после undersampling: {X_resampled.shape}")
    return X_resampled, y_resampled

# Пример для первого набора данных (df)
X_1 = train_df.drop(columns=['Migrants (net)']) 
y_1 = train_df['Migrants (net)']

print("df - Oversampling:")
X_resampled1, y_resampled1 = apply_oversampling(X_1, y_1)

print("\ndf - Undersampling:")
X_resampled1_under, y_resampled1_under = apply_undersampling(X_1, y_1)

# Пример для второго набора данных (df2)
X_2 = train_df2.drop(columns=['Volume'])
y_2 = train_df2['Volume']

print("\ndf2 - Oversampling:")
X_resampled2, y_resampled2 = apply_oversampling(X_2, y_2)

print("\ndf2 - Undersampling:")
X_resampled2_under, y_resampled2_under = apply_undersampling(X_2, y_2)

# Пример для третьего набора данных (df3)
X_3 = train_df3.drop(columns=['Flexibility Level'])
y_3 = train_df3['Flexibility Level']

print("\ndf3 - Oversampling:")
X_resampled3, y_resampled3 = apply_oversampling(X_3, y_3)

print("\ndf3 - Undersampling:")
X_resampled3_under, y_resampled3_under = apply_undersampling(X_3, y_3)
df - Oversampling:
Размер выборки после oversampling: (460, 11)

df - Undersampling:
Размер выборки после undersampling: (115, 11)

df2 - Oversampling:
Размер выборки после oversampling: (21868, 6)

df2 - Undersampling:
Размер выборки после undersampling: (5467, 6)

df3 - Oversampling:
Размер выборки после oversampling: (1332, 10)

df3 - Undersampling:
Размер выборки после undersampling: (222, 10)