机器学习实验(十三):90%的准确率,根据中文名字预测性别!
声明:版权所有,转载请联系作者并注明出处 http://blog.csdn.net/u013719780?viewmode=contents
90%的准确率,根据中文名字预测性别!
一、概述
性别是人类差异最大的特征之一,不同的性别拥有不同的特征,譬如购物、电视剧、书籍等方面男生和女生的爱好有很大的不同。因此,知道了用户的性别就可以更加准确的判断用户的潜在行为和需求。由此可知,性别识别的重要性和价值性不言而喻,每个机器学习模型的构建,基本都会需要准确识别用户的性别。
目前业内预测用户性别的方法有很多,大多数都是基于用户的行为数据、兴趣等方面进行性别判定,识别的准确性也参差不齐。但是,很多的时候我们拿不到用户的行为数据,这个时候用用户的行为数据、兴趣数据建立机器学习模型就显得力不从心了。同时,从用户的行为数据着手建立模型去预测用户的性别效果也并不会见得有多好,因为影响模型准确性的主要原因是这些用户的行为在性别上区分度有多大,如果区分度不明显,那模型和算法的准确性将会遇到明显的瓶颈。同时,基于用户行为的性别识别涉及的数据面非常广、数据依赖链条很长、数据计算复杂度很高,识别效能反而成为了痛点!
二、模型建立
在这里,我们分享一下我们MSO用户性别预测模型:基于用户中文名字的用户性别预测方法!我们仅仅是根据用户的中文名字进行预测,没有用到用户的行为数据,但是实际识别准确率却高达 90% 以上,为什么准确率这么高?主要是因为男生、女生在取名上有很大的差异!下面我们分步骤来讲解下MSO的用户性别识别模型构建过程。
首先,做一个声明,本文中送列举的名字均是泛指,如果正好与你名字相同,纯属巧合!在详细讲解模型之前,为了规范,我们来一个约定,本文中的姓名指的是包括姓和名字,比如‘谭文’,姓是‘谭’,名字是‘文’。名字不包括姓,例如‘谭文’的名字就是‘文’。首先,我们对用户的名字进行简单的处理,本文我们主要讨论两个字和三个字的姓名,超过三个字的姓名不予考虑。对于两个字的姓名(也就是只有一个名字的姓名)我们认为名字的第一个字是‘ ’,第二个字是名字的本身。为了阐述清楚,就以‘谭文’这个姓名为例,我们会将其处理成‘谭 文’。
接下里,我们看看用户名字在第一个字和第二个字上面的差异:
def name_count_bygender(rdd):rdd = rdd.map(lambda x: (x[0][0], x[0][1], x[1]))rdd = pd.DataFrame(rdd.collect(), columns = ['first_name', 'gender', 'num'])rdd = rdd.sort(['num'], ascending=False)return rddfirst_name_count_bygender = name_count_bygender(first_name_count_bygender)first_name_count_bygender[first_name_count_bygender.gender=='男'].head(30)
/opt/cloudera/parcels/anaconda3/lib/python3.5/site-packages/ipykernel/__main__.py:6: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
first_name | gender | num | |
---|---|---|---|
3352 | 男 | 170601 | |
1379 | 先 | 男 | 33423 |
2869 | 建 | 男 | 12792 |
4546 | 志 | 男 | 10636 |
183 | 小 | 男 | 9411 |
5270 | 国 | 男 | 8954 |
4476 | 文 | 男 | 8861 |
4683 | 海 | 男 | 7605 |
5681 | 永 | 男 | 7508 |
5741 | 晓 | 男 | 7399 |
5471 | 伟 | 男 | 4857 |
4593 | 明 | 男 | 4733 |
3995 | 金 | 男 | 4580 |
4939 | 德 | 男 | 4315 |
3133 | 玉 | 男 | 3612 |
4323 | 春 | 男 | 3580 |
1744 | 立 | 男 | 3317 |
2340 | 洪 | 男 | 3157 |
5612 | 振 | 男 | 3089 |
3932 | 俊 | 男 | 3082 |
150 | 新 | 男 | 3005 |
2575 | 世 | 男 | 2963 |
2045 | 学 | 男 | 2768 |
295 | 华 | 男 | 2737 |
3549 | 光 | 男 | 2691 |
3600 | 庆 | 男 | 2669 |
1147 | 云 | 男 | 2601 |
3496 | 红 | 男 | 2580 |
4725 | 正 | 男 | 2519 |
2524 | 成 | 男 | 2464 |
first_name_count_bygender[first_name_count_bygender.gender=='女'].head(30)
first_name | gender | num | |
---|---|---|---|
1871 | 女 | 139268 | |
5896 | 小 | 女 | 15388 |
1929 | 晓 | 女 | 10341 |
5131 | 女 | 女 | 9235 |
1756 | 丽 | 女 | 8348 |
497 | 春 | 女 | 4937 |
2687 | 玉 | 女 | 4815 |
1796 | 海 | 女 | 4604 |
3302 | 文 | 女 | 4387 |
4157 | 秀 | 女 | 4015 |
5446 | 红 | 女 | 3693 |
2371 | 雪 | 女 | 3561 |
5380 | 艳 | 女 | 3501 |
3221 | 美 | 女 | 2852 |
1847 | 建 | 女 | 2787 |
5440 | 金 | 女 | 2691 |
517 | 燕 | 女 | 2486 |
5429 | 亚 | 女 | 2296 |
3611 | 淑 | 女 | 2276 |
1527 | 爱 | 女 | 2130 |
2209 | 志 | 女 | 2083 |
852 | 慧 | 女 | 1904 |
3092 | 明 | 女 | 1864 |
4209 | 桂 | 女 | 1843 |
5205 | 秋 | 女 | 1786 |
698 | 永 | 女 | 1784 |
3204 | 国 | 女 | 1676 |
1283 | 凤 | 女 | 1632 |
1063 | 佳 | 女 | 1475 |
4374 | 玲 | 女 | 1475 |
second_name_count_bygender = name_count_bygender(second_name_count_bygender)second_name_count_bygender[second_name_count_bygender.gender=='男'].head(30)
/opt/cloudera/parcels/anaconda3/lib/python3.5/site-packages/ipykernel/__main__.py:6: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
first_name | gender | num | |
---|---|---|---|
4657 | 生 | 男 | 40584 |
3535 | 军 | 男 | 14480 |
358 | 华 | 男 | 14251 |
6285 | 明 | 男 | 12183 |
678 | 伟 | 男 | 11729 |
800 | 强 | 男 | 10492 |
1189 | 平 | 男 | 9816 |
841 | 勇 | 男 | 8866 |
4880 | 峰 | 男 | 7998 |
5049 | 辉 | 男 | 7810 |
4788 | 波 | 男 | 7650 |
1355 | 林 | 男 | 7460 |
2736 | 杰 | 男 | 6939 |
1576 | 东 | 男 | 6677 |
435 | 龙 | 男 | 6608 |
4366 | 斌 | 男 | 6425 |
6558 | 涛 | 男 | 6361 |
4903 | 刚 | 男 | 6107 |
6080 | 飞 | 男 | 5165 |
5519 | 文 | 男 | 5101 |
7525 | 亮 | 男 | 5060 |
242 | 鹏 | 男 | 4677 |
4243 | 兵 | 男 | 4643 |
6526 | 国 | 男 | 4545 |
2240 | 超 | 男 | 4536 |
1831 | 锋 | 男 | 4306 |
5809 | 海 | 男 | 3926 |
2166 | 荣 | 男 | 3823 |
5337 | 磊 | 男 | 3624 |
3105 | 成 | 男 | 3566 |
second_name_count_bygender[second_name_count_bygender.gender=='女'].head(30)
first_name | gender | num | |
---|---|---|---|
6101 | 士 | 女 | 11092 |
3548 | 姐 | 女 | 8657 |
735 | 英 | 女 | 8441 |
1026 | 芳 | 女 | 8186 |
5770 | 梅 | 女 | 8159 |
7233 | 燕 | 女 | 8051 |
4 | 华 | 女 | 8038 |
2167 | 丽 | 女 | 8019 |
5381 | 玲 | 女 | 7813 |
5159 | 娟 | 女 | 7763 |
6758 | 红 | 女 | 7488 |
1115 | 霞 | 女 | 7345 |
5587 | 萍 | 女 | 6793 |
6662 | 艳 | 女 | 5446 |
484 | 敏 | 女 | 5419 |
3301 | 静 | 女 | 5287 |
3478 | 琴 | 女 | 4763 |
3538 | 平 | 女 | 4444 |
7265 | 婷 | 女 | 4415 |
5736 | 娜 | 女 | 4320 |
6337 | 兰 | 女 | 4273 |
966 | 莉 | 女 | 4044 |
506 | 丹 | 女 | 3845 |
4369 | 珍 | 女 | 3441 |
630 | 云 | 女 | 3380 |
7389 | 芬 | 女 | 3080 |
2156 | 君 | 女 | 3054 |
1034 | 慧 | 女 | 2754 |
1740 | 凤 | 女 | 2680 |
6070 | 琼 | 女 | 2634 |
从以上可以看出,男生、女生的名字中常用的字有很大的差别,同时在名字中第一个字和第二个字上又有不同,表明位置也是一个需要考虑的重要因素。因此,我们建立用户名字中每个字的‘男性偏好极性’,这里的男性偏好极性是我自己命名的,字的‘男性偏好极性’指的是用户名字中的每个字是拥有男生的概率,譬如说‘谭文’,前文已经说了,我们需要将其处理成‘谭 文’,则
' '的男性偏好极性 = 第一个是' '的男生数第一个字是' '的所有用户数
'文'的男性偏好极性 = 第二个字是文的男生数第二个字是文的所有用户数
这样,我们就得到了每个名字的第一个字和第二个字的男性偏好极性。则每个名字的性别预测概率就是第一个名字的男性偏好极性与第二个名字的男性偏好极性的加权平均。这样我们根据每个用户的名字最终得到了其性别。
接下来我们看看测试结果:
test_rdd = test.rdd.map(lambda x: (x[0], x[1], drop_alnum(x[2]), x[3])) test_rdd = test_rdd.filter(lambda x: len(x[2])<4 and len(x[2])>1)def accuracy(rdd, p=0.5, threshold=0.5):rdd = rdd.map(lambda x: (predict(x[2], p), encode_label(x[3])))data = rdd.collect()label = [label for pre, label in data]pre = [1. if pre>0.5 else 0. for pre, label in data]count = 0for i, j in zip(label, pre):if i==j:count += 1return count/len(label)accuracy(test_rdd, p=0.5, threshold=0.5)
0.8180861340309921
从上可以看出,我们的测试结果准确率达到了0.818,是不是不相信自己的眼睛,没看错,效果就是这么好,在我们仅仅根据名字并且没有用到任何算法的条件下得到这样好的结果,应该算是很满意的结果了。
接下来,我们用一些算法来跑跑,看看准确率能否得到提升,我尝试了分别用randomforest、GBDT、LR和MLP神经网络模型进行预测,所用到的特征就是前文提取到的每个名字中第一个字、第二个字的男性偏好极性以及做了一些特征交互,得到的准确率分别如下:
depths = [2, 3, 4, 5, 6, 7, 8] steps = [0.001, 0.01, 0.1] best_gbdtAccuracy = 0 best_gbdtModel = None for depth in depths:for step in steps:gbdt = GBTClassifier(maxIter=100, maxDepth=depth, stepSize=step, featuresCol="features", labelCol="label", predictionCol="prediction")gbdtModel = gbdt.fit(train)gbdtPredictions = gbdtModel.transform(test)gbdtAccuracy = evaluator.evaluate(gbdtPredictions)if gbdtAccuracy > best_gbdtAccuracy:best_gbdtAccuracy = gbdtAccuracybest_gbdtModel = gbdtModelprint("gbdtModel Test set accuracy = " + str(best_gbdtAccuracy))
gbdtModel Test set accuracy = 0.8849167482859941
reg_params = [0.001, 0.01] reg_types = ['l1', 'l2'] best_lrAccuracy = 0 best_lrModel = Nonefor reg_param in reg_params:lr = LogisticRegression(maxIter=100, regParam=reg_param)lrModel = lr.fit(train)lrPredictions = lrModel.transform(test)lrAccuracy = evaluator.evaluate(lrPredictions)if lrAccuracy > best_lrAccuracy:best_lrAccuracy = lrAccuracybest_lrModel = lrModelprint("lrModel Test set accuracy = " + str(best_lrAccuracy))
lrModel Test set accuracy = 0.8888344760039177
steps=[0.005, 0.01, 0.03] batchs = [32, 64, 128] best_mlpAccuracy = 0 best_mlpModel = Nonefor step in steps:for batch_size in batchs:mlp = MultilayerPerceptronClassifier(maxIter=100, layers=[6, 32, 8, 2], blockSize=batch_size, stepSize=step, seed=123)mlpModel = mlp.fit(train)mlpPredictions = mlpModel.transform(test)mlpAccuracy = evaluator.evaluate(mlpPredictions)if mlpAccuracy > best_mlpAccuracy:best_mlpAccuracy = mlpAccuracybest_mlpModel = mlpModelprint("mlpModel Test set accuracy = " + str(best_mlpAccuracy))
mlpModel Test set accuracy = 0.8834476003917727
depths = [2, 3, 4, 5, 6, 7, 8] num_trees = [10, 20, 30] best_rfAccuracy = 0 best_rfModel = Nonefor depth in depths:for num_tree in num_trees:rf = RandomForestClassifier(maxDepth=depth, numTrees=num_tree, featuresCol="features", labelCol="label", predictionCol="prediction")rfModel = rf.fit(train)rfPredictions = rfModel.transform(test)rfAccuracy = evaluator.evaluate(rfPredictions)if rfAccuracy > best_rfAccuracy:best_rfAccuracy = rfAccuracybest_rfModel = rfModelprint("rfModel Test set accuracy = " + str(best_rfAccuracy))
rfModel Test set accuracy = 0.886119257086999
从上述结果可以看到,我们训练的randomforest、GBDT、LR和MLP神经网络模型的准确率已经超过0.88了。最后,对前面做的5个模型做一个简单的ensemble,准确率超过了90%。
三、结果分析
仅仅根据姓名达到0.9的准确率,应该算是很不错了,其实,另外将近百分之十的错误主要是一些中性名字、女生使用偏向男生的名字、男生使用偏向女生的名字导致的,比如我就看到原始数据里有个叫‘某莎莎’的,预测模型将其预测为女性,但是其真实性别是男生。这里我就不贴具体结果了,因为是公司项目。很显然,在没有行为数据的情况下,这样的名字总有一部分是错误的,譬如说“某莎莎”,大多数情况下是女生,但是也有一些男生取名某莎莎,这个时候仅仅根据姓名来预测的结果就是将名字叫莎莎的要么都预测为男生要么都预测为女生,当然,如果有了某莎莎的行为数据,那么模型的准确率应该能够得到进一步提升。譬如说,有两个用户,一个男生一个女生,都叫某莎莎,其中一个某莎莎经常购买女生的生活用品,另一个某莎莎经常购买一些男生的衣服之类的,那么这个时候我们就可以有很大的自信将两个某莎莎都预测准确。但是,有些童鞋可能会说,如果两个某莎莎都是女生,只不过经常购买男生衣服的那个某莎莎是帮她男朋友买的而已,那么这个时候模型也会预测错误。嗯~说的没错,这个时候算法也会预测为男生,但我们仔细想想,其实将其预测为男生应该更合理,因为我们我们更加关注的是其行为性别而不是生理性别,譬如说你给这个某莎莎推荐衣服,她对她男朋友特别好,就是经常给她男朋友买衣服,很少给自己买衣服,你给她推荐女生衣服很大的可能性不会点击进去看,然而你给她推荐男生衣服她反而很感兴趣,点击的可能性很大~
机器学习实验(十三):90%的准确率,根据中文名字预测性别!相关推荐
- 机器学习实验之顾客购买服装的分析与预测
文章目录 顾客购买服装的分析与预测 **[实验内容]** **[实验要求]** 读取顾客购买服装的数据集 分别用ID3算法和CART算法进行决策树模型的配置.模型的训练.模型的预测.模型的评估 数据集 ...
- 快乐学习!Python趣味练手项目:PyQ5模块实现通过中文名字识别性别
嗨~我是小鱼,一个不太厉害混迹编程界的老学姐 今天分享一个超级厉害的模块PyQ5,学过编程的都了解过这个小工具吧?不仅可以生成艺术签名还可以让电脑自己哼唱歌曲.今天我们利用这个pyq5这个小工具和贝叶 ...
- python基于机器学习的姓名预测性别网页app开发
前言 做这个项目的起因是之前csdn给我推荐了一个问答:基于机器学习的姓名预测性别的手机app开发.我点进去发现已经有人回答了,链接点进去一看,好家伙,这不是查表算概率吗,和机器学习有半毛钱关系.而且 ...
- 【机器学习实验】scikit-learn的主要模块和基本使用
[机器学习实验]scikit-learn的主要模块和基本使用 引言 对于一些开始搞机器学习算法有害怕下手的小朋友,该如何快速入门,这让人挺挣扎的. 在从事数据科学的人中,最常用的工具就是R和Pytho ...
- Azure机器学习实验
实验背景 [实验简介] Azure Machine Learning(简称"AML")是微软在其公有云Azure上推出的基于Web使用的一项机器学习服务,机器学习属人工智能的一个分 ...
- Azure机器学习入门(三)创建Azure机器学习实验
在此动手实践中,我们将在Azure机器学习Studio中一步步地开发预测分析模型,首先我们从UCI机器学习库的链接下载普查收入数据集的样本并开始动手实践: http://archive.ics.uci ...
- 机器学习实验:使用sklearn的决策树算法对葡萄酒数据集进行分类
机器学习实验:使用sklearn的决策树算法对葡萄酒数据集进行分类 问题如下: 使用sklearn的决策树算法对葡萄酒数据集进行分类,要求: ①划分训练集和测试集(测试集占20%) ②对测试集的预测类 ...
- 文本情感分析-机器学习实验三
情感分析-机器学习实验三 实验目的: 通过实验,掌握文本分析的整体流程,了解文本分类.情感分析.自动摘要等内容 通过给定的文本内容,完成分词.文本向量化.文本分类.情感分析等相关实验 实验可从文本分类 ...
- Python机器学习实验二:1.编写代码,实现对iris数据集的KNN算法分类及预测
Python机器学习实验二:编写代码,实现对iris数据集的KNN算法分类及预测 1.编写代码,实现对iris数据集的KNN算法分类及预测,要求: (1)数据集划分为测试集占20%: (2)n_nei ...
最新文章
- 基于K8S构建企业级Jenkins CI/CD平台实战(一) 之 环境搭建
- 【Keras】Linux一个shell脚本安装python、keras、tensorflow、anaconda等~
- php制作表格生成器,php表格生成图片.doc
- 设计,成本与开发细节的讨论
- linux kernl网址
- BZOJ5286:[HNOI/AHOI2018]转盘——题解
- git的安装与使用(一)--windows平台 .
- 【ELK】之Kibana使用
- RK3308(5)---编译根文件系统
- ubuntu上装texlive
- 还被python收智商税?做大数据的朋友告诉我月薪2w的方法
- python redis连接池最大连接数_python redis之连接池的原理
- 开启WIN 7下的administrator用户的方法(VISTA一样)
- windows查看本机的IP地址
- 【IoT库】物联网行业仍普遍存在的问题
- 超好用的内网穿透工具【永久免费不限制流量】
- linux的wifi探针源码,运用在公共安全领域的WiFi探针
- 工作态度决定了你的层次
- 转贴--爱的最高境界
- EPICS记录参考--Sequence记录(seq)