首页 » 机器学习实战 » 机器学习实战全文在线阅读

《机器学习实战》12.4 示例:在Twitter源中发现一些共现词

关灯直达底部

我们会用到一个叫做python-twitter的Python库,其源代码可以在http://code.google.com/p/python-twitter/下载。正如你猜到的那样,借助它,我们可以使用Python来访问Twitter。Twitter.com实际上是一个和其他人进行交流的通道,其上发表的内容被限制在140个字符以内,发表的一条信息称为推文(tweet)。

有关Twitter API的文档可以在http://dev.twitter.com/doc找到。API文档与Python模块中的关键词并不完全一致。我推荐直接阅读Python文件twitter.py,以完全理解库的使用方法。有关该模块的安装可以参考附录A。虽然这里只会用到函数库的一小部分,但是使用API可以做更多事情,所以我鼓励读者去探索一下API的所有功能。

示例:发现Twitter源中的共现词 (co-occurring word)

  1. 收集数据:使用Python-twitter模块来访问推文。
  2. 准备数据:编写一个函数来去掉URL、去掉标点、转换成小写并从字符串中建立一个单词集合。
  3. 分析数据:在Python提示符下查看准备好的数据,确保它的正确性。
  4. 训练算法:使用本章前面开发的createTreemineTree函数执行FP-growth算法。
  5. 测试算法:这里不适用。
  6. 使用算法:本例中没有包含具体应用,可以考虑用于情感分析或者查询推荐领域。

在使用API之前,需要两个证书集合。第一个集合是consumer_key和consumer_secret,当注册开发app时(https://dev.twitter.com/apps/new),可以从Twitter开发服务网站获得。这些key对于要编写的app是特定的。第二个集合是access_token_key和access_token_secret,它们是针对特定Twitter用户的。为了获得这些key,需要查看Twitter-Python 安装包中的get_access_token.py文件(或者从Twitter开发网站中获得)。这是一个命令行的Python脚本,该脚本使用OAuth来告诉Twitter应用程序具有用户的权限来发布信息。一旦完成上述工作之后,可以将获得的值放入前面的代码中开始工作。对于给定的搜索词,下面要使用FP-growth算法来发现推文中的频繁单词集合。要提取尽可能多的推文(1400条)然后放到FP-growth算法中运行。将下面的代码添加到fpGrowth.py文件中。

程序清单12-6 访问Twitter Python库的代码

import twitterfrom time import sleepimport redef getLotsOfTweets(searchStr):    CONSUMER_KEY = /'get when you create an app/'    CONSUMER_SECRET = /'get when you create an app/'    ACCESS_TOKEN_KEY = /'get from Oauth, specific to a user/'       ACCESS_TOKEN_SECRET = /'get from Oauth, specific to a user/'    api = twitter.Api(consumer_key=CONSUMER_KEY,consumer_secret=CONSUMER_SECRET,access_token_key=ACCESS_TOKEN_KEY,access_token_secret=ACCESS_TOKEN_SECRET)    #you can get 1500 results 15 pages * 100 per page    resultsPages =     for i in range(1,15):        print /"fetching page %d/" % i        searchResults = api.GetSearch(searchStr, per_page=100, page=i)        resultsPages.append(searchResults)        sleep(6)    return resultsPages  

这里需要导入三个库,分别是twitter库、用于正则表达式的库,以及sleep函数。后面会使用正则表示式来帮助解析文本。

函数getLotsOfTweets处理认证然后创建一个空列表。搜索API可以一次获得100条推文。每100条推文作为一页,而Twitter允许一次访问14页。在完成搜索调用之后,有一个6秒钟的睡眠延迟,这样做是出于礼貌,避免过于频繁的访问请求。print语句用于表明程序仍在执行没有死掉。

下面来抓取一些推文,在Python提示符下输入:

>>> reload(fpGrowth)<module /'fpGrowth/' from /'fpGrowth.py/'>   

接下来要搜索一支名为RIMM的股票:

>>> lotsOtweets = fpGrowth.getLotsOfTweets(/'RIMM/')fetching page 1fetching page 2                          .                          .                          .    

lotsOtweets列表包含14个子列表,每个子列表有100条推文。可以输入下面的命令来查看推文的内容:

>>> lotsOtweets[0][4].textu/"RIM: Open The Network, Says ThinkEquity: In addition, RIMM needs toreinvent its image, not only demonstrating ... http://bit.ly/lvlV1U/"  

正如所看到的那样,有些人会在推文中放入URL。这样在解析时,结果就会比较乱。因此必须去掉URL,以便可以获得推文中的单词。下面程序清单中的一部分代码用来将推文解析成字符串列表,另一部分会在数据集上运行FP-growth算法。将下面的代码添加到 fpGrowth.py文件中。

程序清单12-7 文本解析及合成代码

def textParse(bigString):    urlsRemoved = re.sub(/'(http[s]?:[/][/]|www.)([a-z]|[A-Z]|[0-9]|[.]|[~])*/',/'/', bigString)    listOfTokens = re.split(r/'W*/', urlsRemoved)    return [tok.lower for tok in listOfTokens if len(tok) > 2]def mineTweets(tweetArr, minSup=5):    parsedList =     for i in range(14):        for j in range(100):            parsedList.append(textParse(tweetArr[i][j].text))    initSet = createInitSet(parsedList)    myFPtree, myHeaderTab = createTree(initSet, minSup)    myFreqList =     mineTree(myFPtree, myHeaderTab, minSup, set(), myFreqList)    return myFreqList  

上述程序清单中的第一个函数来自第4章,此外这里添加了一行代码用于去除URL。这里通过调用正则表达式模块来移除任何URL。程序清单12-7中的另一个函数mineTweets为每个推文调用textParse。最后,mineTweets函数将12.2节中用过的命令封装到一起,来构建FP树并对其进行挖掘。最后返回所有频繁项集组成的列表。

下面看看运行的效果:

>>> reload(fpGrowth)<module /'fpGrowth/' from /'fpGrowth.py/'>Let’s look for sets that occur more than 20 times:>>> listOfTerms = fpGrowth.mineTweets(lotsOtweets, 20)How many sets occurred in 20 or more of the documents?>>> len(listOfTerms)455  

我写这段代码的前一天,一家以RIMM股票代码进行交易的公司开了一次电话会议,会议并没有令投资人满意。该股开盘价相对前一天封盘价暴跌22%。下面看下上述情况是否在推文中体现:

>>> for t in listOfTerms:...     print tset([u/'rimm/', u/'day/'])set([u/'rimm/', u/'earnings/'])set([u/'pounding/', u/'value/'])set([u/'pounding/', u/'overnight/'])set([u/'pounding/', u/'drops/'])set([u/'pounding/', u/'shares/'])set([u/'pounding/', u/'are/'])                            .                            .                            .set([u/'overnight/'])set([u/'drops/', u/'overnight/'])set([u/'motion/', u/'drops/', u/'overnight/'])set([u/'motion/', u/'drops/', u/'overnight/', u/'value/'])set([u/'drops/', u/'overnight/', u/'research/'])set([u/'drops/', u/'overnight/', u/'value/', u/'research/'])set([u/'motion/', u/'drops/', u/'overnight/', u/'value/', u/'research/'])set([u/'motion/', u/'drops/', u/'overnight/', u/'research/'])set([u/'drops/', u/'overnight/', u/'value/'])    

尝试一些其他的minSupport值或者搜索词也是蛮有趣的。

我们还记得FP树的构建是通过每次应用一个实例的方式来完成的。这里假设已经获得了所有数据,所以刚才是直接遍历所有的数据来构建FP树的。实际上可以重写createTree函数,每次读入一个实例,并随着Twitter流的不断输入而不断增长树。FP-growth算法还有一个map-reduce版本的实现,它也很不错,可以扩展到多台机器上运行。Google使用该算法通过遍历大量文本来发现频繁共现词,其做法和我们刚才介绍的例子非常类似1。

1. H. Li, Y. Wang, D. Zhang, M. Zhang, E. Chang, “PFP: Parallel FP-Growth for Query Recommendation,” RecSys’08, Proceedings of the 2008 ACM Conference on Recommender Systems; http://infolab.stanford.edu/~echang/recsys08-69.pdf.