[转][转]数据挖掘 - 分词入门

标签: | 发表时间:2015-01-09 23:16 | 作者:heiyeshuwu
出处:http://blog.csdn.net/heiyeshuwu


数据挖掘 - 分词入门


摘要:谷歌4亿英镑收购人工智能公司DeepMind,百度目前正推进“百度大脑”项目,腾讯、阿里等各大巨头布局深度学习。随着社会化数据大量产生,硬件速度上升、成本降低,大数据技术的落地实现,让冷冰冰的数据具有智慧逐渐成为新的热点。要从数据中发现有用的信息就要用到数据挖掘技术,不过买来的数据挖掘书籍一打开全是大量的数学公式,而课本知识早已还给老师了,难以下手、非常头大!

我们可以跳过数学公式,先看看我们了解数据挖掘的目的:发现数据中价值。这个才是关键,如何发现数据中的价值。那什么是数据呢?比如大家要上网首先需要输入网址,打开网页后会自动判断哪些是图片、哪些是新闻、哪些是用户名称、游戏图标等。人大脑可以存储大量的信息,包括文字、声音、视频、图片等,每一个都可以转换数据存储在电脑。人的大脑可以根据输入自动进行判断,电脑可以通过输入判断吗?答案是肯定的! 不过需要我们编写程序来判断每一种信息,就拿文字识别来说吧,怎么从一个人在社交网络的言论判断他今天的心情是高兴还是愤怒!比如:“你假如上午没给我吃冰淇淋,我绝对会不happy的。” 信息发布时间为下午2点。对于我们人类一看这个句子就知道他是吃过冰淇淋了,心情肯定不会是愤怒。那计算机怎么知道呢?

这就是今天的主题,要让计算机理解句子的语义,必须要有个程序,上面的句子和发布时间是输入,输出就是 “高兴”。要得到“高兴”就要建立 “高兴”的规则,可以建一个感情色彩词库,比如 高兴(识别词是高兴、happy),愤怒(识别词是愤怒、生气)。这里的识别词就是输入中出现的词语,比如上面的句子中的“happy”就识别出了“高兴”这个感情色彩词。但是光识别出“happy”肯定是不行的,前面的“假如。。。没。。。,我。。。不。。。”等关键词都需要识别出来,才能完整判断一个句子的意思。为了达到这个效果,就必须要用分词技术了。

我们先人工对上面的句子来进行一下切词,使用斜线分割:“你/假如/上午/没/给/我/吃/冰淇淋/,/我/绝对/会/不/happy/的/。/”。但是程序如何做到自动切分?这个其实中国的前辈们已经做了很多中文分词的研究,常见的分词算法有:

1、基于词典的分词,需要先预设一个分词词典,比如上面句子切分出来的“假如、上午”这些词先存放在词典,然后把句子切分成单字组合成词语去词典里查找,匹配上了就挑选出来一个词。没有匹配上的就切分成单字。

2、基于统计的分词,需要先获取大量的文本语料库(比如新闻、微博等),然后统计文本里相邻的字同时出现的次数,次数越多就越可能构成一个词。当达到一定次数时就构成了一个词即可形成语料概率库。再对上面句子进行单字切分,把字与字结合后在语料概率库里查找对应的概率,如果概率大于一定值就挑选出来形成一个词。这个是大概描述,实际生产环境中还需要对句子的上下文进行结合才能更准确的分词。

3、基于语义的分词,简而言之就是模拟人类对句子的理解来进行分词。需要先整理出中文语句的句法、语义信息作为知识库,然后结合句子的上下文,对句子进行单字切分后组合成词逐个带入知识库进行识别,识别出来就挑选出一个词。目前还没有特别成熟的基于语义的分词系统。

为了让大家快速的了解分词技术,我们采用第一个方式来做测试:基于词典的分词,这种方式简单暴力可以解决百分之七八十的问题。基于词典的分词大概分为以下几种方式:

1、正向最大匹配,沿着我们看到的句子逐字拆分后组合成词语到词典里去匹配,直到匹配不到词语为止。举个实际的例子:“人民大会堂真雄伟”,我们先拆分为单字“人”去词典里去查找,发现有“人”这个词,继续组合句子里的单字组合“人民”去词典里查找,发现有“人民”这个词,以此类推发现到“人民大会堂”,然后会结合“人民大会堂真”去词典里查找没有找到这个词,第一个词“人民大会堂”查找结束。最终分词的结果为:“人民大会堂/真/雄伟”。




2、逆向最大匹配,这个和上面相反,就是倒着推理。比如“沿海南方向”,我们按正向最大匹配来做就会切分成 “沿海/南方/向”,这样就明显不对。采用逆向最大匹配法则来解决这个问题,从句子的最后取得“方向”这两个字查找词典找到“方向”这个词。再加上“南方向”组成三字组合查找词典没有这个词,查找结束,找到“方向”这个词。以此类推,最终分出“沿/海南/方向”。

3、双向最大匹配,顾名思义就是结合正向最大匹配和逆向最大匹配,最终取其中合理的结果。最早由哈工大王晓龙博士理论化的取最小切分词数,比如“我在中华人民共和国家的院子里看书”,正向最大匹配切分出来为“我/在/中华人民共和国/家/的/院子/里/看书”工8个词语,逆向最大匹配切分出来为“我/在/中华/人民/共/和/国家/的/院子/里/看书”共11个词语。取正向最大匹配切出来的结果就是正确的。但是如果把上面那个例子“沿海南方向”双向切分,都是3个词语,改如何选择?看第4个《最佳匹配法则》。

4、最佳匹配法则,先准备一堆文本语料库、一个词库,统计词库里的每一个词在语料库里出现的次数记录下来。最后按照词频高的优先选出,比如“沿海南方向”,正向切分为:“沿海/南方/向”,逆向切分为:“沿/海南/方向”。其中“海南”的频度最高,优先取出来。剩下“沿”、“方向”也就正常切分了。是不是这就是基于词典分词的最佳方案?比如数学之美中提到的:“把手抬起来” 和 “这扇门的把手”,可以分为“把”、“手”、“把手”,不管怎么分总有一句话的意思不对。后续再介绍如何通过统计的分词处理这些问题。

说了这么多,我们来实战一下如何基于词典的分词:

public class TestPositiveMatch {
    public static void main( String[] args) {
         String str = "我爱这个中华人民共和国大家庭";
        List<String> normalDict = new ArrayList<String>();

        normalDict.add("");
        normalDict.add("爱");
        normalDict.add("中华");   //测试词库里有中华和中华人民共和国,按照最大匹配应该匹配出中华人民共和国
        normalDict.add("中华人民共和国");

        int strLen = str.length();  //传入字符串的长度
        int j = 0;
         String matchWord = ""; //根据词库里识别出来的词
        int matchPos = 0; //根据词库里识别出来词后当前句子中的位置
        while (j < strLen) {      //从0字符匹配到字符串结束
            int matchPosTmp = 0;   //截取字符串的位置
            int i = 1;
            while (matchPosTmp < strLen) {   //从当前位置直到整句结束,匹配最大长度
                matchPosTmp = i + j;
                 String keyTmp = str.substring(j, matchPosTmp);//切出最大字符串
                if (normalDict.contains(keyTmp)) { //判断当前字符串是否在词典中
                    matchWord = keyTmp;  //如果在词典中匹配上了就赋值
                    matchPos = matchPosTmp; //同时保存好匹配位置
                }
                i++;
            }
            if (!matchWord.isEmpty()) {
                //有匹配结果就输出最大长度匹配字符串
                j = matchPos;
                //保存位置,下次从当前位置继续往后截取
                 System.out.print(matchWord + " ");
            } else {
                //从当前词开始往后都没有能够匹配上的词,则按照单字切分的原则切分
                 System.out.print(str.substring(j, ++j) + " ");
            }
            matchWord = "";
        }
    }
}

输出结果为: 我 爱 这 个 中华人民共和国 大 家 庭


按照这样我们一个基本的分词程序开发完成。


对于文章一开始提到的问题还没解决,如何让程序识别文本中的感情色彩。现在我们先要构建一个感情色彩词库“高兴”,修饰词库“没”、”不”。再完善一下我们的程序:

public class TestSentimentPositiveMatch {
    public static void main( String[] args) {
         String str = "你假如上午没给我吃冰淇淋,我绝对会不happy的。";

        //语义映射
        Map< String, String> sentimentMap = new HashMap< String, String>();
        sentimentMap.put("happy", "高兴");

        //情感词库
        List<String> sentimentDict = new ArrayList<String>();
        sentimentDict.add("happy");

        //修饰词
        List<String> decorativeDict = new ArrayList<String>();
        decorativeDict.add("不");
        decorativeDict.add("没");

        //修饰词衡量分数
        Map< String, Double> decorativeScoreMap = new HashMap< String, Double>();
        decorativeScoreMap.put("不", -0.5);
        decorativeScoreMap.put("没", -0.5);

        List<String> decorativeWordList = new ArrayList<String>();  //修饰词
         String sentimentResult = ""; //情感结果

        int strLen = str.length();  //传入字符串的长度
        int j = 0;
         String matchSentimentWord = ""; //根据词库里识别出来的情感词
         String matchDecorativeWord = ""; //根据词库里识别出来的修饰词
        int matchPos = 0; //根据词库里识别出来词后当前句子中的位置
        while (j < strLen) {      //从0字符匹配到字符串结束
            int matchPosTmp = 0;   //截取字符串的位置
            int i = 1;
            while (matchPosTmp < strLen) {   //从当前位置直到整句结束,匹配最大长度
                matchPosTmp = i + j;
                 String keyTmp = str.substring(j, matchPosTmp);//切出最大字符串
                if (sentimentDict.contains(keyTmp)) { //判断当前字符串是否在词典中
                    matchSentimentWord = keyTmp;  //如果在词典中匹配上了就赋值
                    matchPos = matchPosTmp; //同时保存好匹配位置
                }
                if (decorativeDict.contains(keyTmp)) { //判断当前字符串是否在词典中
                    matchDecorativeWord = keyTmp;  //如果在词典中匹配上了就赋值
                    matchPos = matchPosTmp; //同时保存好匹配位置
                }
                i++;
            }
            if (!matchSentimentWord.isEmpty()) {
                //有匹配结果就输出最大长度匹配字符串
                j = matchPos;
                //保存位置,下次从当前位置继续往后截取
                 System.out.print(matchSentimentWord + " ");
                sentimentResult = sentimentMap.get(matchSentimentWord);
            }
            if (!matchDecorativeWord.isEmpty()) {
                //有匹配结果就输出最大长度匹配字符串
                j = matchPos;
                //保存位置,下次从当前位置继续往后截取
                 System.out.print(matchDecorativeWord + " ");
                decorativeWordList.add(matchDecorativeWord);
            } else {
                //从当前词开始往后都没有能够匹配上的词,则按照单字切分的原则切分
                 System.out.print(str.substring(j, ++j) + " ");
            }
            matchSentimentWord = "";
            matchDecorativeWord = "";
        }

        double totalScore = 1;
        for ( String decorativeWord : decorativeWordList) {
             Double scoreTmp = decorativeScoreMap.get(decorativeWord);
            totalScore *= scoreTmp;
        }

         System.out.print("\r\n");
        if (totalScore > 0) {
             System.out.println("当前心情是:" + sentimentResult);
        } else {
             System.out.println("当前心情是:不" + sentimentResult);
        }
    }
}


通过传入“你假如上午没给我吃冰淇淋,我绝对会不happy的。”,结果输出为:“当前心情是:高兴”。当然你也可以改变其中的修饰词,比如改为:“你假如上午没给我吃冰淇淋,我绝对会happy的。”,结果输出为:“当前心情是:不高兴”。

机器再也不是冷冰冰的,看起来他能读懂你的意思了。不过这只是一个开始,抛出几个问题:

1、如何让程序识别句子中的时间?比如“上午”、“下午2点”。
2、如何处理“把手抬起来” 和 “这扇门的把手”中的“把”与“手”的问题?
3、如何构建海量的知识库,让程序从“婴儿”变成“成年人”?
4、如何使用有限的存储空间海量的知识库?
5、如何提高程序在海量知识库中查找定位信息的效率?
6、如何识别新词、人名、新鲜事物等未知领域?



这是《纽约时报》刊登的2张照片,一张是老鼠的脑细胞(左),一张是宇宙(右)。早期宇宙中星系互连关系,和大脑神经元相互连接,几乎无法分辨两张图之间的不同,大脑细胞与整个宇宙拥有一样的结构。

宇宙芸芸众生都是相通的,大脑也许就是一个小宇宙,在这个小宇宙又有很多星球、住着很多生物。而电脑也是宇宙中地球上的一个产物,只要存储计算速度发展到足够强大一定可以构建成一个强大的大脑。

你看这个单词 “testaword” 认识吗?可能不认识,因为我们五官先获取到的信息,然后根据大脑以往学习的经验做出判断。但是你看这个短语 ” test a word” 认识吗?再看看开始那个单词“testaword”是不是就亲切多了?


文章来源:http://www.lanceyan.com/tech/datadig_segment_step1.html 


作者:heiyeshuwu 发表于2015-1-9 15:16:10 原文链接
阅读:42 评论:1 查看评论

相关 [数据挖掘 分词] 推荐:

[转][转]数据挖掘 - 分词入门

- - heiyeluren的blog(黑夜路人的开源世界)
摘要:谷歌4亿英镑收购人工智能公司DeepMind,百度目前正推进“百度大脑”项目,腾讯、阿里等各大巨头布局深度学习. 随着社会化数据大量产生,硬件速度上升、成本降低,大数据技术的落地实现,让冷冰冰的数据具有智慧逐渐成为新的热点. 要从数据中发现有用的信息就要用到数据挖掘技术,不过买来的数据挖掘书籍一打开全是大量的数学公式,而课本知识早已还给老师了,难以下手、非常头大.

数据挖掘是神马?

- - 互联网分析
1、数据挖掘需要‘神马样’的流程.  2、哥,有没有详细点的,来个给力的. 4、数据在统计意义上有哪些类型. 9、知道这些工具不知道如何在工作中用呀. 11、还有没有更人性化、智能化的展现. 12、上面这图看起来很给力,背后很复杂吧.  16、转载的留个来源 ,毕竟是我辛苦收集和想出来的,谢谢. 忘记“大数据”,从“中数据”开始.

这就是数据挖掘

- - 互联网分析
当今数据库的容量已经达到上万亿的水平(T)— 1,000,000,000,000个字节. 在这些大量数据的背后隐藏了很多具有决策意义的信息,那么怎么得到这些“知识”呢. 也就是怎样通过一颗颗的树木了解到整个森林的情况. 计 算机科学对这个问题给出的最新回答就是:数据挖掘,在“数据矿山”中找到蕴藏的“知识金块”,帮助企业减少不必要投资的同时提高资金回报.

关于数据挖掘

- - 牛国柱
以下内容来自网络,关于数据挖掘的一些最基本的知识. 数据挖掘是对一系列数据进行分析和挖掘的方法的统称,在精准营销领域,最常用的数据挖掘方法主要包括以下三类:分类、聚类、关联. 分类(Classify)属于预测性模型. 分类模型的构建需要“训练样本”,训练样本中的每一个个体的类别必须是明确的. 分类模型的特征变量一般称为“自变量”,又叫“预测变量”,类别变量称为“目标变量”.

数据挖掘与Taco Bell编程

- everfly - 译言-每日精品译文推荐
来源Data Mining and Taco Bell Programming. Programmer Ted Dziuba suggests an alternative to traditional program that he called "Taco Bell Programming." The Taco Bell chain creates multiple menu items from about eight different ingredients.

使用Weka进行数据挖掘

- - 搜索研发部官方博客
数据挖掘、机器学习这些字眼,在一些人看来,是门槛很高的东西. 诚然,如果做算法实现甚至算法优化,确实需要很多背景知识. 但事实是,绝大多数数据挖掘工程师,不需要去做算法层面的东西. 他们的精力,集中在特征提取,算法选择和参数调优上. 那么,一个可以方便地提供这些功能的工具,便是十分必要的了. 而weka,便是数据挖掘工具中的佼佼者.

数据挖掘 - 分类算法比较

- - IBM developerWorks 中国 : 文档库
随着计算能力、存储、网络的高速发展,人类积累的数据量正以指数速度增长. 对于这些数据,人们迫切希望从中提取出隐藏其中的有用信息,更需要发现更深层次的规律,对决策,商务应用提供更有效的支持. 为了满足这种需求,数据挖掘技术的得到了长足的发展,而分类在数据挖掘中是一项非常重要的任务,目前在商业上应用最多.

数据挖掘分类技术

- - CSDN博客云计算推荐文章
从分类问题的提出至今,已经衍生出了很多具体的分类技术. 下面主要简单介绍四种最常用的分类技术,不过因为原理和具体的算法实现及优化不是本书的重点,所以我们尽量用应用人员能够理解的语言来表述这些技术. 而且我们会在第4章再次给读者讲述分类算法和相关原理. 在我们学习这些算法之前必须要清楚一点,分类算法不会百分百准确.

数据挖掘之R与SQL

- Wolf - 刘思喆 @ 贝吉塔行星
今天看到老同学@JulieJulieJulieJulie 的浪漫求婚,真的很浪漫、很唯美、很感动. 正如评论说的,我们又相信爱情了. 于是,小兴奋,睡不着,爬起来补一篇文章. 最近在数据挖掘专业网站 KDnuggets 上刊出了2011年度关于数据挖掘/分析语言流行度的调查,不出意料R、SQL、Python果然排在了前三位.

数据挖掘的标准流程

- - CSDN博客推荐文章
    CRISP-DM (cross-industry standard process for data mining), 即为"跨行业数据挖掘过程标准". 此KDD过程模型于1999年欧盟机构联合起草. 通过近几年的发展,CRISP-DM 模型在各种KDD过程模型中占据领先位置,采用量达到近60%.(数据引自Cios and Kurgan于2005年合著的论文trands in data mining and knowledge discovery中 )    在1996年,当时数据挖掘市场是年轻而不成熟的,但是这个市场显示了爆炸式的增长.