- 浏览: 1637662 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (405)
- C/C++ (16)
- Linux (60)
- Algorithm (41)
- ACM (8)
- Ruby (39)
- Ruby on Rails (6)
- FP (2)
- Java SE (39)
- Java EE (6)
- Spring (11)
- Hibernate (1)
- Struts (1)
- Ajax (5)
- php (2)
- Data/Web Mining (20)
- Search Engine (19)
- NLP (2)
- Machine Learning (23)
- R (0)
- Database (10)
- Data Structure (6)
- Design Pattern (16)
- Hadoop (2)
- Browser (0)
- Firefox plugin/XPCOM (8)
- Eclise development (5)
- Architecture (1)
- Server (1)
- Cache (6)
- Code Generation (3)
- Open Source Tool (5)
- Develope Tools (5)
- 读书笔记 (7)
- 备忘 (4)
- 情感 (4)
- Others (20)
- python (0)
最新评论
-
532870393:
请问下,这本书是基于Hadoop1还是Hadoop2?
Hadoop in Action简单笔记(一) -
dongbiying:
不懂呀。。
十大常用数据结构 -
bing_it:
...
使用Spring MVC HandlerExceptionResolver处理异常 -
一别梦心:
按照上面的执行,文件确实是更新了,但是还是找不到kernel, ...
virtualbox 4.08安装虚机Ubuntu11.04增强功能失败解决方法 -
dsjt:
楼主spring 什么版本,我的3.1 ,xml中配置 < ...
使用Spring MVC HandlerExceptionResolver处理异常
转载请标明出处:http://fuliang.iteye.com/blog/1122051
公司的蜘蛛抓取的内容一个记录是以TAB分割的各个字段的值,并且随着各种分类得分、正文静态得分策略的添加,版本不断的演变。每次做抽样、分析、分类语料等文本处理都需要写一些样板式的代码,并且得到wiki查找指定版本每个字段的位置。构建一个好的DSL来自动处理这件事情能够省去很多重复的操作,只需要关注要处理的事情即可。
我们想提供简单自然的API来做事情,我们常用的需求有:
1、每次版本变更几乎不需要修改代码、只需要添加配置文件,比如新版本增加一个
travel_confidence,我们不需要修改代码就可以使用:
2、可以自动的识别版本、并得到版本号:
3、按照次序给出各个字段的名字:
4、支持模糊查询字段的名字:
5、根据某个字段的模糊或者精确的值来在一个文件中查找记录
6、数字的字段我们需要支持根据大小关系来查找记录:比如gt(>)、ge(>=)
eq(=)、le(<=)、lt(<)
7、比较复杂的需求,我们可以写一些字段小过滤器,来找到需要的记录:
8.我们需要代码DRY。
我们下面看看如何完成这个功能,首先我们可以使用yaml来配置版本以及记录对应的字段:
以及是各个版本是数字字段的版本集合:
功能一:根据字段数来简单识别版本:
我们通过yaml来load版本配置:
我们根据配置文件动态的定义记录的字段,这样我们修改字段,不需要修改代码:
我们写一个CrawlerFile类来支持上面描述的一些功能:
在这个类中定义数字字段支持的关系操作符:
字段和版本的读取方法:
定义初始化方法:
实现define_help_method
支持字段的组合的查询:
关闭文件:
公司的蜘蛛抓取的内容一个记录是以TAB分割的各个字段的值,并且随着各种分类得分、正文静态得分策略的添加,版本不断的演变。每次做抽样、分析、分类语料等文本处理都需要写一些样板式的代码,并且得到wiki查找指定版本每个字段的位置。构建一个好的DSL来自动处理这件事情能够省去很多重复的操作,只需要关注要处理的事情即可。
我们想提供简单自然的API来做事情,我们常用的需求有:
1、每次版本变更几乎不需要修改代码、只需要添加配置文件,比如新版本增加一个
travel_confidence,我们不需要修改代码就可以使用:
crawler_file.find_by_travel_confidence(90) crawler_file.find_by_travel_confidence_gt(50) ...
2、可以自动的识别版本、并得到版本号:
crawler_file.version
3、按照次序给出各个字段的名字:
crawler_file.field_names
4、支持模糊查询字段的名字:
crawler_file.grep_fields(/url/)
5、根据某个字段的模糊或者精确的值来在一个文件中查找记录
#根据host来查找记录 crawler_file.find_by_host("www.9tour.cn") do |record| printf("%s\t%s\n", record.title, record.host) end #根据标题的字段来模糊查找 crawler_file.find_by_title_like(/线路/) do |record| puts record.title end
6、数字的字段我们需要支持根据大小关系来查找记录:比如gt(>)、ge(>=)
eq(=)、le(<=)、lt(<)
#content_confidence大于50的记录 crawler_file.find_by_content_confidence_gt(50) do |record| printf("%s\t%s\n", record.title, record.content_confidence) end
7、比较复杂的需求,我们可以写一些字段小过滤器,来找到需要的记录:
filter = lambda{|host,title| host == "www.9tour.cn" && title =~ /线路/} crawler_file.find_by_fields([:host,:title],filter) do |record| printf("%s\t%s\n", record.host,record.title) end
8.我们需要代码DRY。
我们下面看看如何完成这个功能,首先我们可以使用yaml来配置版本以及记录对应的字段:
v1: download_time: 0 host: 1 url: 2 url_md5: 3 parent_url_md5: 4 crawl_level: 5 loading_time: 6 anchor_text: 7 title: -4 keywords: -3 description: -2 content: -1 v2: download_time: 0 host: 1 url: 2 url_md5: 3 parent_url_md5: 4 crawl_level: 5 loading_time: 6 http_code: 7 content_confidence: 8 anchor_text: 9 title: -4 keywords: -3 description: -2 content: -1 ...#中间省略 v9: download_time: 0 host: 1 url: 2 url_md5: 3 parent_url_md5: 4 crawl_level: 5 publish_time: 6 http_code: 7 content_confidence: 8 list_confidence: 9 feeling_confidence: 10 travel_confidence: 11 qnc_cat: 12 qnc_chi: 13 qnc_zhu: 14 qnc_xing: 15 qnc_you: 16 qnc_gou: 17 qnc_le: 18 anchor_text: 19 raw_title: -10 title: -9 keywords: -8 description: -7 content: -6 lda_tag: -5 location_text: -4 location_confidence: -3 hotel_confidence: -2 gonglue_confidence: -1
以及是各个版本是数字字段的版本集合:
num_fields: - download_time - crawl_level - publish_time - content_confidence - list_confidence - feeling_confidence - travel_confidence - hotel_confidence - gonglue_confidence
功能一:根据字段数来简单识别版本:
class VersionDetector @@field_num_version_map = { 12 => 1, 14 => 2, 15 => 3, 24 => 4, 25 => 5, 16 => 6, 26 => 7, 27 => 8, 30 => 9 }; class << self def detect(file) version = -1 if file.is_a?(String) then line = File.open(file) do |file| file.gets end version = @@field_num_version_map[line.split(/\t/).size] elsif file.is_a?(File) then before_pos = file.pos file.seek(0) line = file.gets version = @@field_num_version_map[line.split(/\t/).size] file.seek(before_pos) else raise ArgumentError.new 'Argument type: #{file.class} is error, must be a String or File type' end raise Exception.new 'Unkown version file format' if version.nil? return version end end end
我们通过yaml来load版本配置:
require 'yaml' class FieldConfig attr_reader :fields_map, :num_fields def initialize(version) config = YAML.load_file 'conf.yml' @fields_map = config["v#{version}"] @num_fields = config["num_fields"] end end
我们根据配置文件动态的定义记录的字段,这样我们修改字段,不需要修改代码:
class CrawlerRecord def self.config(field_config) @@field_config = field_config attr_reader *(field_config.fields_map.keys) #动态定义字段的读方法 end def initialize(raw_line) @raw_line = raw_line fields = raw_line.split(/\t/) @@field_config.fields_map.each do |key,value|#动态设置各个字段的值 instance_variable_set("@" + key.to_s,fields[value]) end end def raw @raw_line end end
我们写一个CrawlerFile类来支持上面描述的一些功能:
class CrawlerFile end
在这个类中定义数字字段支持的关系操作符:
@@num_fields_op = { :gt => ">", :lt => "<", :eq => "=", :ge => ">=", :le => "<=" };
字段和版本的读取方法:
attr_reader :field_names, :version
定义初始化方法:
def initialize(path) @file = File.new(path) #对应的文件 @version = VersionDetector.detect(@file) #得到版本信息 @@field_config = FieldConfig.new(@version) #得到该版本的配置 @field_names = @@field_config.fields_map.keys #根据配置文件得到字段名字 CrawlerRecord.config(@@field_config) #配置CrawlerRecord动态生成字段读方法 define_help_method #定义帮助方法,来完成上面列举的其他功能 end
实现define_help_method
def define_help_method CrawlerFile.class_eval do #根据配置文件动态定义按照一个字段模糊查找方法find_by_xxx_like @@field_config.fields_map.keys.each do |field| define_method :"find_by_#{field}_like" do |regex,&block| if block.nil? then lines = [] @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) lines << line if line.send(field) =~ regex end lines else @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) block.call(line) if line.send(field) =~ regex end end @file.seek(0) end #根据配置文件动态定义按照一个字段模糊查找方法find_by_xxx define_method :"find_by_#{field}" do |value,&block| if block.nil? then lines = [] @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) lines << line if line.send(field) == value end lines else @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) block.call(line) if line.send(field) == value end end @file.seek(0) end end #为所有的数字字段动态定义按照大小关系查找的方法: @@field_config.num_fields.each do |field| next if not @@field_config.fields_map[field] @@num_fields_op.keys.each do |op| define_method :"find_by_#{field}_#{op.to_s}" do |value,&block| op_val = @@num_fields_op[op] if block.nil? then lines = [] @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) field_val = line.send(field) lines << line if eval("#{field_val} #{op_val} #{value}") end lines else @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) field_val = line.send(field) block.call(line) if eval("#{field_val.to_i} #{op_val} #{value}") end end @file.seek(0) end end end end end
支持字段的组合的查询:
def find_by_fields(fields,cond_checker) if block_given? then @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) yield line if cond_checker.call(*fields.collect{|field| line.send(field) }) end else lines = [] @file.each_line do |line| line = CrawlerRecord.new(raw_line) lines << line if cond_checker.call(*fields.collect{|field| line.send(field)}) end lines end @file.seek(0) end
关闭文件:
def close @file.close end
发表评论
-
[zz]推荐系统-从入门到精通
2013-04-20 14:38 2447为了方便大家从理论到实践,从入门到精通,循序渐进系统地理解和掌 ... -
机器学习在公司的分享
2013-02-23 12:38 2859机器学习在公司的分享,ppt见附件,主要简单介绍了机器学习: ... -
Deep learning的一些教程[rz]
2013-02-03 19:14 27050转载自http://baojie.o ... -
[ZZ]计算机视觉、模式识别、机器学习常用牛人主页链接
2012-11-30 13:13 12130牛人主页(主页有很多论文代码) Serge ... -
Deep learning的一些有用链接
2012-11-12 19:09 3457deeplearning tutorials: http:// ... -
信息论学习总结(二)最大熵模型
2012-06-04 08:13 0显然,如果A表示可能的类别,B表示可能的上下文,p应该最大化熵 ... -
信息论学习总结(一)基础知识
2012-06-02 22:57 4359我们考虑一下一个离散的随机变量x,当我们观察到它的一个值,能给 ... -
loss function
2012-05-11 22:54 2546几种损失函数: 对于回归问题: 平方损失: 绝对值损失: −i ... -
Large-Scale Support Vector Machines: Algorithms and Theory
2012-04-12 00:32 0支持向量机是一种流行 ... -
使用SGD(Stochastic Gradient Descent)进行大规模机器学习
2012-05-11 23:01 44012使用SGD(Stocha ... -
松本行弘的程序世界
2011-10-02 16:49 1352全书涉及到程序设计的方方面面,买这边书的目的希望能看到看看Ru ... -
Ruby HTTP/HTML parser相关资源
2011-09-28 12:04 1800Net::HTTP: http://ruby-doc.org ... -
命令行词典
2011-09-27 14:50 1984经常要查单词,所以利用qq dict api写了一个命令行词典 ... -
构建自己的DSL之三 抓取文件管理
2011-07-18 23:26 1706转载请标明出处:http://fuliang.iteye.co ... -
构建自己的DSL之一 Simple Crawler
2011-07-11 22:08 2962转载请标明出处:http://fuliang.iteye.co ... -
paper and book阅读
2011-06-28 23:19 2606我微博每周读论 ... -
轻松删除所有安装的gem
2011-06-13 12:28 7936删除安装所有的gem: gem list | cut -d ... -
模式识别和机器学习 笔记 第四章 线性分类模型(二)
2011-05-29 23:13 04.3 概率判别模型 对于两类的分类问题,我们已经看到c1的后 ... -
模式识别和机器学习 笔记 第四章 线性分类模型(一)
2011-05-26 23:36 9795转载请标明出处: http:/ ... -
模式识别和机器学习 第六章 核方法
2011-05-11 23:55 0在第3,4章,我们已经考虑了回归和分类的线性参数模型,参数向量 ...
相关推荐
TXT文本替换和转换成DSL文件,,DSL可直接用Abbyy_DLScompiler编译
802D sl 8080报警处理,当西门子802Dsl出现8080报警可以按照文档进行处理
在这篇资源中,我们将详细介绍如何使用DSL来构建复杂的查询语句,以满足各种搜索需求。首先,我们将学习DSL的基本结构和语法规则,包括查询、过滤器、聚合和排序等核心概念。通过深入了解DSL的语法,您将能够灵活地...
840Dsl建立第二编码器[汇编].pdf
使用Groovy可以快速灵活完成文本处理,数据库访问,XML处理等常见任务。研究表明,使用Groovy比使用Java写程序,代码量少3-10倍。 DSL是新一代基于领域设计专用语言。由于Groovy的超级灵活性,你可以使用Groovy快速...
描述了基于840Dsl的二次开发技术,并且使用c++对数控系统进行开发。
job-dsl-gradle-example, 使用Gradle构建和测试的作业DSL项目示例 工作 DSL Gradle示例使用Gradle构建和测试的作业 DSL 项目示例。 签出这里演示文稿这里示例的演练。文件结构.├── src│ ├── jobs # DSL ...
用于构建自定义DSL。 设置 $ npm install --save linear-dsl 用法 解析自定义DSL查询。 const dsl = require ( 'linear-dsl' ) ; let data = dsl . parse ( 'a(foo) AND b(2 bars) OR c(4)' ) ; 验证查询映射。 ...
本文档详细的讲解了LSM6DSL的详细配置,其中讲解了数据的读取,唤醒模式,计步功能等。
840D用户报警文本的制作
anko-example, 使用 Anko DSL构建的小型应用程序 Anko示例项目这个 repo 中的代码展示了如何在 Android Gradle项目中设置 Anko 库。 应用程序非常简单,但是它显示了一些重要的Anko 。 在 Android Studio 中使用这个...
赠送jar包:dsl-1.2.7.jar; 赠送原API文档:dsl-1.2.7-javadoc.jar; 赠送源代码:dsl-1.2.7-sources.jar; 赠送Maven依赖信息文件:dsl-1.2.7.pom; 包含翻译后的API文档:dsl-1.2.7-javadoc-API文档-中文(简体)版...
本篇是哥自己根据《Gradle In Action》翻译的,继哥之前的Groovy DSL...通过gradle这个在项目构建领域的特定DSL,理解如何使用gradle来构建项目,以及更深入的理解前传中讲解的DSL体系。希望本书能给小伙伴们带来帮助。
Jbuilder - 通过一个构建式DSL创建JSON结构
缠绕在Nokogiri DSL,由Nokogiri用于网络抓取。 安装 将此行添加到您的应用程序的Gemfile中: gem 'buzzsaw' 然后执行: $ bundle 或将其自己安装为: $ gem install buzzsaw 用法 Stretch.io用于DSL的就是这...
DSL工程示范站,DSL图片规划,标准化施工
ST原厂LSM6DSL I2C总线驱动 In the 'driver' folder there are the driver files of Mems Sensor (.h and .c) to be included in your project. Driver documentation can be generate using Doxigen tool. The ...
西门子系统840d报警文本的制作!doc的文本,希望对你有用!
针对宽带DSL接入方式下的运营维护的难题,结合开发工作,介绍在DsL接入方式下自动测试的解决方案,对其中的技术要点做重点讨论。
Build RecyclerView With DSL > Let's talk about how to use DSL in RecyclerView, this framework has been widely used in my project. It could help you build RecyclerView List in DSL Style like Anko ...