声明:版权所有,转载请联系作者并注明出处  http://blog.csdn.net/u013719780?viewmode=contents

               90%的准确率,根据中文名字预测性别!

一、概述

  性别是人类差异最大的特征之一,不同的性别拥有不同的特征,譬如购物、电视剧、书籍等方面男生和女生的爱好有很大的不同。因此,知道了用户的性别就可以更加准确的判断用户的潜在行为和需求。由此可知,性别识别的重要性和价值性不言而喻,每个机器学习模型的构建,基本都会需要准确识别用户的性别。

  目前业内预测用户性别的方法有很多,大多数都是基于用户的行为数据、兴趣等方面进行性别判定,识别的准确性也参差不齐。但是,很多的时候我们拿不到用户的行为数据,这个时候用用户的行为数据、兴趣数据建立机器学习模型就显得力不从心了。同时,从用户的行为数据着手建立模型去预测用户的性别效果也并不会见得有多好,因为影响模型准确性的主要原因是这些用户的行为在性别上区分度有多大,如果区分度不明显,那模型和算法的准确性将会遇到明显的瓶颈。同时,基于用户行为的性别识别涉及的数据面非常广、数据依赖链条很长、数据计算复杂度很高,识别效能反而成为了痛点!

二、模型建立

  在这里,我们分享一下我们MSO用户性别预测模型:基于用户中文名字的用户性别预测方法!我们仅仅是根据用户的中文名字进行预测,没有用到用户的行为数据,但是实际识别准确率却高达 90% 以上,为什么准确率这么高?主要是因为男生、女生在取名上有很大的差异!下面我们分步骤来讲解下MSO的用户性别识别模型构建过程。

  首先,做一个声明,本文中送列举的名字均是泛指,如果正好与你名字相同,纯属巧合!在详细讲解模型之前,为了规范,我们来一个约定,本文中的姓名指的是包括姓和名字,比如‘谭文’,姓是‘谭’,名字是‘文’。名字不包括姓,例如‘谭文’的名字就是‘文’。首先,我们对用户的名字进行简单的处理,本文我们主要讨论两个字和三个字的姓名,超过三个字的姓名不予考虑。对于两个字的姓名(也就是只有一个名字的姓名)我们认为名字的第一个字是‘ ’,第二个字是名字的本身。为了阐述清楚,就以‘谭文’这个姓名为例,我们会将其处理成‘谭 文’。

  接下里,我们看看用户名字在第一个字和第二个字上面的差异:

In [26]:
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=.....)

Out[26]:
  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

In [28]:
first_name_count_bygender[first_name_count_bygender.gender=='女'].head(30)

Out[28]:
  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

In [29]:
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=.....)

Out[29]:
  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

In [30]:
second_name_count_bygender[second_name_count_bygender.gender=='女'].head(30)

Out[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)
Out[9]:
0.8180861340309921

  从上可以看出,我们的测试结果准确率达到了0.818,是不是不相信自己的眼睛,没看错,效果就是这么好,在我们仅仅根据名字并且没有用到任何算法的条件下得到这样好的结果,应该算是很满意的结果了。

  接下来,我们用一些算法来跑跑,看看准确率能否得到提升,我尝试了分别用randomforest、GBDT、LR和MLP神经网络模型进行预测,所用到的特征就是前文提取到的每个名字中第一个字、第二个字的男性偏好极性以及做了一些特征交互,得到的准确率分别如下:

In [44]:
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

In [47]:
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

In [48]:
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

In [49]:
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%的准确率,根据中文名字预测性别!相关推荐

  1. 机器学习实验之顾客购买服装的分析与预测

    文章目录 顾客购买服装的分析与预测 **[实验内容]** **[实验要求]** 读取顾客购买服装的数据集 分别用ID3算法和CART算法进行决策树模型的配置.模型的训练.模型的预测.模型的评估 数据集 ...

  2. 快乐学习!Python趣味练手项目:PyQ5模块实现通过中文名字识别性别

    嗨~我是小鱼,一个不太厉害混迹编程界的老学姐 今天分享一个超级厉害的模块PyQ5,学过编程的都了解过这个小工具吧?不仅可以生成艺术签名还可以让电脑自己哼唱歌曲.今天我们利用这个pyq5这个小工具和贝叶 ...

  3. python基于机器学习的姓名预测性别网页app开发

    前言 做这个项目的起因是之前csdn给我推荐了一个问答:基于机器学习的姓名预测性别的手机app开发.我点进去发现已经有人回答了,链接点进去一看,好家伙,这不是查表算概率吗,和机器学习有半毛钱关系.而且 ...

  4. 【机器学习实验】scikit-learn的主要模块和基本使用

    [机器学习实验]scikit-learn的主要模块和基本使用 引言 对于一些开始搞机器学习算法有害怕下手的小朋友,该如何快速入门,这让人挺挣扎的. 在从事数据科学的人中,最常用的工具就是R和Pytho ...

  5. Azure机器学习实验

    实验背景 [实验简介] Azure Machine Learning(简称"AML")是微软在其公有云Azure上推出的基于Web使用的一项机器学习服务,机器学习属人工智能的一个分 ...

  6. Azure机器学习入门(三)创建Azure机器学习实验

    在此动手实践中,我们将在Azure机器学习Studio中一步步地开发预测分析模型,首先我们从UCI机器学习库的链接下载普查收入数据集的样本并开始动手实践: http://archive.ics.uci ...

  7. 机器学习实验:使用sklearn的决策树算法对葡萄酒数据集进行分类

    机器学习实验:使用sklearn的决策树算法对葡萄酒数据集进行分类 问题如下: 使用sklearn的决策树算法对葡萄酒数据集进行分类,要求: ①划分训练集和测试集(测试集占20%) ②对测试集的预测类 ...

  8. 文本情感分析-机器学习实验三

    情感分析-机器学习实验三 实验目的: 通过实验,掌握文本分析的整体流程,了解文本分类.情感分析.自动摘要等内容 通过给定的文本内容,完成分词.文本向量化.文本分类.情感分析等相关实验 实验可从文本分类 ...

  9. Python机器学习实验二:1.编写代码,实现对iris数据集的KNN算法分类及预测

    Python机器学习实验二:编写代码,实现对iris数据集的KNN算法分类及预测 1.编写代码,实现对iris数据集的KNN算法分类及预测,要求: (1)数据集划分为测试集占20%: (2)n_nei ...

最新文章

  1. 基于K8S构建企业级Jenkins CI/CD平台实战(一) 之 环境搭建
  2. 【Keras】Linux一个shell脚本安装python、keras、tensorflow、anaconda等~
  3. php制作表格生成器,php表格生成图片.doc
  4. 设计,成本与开发细节的讨论
  5. linux kernl网址
  6. BZOJ5286:[HNOI/AHOI2018]转盘——题解
  7. git的安装与使用(一)--windows平台 .
  8. 【ELK】之Kibana使用
  9. RK3308(5)---编译根文件系统
  10. ubuntu上装texlive
  11. 还被python收智商税?做大数据的朋友告诉我月薪2w的方法
  12. python redis连接池最大连接数_python redis之连接池的原理
  13. 开启WIN 7下的administrator用户的方法(VISTA一样)
  14. windows查看本机的IP地址
  15. 【IoT库】物联网行业仍普遍存在的问题
  16. 超好用的内网穿透工具【永久免费不限制流量】
  17. linux的wifi探针源码,运用在公共安全领域的WiFi探针
  18. 工作态度决定了你的层次
  19. 转贴--爱的最高境界
  20. EPICS记录参考--Sequence记录(seq)

热门文章

  1. Android仿虾米音乐播放器之自定义进度条seekbar
  2. 2.1 从这里开始不同——命令
  3. php fgets 空行,php fgets函数读取多余的空格解决
  4. windows-打印机无法安装驱动程序的问题
  5. python try except用法
  6. oracle9i卸载
  7. 2021最新分享苹果cms10资讯采集接口,无广告超清通用解析接口
  8. 张赐荣 | C语言指定范围内产生随机数
  9. [代码审计]YCCMS V3.4
  10. 研招网:@2021推免生:关于推免,你必须要知道的三件事