使用朴素贝叶斯算法,通过用户安装的APP列表来推测用户的性别

从本质上来说,这是一个分类问题,类似于通过邮件内容来推测垃圾邮件,通过用户的相关信息来推测用户是否会拖欠贷款,而通过用户的APP安装列表来推测用户的性别也是一个类似的问题。

对于贝叶斯算法来说,我们首先需要一个训练集数据,这个训练集是一个已经打好标签的数据。而要对一堆的数据打标签,人工来做是不太合适的,在这里需要结合人类与计算机各自的优势,来半自动化的识别出比较明显的有性别倾向的APP的列表,再通过这些(有性别标识的)APP在用户的安装列表中所占的比例来判定出性别特征比较明显的用户,并为这些用户打上性别的标签,而这些用户以及其安装的APP列表就成为我们最终使用的贝叶斯算法的训练数据。

1. 首先要筛选出男女各自的代表性APP列表集合

首先,受益于某些APP的命名以及其功能明显的性别倾向性,或者说得益于男女之间的差异,我们能够分别为男女各自定义一组APP名的关键词用来区别男女的用户。比如,对于女性来说,类似于“美丽说”,“美颜相机”,“蘑菇街”,“可爱”之类的关键词就比较能代表其女性的性别倾向性;而类似于“美女”,“体育”,“足球篮球”,“汽车”,“赛车”等关键字又是男性比较有代表性APP关键字。所以最终,我们形成了类似于下面的一组数据,这组数据由人工来完成:

性感美女	男性应用
Sexy	男性应用
汽车	男性应用
体育足球篮球	男性应用
足球	男性应用
篮球	男性应用
男人必玩	男性应用
战斗	男性应用
赛车	男性应用
快播	男性应用
配件	男性应用
暴力	男性应用
坦克	男性应用
美图秀秀	女性应用
大姨妈经期	女性应用
化妆美容	女性应用
美颜	女性应用
宝宝	女性应用
儿童	女性应用
美丽说	女性应用
美柚	女性应用
蘑菇街	女性应用
可爱	女性应用

通过,这组人工整理的数据,我们要将其与APP名称的库中的所有的APP名进行模糊匹配,继而找出所有的能够打上性别标签的APP。为此,我们可以采用ES+IK中文分词插件的方式,将我们的关键词以及其类型录入其中,其中的关键词会被IK插件分词,而类型信息将不会被处理,为此我们需要为ES的索引做以下的设定:

curl -XPUT localhost:9200/appgender -d '{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "ik" : {
                    "tokenizer" : "ik"
                }
            }
        }
    },
    "mappings" : {
        "appgender" : {
            "dynamic" : true,
            "properties" : {
                "appname" : {
                    "type" : "string",
                    "analyzer" : "ik"
                },
                "genre": {
                    "type": "string",
                    "index": "not_analyzed"
                }
            }
        }
    }
}'

但是,通过以上的工作之后,还需要根据需要来为IK插件的字典添加自己定义的词,这样用来优化最终的匹配效果,比如“美图秀秀”这个关键词,如果IK字典中没有“美图”这样的词汇,那么其就可能被分词成“美”和“图”两个字,这样在匹配的时候就会扩大匹配的范围,导致匹配结果失真;但是同时也要注意相反的方向,使用ES的目的就是模糊匹配,也就是要扩大匹配范围,但是正如我们前面说的,要掌握好度,既要保证有足够数量的APP被打上性别标签,也要注意避免太多的APP被打上标签(以致正确率下降)。我们可以通过Python ES API来将这些人工组织的数据写入ES的appgender索引,代码非常简单:

#coding=utf-8

from elasticsearch import Elasticsearch

if __name__ == '__main__':
    es = Elasticsearch()
    with open('data/gender_app_feature.tsv') as appgenre:
        for line in appgenre:
            appname, genre = line.strip().split('\t')
            es.index(index="appgender", doc_type="appgender", body={"appname": appname, "genre": genre})

2.  就是通过以上的ES中的appgender索引中的数据,来匹配APP库中的APP名,并将其结果保存下来,APP库的形式类似于:

GO锁屏    1975242
360省电王    2142434
录音机    2169688
天天爱消除    2450275
系统更新    2517301
Messaging    2533345
今日头条    2625085
墨迹天气    2762610
同花顺    3076707
QQ空间    3131907
漏洞修复    3255717
拨号盘    3609291
开心消消乐    3638686

第一列是APP名,第二列是APP的用户数,或者出现次数。而匹配工作也非常简单:

#coding=utf-8

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from elasticsearch import Elasticsearch

if __name__ == '__main__':
    es = Elasticsearch()
    with open('data/applist.log') as f:
        for line in f:
            line = line.replace('?', '')
            if line.strip():
                t = line.strip().split('    ')
                if len(t) == 2:
                    appname, num = t
                try:
                    num = int(num)
                    if num < 5: continue
                    # print 'Processing: [%s], and its type is [%s]' % (appname, type(appname))
                    r = es.search(index='appgender', doc_type='appgender', body={'query': {'match': {'appname': appname}}})
                    hits = r['hits']['hits']
                    if hits:
                        hit = hits[0]
                        matched_app = hit['_source']['appname']
                        matched_genre = hit['_source']['genre']
                        hit_score = hit['_score']
                        record = u'%s\t%s\t%s\t%d\t%s' % (appname, matched_app, matched_genre, num, hit_score)
                        print record.encode('utf-8')
                except Exception, e:
                    sys.stderr.write(str(e) +  '\n')

通过以上的简单程序,我们就得到类似以下的结果:

玩库赚流量      男人必玩        男性应用        14423   0.17464119
儿童拖拖乐游戏  儿童    女性应用        14699   0.34928238
4D极速沙滩赛车  赛车    男性应用        15583   0.34928238
宝宝树时光      宝宝    女性应用        16620   0.5457385
PPTV第1体育     体育足球篮球    男性应用        25234   0.17464119
汽车报价-汽车之家出品   汽车    男性应用        51951   0.34928238
汽车在线        汽车    男性应用        68215   1.03399
魔秀桌面        美图秀秀        女性应用        88965   0.34108657
球探体育比分    体育足球篮球    男性应用        90670   0.17464119
新浪体育        体育足球篮球    男性应用        102179  0.516995
美丽说  美丽说  女性应用        108899  2.873763
......

一共有5列,第一列是APP库中的某个APP,第二列是匹配到的ES中的关键词,第三列是匹配到的ES关键词所对应的分类(这里就两类,男性应用和女性应用),第四列是APP库中所标记的APP的用户数,可以用这个数来调整结果,第五列是匹配度得分,当然也可以通过这个得分来调整结果。

3. 通过以上的数据,我们可以看到某个用户的APP列表与上面结果的一个交集,有了个这个交集,我们就可以看出这个用户的“男女比重”,你可以通过这个指标定一个阀值(比如说,男性应用的比重在50%以上的定性为男性,否则为女性)来将其标定为男性或女性用户;如果交集为空,那么我们就不能确定这个用户的性别,那我们就不处理它。通过本步的处理,我们能够确定一部分的用户的性别特征,再将这些用户的APP列表展开,我们就能够得到如下的形式的数据:

0052c56f854f363e72a66b4c174e4050        女性应用        搜索
0052c56f854f363e72a66b4c174e4050        女性应用        美图秀秀
0056c01c656c00093a39be1ea783d060        女性应用        腾讯新闻
0056c01c656c00093a39be1ea783d060        女性应用        微信
0056c01c656c00093a39be1ea783d060        女性应用        快乐炸金花
0056c01c656c00093a39be1ea783d060        女性应用        欢乐斗地主
0056c01c656c00093a39be1ea783d060        女性应用        欢乐斗牛
0056c01c656c00093a39be1ea783d060        女性应用        百度
0056c01c656c00093a39be1ea783d060        女性应用        蘑菇街
0056c01c656c00093a39be1ea783d060        女性应用        金山电池医生
005cdf6d9f672ba5cbec4574586a942d        男性应用        快播
0088d4af42a65f864fc356405c73d39c        男性应用        牛仔美女
0088d4af42a65f864fc356405c73d39c        男性应用        美女刮刮乐
008a882683313fc6f64429a6396fed9c        女性应用        爱游戏
008a882683313fc6f64429a6396fed9c        女性应用        蘑菇街
00981a6f972fca3d1eccc942015054d2        女性应用        美图秀秀
00a17e719a86d8f11d534de346e0fcce        女性应用        微信
00a17e719a86d8f11d534de346e0fcce        女性应用        美图秀秀
00a953e662ef896ecde30a9a76e57e96        男性应用        天天基金网

第一列是用户的标识,第二列是根据“男女应用比重”所确定出的本用户的性别,而第三列就是这个用户展开后的全部应用。

4. 最后,就是通过第三步的数据,进行一些简单的统计,以满足贝叶斯模型的需求:

#coding=utf-8

from collections import defaultdict

TRAIN_DATA_FILE = 'data/genderapplist.log'

if __name__ == '__main__':
    gender_dist = defaultdict(set)
    app_dist = defaultdict(lambda: defaultdict(int))
    app_cond_male_prob = defaultdict(float)
    app_cond_female_prob = defaultdict(float)

    with open(TRAIN_DATA_FILE) as train_data:
        for line in train_data:
            line = line.strip()
            cells = line.split('\t')
            if len(cells) == 3:
                imei, gender, appname = cells
                gender = 'female' if gender == '女性应用' else 'male'
                gender_dist[gender].add(imei)
                app_dist[gender][appname] += 1

    # calculate P(male)
    pmale = float(len(gender_dist['male'])) / (len(gender_dist['male']) + len(gender_dist['female']))
    for appname in app_dist['male']:
        app_cond_male_prob[appname] = float(app_dist['male'].get(appname)) / len(gender_dist['male'])
    for appname in app_dist['female']:
        app_cond_female_prob[appname] = float(app_dist['female'].get(appname)) / len(gender_dist['female'])

    def gender_prob(applist):
        male_prob = pmale
        female_prob = (1 - pmale)
        for appname in applist:
            #print app_cond_male_prob.get(appname, 0.5)
            male_prob = male_prob * app_cond_male_prob.get(appname, 0.5)
            female_prob = female_prob * app_cond_female_prob.get(appname, 0.5)

        #print '-----------', male_prob, female_prob
        print 'user male probability %f' % (male_prob / (male_prob + female_prob))
        print male_prob, female_prob

    appsamples = ["蘑菇街",'搜索', '腾讯新闻', '微信', '快乐炸金花', '欢乐斗地主', '欢乐斗牛', '百度', '金山电池医生',]
    gender_prob(appsamples)

    for appname in appsamples:
        print '%s\t%f\t%f' % (appname, app_cond_male_prob.get(appname), app_cond_female_prob.get(appname))

在这里需要注意以下几个事实:

1. 我们的输入是一个用户的APP列表,输出是这个用户为男性的可能性

2. 输入类似于X = ("美图秀秀",‘搜索‘, ‘腾讯新闻‘, ‘微信‘, ‘快乐炸金花‘, ‘欢乐斗地主‘, ‘欢乐斗牛‘, ‘百度‘, ‘蘑菇街‘, ‘金山电池医生‘),而我们输出就是P(male|X)这样的条件概率。

3. 完整的贝叶斯公式为 P(male|X) = P(male) * P(X|male) / P(X),其中P(male)是男性的概率;P(male|X)是安装了这一堆APP的情况下此用户是男性的概率;P(X)是着堆APP被安装的概率。 但是对于一组固定的X来说,P(X)是个常量,我们可以不计算它。

4. 由于P(X)不用计算,我们必须分别计算出P(male) * P(X|male)和P(female) * P(X|female)

5. 由于训练数据集中P(appx|male)=0的情况,可以使用贝叶斯m估计的方法处理

通过以上的方法,最终就可以通过一个用户的APP的安装列表信息,估计这个用户的性别可能性。

如有表述疏漏,欢迎批评指正。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-20 00:52:00

使用朴素贝叶斯算法,通过用户安装的APP列表来推测用户的性别的相关文章

挖掘算法(1)朴素贝叶斯算法

原文:http://www.blogchong.com/post/NaiveBayes.html 1 文档说明 该文档为朴素贝叶斯算法的介绍和分析文档,并且结合应用实例进行了详细的讲解. 其实朴素贝叶斯的概念以及流程都被写烂了,之所以写这些是方便做个整理,记录备忘.而实例部分进行了详细的描述,网络上该实例比较简单,没有过程. 至于最后部分,则是对朴素贝叶斯的一个扩展了,当然只是简单的描述了一下过程,其中涉及到的中文分词以及TFIDF算法,有时间再具体补上. 2 算法介绍 2.1 贝叶斯定理 (1

C#编程实现朴素贝叶斯算法下的情感分析

C#编程实现 这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Language Progressing)中的重要问题,用以对文本进行正负面的判断,以及情感度评分和意见挖掘.本文借助朴素贝叶斯算法,针对文本正负面进行判别,并且利用C#进行编程实现. 不先介绍点基础? 朴素贝叶斯,真的很朴素 朴素贝叶斯分类算法,是一种有监督学习算法,通过对训练集的学习,基于先验概率与贝叶

朴素贝叶斯算法(Naive Bayes)

朴素贝叶斯算法(Naive Bayes) 阅读目录 一.病人分类的例子 二.朴素贝叶斯分类器的公式 三.账号分类的例子 四.性别分类的例子 生活中很多场合需要用到分类,比如新闻分类.病人分类等等. 本文介绍朴素贝叶斯分类器(Naive Bayes classifier),它是一种简单有效的常用分类算法. 回到顶部 一.病人分类的例子 让我从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难. 某个医院早上收了六个门诊病人,如下表. 症状 职业 疾病 打喷嚏 护士 感冒  打喷嚏 农夫 过敏

[Machine Learning] 朴素贝叶斯算法(Naive Bayes)

生活中很多场合需要用到分类,比如新闻分类.病人分类等等. 本文介绍朴素贝叶斯分类器(Naive Bayes classifier),它是一种简单有效的常用分类算法. 一.病人分类的例子 让我从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难. 某个医院早上收了六个门诊病人,如下表. 症状 职业 疾病 打喷嚏 护士 感冒  打喷嚏 农夫 过敏  头痛 建筑工人 脑震荡  头痛 建筑工人 感冒  打喷嚏 教师 感冒  头痛 教师 脑震荡 现在又来了第七个病人,是一个打喷嚏的建筑工人.请问他患

朴素贝叶斯算法 &amp; 应用实例

转载请注明出处:http://www.cnblogs.com/marc01in/p/4775440.html 引 和师弟师妹聊天时经常提及,若有志于从事数据挖掘.机器学习方面的工作,在大学阶段就要把基础知识都带上. 机器学习在大数据浪潮中逐渐展示她的魅力,其实<概率论>.<微积分>.<线性代数>.<运筹学>.<信息论>等几门课程算是前置课程,当然要转化为工程应用的话,编程技能也是需要的,而作为信息管理专业的同学,对于信息的理解.数据的敏感都是很好

朴素贝叶斯算法

一.朴素贝叶斯分类算法简述 1.贝叶斯公式和全概率公式 举一个概率论中的例子.设某工厂有甲.乙.丙三个车间生产同一种产品,已知各车间的产量分别占全厂产量的25%.35%.40%,而且各车间的次品率依次为5%.4%.2%.现问: (1)生产的产品是次品的概率是多少? (2)如果是次品,该次品是甲工厂生产的概率是多少? 显然: 设一个产品属于甲.乙.丙工厂的概率分别为P(A) = 0.25, P(B) = 0.35, P(C) = 0.4.如果用no 表示次品,则有p(no|A) = 0.05, p

统计学习方法 -&gt; 朴素贝叶斯算法

需要知道的是在什么时候可以用朴素贝叶斯算法:需要保证特征条件独立. 主要过程是学习输入和输出的联合概率分布. 预测的时候,就可以根据输入获得对打后验概率对应的输出y. 先验概率:已知输出,求输入.后验概率相反. 简单来说朴素贝叶斯算法,就是在对样本进行学习之后,到了需要做决策的时候,给定x,给出最大概率的y.这个本质上就是一个典型的后验概率模型.不过在该模型的算法推到上,还用到了先验概率的计算.但注意:最终朴素贝叶斯就是一种后验概率模型求P(y|x). 后验概率模型有一个好处,相当于期望风险最小

朴素贝叶斯算法及实现

1.朴素贝叶斯算法介绍 一个待分类项x=(a,b,c...),判断x属于y1,y2,y3...类别中的哪一类. 贝叶斯公式: 算法定义如下: (1).设x={a1, a2, a3, ...}为一个待分类项,而a1, a2, a3...分别为x的特征 (2).有类别集合C={y1, y2,  y3,  ..} (3).计算p(y1|x), p(y2|x), p(y3|x), .... (4).如果p(y(k)|x)=max{p(y1|x), p(y2|x), p(y3|x), ....},则x属于

朴素贝叶斯算法资料整理和PHP 实现版本

朴素贝叶斯算法简洁 http://blog.csdn.net/xlinsist/article/details/51236454 引言 先前曾经看了一篇文章,一个老外程序员写了一些很牛的Shell脚本,包括晚下班自动给老婆发短信啊,自动冲Coffee啊,自动扫描一个DBA发来的邮件啊, 等等.于是我也想用自己所学来做一点有趣的事情.我的想法如下: 首先我写个scrapy脚本来抓取某个网站上的笑话 之后写个Shell脚本每天早上6点自动抓取最新的笑话 然后用朴素贝叶斯模型来判断当前的笑话是否属于成