Этот набор данных в репозитории UCI ML содержит демографические данные, такие как возраст, пол, раса и т. Д., Примерно 45000 человек. Я собираюсь поделиться своим подходом к прогнозированию того, превышает ли доход человека 50 тысяч или нет.

Для этого проекта я использовал python и Jupyter Notebook. Вначале я импортировал соответствующие библиотеки (до того, как Бог создал небо и землю). Кроме того, установите размер визуализаций по своему усмотрению. . Я использовал вероятностный метод для работы с категориальными переменными. Полный код этого проекта можно найти здесь.

import pandas as pd
import numpy as np
import sklearn as sk
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams["figure.figsize"] = (20,10)

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

data = pd.read_csv('adult.data')
data.info()
data.columns = ['age','work-class','fnlwgt','education','edu-num','marital',            'occup','relatnip','race','sex','gain','loss','hours','citizenship','>50k']

Результат указанной выше ячейки. Можно сделать вывод, что нам не нужно сильно беспокоиться об отсутствующих значениях.

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 32560 entries, 0 to 32559
Data columns (total 15 columns):
39                32560 non-null int64
 State-gov        32560 non-null object
 77516            32560 non-null int64
 Bachelors        32560 non-null object
 13               32560 non-null int64
 Never-married    32560 non-null object
 Adm-clerical     32560 non-null object
 Not-in-family    32560 non-null object
 White            32560 non-null object
 Male             32560 non-null object
 2174             32560 non-null int64
 0                32560 non-null int64
 40               32560 non-null int64
 United-States    32560 non-null object
 <=50K            32560 non-null object
dtypes: int64(6), object(9)
memory usage: 3.7+ MB

Поскольку последний столбец имеет тип объекта, нам нужно определить используемую уникальную метку и затем сопоставить ее с целочисленным типом.

data['>50k'].unique()

Соответствующий вывод:

array([' <=50K', ' >50K'], dtype=object)

Теперь сопоставим метку, соответствующую доходу, меньшему или равному 50k, с 0, а другую - с 1. Мы также снова получим информацию и проверим, был ли изменен тип данных столбца на int.

data['>50k'] = data['>50k'].map({' <=50K':0,' >50K':1})
data.info()

Как вы можете заключить из выходных данных, тип данных этих столбцов был изменен на 64-битный целочисленный тип.

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 32560 entries, 0 to 32559
Data columns (total 15 columns):
age            32560 non-null int64
work-class     32560 non-null object
fnlwgt         32560 non-null int64
education      32560 non-null object
edu-num        32560 non-null int64
marital        32560 non-null object
occup          32560 non-null object
relatnip       32560 non-null object
race           32560 non-null object
sex            32560 non-null object
gain           32560 non-null int64
loss           32560 non-null int64
hours          32560 non-null int64
citizenship    32560 non-null object
>50k           32560 non-null int64
dtypes: int64(7), object(8)
memory usage: 3.7+ MB

Теперь я написал функцию, направленную на получение вероятности дохода, превышающей 50К, по любому значению категориальной переменной. Например, какова вероятность того, что доход превысит 50 000 для каждого пола, статуса гражданства и т. Д. Для достижения этой цели я рассчитал среднее значение столбца «› 50 000 ». Поскольку единственными возможными значениями являются 0 и 1, среднее значение будет соответствовать вероятности получения 1.

def rep_mean(var,data):   
   l = list(data[var].unique())
   d = dict()     
   for obj in l:      
      d[obj] = data[data[var]==obj]['>50k'].mean()
   return d

Давайте проверим эту функцию на столбцах рабочего класса, так как она бывает категориальной.

temp1 = rep_mean('work-class',data)
temp1

На выходе возвращается словарь.

{' Self-emp-not-inc': 0.2849271940181031,
 ' Private': 0.21867289390200917,
 ' State-gov': 0.27216653816499614,
 ' Federal-gov': 0.38645833333333335,
 ' Local-gov': 0.29479216435738176,
 ' ?': 0.10403050108932461,
 ' Self-emp-inc': 0.557347670250896,
 ' Without-pay': 0.0,
 ' Never-worked': 0.0}

Этот словарь можно сопоставить со столбцом рабочего класса.

data['work-class'] = data['work-class'].map(temp1)
data.info()

Как вы можете заключить из выходных данных, тип данных был изменен на 64-битное число с плавающей запятой.

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 32560 entries, 0 to 32559
Data columns (total 15 columns):
age            32560 non-null int64
work-class     32560 non-null float64
fnlwgt         32560 non-null int64
education      32560 non-null object
edu-num        32560 non-null int64
marital        32560 non-null object
occup          32560 non-null object
relatnip       32560 non-null object
race           32560 non-null object
sex            32560 non-null object
gain           32560 non-null int64
loss           32560 non-null int64
hours          32560 non-null int64
citizenship    32560 non-null object
>50k           32560 non-null int64
dtypes: float64(1), int64(7), object(7)
memory usage: 3.7+ MB

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

data['net'] = data['gain']+data['loss']
x = data.corr() 
x

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

data['thresh1'] = 1000*(0.368866*data['education']+0.351885*data['occup'])
data['thresh2'] = 1000*(0.447396*data['marital']+0.453578*data['relatnip'])

Я тестировал множество алгоритмов. Наконец, я выбрал режим Gradient Boosting, хотя он не очень хорошо работал с данными обучения. Однако он не страдает от чрезмерной подгонки, в отличие от деревьев решений и случайного леса. Весь код и вывод можно найти здесь на Github.