华杰手把手教你大数据分析

  题目貌似取得有些大,准确的说应该叫基于大数据的机器学习,不过就这样吧>_<

  

  每当说到大数据分析,有些人就很讳莫如深,故意讲得很复杂,生怕别人听懂就low了。然而其实可能没那么复杂,就像陈皓说的——所谓大数据不就是因为硬盘便宜了,所以不用删日志了吗?  <_<

  好了,废话不多说,这次实现的目标很简单,就是通过已知数据,通过某人的姓名分析出他的性别。如你所知,中国的姓名那是千千万万,不像老外来来回回就是那几个名字,拿个数据表对照一下就可以了——毛子更懒,男的叫朱可夫,女的就叫朱可娃,自带性别标识,生怕别人以为自己是伪娘。。。

  也许此刻你或许会问这有什么用啊,简单来说你想给自己的网站做一个性别统计,并分析出各自的爱好,购买习惯等,类似淘宝每年的公众那个统计报表,此时就可以用到——也许你会说可以直接统计用户信息里面啊,然而你确定有多少用户会愿意填?又有多少是认真的呢?不过有一个数据一般是真实的,那就是快递单及收货人姓名!

  以下内容均在win10+python2.7+mysql5.5上验证通过。

  数据分析,数据分析,没数据当然不行,所以程序未动,数据先行。本次我选择的是某2000w的那个数据——不要问我为什么会有,这不是本次的重点——之所以选择这个是有一定理由的,这个我下面会说到。

  首先这次我们要做的是基于中文名的数据,所以老外很多开源的训练数据库直接over了。。。然后要有足够的基础量,也就是说作为训练数据库应该有200w左右的数据,这样可以保证数据的覆盖面足够广。其次需要有自检功能,也就是说我能通过已知的数据去修复某些受损数据,且不带来其他任何影响,这点尤其重要!因此你可以选择这个2000w或者某数字订票的。。。

  不过这个数据也并不是完美的,最明显的一点就是本身其性别差就很大,男的多,女的少,而标准的训练数据应该保证所有姓名的单字值总和为0,即未计算前这个名字是男是女各是0.5,不过影响不算特别大,可以通过程序修正部分。

  导数据这部分我就不说了,导完之后就是苦逼的洗数据。这是大头,也是占这次示例里面时间最多的部分。

  1、筛选出是中文名的数据,并在info表添加一个is_China。

  select * from info where not name regexp ‘^[1-9A-Za-z]‘;

   或者直接删除这部分不用的数据

  delete from info where  name regexp ‘^[1-9A-Za-z]‘;

  2、进行数据自检

  之前说过之所以选择这个数据,一个很重要的原因就是可以自检。因为你可以通过身份证号来重新计算性别。

  如果你之前已经看过这个数据库,应该会发现其中有很多的数据实际上是不对的,比如,你查看“雯”这个字,会发现几乎男女的性别是各一半,这显然是不对的——当然也有一种可能,就是现在已经基佬遍地了<_<

  为此,首先第一步是将正确的身份证号筛选出来,虽然你可以通过相互对照来修复部分身份证,但还是不推荐这么做,所以只需将不符合规则的身份证给剔除掉。

  delete FROM info
  WHERE
      is_China = 1
  AND CtfTp = ‘ID‘
  AND (CHAR_LENGTH(CtfId) <>18 and CHAR_LENGTH(CtfId) <>15) 

  当有了正确的身份证之后,就可以进行自检修复了。

    update info a inner join
    (
    SELECT
        id,
        NAME,
        Gender,
        CASE (CASE CHAR_LENGTH(CtfId)
        WHEN 18 THEN substring(CtfId, 17, 1)
        ELSE substring(CtfId, 15, 1)
        END)%2
        WHEN 0 THEN ‘F‘
        WHEN 1 THEN ‘M‘
        END sex,
        CtfId

    FROM
        `info`
    WHERE
        is_China = 1
    AND CtfTp = ‘ID‘) b
    set a.Gender = b.sex
    where a.id=b.id

  以上SQL基本上没什么难度,就是截取和更新。执行的时候,你可以出去喝杯咖啡,或者运动一番,又或是去趟卫生间。。。反正什么打发时间做什么。

  基本上上述工作做完,你的可用数据在180w左右。

  

  3、建立字符表,将文本转化为数值

  首先先建表

  CREATE TABLE `name` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `chars` varchar(2) COLLATE utf8_unicode_ci DEFAULT NULL,
    `val` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `IDX_NAME` (`chars`,`val`)
  ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

  这里我偷懒选择了将值直接插入数据库,即每个文字都是有多行的,而不是分类统计的方法,如果你有兴趣可以试着改写一下表结构,val变成三列——男、女、总和,使得读取更加快速方便。

  接着我们就要往里面灌数据了。虽然用复杂的SQL应该也能实现,不过这里我们使用python来完成这项工作。如果你对python还不是很熟悉,可以去这里学习一下

  

  

#encoding=utf-8
import sys
import MySQLdb
import random
import time
import traceback
import math

reload(sys)
sys.setdefaultencoding(‘utf-8‘) #设置Python的默认编码为 utf-8

########################################################################

db=MySQLdb.connect(host="localhost",user="root",passwd="",charset=‘utf8‘)
cur=db.cursor(cursorclass = MySQLdb . cursors . DictCursor )    #让返回的是字典类型
cur.execute(‘use 2000w‘)
cur.execute(‘SELECT id,Name,Gender FROM `info` WHERE is_China=1;‘)
rets=cur.fetchall()

chars=[]
chars_gender=[]
for ret in rets:
    length=len(ret[‘Name‘])/2
    char=ret[‘Name‘][length:]
    for x in xrange(length,len(char)+1):
        c=char[x-1:x]
        chars.append(c);
        sex=0
        if(ret[‘Gender‘]==‘M‘):
            sex=1
        else:
            sex=-1
        chars_gender.append(sex)

for k in xrange(0,len(chars)):

    sql="INSERT INTO name (chars, val) VALUES (‘"+chars[k]+"‘,"+(str)(chars_gender[k])+");"
    # print sql
    try:
        cur.execute(sql)
        db.commit()        #加上这句之后才会提交执行,否则不执行
    except:
        # 发生错误时回滚
        db.rollback()

  现在知道我为什么偷懒了吧,因为这样可以少些很多行,顺带可以不用动脑筋——哈哈哈哈哈哈哈哈——pia飞。。。

  接着你又可以去喝杯咖啡,上趟厕所了。。。

  至此,我们的数据处理部分就全部结束了。是不是很简单呢。理论上应该没什么不容易理解的,那么,OK,下面就是使用这些数据了。

  模型设计。老实说,这部分一般都是由Scientist来设计完成的,不过这次我们不需要这么复杂,就用最简单的条件概率就OK了。

  条件概率,如果你还记的高中或大学的知识的话应该知道,他是计算在某条件下某事发生的概率。因此我们将这次的命题转化一下就可以知道,其实质是已知我们选了某字则该字是属于女生/男生的概率。至于公式的话,自己翻书吧。

  好,接下来就到了coding时间了。废话不多说,直接上代码

  

#encoding=utf-8
import sys
import MySQLdb
import random
import time
import traceback
import math
import decimal

reload(sys)
sys.setdefaultencoding(‘utf-8‘) #设置Python的默认编码为 utf-8

########################################################################

name=raw_input(‘please input name:‘);
name=name.decode("gbk")
chars=[]
length=len(name)/2
char=name[length:]
for x in xrange(length,len(char)+1):
    c=char[x-1:x]
    chars.append(c);

# 简单的叠字处理修正

chars_unique=set(chars)

is_overlapping=False

if len(chars_unique)!=len(chars):
    is_overlapping=True

db=MySQLdb.connect(host="localhost",user="root",passwd="",charset=‘utf8‘)
cur=db.cursor(cursorclass = MySQLdb . cursors . DictCursor )    #让返回的是字典类型
cur.execute(‘use 2000w‘)

# sql="SELECT Gender,COUNT(Name) total_num FROM `info` WHERE is_China=1 GROUP BY Gender"
# cur.execute(sql)
# rets=cur.fetchall()
# F_total_num=rets[0][‘total_num‘]
# M_total_num=rets[1][‘total_num‘]
# total_num=M_total_num+F_total_num
# 加速运行 每次都去统计其实意义不大,因为当数量足够大时,微小的变化并不会影响统计结果,因为在那之前精度已经不足了
total_num=1870562
F_total_num=562496
M_total_num=1308066

pro1_arr=[]
pro2_arr=[]
overlapping_word=‘‘
for x in xrange(0,len(chars)):
    sql="SELECT SUM(val) v FROM `name` WHERE chars=‘" +chars[x]+ "‘ GROUP BY val"
    cur.execute(sql)
    rets=cur.fetchall()

    if(len(rets)==1):
        if(rets[0][‘v‘]>=0):
            m_nums=rets[0][‘v‘]
            f_nums=0;
        else:
            f_nums=rets[0][‘v‘]
            m_nums=0;
    else:
        try:
            f_nums=rets[0][‘v‘]
        except:
            f_nums=0

        try:
            m_nums=rets[1][‘v‘]
        except:
            m_nums=0    

    if f_nums==0 and m_nums==0:
        # 此处为不存在的字符做异常处理,可以调用类似createSex.py的方法将不存在的数据加入那么表
        print "Sorry,I don‘t know the name sex,maybe you can help me"
        sys.exit(0)

    char_total_num=abs(m_nums)+abs(f_nums)
    pro1_val=(abs(f_nums)/total_num)/(char_total_num/total_num)
    pro2_val=(abs(m_nums)/total_num)/(char_total_num/total_num)
    pro1_arr.append(pro1_val)
    pro2_arr.append(pro2_val)

    if overlapping_word==chars[x]:
        if pro1_val > 0.8 or pro2_val > 0.8:
            is_overlapping=False
    else:
        overlapping_word=chars[x]

pro1=sum(pro1_arr)/len(chars);
pro2=sum(pro2_arr)/len(chars);

if is_overlapping:
    pro1+=decimal.Decimal(0.3)
    pro2-=decimal.Decimal(0.3)
if pro1>decimal.Decimal(1):
  pro1=decimal.Decimal(1);
  pro2=decimal.Decimal(0);
if pro1>pro2:
    print "The Name have "+(str)(pro1*100)+" is a woman name";
else:
    print "The Name have "+(str)(pro2*100)+" is a man name";

  看到这里,也许有人会说,卧槽,这不是坑爹吗?就这100来行的代码就完成了?这他喵的也算大数据分析?但是,why not ?

  好了,收起无谓的口水仗吧,来看看我们的程序做了什么。第一将新的名字处理成单字,然后分别再去计算每个单字的条件概率,最后将所有的概率相加然后平均。然后还为叠字做了一些小小的处理。别看虽然代码不多,但如果只看结果的话,还是可以接受的,基本上可以达到80%以上的识别率(日文名字不行,哪怕是汉字,不要问我为什么——自己往前看,当然有例外,比如西木野真姬<_<)。

  是不是感觉很简单!蹭蹭几下,你就会大数据分析了!(伪

  

  如你所见,除了陆无双判断有些失误之外其他均可以,当然这里还有一部分原因是由于之前提到过的本身数据问题造成的,还有部分是程序的原因,比如这边计算总的概率时只是简单的相加平均,这会导致某些字由于两极分化严重而导致总结果的不准确,因此应该才用加权计算来消磨掉这部分的错误。当然其他方法也是有的,我在这里只是做一个抛砖引玉的作用,如果各位有兴趣或者有更好的思路欢迎来这里,互相探♂讨♂交♂流

时间: 2024-10-24 09:29:25

华杰手把手教你大数据分析的相关文章

大数据江湖之即席查询与分析(下篇)--手把手教你搭建即席查询与分析Demo

上篇小弟分享了几个"即席查询与分析"的典型案例,引起了不少共鸣,好多小伙伴迫不及待地追问我们:说好的"手把手教你搭建即席查询与分析Demo"啥时候能出?说到就得做到,差啥不能差人品,本篇只分享技术干货,目的只有一个,就是让每一个伙伴都能根据本篇向导搭建出一个"即席查询与分析Demo". 为了让各位伙伴能够尽快上手体验,所选案例就以上一篇中的"机动车缉查布控即席查询与分析"为例,上篇我们已经比较详尽的分析了用户需求,没好好听课的

手把手教你提交文件到git

手把手教你使用git提交到github 作者 数据分析与优化 关注 2016.07.17 10:25 字数 7342 阅读 399评论 1喜欢 6 摘要Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上.既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了. 一:Git

大数据分析挖掘全流程实战视频教程:电商市场与销售趋势预测

大数据分析挖掘全流程实战视频教程:电商市场与销售趋势预测资源下载:https://pan.baidu.com/s/1VPydETNHqhDDcJ1Lpko1AA 提取码:o9mk 课程特色:特色一:一套课程,搞定企业级数据分析与挖掘全栈技术特色二:基于Linux+Windows两套系统手把手教你搭建企业数据分析/挖掘开发环境,带你从0~1特色三:电商企业经典数据分析与挖掘项目全程贯穿,教你从1~100 课程目标:1.掌握预测分析的理论基础,一些数据分析挖掘软件的使用技巧2.通过掌握的分析技术及软

大数据分析案例

部分数据来源于网络,如有侵权请告知. 一.大数据分析在商业上的应用 1.体育赛事预测 世界杯期间,谷歌.百度.微软和高盛等公司都推出了比赛结果预测平台.百度预测结果最为亮眼,预测全程64场比赛,准确率为67%,进入淘汰赛后准确率为94%.现在互联网公司取代章鱼保罗试水赛事预测也意味着未来的体育赛事会被大数据预测所掌控. “在百度对世界杯的预测中,我们一共考虑了团队实力.主场优势.最近表现.世界杯整体表现和博彩公司的赔率等五个因素,这些数据的来源基本都是互联网,随后我们再利用一个由搜索专家设计的机

手把手教你构建gradle项目

我先来阐述一下我认为的gradle项目的优势吧 1:语法简单,集成了ant和maven的很多优点,简单的语法和完善的文档造就了其不可估计的前途 2:构建容易,一个build.gradle文件,一行指令,即可构建你的项目 3:方便导入依赖库 我这个人就喜欢瞎捉摸,虽然不是计算机专业的,但是读研这段时间确喜欢上了计算机,第一次接触gradle是在学libgdx引擎的时候,那时候还不知道gradle的作用,后面越学越深的时候发现了很多问题,构建项目的时候往往导入一个包不能解决问题,现在的工程越来越大,

手把手教你简单接入微信SDK

就看微信现在这么火的样子,如果你的APP不接入微信的SDK好像就有点脱离了时代大车轮一样.一个成功的APP,不单单凭借着一个好的想法,一个好的功能,最主要还是用户量.用户量就好像是水,我们的APP就一艘船,而好的推广就像是好的帆.这艘船我可以造得很大,很华丽,但是少了水,我们仅仅是摆设:少了帆,我们仅仅靠桨来划,速度也太慢.因此接入微信SDK的功能也是必不可少,相信有点才能的领导都会要求加上这一个功能.好了,言归正传,正式开始手把手教你简单接入微信SDK. 1.首先我们需要建立一个android

手把手教你如何恢复 /boot 目录

前言 /boot目录是一个系统启动最重要的目录,系统在上电自检MBR引导之后,系统就要读取/boot目 录下的文件.详细的内容见:http://vinsent.blog.51cto.com/13116656/1963546.总之/boot被破坏 了是很大的问题,今天就带大家一步步恢复/boot目录中的各文件,欢迎您的阅读!! 一.破坏现象 我们都知道/boot/目录是一个用于引导系统开机启动的目录,如果你不小心破坏了该目录.你将的系统将不能启动.CentOS 6会进入都如下界面: CentOS

手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单

手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩展二:为html添加行为 手把手教你开发Chrome扩展三:关于本地存储数据 Chrome的更新速度可以说前无古人,现在我每天开机的第一件事就是打开Chrome检查是不是有了新版本.界面清爽.操作人性化.网络备份资料和快速的启动速度令我爱不释手,还有它拥有众多的扩展程序,相对于firefox的插件来说,

手把手教你写专利申请书/怎样申请专利

手把手教你写专利申请书·怎样申请专利 摘要小前言(一)申请前的准备工作    1.申请前查询    2.其它方面的考虑    3.申请文件准备(二)填写专利申请系列文档    1.实际操作步骤    2.详细操作    3.经验分享.注意事项(三)关于费用(四)其它的话參考资源提示常见问题的问与答 摘要: 怎样写好专利申请?由于非常多专利申请人都是第一次申请,因此,可能有一种神奇和些许恐惧.本文写的是怎样写专利申请书,手把手教你写专利申请并提供申请专利时的注意事项,专利申请费用及费用减缓等相关參