对于使用机器学习方法进行MBTI人格预测的简要讨论与代码学习

原项目链接:https://www.kaggle.com/code/mmm8989/mbti-personality-predictor-using-machine-learning

发现原来的数据集似乎甚至是直接从国外一个专门讨论人格的论坛爬的mbti数据,也没考证做没做问卷啥的…具体模式是:我在INFJ论坛发帖,爬虫就给我记下来,然后爬我50条记录?
其实是相对宽松的管理条例...对于大数据而言

使用了sklearn,简要介绍:https://zhuanlan.zhihu.com/p/58358393

数据结构与预处理:

人格类型 50条推文

计算:word_each_comment, variance_word_count

plt.figure(figsize=(15,10))
sns.swarmplot("type", "word_each_comment", data=MBTI_DS_C)

漂亮的作图

将四个倾向分别编码
作用:将1x16分解为4x2?大概

描述统计
统计学上果然是INFP最少,尽管他们发帖最多,而且MBTI分类就是不太科学的(

然后讲了一些文本预处理之类的事情

# Splitting the MBTI personality into 4 letters and binarizing it

b_Pers = {'I':0, 'E':1, 'N':0, 'S':1, 'F':0, 'T':1, 'J':0, 'P':1}
b_Pers_list = [{0:'I', 1:'E'}, {0:'N', 1:'S'}, {0:'F', 1:'T'}, {0:'J', 1:'P'}]

def translate_personality(personality):
    # Transform MBTI to binary vector
    return [b_Pers[l] for l in personality]

#Show result output for personality prediction
def translate_back(personality):
    # transform binary vector to MBTI personality
    s = ""
    for i, l in enumerate(personality):
        s += b_Pers_list[i][l]
    return s

list_personality_bin = np.array([translate_personality(p) for p in MBTI_DS_N.type])
print("Binarize MBTI list: \n%s" % list_personality_bin)

一些将MBTI翻译成4x2结构的代码

nltk.download('wordnet')

从nltk(自然语言处理工具包)导入wordnet,不过我们不做自然语言处理

每个被试实际进入机器学习模型的数据:
实际
再加上一个类似[0,0,0,0]的向量

进入模型的数据

"Therefore we now have 595 features for each user post."

595维度的向量...是我对于维度灾难的理解浅薄了
这里他们将post文本转换为向量,而MBTI人格的数据组织方式也为一个行向量

数据分析的机器学习模型方法

Logistic回归分类器

模型:Logistic回归(aka logit,MaxEnt)分类器,本质上只是sklearn的某个回归算法,具体区别不是很懂
具体可参考:https://blog.csdn.net/TeFuirnever/article/details/100180553

不过细节不重要,总之直接拿来应用(

从整体思路上讲,原作者运用这个模型分别对于MBTI的每一个倾向进行预测

X = X_tfidf
for l in range(len(personality_type)):
    Y = list_personality[:,l]
    X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
    #后略

train_test_split函数用来将x,y分为训练集与测试集

    # fit model on training data
    model = LogisticRegression() 
    model.fit(X_train, y_train)
    # make predictions for test data
    y_pred = model.predict(X_test)

选择模型,并且进行训练、拟合,将训练出的模型在测试集上进行预测

    predictions = [round(value) for value in y_pred]
    # evaluate predictions
    accuracy = accuracy_score(y_test, predictions)

按照二分变量的划分方式对于y_pred进行四舍五入,计算准确性
之后输出了模型的预测准确性:77.54% 86.06% 72.44% 64.51%
平均正确率为75.14%

绘制ROC曲线

之后绘制了ROC曲线,刚看到这个东西的时候就觉得特别信号检测论,后来发现果然是信号检测论
csdn
注:原blog的最后一行应为假正样 FP (False Positive)
*击中率,虚惊率

用绘图的方式描述模型的预测效果,判断机器学习效果的好坏

实际绘图
详细介绍:https://blog.csdn.net/hesongzefairy/article/details/104295431

KNN算法

“k个最近的邻居”...真的很像k均值聚类算法...不过本质上是有监督的。k均值聚类的根本思想在于“聚类”,强化学习找规律,在统计上找出可能的分类。而KNN是已经知道了一些分类,根据n维线性空间中最近的k个邻居数量、类别判断新的数据应该属于那个分类。

说起来我还真考虑过要不要算k均值聚类,但MBTI总归还是不太科学的分类方式,嗯算搞不好能弄出非常奇怪的结果...不过有空的话可以试试?万一跑成了就成大新闻了

具体参考:https://zhuanlan.zhihu.com/p/143092725

k_vals = [1,2]
for i in range(len(k_vals)):
    knn_fit = KNeighborsClassifier(n_neighbors=k_vals[i],p=2,metric='minkowski')
    knn_fit.fit(X_train,y_train)

KNeighborsClassifier:
n_neighbors:分别为1和2个最近邻居,不知道为什么要这么取
p = 2:欧氏距离(默认)
metric:闵可夫斯基距离(默认,虽然一般应使用欧氏距离)

k值分别为1和2...挺小的值,不过k=2时测试集正确率就已经只有40%了
这哪是KNN?这整个一就近原则

之后打印了混淆矩阵,训练正确率测试正确率

实际绘图
测试集正确率为60.6%

最后一个算法模型:XGBoost

基本思路和之前差不多,算法之前没学过,感觉比较抽象,摆了(

分别输出了测试集的正确率:
76.18% 85.37% 67.73% 62.84%
平均为73.03%

总结:当前数据可改进的&将来要做的

我们希望实现的:使用bilibili爬虫对于播放记录进行预测

各分类(不包括影视等无法通过爬虫获取详细分类的有99个,而加上六项与直播的数据后,可以得到106个数据,或许还可以计算专栏和笔记的数量?尽管后者无法获得详细的阅读时间)

或许可以利用起来的变量:

duration(O):视频时长
progress(L):观看时长(-1为完播)
is_fav(T):是否收藏

没办法利用的变量:

is_finish:似乎只能对于电影电视剧等分类有用

对于每个数据可收集的信息

1.每个子标签下的视频数量(105)
2.每个子标签的播放总时长(105)
3.每个子标签的平均完播率(105)
4.每个子标签的收藏数量(105)
MBTI人格:使用之前的数据组织方式,为一个1x4的向量
维度暂且为420+4

因此可行的传输方式:使用,分割压缩为一个长字符串?直接复制或是传输到服务器?

极端的想法:

历史记录中标题的自然语言处理

算法问题:

看到了用pytorch写的预测算法,神经网络还是更先进一点的,应该吧(
虽然做本基项目大概也足够了,但总之先挖个坑:https://github.com/coffee-cup/mbti

没看到支持向量机...
再就是整体上第一种算法正确率好像稍高一点,虽然平均下和最后一种不相上下
至少对于最后一个二分人格特质的预测效果不太好?考虑MBTI人格本身就不太科学的特点,不过也可能是输入材料的问题(

具体的效果没法预期啊,还是要做一下才知道

最后,kaggle真的很好用

文章最后更新时间为:2023 年 03 月 24 日 13:27:21

已有 2 条评论
  1. Hoshino Hoshino

    这种简单的分类问题搞不好还是传统的机器学习干得比较好,不是非得神经网络

    1. 确实!之前问过其他大佬也说SVM会更好...
      不过名词多一点更能唬住啥都不懂的答辩老师(
      毕竟我们也确实真的会做一个神经网络(

添加新评论