Почему шоу Netflix «Внутри самых суровых тюрем мира» вдохновило меня сформулировать постановку задачи для науки о данных

Я смотрел все серии Самых суровых тюрем мира на Netflix. Мне нравится видеть хорошие результаты в плохих ситуациях. Норвежская тюрьма дает отличный результат, но всегда есть по крайней мере один полезный урок и у других тюрем.

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

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

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

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

Ведущий второго и третьего сезонов - британский журналист Рафаэль Роу, который был заключен в тюрьму за преступление, которого не совершал, и приговорен к пожизненному заключению без права досрочного освобождения. В конце концов, он был оправдан после 12 лет службы. Его опыт и чувства не только сильно повлияют на результат шоу, но и, в конечном итоге, вместе с чувствами всех остальных, кто встанет и выставит себя напоказ, внесут изменения к лучшему.

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

Чтобы что-то изменить к лучшему, вам нужны данные, поэтому я начал просматривать Kaggle в поисках набора данных и нашел NYS Recidivism: Beginning 2008. Но, как это часто бывает с наборами данных, мягкие факторы отсутствуют. Я считаю полезными данные, которые говорят о том, получают ли заключенные достаточно качественную социализацию, что они умеют читать, чем они занимаются и чувствуют ли они себя нужными в каком-либо контексте.

Если заключенные будут продолжать проводить здоровое время с родственниками во время отбывания наказания, их отношения сохранятся. Как только они выйдут из тюрьмы, здоровый круг общения, по которому они ужасно скучали, будет ждать их возвращения. Они будут много работать, чтобы снова не разорвать этот круг.

У меня возникла идея сгенерировать и обогатить набор данных столбцами soft factor. Но я начал с исследовательского анализа данных. С помощью корреляционной матрицы я обнаружил, что особенно женщины и, как правило, заключенные в возрасте от 33 до 82 лет (но особенно в возрастной группе от 50 до 64 лет) имеют высокую вероятность возвращения в тюрьму.

Вот как я сгенерировал дополнительные синтетические данные для набора данных с помощью Faker:

Как это сделать, шаг за шагом

Я уже закодировал набор данных с помощью горячей кодировки, чтобы использовать его для машинного обучения. Затем я создаю пустой список, в котором с помощью Faker генерирую логическое значение, в зависимости от значения в DataFrame, используя iloc.

pip install Faker
fakies = []
for i in range(len(new_df)):
    if (new_df.iloc[i].gender_MALE==1) 
    and (new_df.iloc[i].age_16_32==1):
        fakies.append(fake.boolean(chance_of_getting_true=85))
    elif (new_df.iloc[i].gender_MALE==1) 
    and (new_df.iloc[i].age_50_64==1):
        fakies.append(fake.boolean(chance_of_getting_true=75))
    elif (new_df.iloc[i].gender_MALE==1) 
    and (new_df.iloc[i].age_33_49==1):
        fakies.append(fake.boolean(chance_of_getting_true=70))
    elif (new_df.iloc[i].gender_MALE==1) 
    and (new_df.iloc[i].age_65_82==1):
        fakies.append(fake.boolean(chance_of_getting_true=65))
    elif (new_df.iloc[i].gender_FEMALE==1) 
    and (new_df.iloc[i].age_16_32==1):
        fakies.append(fake.boolean(chance_of_getting_true=55))
    elif (new_df.iloc[i].gender_FEMALE==1) 
    and (new_df.iloc[i].age_50_64==1):
        fakies.append(fake.boolean(chance_of_getting_true=25))
    elif (new_df.iloc[i].gender_FEMALE==1) 
    and (new_df.iloc[i].age_33_49==1):
        fakies.append(fake.boolean(chance_of_getting_true=40))
    elif (new_df.iloc[i].gender_FEMALE==1) 
    and (new_df.iloc[i].age_65_82==1):
        fakies.append(fake.boolean(chance_of_getting_true=45))
   
    else:
        fakies.append(fake.boolean(chance_of_getting_true=30))

Я добавляю список Faker в DataFrame:

new_df['visitors_family'] = pd.DataFrame(fakies)

Затем я кодирую новый столбец горячей кодировкой:

df_visitors_family_one_hot = pd.get_dummies(new_df['visitors_family'], prefix='fam')

Я объединяю два закодированных столбца с DataFrame:

new_df_con_enc = pd.concat([new_df, df_visitors_family_one_hot], axis=1)

Я переименовываю DataFrame и отбрасываю столбец добавленного списка Faker:

final_df = new_df_con_enc.drop(['visitors_family'], axis=1)

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

plt.figure(figsize=(15,5))
sns.heatmap(final_df.corr(),
        vmin=-1,
        cmap='coolwarm',
        annot=True);

Выглядит неплохо, но мне нужно немного подправить значения chance_of_getting_true.

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

Спасибо за прочтение!