2024-12-07 08:30:32 +04:00

24 KiB
Raw Blame History

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

1. Загружаем три датасета

In [1]:
import pandas as pd
df = pd.read_csv(".//datasetlab2//kc_house_data.csv", sep=",")
df2 = pd.read_csv(".//datasetlab2//Stores.csv", sep=",")
df3 = pd.read_csv(".//datasetlab2//Forbes Billionaires.csv", sep=",")

2. Проблемные области:

stores.csv - магазины
kc_house_data.csv - продажа домов
Forber Billionares.csv - миллионеры

3. Объекты:

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

4. Примеры бизнес-целей:

Датасет миллионеров нужны например для сайта forbes - чтобы составить тир лист. В целом, другие датасеты тоже подходят для составления тир листа)

5. Примеры целей технического проекта:

Технический проект - тир лист, на входе датасет

6. Проблемы выбранных наборов данных:

Пункт будем выполнять в коде, оставлю к каждому комменты:

In [2]:
# Проверка на пропущенные значения
print(df.isnull().sum())
print(df2.isnull().sum())
print(df3.isnull().sum())
id               0
date             0
price            0
bedrooms         0
bathrooms        0
sqft_living      0
sqft_lot         0
floors           0
waterfront       0
view             0
condition        0
grade            0
sqft_above       0
sqft_basement    0
yr_built         0
yr_renovated     0
zipcode          0
lat              0
long             0
sqft_living15    0
sqft_lot15       0
dtype: int64
Store ID                0
Store_Area              0
Items_Available         0
Daily_Customer_Count    0
Store_Sales             0
dtype: int64
Rank        0
Name        0
Networth    0
Age         0
Country     0
Source      0
Industry    0
dtype: int64
In [4]:
# Статистика по числовым данным для выявления аномальных распределений
print(df.describe())
print(df2.describe())
print(df3.describe())
                 id         price      bedrooms     bathrooms   sqft_living  \
count  2.161300e+04  2.161300e+04  21613.000000  21613.000000  21613.000000   
mean   4.580302e+09  5.400881e+05      3.370842      2.114757   2079.899736   
std    2.876566e+09  3.671272e+05      0.930062      0.770163    918.440897   
min    1.000102e+06  7.500000e+04      0.000000      0.000000    290.000000   
25%    2.123049e+09  3.219500e+05      3.000000      1.750000   1427.000000   
50%    3.904930e+09  4.500000e+05      3.000000      2.250000   1910.000000   
75%    7.308900e+09  6.450000e+05      4.000000      2.500000   2550.000000   
max    9.900000e+09  7.700000e+06     33.000000      8.000000  13540.000000   

           sqft_lot        floors    waterfront          view     condition  \
count  2.161300e+04  21613.000000  21613.000000  21613.000000  21613.000000   
mean   1.510697e+04      1.494309      0.007542      0.234303      3.409430   
std    4.142051e+04      0.539989      0.086517      0.766318      0.650743   
min    5.200000e+02      1.000000      0.000000      0.000000      1.000000   
25%    5.040000e+03      1.000000      0.000000      0.000000      3.000000   
50%    7.618000e+03      1.500000      0.000000      0.000000      3.000000   
75%    1.068800e+04      2.000000      0.000000      0.000000      4.000000   
max    1.651359e+06      3.500000      1.000000      4.000000      5.000000   

              grade    sqft_above  sqft_basement      yr_built  yr_renovated  \
count  21613.000000  21613.000000   21613.000000  21613.000000  21613.000000   
mean       7.656873   1788.390691     291.509045   1971.005136     84.402258   
std        1.175459    828.090978     442.575043     29.373411    401.679240   
min        1.000000    290.000000       0.000000   1900.000000      0.000000   
25%        7.000000   1190.000000       0.000000   1951.000000      0.000000   
50%        7.000000   1560.000000       0.000000   1975.000000      0.000000   
75%        8.000000   2210.000000     560.000000   1997.000000      0.000000   
max       13.000000   9410.000000    4820.000000   2015.000000   2015.000000   

            zipcode           lat          long  sqft_living15     sqft_lot15  
count  21613.000000  21613.000000  21613.000000   21613.000000   21613.000000  
mean   98077.939805     47.560053   -122.213896    1986.552492   12768.455652  
std       53.505026      0.138564      0.140828     685.391304   27304.179631  
min    98001.000000     47.155900   -122.519000     399.000000     651.000000  
25%    98033.000000     47.471000   -122.328000    1490.000000    5100.000000  
50%    98065.000000     47.571800   -122.230000    1840.000000    7620.000000  
75%    98118.000000     47.678000   -122.125000    2360.000000   10083.000000  
max    98199.000000     47.777600   -121.315000    6210.000000  871200.000000  
        Store ID    Store_Area  Items_Available  Daily_Customer_Count  \
count  896.000000   896.000000       896.000000            896.000000   
mean   448.500000  1485.409598      1782.035714            786.350446   
std    258.797218   250.237011       299.872053            265.389281   
min      1.000000   775.000000       932.000000             10.000000   
25%    224.750000  1316.750000      1575.500000            600.000000   
50%    448.500000  1477.000000      1773.500000            780.000000   
75%    672.250000  1653.500000      1982.750000            970.000000   
max    896.000000  2229.000000      2667.000000           1560.000000   

         Store_Sales  
count     896.000000  
mean    59351.305804  
std     17190.741895  
min     14920.000000  
25%     46530.000000  
50%     58605.000000  
75%     71872.500000  
max    116320.000000  
             Rank      Networth          Age
count  2600.000000  2600.000000  2600.000000
mean   1269.570769     4.860750    64.271923
std     728.146364    10.659671    13.220607
min       1.000000     1.000000    19.000000
25%     637.000000     1.500000    55.000000
50%    1292.000000     2.400000    64.000000
75%    1929.000000     4.500000    74.000000
max    2578.000000   219.000000   100.000000

7. Примеры решения обнаруженных проблем

После проверки на пропущенные значения выявлено, что все супео.
А дальше обнаружилась аномалию: в датасете миллионеров есть столбец networth - чистое количество денег во всех формах ( в миллиардах ), там минимальное значение = 1, медиана в районе 2.4, а максимальное - 219

8. Оценить качество каждого набора данных:

Наши датасеты довольно информационные. Например у миллионер датасета можно посмотреть фио, сколько у него денег, что он сделал.
Датасет по продаже домов гораздо информационнее, является лидером по наполненности и соответствует реальности.
А вот датасет магазинов слабоват, можно например добавить: количество филлиалов, работников, прибыль

9. Устранить проблему пропущенных данных

Возьмём датасет магазинов, будем удалять столбцы, где площадь ниже 2130

In [5]:
df2_filtered = df2[df2['Store_Area'] >= 2130]
print(df2_filtered)
     Store ID   Store_Area  Items_Available  Daily_Customer_Count  Store_Sales
91          92        2169             2617                   600        67080
466        467        2229             2667                   660        87410
540        541        2214             2647                   740        65900

Теперь в датасете магазнов price заменим у всех на константное значение - 1 500 000

In [6]:
df['price'] = 1500000
print(df)
               id             date    price  bedrooms  bathrooms  sqft_living  \
0      7129300520  20141013T000000  1500000         3       1.00         1180   
1      6414100192  20141209T000000  1500000         3       2.25         2570   
2      5631500400  20150225T000000  1500000         2       1.00          770   
3      2487200875  20141209T000000  1500000         4       3.00         1960   
4      1954400510  20150218T000000  1500000         3       2.00         1680   
...           ...              ...      ...       ...        ...          ...   
21608   263000018  20140521T000000  1500000         3       2.50         1530   
21609  6600060120  20150223T000000  1500000         4       2.50         2310   
21610  1523300141  20140623T000000  1500000         2       0.75         1020   
21611   291310100  20150116T000000  1500000         3       2.50         1600   
21612  1523300157  20141015T000000  1500000         2       0.75         1020   

       sqft_lot  floors  waterfront  view  ...  grade  sqft_above  \
0          5650     1.0           0     0  ...      7        1180   
1          7242     2.0           0     0  ...      7        2170   
2         10000     1.0           0     0  ...      6         770   
3          5000     1.0           0     0  ...      7        1050   
4          8080     1.0           0     0  ...      8        1680   
...         ...     ...         ...   ...  ...    ...         ...   
21608      1131     3.0           0     0  ...      8        1530   
21609      5813     2.0           0     0  ...      8        2310   
21610      1350     2.0           0     0  ...      7        1020   
21611      2388     2.0           0     0  ...      8        1600   
21612      1076     2.0           0     0  ...      7        1020   

       sqft_basement  yr_built  yr_renovated  zipcode      lat     long  \
0                  0      1955             0    98178  47.5112 -122.257   
1                400      1951          1991    98125  47.7210 -122.319   
2                  0      1933             0    98028  47.7379 -122.233   
3                910      1965             0    98136  47.5208 -122.393   
4                  0      1987             0    98074  47.6168 -122.045   
...              ...       ...           ...      ...      ...      ...   
21608              0      2009             0    98103  47.6993 -122.346   
21609              0      2014             0    98146  47.5107 -122.362   
21610              0      2009             0    98144  47.5944 -122.299   
21611              0      2004             0    98027  47.5345 -122.069   
21612              0      2008             0    98144  47.5941 -122.299   

       sqft_living15  sqft_lot15  
0               1340        5650  
1               1690        7639  
2               2720        8062  
3               1360        5000  
4               1800        7503  
...              ...         ...  
21608           1530        1509  
21609           1830        7200  
21610           1020        2007  
21611           1410        1287  
21612           1020        1357  

[21613 rows x 21 columns]

Теперь у миллионеров в networth подставим среднее по столбцу:

In [10]:
networth_mean = df3['Networth'].mean()
df3['Networth'] = networth_mean
print(df3[['Networth']])
      Networth
0      4.86075
1      4.86075
2      4.86075
3      4.86075
4      4.86075
...        ...
2595   4.86075
2596   4.86075
2597   4.86075
2598   4.86075
2599   4.86075

[2600 rows x 1 columns]

10. Выполнить разбиение каждого набора данных

Делаем разбиение на три выборки: 70%, 15% и 15%.
Подключил библиотеку scikit-learn и использовал функцию train_test_split

In [11]:
from sklearn.model_selection import train_test_split

train_df, temp_df = train_test_split(df, test_size=0.3, random_state=42)
val_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=42) 

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

train_df3, temp_df3 = train_test_split(df3, test_size=0.3, random_state=42)
val_df3, test_df3 = train_test_split(temp_df3, test_size=0.5, random_state=42)
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: (15129, 21), Validation df: (3242, 21), Test df: (3242, 21)
Train df2: (627, 5), Validation df2: (134, 5), Test df2: (135, 5)
Train df3: (1820, 7), Validation df3: (390, 7), Test df3: (390, 7)

11. Оценить сбаланисрованность

Из пункта 15 понимаем что все сбалансированные

12. Выполнить приращение данных

Скачал библиотеку imbalanced-learn, использую разные функции

In [12]:
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
df = pd.read_csv(".//datasetlab2//kc_house_data.csv", sep=",")
df['price_category'] = pd.cut(df['price'], bins=[0, 300000, 600000, 1000000, float('inf')],
                              labels=['Low', 'Medium', 'High', 'Luxury'])

y = df['price_category']
X = df.drop(columns=['price', 'price_category'])

oversampler = RandomOverSampler(random_state=42)
X_resampled, y_resampled = oversampler.fit_resample(X, y)

undersampler = RandomUnderSampler(random_state=42)
X_resampled_under, y_resampled_under = undersampler.fit_resample(X, y)

print("Class distribution after oversampling (df):")
print(pd.Series(y_resampled).value_counts())

print("Class distribution after undersampling (df):")
print(pd.Series(y_resampled_under).value_counts())
Class distribution after oversampling (df):
price_category
Low       10787
Medium    10787
High      10787
Luxury    10787
Name: count, dtype: int64
Class distribution after undersampling (df):
price_category
Low       1465
Medium    1465
High      1465
Luxury    1465
Name: count, dtype: int64
In [13]:
df3 = pd.read_csv(".//datasetlab2//Forbes Billionaires.csv", sep=",")

df3['AGE_category'] = pd.cut(df3['Age'], bins=[0, 30, 50, 70, float('inf')],
                              labels=['Young', 'Middle-aged', 'Senior', 'Elderly'])

y3 = df3['AGE_category']
X3 = df3.drop(columns=['Age', 'AGE_category'])

oversampler3 = RandomOverSampler(random_state=42)
X_resampled_3, y_resampled_3 = oversampler3.fit_resample(X3, y3)

undersampler3 = RandomUnderSampler(random_state=42)
X_resampled_3_under, y_resampled_3_under = undersampler3.fit_resample(X3, y3)

print("Class distribution after oversampling (df3):")
print(pd.Series(y_resampled_3).value_counts())

print("Class distribution after undersampling (df3):")
print(pd.Series(y_resampled_3_under).value_counts())
Class distribution after oversampling (df3):
AGE_category
Young          1401
Middle-aged    1401
Senior         1401
Elderly        1401
Name: count, dtype: int64
Class distribution after undersampling (df3):
AGE_category
Young          15
Middle-aged    15
Senior         15
Elderly        15
Name: count, dtype: int64
In [14]:
df2 = pd.read_csv(".//datasetlab2//Stores.csv", sep=",")

df2['Sales_category'] = pd.cut(df2['Store_Sales'], bins=[0, 50000, 100000, 200000, float('inf')],
                                labels=['Low', 'Medium', 'High', 'Luxury'])

y2 = df2['Sales_category']
X2 = df2.drop(columns=['Store_Sales', 'Sales_category'])

oversampler2 = RandomOverSampler(random_state=42)
X_resampled_2, y_resampled_2 = oversampler2.fit_resample(X2, y2)

undersampler2 = RandomUnderSampler(random_state=42)
X_resampled_2_under, y_resampled_2_under = undersampler2.fit_resample(X2, y2)

print("Class distribution after oversampling (df2):")
print(pd.Series(y_resampled_2).value_counts())

print("Class distribution after undersampling (df2):")
print(pd.Series(y_resampled_2_under).value_counts())
Class distribution after oversampling (df2):
Sales_category
Low       598
Medium    598
High      598
Luxury      0
Name: count, dtype: int64
Class distribution after undersampling (df2):
Sales_category
Low       7
Medium    7
High      7
Luxury    0
Name: count, dtype: int64