В своем последнем блоге Ссылка я объяснил недостающие значения и их типы.

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

Непрерывные данные. Непрерывные данные - это количественные данные, которые можно измерить, они имеют бесконечное количество возможных значений в пределах выбранного диапазона, например диапазон температур, рост, вес и т. д.

Набор данных, используемый для объяснения, - это Титаник (набор данных Kaggle).

import pandas as pd
import numpy as np
Data = pd.read_csv("train.csv")
Data.isnull().sum()

  1. Среднее / Медианное / Расчет режима:

Предположение: данные отсутствуют случайно (MCAR).

Описание. Замена значений NAN на наиболее частое появление переменной.

Реализация: обработка отсутствующих значений возраста

# function use to impute_nan values with mean/median/mode
def impute_nan(DataFrame, ColumnName, ImputeValue):
    DataFrame[ColumnName + "_Imputed"] =                                                     DataFrame[ColumnName].fillna(ImputeValue)
# Call function to impute median value
median = Data.Age.median()
impute_nan(Data, 'Age', median)

Точно так же мы можем заменить значение NAN на среднее значение / режим.

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

# Code to plot distribution of vairance in data columns
fig = plt.figure()
ax = fig.add_subplot(111)
Data['Age'].plot(kind='kde', ax=ax)
Data['Age_Imputed'].plot(kind='kde', ax=ax, color='red')
lines, labels = ax.get_legend_handles_labels()
ax.legend(lines, labels, loc='best')

2. Вменение случайной выборки

Предположение: данные отсутствуют случайно (MCAR).

Описание. Взять случайное наблюдение из набора данных и использовать эти наблюдения для замены значений NAN.

Реализация: обработка отсутствующих значений возраста

Шаг 1. Создайте копию столбца «Возраст».

Шаг 2: Выберите случайные выборочные значения для заполнения NAN (игнорируйте значения NAN и выбирайте только значения, отличные от NAN).

Шаг 3. Замените значения NAN значениями случайной выборки с индексом значений NAN.

# function to impute_nan values with random observations
def impute_random_nan(Data,ColName):
    
    #Make copy of Column
    Data[ColName+"_random"]=Data[ColName]
    
    #Select random sample value to fill the na
    # .dropna() - to ignore NAN values and select non-NAN values
    
    random_sample =       Data[ColName].dropna().sample(Data[ColName].isnull().sum(),random_state=0)
    
    # Merge - pandas need to have same index in order to merge the dataset.
    
   random_sample.index = Data[Data[ColName].isnull()].index
    
    Data.loc[Data[ColName].isnull(),ColName+'_random']=random_sample
#Call function to impute median value
median = Data.Age.median()
impute_nan(Data, 'Age', median)

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

# Code to plot distribution of vairance in data columns
fig = plt.figure()
ax = fig.add_subplot(111)
DataFrame['Age'].plot(kind='kde', ax=ax)
DataFrame['Age_random'].plot(kind='kde', ax=ax, color='red')
lines, labels = ax.get_legend_handles_labels()
ax.legend(lines, labels, loc='best')

Недостаток: эта случайность работает не во всех ситуациях.

3. Получение значений NAN с помощью новой функции

Предположение: данные НЕ отсутствуют случайно (MCAR).

Описание. Добавьте новую функцию, чтобы придать определенный вес / важность не исчисленным и не исчисленным наблюдениям.

Реализация: обработка отсутствующих значений возраста

Шаг 1. Замените нулевые значения средним / режимом / медианой или random_sample_value.

Шаг 2: Добавьте новую функцию / столбец, чтобы указать, что значение NAN заменено / не заменено.

Шаг 3. Отбросьте столбец «Возраст» и оставьте столбцы вмененной и новой важности.

#1. Add new column with 1 for null values and 0 for not null values
DataFrame['Age_NAN']=np.where(DataFrame['Age'].isnull(),1,0)
#2. impute random sample values in Age column - call function
impute_random_nan (DataFrame, 'Age')
#Display results
DataFrame[['Age','Age_random','Age_NAN']].head(10)
#3. Drop Age Column
DataFrame = DataFrame.drop('Age',axis=1)

Преимущество. Подчеркните важность отсутствия.

Недостаток: создание дополнительных функций (проклятие размерности), например. если есть 10 столбцов с нулевыми значениями, необходимо создать 10 дополнительных столбцов.

4. Расчет конечного распределения

Допущения: данные НЕ отсутствуют случайно (MAR); Данные искажены в конце.

Описание:. Возьмите конечное значение распределения хвоста (после 3-го стандартного отклонения кривой распределения) и замените значения NAN / Null.

Реализация: обработка отсутствующих значений возраста

Шаг 1. Получите значение конечного распределения, постройте график распределения данных, используя приведенный ниже код:

# Take non NAN values
NonNANData = DataFrame['Age'].dropna().sample(DataFrame['Age'].isnull().sum())
# Fit a normal distribution to the data:
mu, std = norm.fit(NonNANData)
# Plot the histogram.
plt.hist(NonNANData, bins=50, density=True, alpha=0.6, color='g')
plt.plot(x, p, 'k', linewidth=2)
plt.show()

Шаг 2: вычислить среднее (среднее) экстремальных значений (конечные значения хвоста) и заменить значениями NAN

#function to impute NAN values with Extreme tail value
def impute_nan_TailValue(DataFrame,variable,ExtremeValue):
    DataFrame[variable+"_end_distribution"] =     DataFrame[variable].fillna(extreme)
# Calculate extreme end tail mean value
ExtremeEndTailMean = DataFrame.Age.mean()+3*DataFrame.Age.std()
# Call funtion to replace NAN values with extreme values
impute_nan_TailValue(DataFrame,'Age',ExtremeEndTailMean)
# Display histograms - Data distribution
DataFrame.Age.hist(bins=50, color = 'g')
plt.title('AGE : Normal Distribution Histogram',fontsize=15)
plt.title('Age End Distribution : Normal Distribution Histogram',fontsize=15)
DataFrame.Age_end_distribution.hist(bins=50, color = 'g')

Преимущество: учитывайте важность отсутствия, если оно есть.

Недостаток:

  • Изменяет ковариацию / дисперсию, т.е. искажает исходное распределение; может создавать предвзятые данные.
  • Если количество значений NAN больше, оно может маскировать истинные выбросы.
  • Если количество значений NAN меньше, заменяемые значения NAN могут рассматриваться как выброс.

5. Произвольное вменение

Предположения: данные НЕ отсутствуют случайно (MAR)

Описание. Замена значений NAN фиксированным произвольным значением (случайным значением). Произвольное значение не должно часто встречаться в наборе данных.

Реализация: обработка отсутствующих значений возраста

Произвольное значение может быть любым случайным значением по выбору. Иногда это решение основывается на знании предметной области или системы.

Здесь мы выбираем 0 и 100 для замены значений NAN.

# Function to replace NAN values with Arbitary values
def impute_nan_ArbitaryValue(df,variable, value):
    df[variable+"_"+ str(value)]=df[variable].fillna(value)
# Call funtion to replace NAN values with arbitary values
impute_nan_ArbitaryValue(DataFrame,'Age',0)
impute_nan_ArbitaryValue(DataFrame,'Age',100)
# Display top 10 data
DataFrame[['Age','Age_0','Age_100']].head(10)

Преимущество. Подчеркните важность отсутствия.

Недостаток:

  • Изменяет ковариацию / дисперсию; может создавать выбросы
  • Может исказить исходное распределение данных.
  • Трудно решить, какое значение использовать.

Вывод:

Вышеупомянутая реализация призвана объяснить различные способы обработки недостающих непрерывных данных. Наиболее широко используются методы вменения случайной выборки и вменение среднего / среднего / режима.

Для справки: блокнот Jupyter - код доступен на GitHub: https://github.com/GDhasade/Medium.com_Contents/blob/master/Handle_Continous_Missing_Data.ipynb