2024-09-28 22:20:22 +03:00

37 KiB
Raw Blame History

Загрузка данных в DataFrame "Список форбс"

О рейтинге The World's Billionaires ("Миллиардеры мира") - ежегодный рейтинг самых богатых миллиардеров мира, составляемый и публикуемый в марте американским деловым журналом Forbes. Общее состояние каждого человека, включенного в список, оценивается в долларах США на основе его документально подтвержденных активов, а также с учетом долгов и других факторов. Этот рейтинг представляет собой список самых богатых людей, зарегистрированных по документам, за исключением тех, чье благосостояние не может быть полностью установлено.

Методология Forbes Каждый год Forbes нанимает команду из более чем 50 репортеров из разных стран, чтобы отслеживать деятельность самых богатых людей мира, а иногда и групп или семей, которые делятся богатством. Предварительные опросы рассылаются тем, кто может попасть в список.

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

Для проверки данных и уточнения оценки активов отдельных лиц проводятся собеседования. И, наконец, котировки акций, обращающихся на бирже, оцениваются по рыночным ценам примерно за месяц до публикации. Частные компании оцениваются в соответствии с преобладающим соотношением цены к продажам или цены к прибыли. Известные долги вычитаются из активов, чтобы получить окончательную оценку предполагаемого состояния человека в долларах США. Поскольку цены на акции быстро колеблются, истинное состояние человека и его рейтинг на момент публикации могут отличаться от того, в котором он находился на момент составления списка.

In [8]:
import pandas as pd

df = pd.read_csv("..//..//static//csv//Forbes Billionaires.csv", index_col="Rank")

df.info()

print(df.shape)

df.head()
<class 'pandas.core.frame.DataFrame'>
Index: 2600 entries, 1 to 2578
Data columns (total 6 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   Name      2600 non-null   object 
 1   Networth  2600 non-null   float64
 2   Age       2600 non-null   int64  
 3   Country   2600 non-null   object 
 4   Source    2600 non-null   object 
 5   Industry  2600 non-null   object 
dtypes: float64(1), int64(1), object(4)
memory usage: 142.2+ KB
(2600, 6)
Out[8]:
Name Networth Age Country Source Industry
Rank
1 Elon Musk 219.0 50 United States Tesla, SpaceX Automotive
2 Jeff Bezos 171.0 58 United States Amazon Technology
3 Bernard Arnault & family 158.0 73 France LVMH Fashion & Retail
4 Bill Gates 129.0 66 United States Microsoft Technology
5 Warren Buffett 118.0 91 United States Berkshire Hathaway Finance & Investments

2. Проблемная область

Анализ данных из списка миллиардеров Forbes позволяет не только понять текущее состояние богатства в мире, но и выявить более глубокие тенденции и паттерны, которые могут помочь в принятии бизнес-решений, понимании экономических процессов и определении направлений для дальнейших исследований. Эти данные могут быть основой для многочисленных статей, отчетов и аналитических исследований, что делает их ценными для широкого круга специалистов в различных областях.

3. Анализ содержимого

  1. Объектами наблюдения являются миллиардеры.
  2. В качестве атбирутов вредставлены: имя, величина богатства, возраст, страна, источник, индустрия
  3. Связей между объектами нет

4. Бизнес-цели

  1. Сравнив свой бизнес с другими успешными компаниями, основанными миллиардерами, можно извлечь ценные уроки о сильных сторонами и недостатках своей компании.
  2. Анализируя, в каких секторах работают миллиардеры и какие компании они развивают, можно выявить растущие рынки и индустрии, в которые стоит инвестировать.

Привести примеры целей технического проекта для каждой выделенной ранее бизнес-цели. Что поступает на вход, что является целевым признаком?

In [ ]:

Получение сведений о пропущенных данных

Типы пропущенных данных:

  • None - представление пустых данных в Python
  • NaN - представление пустых данных в Pandas
  • '' - пустая строка
In [7]:
# Количество пустых значений признаков
print(df.isnull().sum())

print()

# Есть ли пустые значения признаков
print(df.isnull().any())

print()

# Процент пустых значений признаков
for i in df.columns:
    null_rate = df[i].isnull().sum() / len(df) * 100
    if null_rate > 0:
        print(f"{i} процент пустых значений: %{null_rate:.2f}")
Name        0
Networth    0
Age         0
Country     0
Source      0
Industry    0
dtype: int64

Name        False
Networth    False
Age         False
Country     False
Source      False
Industry    False
dtype: bool

In [3]:
fillna_df = df.fillna(0)

print(fillna_df.shape)

print(fillna_df.isnull().any())

# Замена пустых данных на 0
df["AgeFillNA"] = df["Age"].fillna(0)

# Замена пустых данных на медиану
df["AgeFillMedian"] = df["Age"].fillna(df["Age"].median())

df.tail()
(891, 11)
Survived    False
Pclass      False
Name        False
Sex         False
Age         False
SibSp       False
Parch       False
Ticket      False
Fare        False
Cabin       False
Embarked    False
dtype: bool
Out[3]:
Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked AgeFillNA AgeFillMedian
PassengerId
887 0 2 Montvila, Rev. Juozas male 27.0 0 0 211536 13.00 NaN S 27.0 27.0
888 1 1 Graham, Miss. Margaret Edith female 19.0 0 0 112053 30.00 B42 S 19.0 19.0
889 0 3 Johnston, Miss. Catherine Helen "Carrie" female NaN 1 2 W./C. 6607 23.45 NaN S 0.0 28.0
890 1 1 Behr, Mr. Karl Howell male 26.0 0 0 111369 30.00 C148 C 26.0 26.0
891 0 3 Dooley, Mr. Patrick male 32.0 0 0 370376 7.75 NaN Q 32.0 32.0
In [4]:
df["AgeCopy"] = df["Age"]

# Замена данных сразу в DataFrame без копирования
df.fillna({"AgeCopy": 0}, inplace=True)

df.tail()
Out[4]:
Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked AgeFillNA AgeFillMedian AgeCopy
PassengerId
887 0 2 Montvila, Rev. Juozas male 27.0 0 0 211536 13.00 NaN S 27.0 27.0 27.0
888 1 1 Graham, Miss. Margaret Edith female 19.0 0 0 112053 30.00 B42 S 19.0 19.0 19.0
889 0 3 Johnston, Miss. Catherine Helen "Carrie" female NaN 1 2 W./C. 6607 23.45 NaN S 0.0 28.0 0.0
890 1 1 Behr, Mr. Karl Howell male 26.0 0 0 111369 30.00 C148 C 26.0 26.0 26.0
891 0 3 Dooley, Mr. Patrick male 32.0 0 0 370376 7.75 NaN Q 32.0 32.0 32.0

Удаление наблюдений с пропусками

In [5]:
dropna_df = df.dropna()

print(dropna_df.shape)

print(fillna_df.isnull().any())
(183, 14)
Survived    False
Pclass      False
Name        False
Sex         False
Age         False
SibSp       False
Parch       False
Ticket      False
Fare        False
Cabin       False
Embarked    False
dtype: bool

Создание выборок данных

Библиотека scikit-learn

https://scikit-learn.org/stable/index.html

No description has been provided for this image
In [6]:
# Функция для создания выборок
from sklearn.model_selection import train_test_split


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,
):
    """
    Splits a Pandas dataframe into three subsets (train, val, and test)
    following fractional ratios provided by the user, where each subset is
    stratified by the values in a specific column (that is, each subset has
    the same relative frequency of the values in the column). It performs this
    splitting by running train_test_split() twice.

    Parameters
    ----------
    df_input : Pandas dataframe
        Input dataframe to be split.
    stratify_colname : str
        The name of the column that will be used for stratification. Usually
        this column would be for the label.
    frac_train : float
    frac_val   : float
    frac_test  : float
        The ratios with which the dataframe will be split into train, val, and
        test data. The values should be expressed as float fractions and should
        sum to 1.0.
    random_state : int, None, or RandomStateInstance
        Value to be passed to train_test_split().

    Returns
    -------
    df_train, df_val, df_test :
        Dataframes containing the three splits.
    """

    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
In [7]:
# Вывод распределения количества наблюдений по меткам (классам)
print(df.Pclass.value_counts())

data = df[["Pclass", "Survived", "AgeFillMedian"]].copy()

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

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

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

print("Тестовая выборка: ", df_test.shape)
print(df_test.Pclass.value_counts())
Pclass
3    491
1    216
2    184
Name: count, dtype: int64
Обучающая выборка:  (534, 3)
Pclass
3    294
1    130
2    110
Name: count, dtype: int64
Контрольная выборка:  (178, 3)
Pclass
3    98
1    43
2    37
Name: count, dtype: int64
Тестовая выборка:  (179, 3)
Pclass
3    99
1    43
2    37
Name: count, dtype: int64
In [8]:
from imblearn.over_sampling import ADASYN

ada = ADASYN()

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

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

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

df_train_adasyn
Обучающая выборка:  (534, 3)
Pclass
3    294
1    130
2    110
Name: count, dtype: int64
Обучающая выборка после oversampling:  (864, 3)
Pclass
3    294
2    290
1    280
Name: count, dtype: int64
Out[8]:
Pclass Survived AgeFillMedian
0 3 0 28.000000
1 3 0 32.000000
2 3 1 28.000000
3 1 0 45.000000
4 3 0 7.000000
... ... ... ...
859 2 0 26.887761
860 2 1 0.890459
861 2 0 17.481437
862 2 0 17.078473
863 2 1 17.220445

864 rows × 3 columns