文本挖掘

一个暑假回来到了该找工作的紧张时期了。不过项目还是要继续做嘛,╮(╯_╰)╭,放假前用python爬到了一些网页,也尝试着分了词。现在进入文本挖掘阶段吧。

R在数据挖掘和机器学习方面好似很方便,安了试试看。界面跟Matlab有几分相似呢……o(≧v≦)o~~

-------2013.9.13----python分词、词频统计、寻找公共词--

R还是有点偏向学术计算的语言了,最后还是换上半生不熟的python来做。之前爬到了网页数据(见上片文章【网络爬虫】最后8.3的记录),而且尝试了分词。现在完善了以下处理:

1、对所有爬到是网页数据进行分词(没有设立自定义词典)

如果设置自定义词典,那么分词效果会更好

2、对各个网页的词进行词频统计,尔后用python的sorted函数对dictionary对象进行统计

python中的词频统计没有找到像hadoop那样的map-reduce方法,最后用for循环统计的,应该有改进的空间

3、找出公共词部分

因为是从百度旅游上抓的测试数据,因此会有一些公共词诸如:

“用户,登录,lvyou,百度,com,/,下载,http,2013Baidu,注册,baidu,©,,,】,日,我们,游记,【,旅游,必读,|,前,使用,攻略,联系,免费,自由,指南,目的地,画册,台湾,首页,美食,协议,”

这些词在之后的聚类中是没有意义的分量,所以感觉应该在做特征向量前清洗掉。这些公共词统计是采用抽样的方法做的,而不是把每一个页面文件都拿出来进行统计。采样先定义一个长度为N的随机数组,N就是要采样的样本数,然后在处理每个页面时,如果刚好是第i个页面,而且i属于随机数组中的数,那么就把这个页面中的单词加入到公共词的统计中。

基本上公共词统计就是取若干个集合的“交集”,不过这里不是严格意义上的要求某个单词在所有集合中都出现才算,只要满足出现在60%的页面中,就算是公共词了。这个筛选比例和采样数量N的不同组合也会有有不同的公共词提取效果。

当N=50,出现率为66.6%时,提取到的公共词为:

当N=100,出现率为66.6%时,提取到的公共词为:

所有的词都很容易想到为什么会成为公共词,但是为什么会有“台湾”这个词呢?不可能所有人的游记里面都提到“台湾”吧?现在回忆一下是因为当时在抓数据的时候百度旅游刚好在推一个台湾自由行的项目,所以的页面都有这个项目的广告链接。

如果我们放宽出现率的限制到50%时,会是什么效果呢?

当N=50,出现率为50%时,提取到的公共词为:

似乎变化不大。再放宽到15%呢?

当N=100,出现率为15%时(即在100个样本中,出现的次数在100*0.15次以上的词语),提取到的公共词为:

第一次运行:

第二次运行:

第三次运行:

可以看到还是有被错提取的词,那么再看一下它们的补集(即100个样本中,出现次数小于100*0.15次的词语),截取了一部分如下图

可以看到是很多具体的地名或者形容词。

备份一下代码(没有做代码的结构设计,只是在做算法验证)

 

# -*- coding: utf-8 -*-
import os
import collections
import random
from operator import itemgetter
import jieba
import jieba.analyse
from collections import Counter

sampleNumber = 100 #采集样本的个数
filterRate = 0.15 #字符的出现率(筛选率)
readpath = 'G:\DMProject\pages'
writepath = 'G:\DMProject\wordsVectors'
freqpath = 'G:\DMProject\\freq'
commonWords = {}    #公共词

def writeFile(fileName, content):
    wfile = open(fileName,'wb')
    wfile.write(content)
    wfile.close()

def getRandomList(n, range_start, range_end):
    rand_list = []
    count = 1;
    while count != n:
        temp = random.randrange(range_start,range_end,1)
        if temp not in rand_list:
            rand_list = rand_list + [temp]
        count = count + 1;
    return rand_list

filelist=os.listdir(readpath)

#获得随机序列,并排序
randlist = getRandomList(sampleNumber,1,len(filelist))
randlist.sort()
print randlist

index = 1
for item in filelist:
    #定义读写路径
    tempreadPath = readpath + "\\" + item
    tempwritePath = writepath + "\\" + item
    tempfreqPath = freqpath + "\\" + item

    #获得文本内容
    handler = open(tempreadPath,'r')
    content = handler.read()
    handler.close()

    #去掉文本中的空格、回车符
    cleanContent = "".join(content.split())

    #分词
    seg_list = jieba.cut(cleanContent)
    wordsList = (','.join(seg_list)).split(',')

    #以回车分隔各词并写入文件
    after = '\n'.join(seg_list).encode('utf-8')
    writeFile(tempwritePath,after)

    #统计词频并写入文件
    table = {}
    for word in wordsList:
        if table.has_key(word):
            table[word] = table[word] + 1
        else:
            table[word] = 1
    
    sorted_table = sorted(table.iteritems(), key=itemgetter(1),reverse = True)
    #打印词频
    freqContent = "";
    for key,value in sorted_table:
        freqContent +=  key.encode('utf-8')+ "," + str(value).encode('utf-8') + '\n'
    writeFile(tempfreqPath,freqContent)

    #若该文件刚好是被抽样到的文件,则进行公共词统计
    
    if index in randlist:
        for key,value in sorted_table:
            if commonWords.has_key(key):
                commonWords[key] = commonWords[key] + 1
            else:
                commonWords[key] = 1

    index += 1

commonWordsCache = []
sorted_commonWords = sorted(commonWords.iteritems(), key=itemgetter(1),reverse = True)
for word, count in sorted_commonWords:
    if count > sampleNumber*filterRate:
        commonWordsCache = commonWordsCache + [word]
commonWordsCache = ','.join(commonWordsCache).encode('utf-8')
print commonWordsCache

    
        
    
    
View Code

 

------ 2013.9.4 ----R中的中英文分词-----

有个分词的插件,叫snowball。直接在R的菜单栏上点击Packages-> install package(s),然后选择beijing,然后在列表里面找到snowball就可以了。

按完以后可以看到界面中的提示。

我们按照 @刘思喆 在Text Mining With R中的例子测试一下是否安装成功。

> library(Snowball)
> SnowballStemmer(c('functions', 'stemming', 'liked', 'doing'))
[1] "function" "stem"     "like"     "do"      
> 

可以看到snowball已经可以帮我们提取词干了。

现在我们来试试tokenizer:

> library(RWeka)
> NGramTokenizer('吃货 都是 热爱生活 的 好孩子')
 [1] "吃货 都是 热爱生活" "都是 热爱生活 的"   "热爱生活 的 好孩子"
 [4] "吃货 都是"          "都是 热爱生活"      "热爱生活 的"       
 [7] "的 好孩子"          "吃货"               "都是"              
[10] "热爱生活"           ""                 "好孩子"

如果我们不认为添加空格会是什么情况呢?

> NGramTokenizer('欢迎光临Elar的博客,今天是2013年9月4号')
character(0)

可以看到没有什么结果呢……

那如果想对普通的中文文本分词,可以使用一个叫Rwordseg的包。这个包是李健开发的中文分词工具。

在R中安装Rwordseg的指令为:

install.packages("Rwordseg", repos = "http://R-Forge.R-project.org")

安装好可见提示信息:

我们测试一下Rwordseg的分词功能:

> library(Rwordseg)
Loading required package: rJava
# Version: 0.0-5
> segmentCN('欢迎光临Elar的博客,今天是2013年9月4号,这里是中国陕西西安')
 [1] "欢迎"   "光临"   "elar"   ""     "博客"   "今天"   ""     "2013年"
 [9] "9月"    "4号"    "这里"   ""     "中国"   "陕西"   "西安"  
> 

现在中文分词也搞定了,我们来试试Text Mining吧。

安装tm包。

可以看到tm包还有mail和webmining插件,是不是用来挖掘邮件和网络内容的呢?以后探索。

先安装最基本的tm包,安装完成后的提示:

tm包中可以对动态语料库(语料库在内存中)和静态语料库(语料库在硬盘中)进行分析。静态语料库要用到一个叫filehash包的支持。

 

Reference:

1、刘思喆 《Text Mining With R

2、李健 《Rwordseg

3、苍梧 《机器学习中的相似性度量

posted @ 2013-09-04 21:04  elar  阅读(13509)  评论(0编辑  收藏  举报