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

Типология Майерс-Бригг основана на теории психологических типов Юнга. Он был построен командой матери и дочери Кэтрин Кук Бриггс и Изабель Бриггс Майерс. Кэтрин Бриггс использовала юнгианские представления о личности для анализа литературных персонажей. Хотя MBTI основан на юнгианской теории, на самом деле в основе конструкции теста лежит интерпретация этой теории Изабель Майерс. Например, в теории Юнга нет измерения «суждение-восприятие» (J vs.P), которое было создано Майерсом и Бриггсом.

В настоящее время MBTI чаще всего используется при карьерном консультировании (например, предлагая мыслящим типам перейти к более структурированной работе, экстравертам - к «человеческим профессиям» и т. Д.). Когда психолог проводит тест MBTI, есть небольшая вероятность, что он может быть неправильным. Эту модель прогнозирования можно использовать как дублирующую диагностику лицом к лицу, чтобы подтвердить диагноз психолога.

Итак, начнем с загрузки данных.

Проект MBTI Personality Prediction находится здесь.

Описание проблемы

Цель состоит в том, чтобы предсказать меткуtype, которая представляет, какой тип личности имеет человек из комментариев.

Данные для этого проекта взяты из известного портала репо и конкурса данных kaggle. Https://www.kaggle.com/datasnaek/mbti-type/kernels.

Этот набор данных содержит более 8600 строк данных, в каждой из которых есть данные о человеке:

Тип (это люди 4-буквенный код / ​​тип MBTI)

Раздел каждого из последних 50 опубликованных ими сообщений (каждая запись разделена знаком «|||» (3 символа вертикальной черты)).

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

Набор данных

В наборе данных есть 2 столбца, где

  • type (тип: объект): содержит метку или зависимую переменную, которая должна быть предсказана.
  • post (type: object) содержит текстовые данные, 50 комментариев пользователя, разделенных 3 символами вертикальной черты (|||). Столбец также содержит URL-адрес, специальные символы, смайлы и тип сообщения.

Установка зависимости

Я надеюсь, что в вашей системе установлена ​​зависимость, если не просто выполнить pip install ‹имя зависимости›.

Ниже приведены несколько пакетов, которые нам понадобятся, я объясню необходимость в дальнейшем.

import pandas as pd
import numpy as np
import re
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split

Модели зависимости, которые нам понадобятся…

from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import SGDClassifier
from sklearn.neighbors import KNeighborsClassifier
from xgboost import XGBClassifier
from sklearn.naive_bayes import MultinomialNB

После установки всех зависимостей мы продолжим и импортируем наши данные во фрейм данных pandas.

mbti_df= pd.read_csv(‘mbti_1.csv’)

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

mbti_df.head()

Шаг 2: очистка и подготовка

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

Поскольку наши данные загрязнены, мы выполняем предварительную обработку для удаления символов и URL-адресов и всего, что кроме слов, из наших данных с помощью библиотеки регулярных выражений. В python «import re» импортирует в python возможность регулярного выражения.

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

lbl_rmv=list(mbti_df[‘type’].unique())
lbl_rmv = [item.lower() for item in lbl_rmv]

Ниже приводится содержание нашего списка: -

['infj', 'entp', 'intp', 'intj', 'entj', 'enfj', 'infp', 'enfp', 'isfp', 'istp', 'isfj', 'istj', 'estp', 'esfp', 'estj', 'esfj']

Чтобы удалить из наших данных что-либо, кроме текста, мы воспользуемся приведенным ниже кодом. Этот код очистит наши данные от символов, каналов, URL-адресов, смайлов и меток, содержащихся в сообщениях.

for i in range(0,8675) : 
 mbti_df[‘posts’][i] = re.sub(‘http[s]?://(?:[a-zA-Z]|[0–9]|[$-_@.&+]|(?:%[0–9a-fA-F][0–9a-fA-F]))+’, ‘ ‘, mbti_df[‘posts’][i])
 mbti_df[‘posts’][i] = re.sub(“[^a-zA-Z]”, “ “, mbti_df[‘posts’][i])
 mbti_df[‘posts’][i] = re.sub(‘ +’, ‘ ‘, mbti_df[‘posts’][i]).lower()
 for j in range(0,16):
 mbti_df[‘posts’][i]=re.sub(lbl_rmv[j], ‘ ‘, mbti_df[‘posts’][i])
 
mbti_df[‘posts’] = mbti_df[‘posts’].str.strip()

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

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

В приведенном ниже методе мы сделали следующее:

  1. Заменил любые оставшиеся пробелы одним пробелом.
  2. разделять слова с пробелами между ними
  3. удалены стоп-слова с помощью стоп-слов () из nltk.
  4. выводил корневое слово с помощью PorterStemmer () из nltk.
  5. В конце концов, мы объединили все сообщения с пробелом в них с помощью .join ().
def pre_process(post):
 posts = re.sub(‘\s+’, ‘ ‘, post)
 posts = posts.split()
 posts = [word for word in posts if not word in set(stopwords.words(‘english’))]
 ps = PorterStemmer()
 posts = [ps.stem(word) for word in posts]
 posts = ‘ ‘.join(posts)
 return posts
 
corpus = mbti_df[“posts”].apply(pre_process)

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

from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_features = 2000)
features = cv.fit_transform(mbti_df[‘posts’]).toarray()
label = mbti_df['type'].values

Шаг 3 и 4: Обучите и протестируйте модель

Чтобы проверить точность модели, мы разделяем набор данных на 2 части, обучаем и тестируем, сохраняя 80% данных в наборе данных поезда и 20% набора данных в наборе данных тестов и сохраняя случайное состояние 0 с помощью внутреннего модуля sci-kit learn train_test_split.

from sklearn.model_selection import train_test_split
features_train, features_test, label_train, label_test = train_test_split(features, label, test_size = 0.20, random_state = 0)

Теперь обучаем нашу модель с помощью приведенного выше набора данных:

# Random Forest ####################################################################
random_forestt = RandomForestClassifier(n_estimators=20)
random_forestt.fit(features_train,IE_train)
acc_rff_train = round(random_forestt.score(features_train,IE_train) * 100, 4)
acc_rff_test = round(random_forestt.score(features_test,IE_test) * 100, 4)
print(‘RF score train’,acc_rff_train, “%”)
print(‘RF score test’,acc_rff_test, “%”)
# Logistic Regression ####################################################################
logregg = LogisticRegression()
logregg.fit(features_train,IE_train)
acc_logg = round(logregg.score(features_train,label_test) * 100, 2)
print(“Logisitic Regression Prediction Accuracy on train data”,acc_logg,2, “%”)
acc_logg = round(logregg.score(features_test,label_test) * 100, 2)
print(“Logisitic Regression Prediction Accuracy on test data”,acc_logg, “%”)
# KNN ####################################################################
knnn = KNeighborsClassifier(n_neighbors = 3)
knnn.fit(features_train,IE_train)
acc_knnn = round(knnn.score(features_train,label_train) * 100, 2)
print(“Knn neighbor prediction value on train data”, acc_knnn,2, “%”)
acc_knnn = round(knnn.score(features_test,label_test) * 100, 2)
print(“Knn neighbor prediction value on test data”,acc_knnn, “%”)
# Multinomial NaiveBayes
####################################################################from sklearn.naive_bayes import MultinomialNB
mnb = MultinomialNB()
mnb.fit(features_train,IE_train)
mnb_train=round(mnb.score(features_train,label_test)*100,2)
mnb_test=round(mnb.score(features_test,label_test)*100,2)
print(‘MNB score train’,mnb_train, “%”)
print(‘MNB score test’,mnb_test, “%”)

После запуска модели мы получаем точность, как показано ниже.

Шаг 5. Улучшение

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

  • Интроверсия (I) - экстраверсия (E) [0 или 1]
  • Интуиция (N) - Ощущение (S) [0 или 1]
  • Мышление (T) - чувство (F) [0 или 1]
  • Оценка (J) - Восприятие (P) [0 или 1]

Давайте построим модель, которая учитывает стоимость ошибок.
Преобразование 1 метки в 4 метки с помощью функции карты ниже:

# converting the personality types to 8 respective binary identifiers(I-E,N-S,T-F,J-P)
map1 = {“I”: 0, “E”: 1}
map2 = {“N”: 0, “S”: 1}
map3 = {“T”: 0, “F”: 1}
map4 = {“J”: 0, “P”: 1}
mbti_df[‘I-E’] = mbti_df[‘type’].astype(str).str[0]
mbti_df[‘I-E’] = mbti_df[‘I-E’].map(map1)
mbti_df[‘N-S’] = mbti_df[‘type’].astype(str).str[1]
mbti_df[‘N-S’] = mbti_df[‘N-S’].map(map2)
mbti_df[‘T-F’] = mbti_df[‘type’].astype(str).str[2]
mbti_df[‘T-F’] = mbti_df[‘T-F’].map(map3)
mbti_df[‘J-P’] = mbti_df[‘type’].astype(str).str[3]
mbti_df[‘J-P’] = mbti_df[‘J-P’].map(map4)

Map () выполняет итерацию по этому словарю для сопоставления значений и присваивает им соответствующее значение.

Теперь у нас есть 4 новых метки, которые мы собираемся использовать для обучения нашей модели.
Назначение новых меток и их разделение для целей обучения и тестирования с сохранением соотношения разделения 80:20 и случайного состояния 0.

IE = mbti_df[‘I-E’].values
NS = mbti_df[‘N-S’].values
TF = mbti_df[‘T-F’].values
JP = mbti_df[‘J-P’].values
from sklearn.model_selection import train_test_split
features_train, features_test, IE_train, IE_test, NS_train, NS_test, TF_train, TF_test, JP_train, JP_test = train_test_split(features, IE,NS,TF,JP, test_size = 0.20, random_state = 0)

Обучение модели на всех известных ниже классификаторах для ярлыка Интроверт-Экстраверт (IE):

## Random Forest ###########################################################################
random_forestt = RandomForestClassifier(n_estimators=20)
random_forestt.fit(features_train,IE_train)
acc_rff_train = round(random_forestt.score(features_train,IE_train) * 100, 4)
acc_rff_test = round(random_forestt.score(features_test,IE_test) * 100, 4)
print(‘RF score train’,acc_rff_train, “%”)
print(‘RF score test’,acc_rff_test, “%”)
# Logistic Regression ########################################################################
logregg = LogisticRegression()
logregg.fit(features_train,IE_train)
acc_logg = round(logregg.score(features_train,IE_train) * 100, 2)
print(“Logisitic Regression Prediction Accuracy”,round(acc_logg,2,), “%”)
acc_logg = round(logregg.score(features_test,IE_test) * 100, 2)
print(“Logisitic Regression Prediction Accuracy on test data”,round(acc_logg,2,), “%”)
# KNN ############################################################################################
knnn = KNeighborsClassifier(n_neighbors = 3)
knnn.fit(features_train,IE_train)
acc_knnn = round(knnn.score(features_train,IE_train) * 100, 2)
print(“Knn neighbor prediction value”,round(acc_knnn,2,), “%”)
acc_knnn = round(knnn.score(features_test,IE_test) * 100, 2)
print(“Knn neighbor prediction value on test data”,round(acc_knnn,2,), “%”)
# Multinomial NaiveBayes
####################################################################
from sklearn.naive_bayes import MultinomialNB
mnb = MultinomialNB()
mnb.fit(features_train,IE_train)
mnb_train=mnb.score(features_train,IE_train)*100
mnb_test=mnb.score(features_test,IE_test)*100
print(‘MNB score train’,mnb_train, “%”)
print(‘MNB score test’,mnb_test, “%”)

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

Этот результат, безусловно, лучше, чем раньше, но недостаточно хорош, чтобы ему можно было доверять для прогнозов.

Для дальнейшего улучшения мы попробовали классификатор XGBoost (eXtreme Gradient Boosting), который, как известно, повышает точность в соревнованиях kaggle.

Эта модель немного лучше предыдущей, так как мы получили среднюю точность 76,88%, что является приемлемым для прогнозирования.

Анализ результатов

Чтобы предсказывать текст в реальном времени, мы также создали пользовательский интерфейс с помощью flask.
В нашем веб-приложении мы передали комментарий пользователя и предсказали его личность.

Ниже приведены скриншоты результата:

На основании комментария пользователя было установлено, что он является личностью INTP.

Резюме

Таким образом, мы продемонстрировали вариант использования и показали, как можно использовать мощь машинного обучения и применить ее к реальным проблемам. Модель прогнозирования личности MBTI - идеальная модель для прогнозирования личности.

Реализация этого проекта проводилась в Forsk Labs под руководством замечательных людей из Forsk Technologies во время нашей стажировки.

О нас

Этот проект был выполнен Тапаном Виджайвергией и Викас Шарма во время нашей стажировки в Forsk Technologies.