В своем последнем блоге Ссылка я объяснил недостающие значения и их типы.
В этом блоге я объясню, как обрабатывать отсутствующие значения для столбца непрерывных данных в наборе данных с помощью реализации.
Непрерывные данные. Непрерывные данные - это количественные данные, которые можно измерить, они имеют бесконечное количество возможных значений в пределах выбранного диапазона, например диапазон температур, рост, вес и т. д.
Набор данных, используемый для объяснения, - это Титаник (набор данных Kaggle).
import pandas as pd import numpy as np Data = pd.read_csv("train.csv") Data.isnull().sum()
- Среднее / Медианное / Расчет режима:
Предположение: данные отсутствуют случайно (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