<?xml version="1.0" encoding="gb2312"?>

<!-- RSS generated by oioj.net on 4/16/2004 ; 感谢LeXRus提供 RSS 2.0 文档; 此文件可自由使用，但请保留此行信息 --> 
<!-- Source download URL: http://blogger.org.cn/blog/rss2.asp       -->
<rss version="2.0">

<channel>
<title>宿命宽恕轮回修仙</title>
<link>http://blogger.org.cn/blog/blog.asp?name=reincarnation</link>
<description>宿命宽恕轮回修仙的博客</description>
<copyright>blogger.org.cn</copyright>
<generator>W3CHINA Blog</generator>
<webMaster>webmaster@blogger.org.cn</webMaster>
<item>
<title><![CDATA[主机屋很不错的]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=50543</link>
<author>reincarnation</author>
<pubDate>2010/11/16 19:39:27</pubDate>
<description><![CDATA[<a>用主机屋建自己的网站挺不错的，永久免费。</a>]]></description>
</item><item>
<title><![CDATA[（转）网页设计者和开发人员常用的Firefox插件]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=47192</link>
<author>reincarnation</author>
<pubDate>2009/10/8 9:51:46</pubDate>
<description><![CDATA[Dejan Cancarevic是一名优秀的网页设计者和开发人员，下面他精选了30个他经常使用的Firefox插件，这些插件都能很好的帮助网页设计者和开发人员，简化工作量，或是增加设计应用功能等等。<br><br>1. CSSMate - 在线的CSS编辑器扩展插件<br><br>2. ViewSourceWith - 让你查看页面资源的Firefox扩展应用<br><br>3. PicLens - 变换你的浏览器为一个三维的浏览环境来查看网页图片的Firefox扩展插件<br><br>4. FireShot -强大的网页截图/截屏插件<br><br>5. SeoQuake - 搜索引擎优化和网站推广插件<br><br>6. Font Finder -简单的高亮一个事件并且左键点击弹出菜单可以查看CSS样式<br><br>7. Live HTTP Headers - 在浏览网页的同时查看一个页面的HTTP头部信息<br><br>8. Modify Headers - 允许你添加、修改或过滤http头部请求信息的Firefox扩展插件<br><br>9. CSSViewer -一个简单实用的扩张，可以让你查看当前网页中任何部分的CSS代码<br><br>10. EditCSS - 只需要右键点击就可以在浏览器的侧边栏中查看和编辑样式表代码<br><br>11. Firebug - 查看，编辑和跟踪 网页上面的CSS, HTML和Javascript的Firefox插件<br><br>12. View Formatted Source -为网页上的每一个元素格式化并使用不同的颜色高亮显示<br><br>13. Professor X -让你不看源代码就能看到页面头部信息的Firefox插件<br><br>14. CSS validator - 一键检查当前网页是否符合W3C CSS 标准的验证器插件<br><br>15. Validaty -提供给你一个类似于validator.w3.org的校验器按钮<br><br>16. Html Validator - 添加HTML校验器<br><br>17. Copy as HTML Link -给选中的文本创建一个当前页面的HTML链接<br><br>18. TableTools - 过滤、排序 HTML表格等的Firefox扩展插件<br><br>19. CHM Reader - 让Firefox支持HTML编译文件的Firefox扩展插件<br><br>20. PageDiff - 帮助网页设计者和开发人员在不同的网页之前查看页面源代码<br><br>21. Clipmarks - 让你保存当前页面中的任何元素的Firefox插件<br><br>22. SourceEditor - 查看和编辑HTML元素代码的Firefox扩展插件<br><br>23. Total Validator -使用官方DTDs提供一个真正的HTML检查器的Firefox扩展插件<br><br>24. LinkChecker - 检查任何网页上面的有效链接的Firefox扩展插件<br><br>25. Web Developer - 添加一个菜单和工具栏，包含各种网页开发工具的Firefox扩展插件<br><br>26. Style Sheet Chooser II - 让你选择网站作者为网站提供的候补风格的Firefox扩展插件<br><br>27. View Dependencies -显示网页上面所有被装载的元素信息的Firefox扩展插件<br><br>28. Accessibar - 可以轻松地操纵网页显示和文本语音输出的Firefox扩展插件<br><br>29. Aardvark - 用来清楚网页的冗余信息和打印网页等功能的Firefox扩展插件<br><br>30. JSview - 添加能够查看外部档案源代码的功能<br><br><br><br>------------------------------------------<br><p><strong>1.</strong><a target="_blank" href="http://www.joehewitt.com/software/firebug/"><strong>FireBug</strong></a></p>
<p>Firebug是测试Javascript,查看CSS和HTML的绝佳工具.你可以在修改代码后立即测试页面的变化.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/firebug.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/firebug-thumb.png" alt="firebug" height="171" width="450"></a></p>
<p><a target="_blank" href="http://www.getfirebug.com/releases/firebug1.0-current.xpi">点击下载</a>&nbsp;&nbsp;</p>
<p><strong>2.</strong><a href="http://chrispederick.com/work/webdeveloper/"><strong>Web Developer Extension</strong></a></p>
<p>这个扩展是我最早听说也是最常用的一个网页设计扩展,当时修改模板的时候起了很大作用.它几乎囊括了网页设计的所有元素,主要作用在于监测和查看代码.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/web-developer.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/web-developer-thumb.png" alt="Web_developer" height="25" width="345"></a></p>
<p><a target="_blank" href="http://downloads.chrispederick.com/work/web-developer/web-developer.xpi">点击下载</a></p>
<p><strong>3.</strong><a href="http://www.karmatics.com/aardvark/"><strong>Aardvark Extension</strong></a></p>
<p>这个轻量级扩展可以简单地显示网页元素的Class和ID,当你只想快速获得某个元素的信息时非常有用,你还可以通过它移除网页上的元素.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/aardvark.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/aardvark-thumb.png" alt="Aardvark" height="55" width="225"></a></p>
<p><a target="_blank" href="http://karmatics.com/aardvark/aardvark.xpi">点击下载</a></p>
<p><strong>4.</strong><a href="http://www.iosart.com/firefox/colorzilla/index.html"><strong>Colorzilla</strong></a><strong> </strong></p>
<p>直接从网页上获取色彩代码和RGB信息,相当于图像编辑软件里的拾色器.</p>
<p><strong><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/colorzilla.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/colorzilla-thumb.png" alt="colorzilla" height="64" width="390"></a> </strong></p>
<p><a target="_blank" href="http://www.iosart.com/firefox/colorzilla/ColorZilla_1.0.xpi">点击下载</a></p>
<p><strong>5.</strong><a href="https://addons.mozilla.org/en-US/firefox/addon/394"><strong>View Source With</strong></a></p>
<p>使用多种外部软件查看网页代码.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/view-source-with.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/view-source-with-thumb.png" alt="View_source_with" height="120" width="385"></a></p>
<p><a target="_blank" href="https://addons.mozilla.org/en-US/firefox/downloads/file/15007/viewsourcewith-0.0.9-fx+mz+tb+nvu+ns+sm+fl.xpi">点击下载</a></p>
<p><strong>6.</strong><a href="http://users.skynet.be/mgueury/mozilla/"><strong>HTML Validator</strong></a></p>
<p>快速验证HTML代码的合法性.</p>
<p><a target="_blank" href="http://htmlvalidator.sourceforge.net/mozilla/tidy_firefox_win_0840.xpi">Windows平台下载</a></p>
<p><a target="_blank" href="http://htmlvalidator.sourceforge.net/mozilla/tidy_firefox_linux_0840.xpi">Linux平台下载</a></p>
<p><strong>7.</strong><a href="http://www.kevinfreitas.net/extensions/measureit/"><strong>Measure It</strong></a></p>
<p>距离测量工具.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/meanure.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/meanure-thumb.png" alt="meanure" height="75" width="370"></a></p>
<p><a target="_blank" href="http://www.kevinfreitas.net/extensions/measureit/measureit.xpi">点击下载</a></p>
<p><strong>8.</strong><a href="http://ieview.mozdev.org/"><strong>IE View</strong></a><strong>&nbsp;/ </strong><a href="https://addons.mozilla.org/extensions/moreinfo.php?id=1419"><strong>IE Tab</strong></a><strong>&nbsp;/ </strong><a href="https://addons.mozilla.org/en-US/firefox/addon/1190"><strong>OperaView</strong></a><strong>&nbsp;/ </strong><a href="https://addons.mozilla.org/en-US/firefox/addon/223"><strong>FirefoxView</strong></a><strong>&nbsp;/ </strong><a href="https://addons.mozilla.org/en-US/firefox/addon/4641"><strong>Safari View</strong></a><strong>&nbsp;/ </strong><a href="https://addons.mozilla.org/en-US/firefox/addon/1429"><strong>IE View Lite</strong></a></p>
<p>在Firefox中调用其他浏览器渲染网页.测试网页的兼容性时很有用.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/ietab.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/ietab-thumb.png" alt="ietab" height="110" width="220"></a></p>
<p><strong>9.</strong><a href="https://addons.mozilla.org/extensions/moreinfo.php?id=1801&amp;application=firefox"><strong>Clear Cache Button</strong></a></p>
<p>清除网页缓存,检查CSS更改时非常有用.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/cleancache.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/cleancache-thumb.png" alt="cleancache" height="65" width="110"></a></p>
<p><a target="_blank" href="https://addons.mozilla.org/en-US/firefox/downloads/file/7326/clear_cache_button-0.5-fx.xpi">点击下载</a></p>
<p><strong>10.</strong><a href="https://addons.mozilla.org/en-US/firefox/addon/1249"><strong>Restart Firefox</strong></a><strong> </strong></p>
<p>在不损坏当前标签和进程的情况下重启Firefox.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/restart-firefox.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/restart-firefox-thumb.png" alt="restart_firefox" height="95" width="210"></a></p>
<p><a target="_blank" href="https://addons.mozilla.org/en-US/firefox/downloads/file/5525/restart_firefox-0.3-fx.xpi">点击下载</a></p>
<p><strong>11.</strong><a href="https://addons.mozilla.org/en-US/firefox/addon/1122"><strong>Tab Mix Plus</strong></a></p>
<p>尽管这是一个常规扩展,但是复制标签和复制标签链接功能对网页设计很有作用.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/tabmix.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/tabmix-thumb.png" alt="tabmix"></a></p>
<p><a target="_blank" href="https://addons.mozilla.org/en-US/firefox/downloads/file/16566/tab_mix_plus-0.3.6-fx.xpi">点击下载</a></p>
<p><strong>12.</strong><a href="http://developer.yahoo.com/yslow/"><strong>YSlow</strong></a></p>
<p>Yslow是雅虎新近出品的一个网页分析工具.它能够给你提供网页错误信息以及网页优化建议.必须安装Firebug后才能使用该扩展.</p>
<p><a atomicselection="true" href="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/yslow.png"><img src="http://www.digglife.cn/wp-content/uploads/3/379/2007/08/yslow-thumb.png" alt="yslow" height="360" width="450"></a></p><br><br><br>--------------------------------------------<br><br>Firefox是一款越来越热的Web浏览器,多种多样的扩展,主题,插件,是它快速流行的重要原因.
Mozilla的网站上提供了许多扩展和插件的下载,由于众多开发者的支持,这些扩展和插件的数量也在随着需求日益增长,下面列举13款比较优秀的可以辅
助Web Designer工作的扩展.其实下面许多扩展大家都是知道的，大部分现在都升级至支持firefox3，下面简单总结一下。
		<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/1419">1、IE Tab</a></strong> <br>
<img alt="" src="http://lh5.ggpht.com/Sonny.zhang87/SNhdIktG_zI/AAAAAAAACG4/Dp9M5HYrKdc/s800/1.jpg"><br>
<br>
浏览器兼容是所有Web开发者都要考虑的问题,IE Tab能够让您再Firefox中以IE的渲染方式来呈现页面,并且可以方便的在两者之间切换。<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/1386"><br>
2、Style Sheet Chooser II</a></strong> <br>
<img alt="" src="http://lh4.ggpht.com/Sonny.zhang87/SNhdIpBlgzI/AAAAAAAACHA/5F5Jpi4T31Y/s800/2.jpg"><br>
<br>
Style Sheet Chooser II
允许浏览者或开发者迅速的在为同一页面编写的不同样式之间来回的切换,甚至能够保证被选择样式应用到该站点的全部页面上. Style Sheet
Chooser II 会覆盖Firefox内置的样式表切换器[style-sheet-switcher].<br>
<br>
你可以用多种方式来调用它:<br>
a. 通过"查看"[View]-&gt;"页面样式"[Page Style]下面的选项;<br>
b. 通过工具栏[Toolbar]的一键切换;<br>
c. 通过状态栏[Status Bar]的图标按钮;<br>
<br>
小提示: 是否在状态栏和工具栏中显示图标,可以在<a href="http://www.jianbitou.com/post/13-amazing-firefox-add-ons-to-make-designers-lives-easier.html">扩展</a>偏好[Extension Preference]中设置<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/2104"><br>
3、CSSViewer</a></strong> <br>
<a href="http://www.jianbitou.com/post/13-amazing-firefox-add-ons-to-make-designers-lives-easier.html"><img alt="" rel="lightbox[212]" src="http://lh5.ggpht.com/Sonny.zhang87/SNhdIp66ZZI/AAAAAAAACHI/MnFjkrfxG80/s800/3.jpg"></a><br>
<br>
一款小巧的CSS(<a href="http://www.jianbitou.com/post/7cssresources.html">7个最好的网上CSS资源</a>，<a href="http://www.jianbitou.com/post/20_websites-learn-master-css.html">20个优秀网站助你征服CSS</a>)属性查看器,随着鼠标的移动显示当前所指示元素的CSS样式信息,其中包括了所有从父级元素继承而来,用户自定义以及浏览器自定义的样式信息. 同Style Sheet Chooser II 一样,你也可以通过在工具栏添加该扩展的图标按钮来激活/禁用该扩展。<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/2289"><br>
4、CSS validator</a></strong> <br>
<img alt="" src="http://lh4.ggpht.com/Sonny.zhang87/SNhdIyTYlgI/AAAAAAAACHQ/j0zjv0EuAPs/s800/4.jpg"><br>
<br>
用W3C的CSS标准来校检页面,在新页面中显示校检结果,不过只对包含了CSS样式文件的页面起作用,例如<a href="http://www.w3.org/">http://www.w3.org/</a><br>
其快捷按钮既可添加在右键菜单中也可添在工具栏上,<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/271"><br>
5、ColorZilla 2.0</a></strong> <br>
<a href="http://www.jianbitou.com/post/13-amazing-firefox-add-ons-to-make-designers-lives-easier.html"><img alt="" rel="lightbox[212]" src="http://lh3.ggpht.com/Sonny.zhang87/SNhdJKYKqZI/AAAAAAAACHY/0ge2TVO_OV0/s800/5.jpg"></a><br>
<br>
ColorZilla的主要功能有:<br>
将浏览器页面内的任何一点转换为16进制的颜色字符串,方便您快速的将其粘贴到其他的CSS样式中;<br>
通过缩放页面来测量其上任何两点之间的距离;<br>
从内置的调色板中选择预置的颜色,并把最常使用的颜色添加到自定义的调色板中;<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/5648"><br>
6、FireShot 0.59</a></strong> <br>
<img alt="" src="http://lh6.ggpht.com/Sonny.zhang87/SNhdh6tGRvI/AAAAAAAACHg/N6RWhGNqbx0/s800/6.jpg"><br>
<br>
FireShot能够方便的创建页面的截图[略缩图],相比于其他的扩展,FireShot提供了一系列的编辑和注释工具,方便你快速的修改所捕获
图像或者添加文本,图像注释. 这些功能对于网页设计者,测试者,和浏览者都很有用,
此外用户还可以自己定制所要捕获的范围,是页面全部还是屏幕的可见部分<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/532"><br>
7、LinkChecker 0.6.3 </a></strong> <br>
<a href="http://www.jianbitou.com/post/13-amazing-firefox-add-ons-to-make-designers-lives-easier.html"><img alt="" rel="lightbox[212]" src="http://lh4.ggpht.com/Sonny.zhang87/SNhdiKQP2hI/AAAAAAAACHo/YFQ4NQz7QGs/s800/7.jpg"></a><br>
<br>
LinkChecker用于检查页面上超级连接的有效性,验证其是否已经损坏<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/4415"><br>
8、Font Finder 0.5c</a></strong> <br>
<img alt="" src="http://lh4.ggpht.com/Sonny.zhang87/SNhdiOyrS1I/AAAAAAAACHw/dHKlCs6u_SE/s800/8.jpg"><br>
<br>
选择一段文本或一个元素,单击右键并在菜单中选择"Font Finder",就能看到所选取对象的字体信息<br>
<strong><a href="http://livehttpheaders.mozdev.org/index.html"><br>
9、LiveHTTPHeaders</a></strong> <br>
<img alt="" src="http://lh5.ggpht.com/Sonny.zhang87/SNhdiXSn7sI/AAAAAAAACH4/YmEaGpY37oY/s800/9.jpg"><br>
<br>
这个项目的目的是通过以下两种途径实时显示页面的HTTP请求信息:<br>
a. 在"查看页面信息"[View Page Info]中添加"头部信息"[Hearders]选项卡;<br>
b. 添加"工具"-&gt;"Web设计"[Tools-&gt;Web Development]菜单项;<br>
此外用户还能利用它修改HTTP Headers并发起新请求!<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/321"><br>
10、SearchStatus 1.26</a></strong> <br>
<img alt="" src="http://lh6.ggpht.com/Sonny.zhang87/SNhdiXN8cII/AAAAAAAACIA/HOH3fVvnDfI/s800/10.jpg"><br>
<br>
再你的浏览器中显示Google的PageRank,Alexa排名,竞争力排名,高速关键字密度分析器,关键字高亮显示,后退/相关链接,Alexa的信息和其他的[SEO]搜索引擎优化工具.<br>
<strong><a href="http://fireftp.mozdev.org/"><br>
11、FireFTP</a></strong> <br>
<a href="http://www.jianbitou.com/post/13-amazing-firefox-add-ons-to-make-designers-lives-easier.html"><img alt="" rel="lightbox[212]" src="http://lh5.ggpht.com/Sonny.zhang87/SNhd0bbbG3I/AAAAAAAACII/_UDvd9YQ2OU/s800/11.jpg"></a><br>
<br>
FireFTP,一款免费,高效,跨平台的FTP客户端,让你快速直观的访问FTP Server<br>
<strong><a href="http://www.kevinfreitas.net/extensions/measureit/"><strong><br>
12、MeasureIt 0.3.8</strong></a></strong> <br>
<img alt="" src="http://lh5.ggpht.com/Sonny.zhang87/SNhd0fYLtLI/AAAAAAAACIQ/kfhBsdvmGTk/s800/12.jpg"><br>
<br>
通过可以绘制在页面任何地方的刻度尺来显示以像素(px)计算的宽度,高度,元素缩进量<br>
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/249"><br>
13、Html Validator 0.8.5.2 </a></strong> <br>
<img alt="" src="http://lh3.ggpht.com/Sonny.zhang87/SNhd0nJYxpI/AAAAAAAACIY/G_QUGODOkk8/s800/13.jpg"><br>
<br>
<br>
&nbsp; HTML Validator,一款为Mozilla和Firefox添加HTML验证的扩展,能够在状态栏的图标上标注当前页面的HTML语法错误数量,不仅会校检服务器发送来的HTML文件,也会校检内存中的HTML代码(通常为执行Ajax请求后的返回值)。<br>]]></description>
</item><item>
<title><![CDATA[（转）CSS hack:区分IE6，IE7，firefox]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=47190</link>
<author>reincarnation</author>
<pubDate>2009/10/7 18:58:41</pubDate>
<description><![CDATA[<P><STRONG>区别IE6与FF：</STRONG></P>
<P>background:<SPAN class=orange>orange</SPAN>;<SPAN class=red>*</SPAN>background:<SPAN class=blue>blue</SPAN>;</P>
<P><STRONG>区别<SPAN class=blue>IE6</SPAN>与<SPAN class=green>IE7</SPAN>：</STRONG></P>
<P>background:<SPAN class=green>green</SPAN>&nbsp;<SPAN class=red>!important</SPAN>;background:<SPAN class=blue>blue</SPAN>;</P>
<P><STRONG>区别<SPAN class=green>IE7</SPAN>与<SPAN class=orange>FF</SPAN>：</STRONG></P>
<P>background:<SPAN class=orange>orange</SPAN>;&nbsp;<SPAN class=red>*</SPAN>background:<SPAN class=green>green</SPAN>;</P>
<P><STRONG>区别<SPAN class=orange>FF</SPAN>，<SPAN class=green>IE7</SPAN>，<SPAN class=blue>IE6</SPAN>：</STRONG></P>
<P>background:<SPAN class=orange>orange</SPAN>;<SPAN class=red>*</SPAN>background:<SPAN class=green>green</SPAN>&nbsp;<SPAN class=red>!important</SPAN>;*background:<SPAN class=blue>blue</SPAN>;</P>
<P>注：IE都能识别*;标准浏览器(如FF)不能识别*；</P>
<P><STRONG>IE6能识别*，但不能识别 !important,</STRONG></P>
<P><STRONG>IE7能识别*，也能识别!important;</STRONG></P>
<P><STRONG>FF不能识别*，但能识别!important;</STRONG></P>
<TABLE class=hack style="WIDTH: 555px; HEIGHT: 74px" cellSpacing=1 cellPadding=0 border=0>
<TBODY>
<TR>
<TD><BR>&nbsp;</TD>
<TD>IE6</TD>
<TD>IE7</TD>
<TD>FF</TD></TR>
<TR>
<TD>*</TD>
<TD>√</TD>
<TD>√</TD>
<TD>×</TD></TR>
<TR>
<TD>!important</TD>
<TD>×</TD>
<TD>√</TD>
<TD>√</TD></TR></TBODY></TABLE>
<P>
<HR>

<P></P>
<P>另外再补充一个，下划线"<SPAN class=red>_</SPAN>",<BR>IE6支持下划线，IE7和firefox均不支持下划线。<BR><BR>于是大家还可以这样来区分<SPAN class=blue>IE6</SPAN>，<SPAN class=green>IE7</SPAN>，<SPAN class=orange>firefox</SPAN><BR>: background:<SPAN class=orange>orange</SPAN>;<SPAN class=red>*</SPAN>background:<SPAN class=green>green</SPAN>;<SPAN class=red>_</SPAN>background:<SPAN class=blue>blue</SPAN>; <BR></P>]]></description>
</item><item>
<title><![CDATA[（转）利用Weka实现文本分类]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45833</link>
<author>reincarnation</author>
<pubDate>2009/6/5 23:14:09</pubDate>
<description><![CDATA[
<P><SPAN style="FONT-SIZE: 10pt">来源：<A href="http://www.w3china.org/blog/more.asp?name=DMman&amp;id=25987">http://www.w3china.org/blog/more.asp?name=DMman&amp;id=25987</A></SPAN></P><SPAN style="FONT-SIZE: 10pt"></SPAN><SPAN style="FONT-SIZE: 10pt">
<P>1 介绍：嵌入式机器学习，在自己的算法中调用Weka现文本分类,是一个小的数据挖掘程序，虽然实用价值不是很大，但对于Weka的理解和使用是有帮助的。本例子来自《数据挖掘：实用机器学习技术》第2版（好像是倒数第三章）。大家可以到<A href="http://blogger.org.cn/blog/message.asp?name=DMman#23691">http://blogger.org.cn/blog/message.asp?name=DMman#23691</A> 下载该书察看对算法的详细解释。算法中作了详细的注释，虽然是英文的，但还是比较简单。下面对例子的使用作了浅显的介绍，有兴趣的朋友可以研究。</P>
<P>2 功能：使用weka中的j48分类器实现了文本分类的一个小程序。文本文件通过weka的过滤器StringToWordVector预处理。</P>
<P>3 注意：把weka.jar加入你的classpath中，才可以通过编译。</P>
<P>4 使用方法：<BR>命令行参数：<BR>&nbsp;-t 文本文件路径<BR>&nbsp;-m 你的模型文件路径<BR>&nbsp;-c 可选，类别（hit 或 miss）<BR>如果提供了-c则用于训练，否则被模型分类，输出该文本的类型（hit或miss） </P>
<P>&nbsp;模型是动态建立的，第一次使用命令行必须指定-c参数，才可以建立模型。<BR>1) 建立模型<BR>&gt;java MessageClassifier -t data/1.bmp -m myModel -c hit<BR>可以看到myModel建立了。然后继续训练一下这个模型。使用的文本实例越多，模型的分类性能越好<BR>&gt;java MessageClassifier -t data/2.bmp -m myModel -c hit<BR>&gt;java MessageClassifier -t data/1.gif -m myModel -c miss<BR>......<BR>2) 使用模型分类<BR>有了模型，就可以使用它为文本文件分类了，如<BR>&gt;java MessageClassifier -t data/2.gif -m myModel <BR>3) 可以使用提供-c参数的命令继续完善模型</P>
<P>&nbsp;</P>
<P>原文件MessageClassifier&nbsp;.java</P>
<P>
<TABLE class=tableborder1 style="WIDTH: 100%" cellSpacing=1 cellPadding=5>
<TBODY>
<TR>
<TD class=tablebody2 width="100%"><STRONG>/**<BR>*&nbsp;Java&nbsp;program&nbsp;for&nbsp;classifying&nbsp;text&nbsp;messages&nbsp;into&nbsp;two&nbsp;classes.<BR>*/<BR>import&nbsp;weka.core.Attribute;<BR>import&nbsp;weka.core.Instance;<BR>import&nbsp;weka.core.Instances;<BR>import&nbsp;weka.core.FastVector;<BR>import&nbsp;weka.core.Utils;<BR>import&nbsp;weka.classifiers.Classifier;<BR>import&nbsp;weka.classifiers.trees.J48;<BR>import&nbsp;weka.filters.Filter;<BR>import&nbsp;weka.filters.unsupervised.attribute.StringToWordVector;<BR>import&nbsp;java.io.*;<BR>public&nbsp;class&nbsp;MessageClassifier&nbsp;implements&nbsp;Serializable&nbsp;{<BR>/*&nbsp;The&nbsp;training&nbsp;data&nbsp;gathered&nbsp;so&nbsp;far.&nbsp;*/<BR>private&nbsp;Instances&nbsp;m_Data&nbsp;=&nbsp;null;<BR>/*&nbsp;The&nbsp;filter&nbsp;used&nbsp;to&nbsp;generate&nbsp;the&nbsp;word&nbsp;counts.&nbsp;*/<BR>private&nbsp;StringToWordVector&nbsp;m_Filter&nbsp;=&nbsp;new&nbsp;StringToWordVector();<BR>/*&nbsp;The&nbsp;actual&nbsp;classifier.&nbsp;*/<BR>private&nbsp;Classifier&nbsp;m_Classifier&nbsp;=&nbsp;new&nbsp;J48();<BR>/*&nbsp;Whether&nbsp;the&nbsp;model&nbsp;is&nbsp;up&nbsp;to&nbsp;date.&nbsp;*/<BR>private&nbsp;boolean&nbsp;m_UpToDate;<BR>/**<BR>*&nbsp;Constructs&nbsp;empty&nbsp;training&nbsp;dataset.<BR>*/<BR>public&nbsp;MessageClassifier()&nbsp;throws&nbsp;Exception&nbsp;{<BR>String&nbsp;nameOfDataset&nbsp;=&nbsp;"MessageClassificationProblem";<BR>//&nbsp;Create&nbsp;vector&nbsp;of&nbsp;attributes.<BR>FastVector&nbsp;attributes&nbsp;=&nbsp;new&nbsp;FastVector(2);<BR>//&nbsp;Add&nbsp;attribute&nbsp;for&nbsp;holding&nbsp;messages.<BR>attributes.addElement(new&nbsp;Attribute("Message",&nbsp;(FastVector)null));<BR>//&nbsp;Add&nbsp;class&nbsp;attribute.<BR>FastVector&nbsp;classValues&nbsp;=&nbsp;new&nbsp;FastVector(2);<BR>classValues.addElement("miss");<BR>classValues.addElement("hit");<BR>attributes.addElement(new&nbsp;Attribute("Class",&nbsp;classValues));<BR>//&nbsp;Create&nbsp;dataset&nbsp;with&nbsp;initial&nbsp;capacity&nbsp;of&nbsp;100,&nbsp;and&nbsp;set&nbsp;index&nbsp;of&nbsp;class.<BR>m_Data&nbsp;=&nbsp;new&nbsp;Instances(nameOfDataset,&nbsp;attributes,&nbsp;100);<BR>m_Data.setClassIndex(m_Data.numAttributes()&nbsp;-&nbsp;1);<BR>}<BR>/**<BR>*&nbsp;Updates&nbsp;data&nbsp;using&nbsp;the&nbsp;given&nbsp;training&nbsp;message.<BR>*/<BR>public&nbsp;void&nbsp;updateData(String&nbsp;message,&nbsp;String&nbsp;classValue)&nbsp;throws&nbsp;Exception&nbsp;{<BR>//&nbsp;Make&nbsp;message&nbsp;into&nbsp;instance.<BR>Instance&nbsp;instance&nbsp;=&nbsp;makeInstance(message,&nbsp;m_Data);<BR>//&nbsp;Set&nbsp;class&nbsp;value&nbsp;for&nbsp;instance.<BR>instance.setClassValue(classValue);<BR>//&nbsp;Add&nbsp;instance&nbsp;to&nbsp;training&nbsp;data.<BR>m_Data.add(instance);<BR>m_UpToDate&nbsp;=&nbsp;false;<BR>}<BR>/**<BR>*&nbsp;Classifies&nbsp;a&nbsp;given&nbsp;message.<BR>*/<BR>public&nbsp;void&nbsp;classifyMessage(String&nbsp;message)&nbsp;throws&nbsp;Exception&nbsp;{<BR>//&nbsp;Check&nbsp;whether&nbsp;classifier&nbsp;has&nbsp;been&nbsp;built.<BR>if&nbsp;(m_Data.numInstances()&nbsp;==&nbsp;0)&nbsp;{<BR>////throw&nbsp;new&nbsp;Exception("No&nbsp;classifier&nbsp;available.");<BR>}<BR>//&nbsp;Check&nbsp;whether&nbsp;classifier&nbsp;and&nbsp;filter&nbsp;are&nbsp;up&nbsp;to&nbsp;date.<BR>if&nbsp;(!m_UpToDate)&nbsp;{<BR>&nbsp;//&nbsp;Initialize&nbsp;filter&nbsp;and&nbsp;tell&nbsp;it&nbsp;about&nbsp;the&nbsp;input&nbsp;format.<BR>m_Filter.setInputFormat(m_Data);<BR>//&nbsp;Generate&nbsp;word&nbsp;counts&nbsp;from&nbsp;the&nbsp;training&nbsp;data.<BR>Instances&nbsp;filteredData&nbsp;=&nbsp;Filter.useFilter(m_Data,&nbsp;m_Filter);<BR>//&nbsp;Rebuild&nbsp;classifier.<BR>m_Classifier.buildClassifier(filteredData);<BR>m_UpToDate&nbsp;=&nbsp;true;<BR>}<BR>//&nbsp;Make&nbsp;separate&nbsp;little&nbsp;test&nbsp;set&nbsp;so&nbsp;that&nbsp;message<BR>//&nbsp;does&nbsp;not&nbsp;get&nbsp;added&nbsp;to&nbsp;string&nbsp;attribute&nbsp;in&nbsp;m_Data.<BR>Instances&nbsp;testset&nbsp;=&nbsp;m_Data.stringFreeStructure();<BR>//&nbsp;Make&nbsp;message&nbsp;into&nbsp;test&nbsp;instance.<BR>Instance&nbsp;instance&nbsp;=&nbsp;makeInstance(message,&nbsp;testset);<BR>//&nbsp;Filter&nbsp;instance.<BR>m_Filter.input(instance);<BR>Instance&nbsp;filteredInstance&nbsp;=&nbsp;m_Filter.output();<BR>//&nbsp;Get&nbsp;index&nbsp;of&nbsp;predicted&nbsp;class&nbsp;value.<BR>double&nbsp;predicted&nbsp;=&nbsp;m_Classifier.classifyInstance(filteredInstance);<BR>//&nbsp;Output&nbsp;class&nbsp;value.<BR>System.err.println("Message&nbsp;classified&nbsp;as&nbsp;:&nbsp;"&nbsp;+<BR>m_Data.classAttribute().value((int)predicted));<BR>}<BR>/**<BR>*&nbsp;Method&nbsp;that&nbsp;converts&nbsp;a&nbsp;text&nbsp;message&nbsp;into&nbsp;an&nbsp;instance.<BR>*/<BR>private&nbsp;Instance&nbsp;makeInstance(String&nbsp;text,&nbsp;Instances&nbsp;data)&nbsp;{<BR>//&nbsp;Create&nbsp;instance&nbsp;of&nbsp;length&nbsp;two.<BR>Instance&nbsp;instance&nbsp;=&nbsp;new&nbsp;Instance(2);<BR>//&nbsp;Set&nbsp;value&nbsp;for&nbsp;message&nbsp;attribute<BR>Attribute&nbsp;messageAtt&nbsp;=&nbsp;data.attribute("Message");<BR>instance.setValue(messageAtt,&nbsp;messageAtt.addStringValue(text));<BR>//&nbsp;Give&nbsp;instance&nbsp;access&nbsp;to&nbsp;attribute&nbsp;information&nbsp;from&nbsp;the&nbsp;dataset.<BR>instance.setDataset(data);<BR>return&nbsp;instance;<BR>}<BR>/**<BR>*&nbsp;Main&nbsp;method.<BR>*/<BR>public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;options)&nbsp;{<BR>try&nbsp;{<BR>//&nbsp;Read&nbsp;message&nbsp;file&nbsp;into&nbsp;string.<BR>String&nbsp;messageName&nbsp;=&nbsp;Utils.getOption('t',&nbsp;options);<BR>if&nbsp;(messageName.length()&nbsp;==&nbsp;0)&nbsp;{<BR>throw&nbsp;new&nbsp;Exception("Must&nbsp;provide&nbsp;name&nbsp;of&nbsp;message&nbsp;file.");<BR>}<BR>FileReader&nbsp;m&nbsp;=&nbsp;new&nbsp;FileReader(messageName);<BR>StringBuffer&nbsp;message&nbsp;=&nbsp;new&nbsp;StringBuffer();&nbsp;int&nbsp;l;<BR>while&nbsp;((l&nbsp;=&nbsp;m.read())&nbsp;!=&nbsp;-1)&nbsp;{<BR>message.append((char)l);<BR>}<BR>m.close();<BR>//&nbsp;Check&nbsp;if&nbsp;class&nbsp;value&nbsp;is&nbsp;given.<BR>String&nbsp;classValue&nbsp;=&nbsp;Utils.getOption('c',&nbsp;options);<BR>//&nbsp;If&nbsp;model&nbsp;file&nbsp;exists,&nbsp;read&nbsp;it,&nbsp;otherwise&nbsp;create&nbsp;new&nbsp;one.<BR>String&nbsp;modelName&nbsp;=&nbsp;Utils.getOption('m',&nbsp;options);<BR>if&nbsp;(modelName.length()&nbsp;==&nbsp;0)&nbsp;{<BR>throw&nbsp;new&nbsp;Exception("Must&nbsp;provide&nbsp;name&nbsp;of&nbsp;model&nbsp;file.");<BR>}<BR>MessageClassifier&nbsp;messageCl;<BR>try&nbsp;{<BR>ObjectInputStream&nbsp;modelInObjectFile&nbsp;=<BR>new&nbsp;ObjectInputStream(new&nbsp;FileInputStream(modelName));<BR>messageCl&nbsp;=&nbsp;(MessageClassifier)&nbsp;modelInObjectFile.readObject();<BR>modelInObjectFile.close();<BR>}&nbsp;catch&nbsp;(FileNotFoundException&nbsp;e)&nbsp;{<BR>messageCl&nbsp;=&nbsp;new&nbsp;MessageClassifier();<BR>}<BR>//&nbsp;Check&nbsp;if&nbsp;there&nbsp;are&nbsp;any&nbsp;options&nbsp;left<BR>Utils.checkForRemainingOptions(options);<BR>//&nbsp;Process&nbsp;message.<BR>if&nbsp;(classValue.length()&nbsp;!=&nbsp;0)&nbsp;{<BR>messageCl.updateData(message.toString(),&nbsp;classValue);<BR>}&nbsp;else&nbsp;{<BR>messageCl.classifyMessage(message.toString());<BR>}<BR>//&nbsp;Save&nbsp;message&nbsp;classifier&nbsp;object.<BR>ObjectOutputStream&nbsp;modelOutObjectFile&nbsp;=<BR>new&nbsp;ObjectOutputStream(new&nbsp;FileOutputStream(modelName));<BR>modelOutObjectFile.writeObject(messageCl);<BR>modelOutObjectFile.close();<BR>}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{<BR>e.printStackTrace();<BR>}<BR>}<BR>}</STRONG></TD></TR></TBODY></TABLE><BR></P>
<P>下载源码:<BR><A href="http://blogger.org.cn/blog/images/file/zip.gif" target=_blank><IMG onmousewheel="return bbimg(this)" title=点击在新窗口查看原始图片 src="http://blogger.org.cn/blog/images/file/zip.gif" onload="java_script_:if(this.width>500)this.width=500" border=0></A><A href="http://blogger.org.cn/blog/uploadfile/200711221593137.RAR" target=_blank>文本分类算法.rar</A></P></SPAN>]]></description>
</item><item>
<title><![CDATA[（转）WEKA编写新学习方案]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45831</link>
<author>reincarnation</author>
<pubDate>2009/6/5 20:43:59</pubDate>
<description><![CDATA[
<P><A>来源：</A><A href="http://blog.csdn.net/comlc/archive/2007/12/13/1933775.aspx">http://blog.csdn.net/comlc/archive/2007/12/13/1933775.aspx</A></P>
<P>1.编写新学习方案<BR>如果用户需要实现一个Weka所没有的特殊目的的学习算法,或者用户正在进行机器学习的研究,并且想试验一个新的学习方案,或者用户只是想通过亲自动手编程,了解更多有关一个归纳算法的内部运作,本节用一个简单的范例演示在编写分类器时,如何充分利用Weka的类的层级结构,从而满足用户的需要.</P>
<P>Weka包含了表15-1中所列的基本的、主要用于教育目的的学习方案.表中的方案对于接受命令行选项没有特别要求.它们对于理解分类器的内部运作都很有用.我们会将weka.classifiers.trees.Id3作为一个例子讨论,该方案实现了第4.3节中的ID3决策树学习器.<BR>表15-1 Weka中的简单学习方案</P>
<P>方案&nbsp; 描述 <BR>weka.classifiers.bayes.NaiveBayesSimple&nbsp; 概率学习器 <BR>weka.classifiers.trees.Id3&nbsp; 决策树学习器 <BR>weka.classifiers.rules.Prism&nbsp; 规则学习器 <BR>weka.classifiers.lazy.IB1&nbsp; 基于实例的学习器 </P>
<P>&nbsp;<BR>2．一个分类器范例<BR>图15-1给出了weka.classifiers.trees.Id3的源代码,用户从代码中可看出它扩展Classifier类.无论是用于预测名词性类还是预测数值性类,每个Weka中的分类器都必须扩展Classifier类.<BR>weka.classifiers.trees.Id3方案中的第一个方法是globalInfo():我们在进人到更有趣的部分之前先谈谈这个方法.当这个方案在Weka的图形用户界面上被选中时,该方法只是简单地返回一个显示在屏幕上的字符串.<BR>package weka.classifiers.trees;<BR>import weka.classifiers.*;<BR>import weka.core.*;<BR>import java.io.*;<BR>import java.util.*;<BR>/**<BR>* Class implementing an Id3 decision tree classifier.<BR>*/<BR>public class Id3 extends Classifier {<BR>/** The node's successors. */<BR>private Id3[] m_Successors;<BR>/** Attribute used for splitting. */<BR>private Attribute m_Attribute;<BR>/** Class value if node is leaf. */<BR>private double m_ClassValue;<BR>/** Class distribution if node is leaf. */<BR>private double[] m_Distribution;<BR>/** Class attribute of dataset. */<BR>private Attribute m_ClassAttribute;<BR>/**<BR>* Returns a string describing the classifier.<BR>* @return a description suitable for the GUI.<BR>*/<BR>public String globalInfo() {<BR>return "Class for constructing an unpruned decision tree based on the ID3 "<BR>+ "algorithm. Can only deal with nominal attributes. No missing values "<BR>+ "allowed. Empty leaves may result in unclassified instances. For more "<BR>+ "information see: \n\n"<BR>+ " R. Quinlan (1986). \"Induction of decision "<BR>+ "trees\". Machine Learning. Vol.1, No.1, pp. 81-106";<BR>}<BR>/**<BR>* Builds Id3 decision tree classifier.<BR>*<BR>* @param data the training data<BR>* @exception Exception if classifier can't be built successfully<BR>*/<BR>public void buildClassifier(Instances data) throws Exception {<BR>if (!data.classAttribute().isNominal()) {<BR>throw new UnsupportedClassTypeException("Id3: nominal class, please.");<BR>}<BR>Enumeration enumAtt = data.enumerateAttributes();<BR>while (enumAtt.hasMoreElements()) {<BR>if (!((Attribute) enumAtt.nextElement()).isNominal()) {<BR>throw new UnsupportedAttributeTypeException("Id3: only nominal " +<BR>"attributes, please.");<BR>}<BR>}<BR>Enumeration enum = data.enumerateInstances();<BR>while (enum.hasMoreElements()) {<BR>if (((Instance) enum.nextElement()).hasMissingValue()) {<BR>throw new NoSupportForMissingValuesException("Id3: no missing values, "<BR>+ "please.");<BR>}<BR>}<BR>data = new Instances(data);<BR>data.deleteWithMissingClass();<BR>makeTree(data);<BR>}<BR>/**<BR>* Method for building an Id3 tree.<BR>*<BR>* @param data the training data<BR>* @exception Exception if decision tree can't be built successfully<BR>*/<BR>private void makeTree(Instances data) throws Exception {<BR>// Check if no instances have reached this node.<BR>if (data.numInstances() == 0) {<BR>m_Attribute = null;<BR>m_ClassValue = Instance.missingValue();<BR>m_Distribution = new double[data.numClasses()];<BR>return;<BR>}<BR>// Compute attribute with maximum information gain.<BR>double[] infoGains = new double[data.numAttributes()];<BR>Enumeration attEnum = data.enumerateAttributes();<BR>while (attEnum.hasMoreElements()) {<BR>Attribute att = (Attribute) attEnum.nextElement();<BR>infoGains[att.index()] = computeInfoGain(data, att);<BR>}<BR>m_Attribute = data.attribute(Utils.maxIndex(infoGains));<BR>// Make leaf if information gain is zero.<BR>// Otherwise create successors.<BR>if (Utils.eq(infoGains[m_Attribute.index()], 0)) {<BR>m_Attribute = null;<BR>m_Distribution = new double[data.numClasses()];<BR>Enumeration instEnum = data.enumerateInstances();<BR>while (instEnum.hasMoreElements()) {<BR>Instance inst = (Instance) instEnum.nextElement();<BR>m_Distribution[(int) inst.classValue()]++;<BR>}<BR>Utils.normalize(m_Distribution);<BR>m_ClassValue = Utils.maxIndex(m_Distribution);<BR>m_ClassAttribute = data.classAttribute();<BR>} else {<BR>Instances[] splitData = splitData(data, m_Attribute);<BR>m_Successors = new Id3[m_Attribute.numValues()];<BR>for (int j = 0; j &lt; m_Attribute.numValues(); j++) {<BR>m_Successors[j] = new Id3();<BR>m_Successors[j].makeTree(splitData[j]);<BR>}<BR>}<BR>}<BR>/**<BR>* Classifies a given test instance using the decision tree.<BR>*<BR>* @param instance the instance to be classified<BR>* @return the classification<BR>*/<BR>public double classifyInstance(Instance instance)<BR>throws NoSupportForMissingValuesException {<BR>if (instance.hasMissingValue()) {<BR>throw new NoSupportForMissingValuesException("Id3: no missing values, "<BR>+ "please.");<BR>}<BR>if (m_Attribute == null) {<BR>return m_ClassValue;<BR>} else {<BR>return m_Successors[(int) instance.value(m_Attribute)].<BR>classifyInstance(instance);<BR>}<BR>}<BR>/**<BR>* Computes class distribution for instance using decision tree.<BR>*<BR>* @param instance the instance for which distribution is to be computed<BR>* @return the class distribution for the given instance<BR>*/<BR>public double[] distributionForInstance(Instance instance)<BR>throws NoSupportForMissingValuesException {<BR>if (instance.hasMissingValue()) {<BR>throw new NoSupportForMissingValuesException("Id3: no missing values, "<BR>+ "please.");<BR>}<BR>if (m_Attribute == null) {<BR>return m_Distribution;<BR>} else {<BR>return m_Successors[(int) instance.value(m_Attribute)].<BR>distributionForInstance(instance);<BR>}<BR>}<BR>/**<BR>* Prints the decision tree using the private toString method from below.<BR>*<BR>* @return a textual description of the classifier<BR>*/<BR>public String toString() {<BR>if ((m_Distribution == null) &amp;&amp; (m_Successors == null)) {<BR>return "Id3: No model built yet.";<BR>}<BR>return "Id3\n\n" + toString(0);<BR>}<BR>/**<BR>* Computes information gain for an attribute.<BR>*<BR>* @param data the data for which info gain is to be computed<BR>* @param att the attribute<BR>* @return the information gain for the given attribute and data<BR>*/<BR>private double computeInfoGain(Instances data, Attribute att)<BR>throws Exception {<BR>double infoGain = computeEntropy(data);<BR>Instances[] splitData = splitData(data, att);<BR>for (int j = 0; j &lt; att.numValues(); j++) {<BR>if (splitData[j].numInstances() &gt; 0) {<BR>infoGain -= ((double) splitData[j].numInstances() /<BR>(double) data.numInstances()) *<BR>computeEntropy(splitData[j]);<BR>}<BR>}<BR>return infoGain;<BR>}<BR>/**<BR>* Computes the entropy of a dataset.<BR>*<BR>* @param data the data for which entropy is to be computed<BR>* @return the entropy of the data's class distribution<BR>*/<BR>private double computeEntropy(Instances data) throws Exception {<BR>double [] classCounts = new double[data.numClasses()];<BR>Enumeration instEnum = data.enumerateInstances();<BR>while (instEnum.hasMoreElements()) {<BR>Instance inst = (Instance) instEnum.nextElement();<BR>classCounts[(int) inst.classValue()]++;<BR>}<BR>double entropy = 0;<BR>for (int j = 0; j &lt; data.numClasses(); j++) {<BR>if (classCounts[j] &gt; 0) {<BR>entropy -= classCounts[j] * Utils.log2(classCounts[j]);<BR>}<BR>}<BR>entropy /= (double) data.numInstances();<BR>return entropy + Utils.log2(data.numInstances());<BR>}<BR>/**<BR>* Splits a dataset according to the values of a nominal attribute.<BR>*<BR>* @param data the data which is to be split<BR>* @param att the attribute to be used for splitting<BR>* @return the sets of instances produced by the split<BR>*/<BR>private Instances[] splitData(Instances data, Attribute att) {<BR>Instances[] splitData = new Instances[att.numValues()];<BR>for (int j = 0; j &lt; att.numValues(); j++) {<BR>splitData[j] = new Instances(data, data.numInstances());<BR>}<BR>Enumeration instEnum = data.enumerateInstances();<BR>while (instEnum.hasMoreElements()) {<BR>Instance inst = (Instance) instEnum.nextElement();<BR>splitData[(int) inst.value(att)].add(inst);<BR>}<BR>for (int i = 0; i &lt; splitData.length; i++) {<BR>splitData[i].compactify();<BR>}<BR>return splitData;<BR>}<BR>/**<BR>* Outputs a tree at a certain level.<BR>*<BR>* @param level the level at which the tree is to be printed<BR>*/<BR>private String toString(int level) {<BR>StringBuffer text = new StringBuffer();<BR>if (m_Attribute == null) {<BR>if (Instance.isMissingValue(m_ClassValue)) {<BR>text.append(": null");<BR>} else {<BR>text.append(": " + m_ClassAttribute.value((int) m_ClassValue));<BR>}<BR>} else {<BR>for (int j = 0; j &lt; m_Attribute.numValues(); j++) {<BR>text.append("\n");<BR>for (int i = 0; i &lt; level; i++) {<BR>text.append("| ");<BR>}<BR>text.append(m_Attribute.name() + " = " + m_Attribute.value(j));<BR>text.append(m_Successors[j].toString(level + 1));<BR>}<BR>}<BR>return text.toString();<BR>}<BR>/**<BR>* Main method.<BR>*<BR>* @param args the options for the classifier<BR>*/<BR>public static void main(String[] args) {<BR>try {<BR>System.out.println(Evaluation.evaluateModel(new Id3(), args));<BR>} catch (Exception e) {<BR>System.err.println(e.getMessage());<BR>}<BR>}<BR>}<BR>图15-1 ID3决策树学习器的源代码 <BR>3．buildClassifier()</P>
<P>buildClassifier()方法根据训练数据集构建一个分类器.因为ID3算法无法处理非名词性类,残缺属性值,或任何非名词性的属性,因此,buildClassifier()方法首先在数据中对以上提到的进行查验.然后,它会生成一个训练集的复制件(以避免改变原始数据),并调用weka.core.Instances中的一个方法来删除所有含残缺类值的实例,因为这些实例在训练过程中不起作用.最后,它会调用makeTree(),该方法实际上通过递归的方式产生所有附加到根节点上的子树,从而生成一个决策树.<BR>4．makeTree()</P>
<P>在makeTree()中,第一步是检查数据集是否为空.如果是,通过将m_Attribute设为空生成一个叶节点.为该叶指定的类值m_ClassValue设定为残缺,且m_Distribution中为数据集中的每个类所估计的概率皆初始化为0.如果训练实例已准备好,makeTree()会找出令这些实例产生最大信息增益的属性.它首先生成一个数据集属性的Java枚举.如果类属性的索引已经设定,像正在讨论的这个数据集设定一样,该类属性会被自动排除在该枚举之外.</P>
<P>在枚举内部,每个属性的信J氢增益都由computelnfoGain()计算出来并存储在一个数组中.我们以后会重新讲这个方法.weka.core.Attribute中的index()方法可返回数据集中属性的索引.它可为刚刚提到的数组编制索引.一旦完成了枚举,具有最大信息增益的属性就会存储在实例变量m Attribute中.weka.core.Utils中的maxlndex()方法会返回一个由整数或双精度浮点小数构成的数组中最大值的索引.(如果具有最大值的组元不止一个,那么只有第一个被返回.)该属性的索引会被传给weka.core.Instances中的attribute()方法,该方法返回与索引相对应的属性.</P>
<P>用户也许在想,数组中与类属性相对应的那个值域怎么样了?这个不必担心,因为Java会自动将数组中所有组元初始化为整数0,而信息增益总是大于或等于0.如果最大信息增益是0,makeTree()会生成一个叶节点.在这种情况下,makeTree()会设为空,且makeTree()会同时计算类概率的分布以及具有最大概率的类.(weka,core.Utils中的normalize()方法会将一个双精度浮点小数数组正常化使其组员相加总和为1.)</P>
<P>当它产生一个已指定类值的叶节点时,makeTree()将类属性存储到m_ClassAttrfbute中.这是因为用来输出决策树的方法需要读取该类值以便显示类标签.</P>
<P>如果发现了一个具有非零信息增益的属性,makeTree()会根据该属性的值分割数据集,并以递归的方式为每个新产生的数据集构建子树.该方法调用另一个方法splitData()进行分割.这样就会生成与属性值一样多个空的数据集,且把这些数据集存储到一个数组中(将每个数据集的初始容量设定为原始数据集中所含实例的数量),然后在原始数据集中将每个实例依次循环一遍,并在新数据集中根据相对应的属性值为这些实例开辟空间.然后压缩Instances对象以减少占用的存储器.返回到makeTree()后,所得到的数据集数组用于构建子树.该方法会生成一个由Id3对象构成的数组,数组中的每个对象对应着一个属性值9并将相对应的数据集传给makeTree(),从而在每个对象上调用该方法.<BR>5．computeInfoGain()</P>
<P>现在回到corrtputeInfoGain(),与一个属性和一个数据集相关联的信息增益是用第4.3节中介绍过的方程式的一个直接实现计算出来的.首先计算出数据集的熵,然后用splitData()将数据集分割成子集,并在每个子集上调用computeEntr0py().最后,将前面计算出来的熵与后面计算出来的每个熵的加权总和相减的差,即信息增益返回.computeEntropy()方法使用weka.core.Utils中的log2()方法得出一个数的对数(以2为基数).<BR>6．classifyInstance()</P>
<P>看过了ID3如何构建决策树,我们再来看如何利用树结构来预测类值及概率.每一个分类器都必须实现classifylnstance()方法或distributionFor.Instance()方法(或两个方法都实现).Classifier超类含有这两种方法的默认实现.classifylnstance()的默认实现调用distributionForlns tance().如果类是名词性的,classifyInstance()会把具有最大概率的属性预测为类,否则,如果从distributionForInstance()返回的所有概率都是零,classifylllstarlce()会返回一个残缺值.如果类是数值性的,distributionForlnstance()必须返回有数值性预测的单一组元数组,该数组也就是classifylnstance()要提取并返回的.最后,distributionForlnstance()的默认实现反过来把从classifyInstance()中得来的预测包装成一个单一组元数组.如果类是名词性的,distributionForInstance()将概率1指定给classihzlnstance()预测出的类属性,把概率0指定给其他属性.如果classi.fylnstance()返回一个残缺值,所有属性的概率都设为0.为了让用户更好地了解这些方法所做的工作,weka.classifiers.trees,Id3类重新编写了这两个方法.</P>
<P>我们先来看看针对一个给定实例预测类值的classifylnstance().上一节曾经讲过,与名词性属性值一样,名词性类值是以double变量的形式编码及存储的,表示值的名字在属性声明中的索引.这种更简洁有效的面向对象的处理方式可加快运行速度.在ID3的实现中,classifyInstance()首先查看待分类的实例中是否有残缺值.如果有的话,就丢弃一个异常.否则,它就以递归的方式,根据待分类实例的属性值,沿着树自上而下,直至到达某个末端叶节点.然后,它会返回存储在该叶节点的类值m_ClassValue.要注意所返回的也有可能是残缺值,如果是残缺值,该实例则成为未被分类的实例.distributionForInstance()方法的工作方式与此完全一样,它返回存储于m_Distribution中的概率分布.</P>
<P>大多数机器学习模型,特别是决策树,大致上全面反映了数据本身的结构.因此每个Weka分类器,如同许多其他Java对象一样,实现toString()方法从而以字符串变量的形式生成一个它自身的文本表述.ID3的toString()方法输出一个与J4.8格式大致相同的决策树(图10-5).它通过读取存储于节点上的属性信息,以递归的方式将树的结构输入一个字符串变量.它使用weka.core.Attribute中的name()和value()方法得到每个属性的名字和值.不含类值的空末端叶节点由字符串null标示出来.<BR>7．main()</P>
<P>weka.classifiers.tree.Id3中还没有被描述的唯一方法就是main(),每当由命令行执行一个类, 该方法都会被调用.正如用户看到的一样,该方法很简单:基本上就是告诉Weka的类Evaluation用所给的命令行选项评估Id3,并输出所得到的字符串.完成此项任务的单行表达式就包含在一个try-catch语句中,该语句能捕获各种各样由Weka例程或其他Java方法丢出的异常.</P>
<P>Weka.classifiers.Evaluation中的evaluation()方法解释了第13.3节中讨论过的,可适用于任何学习方案的通用命令行选项及相应的作用.例如,它可接受训练文件名字的-L选项,并载人相对应的数据集.如果没有测试文件,它就进行交叉验证,方式是生成一个分类器,并在训练数据的不同的子集上重复调用buildClassifier(),classify Instance()和distributionForlnstance().除非用户设定了相应的命令行选项从而阻止模型的输出,它还会调用toString()方法,输出由整个训练数据集生成的模型.</P>
<P>如果某个学习方案需要解释一个具体的选项,比如一个修剪参数,怎么办?这可由weka.core中的OptionHandler接口来解决.实现该接口的分类器含有三个方法:listOptions(),setOptions()和getOption().它们分别用来列出所有针对该分类器的选项,设定其中某些选项,以及取得目前已设定的选项.如果一个分类器实现了OptionHandle r接口,Evaluation类中的evaluation()方法会自动调用这些方法.处理完通用选项后,evaluation()会调用setOption()来处理余下的选项,然后利用buildClassifier()产生一个新的分类器.输出所产生的分类器,evaluation()会用getOptions()输出一列目前已设定的选项.在weka.classifiers.rules.0neR的源代码中可找到一个如何实现这些方法的简单范例.</P>
<P>OptionHandler使得在命令行中设定选项成为可能.要在图形用户界面中设定这些选项,Weka使用的是Java豆的架构.实施该构架所要做的全部工作就是为一个类中所用到的每个参数都提供set...()及get...()方法.比方说,方法setPruningParameter()和getPruningParameter()对于一个修剪参数来说就是必须的.还有一个方法也必不可少,pruningParameterTipText()返回的是显示在图形用户界面上的对该参数的一个描述.再强调一次,见weka.classifiers.rules.OneR中的例子.</P>
<P>一些分类器可在新的训练实例陆续到达时进行递增更新,并且不需要在同一批中处理全部数据.在Weka中,递增分类器须实现weka.classifiers中的UpdateableClassifier接口.该接口只声明了一个名为updateClassifier()的方法,该方法只接受一个单独的训练实例作为它的可变参数.要参考一个如何使用该接口的例子,见weka.classifiers.lazy.IBk的源代码.</P>
<P>如果一个分类器能运用实例的权,它必须实现weka.core中的Weightedlnstartce sHandler()接口.如此一来其他的算法,比方说那些用于提升的算法,就可对该属性加以利用.</P>
<P>在weka.core中还有很多其他对于分类器来说很有用的接口,例如,rondomizable,summarizable,drawable,和graphable这些用于分类器的接口.有关接口的更多信息,见weka.core中相应类的Javadoc.<BR>8．与实现分类器有关的惯例</P>
<P>在实现Weka中的分类器时,有一些惯例用户必须遵守.否则,程序会出错.比方说,Weka的评估模块在评估分类器时可能会无法恰当地计算它的统计数据.<BR>第一个惯例前面已经提到过,当一个分类器的buildClassifier()方法被调用时,必须令模型重新复位.类CheckClassifier进行测试,确保模型的确被复位了.当buildC`assifier()在某个数据集上被调用时,无论该分类器以前已经在同一个或其他的数据集上被调用过多少次,所得到的结果必须是一样的.还有,一些实例变量是与某些只适用于具体方案的选项相对应的,buildClassifier()方法绝对不可以将这些变量复位,因为这些变量的值一旦被设定,它们在多次调用buildClassifier()的过程中必须保持不变.还有,调用buildClassifier()绝对不可以改动输人数据.</P>
<P>另外两个惯例以前也提到过.一个是当某个分类器无法做出预测时,它的classifyInstance()方法必须返回Instance.missingValue(),且它的distributionForlnstance()方法必须针对所有类属性都返回0概率.图15-1中的ID3实现就是这么做的.另外一个惯例是这样的,对手用作数值性预测的分类器来说,它的classifyInstance()要返回分类器所预测出的数值性类值.还有一些分类器可以对名词性的类和类概率,以及数值性的类值做出预测,weka.classifiers.lazy.IBk就是一个例子.这些分类器实现了distributionForlnstance()方法,如果类是数值性的,它会返回一个单一组元数组,其唯一组元就含有所预测的数值性值.</P>
<P>另外一个惯例虽然并不是不可或缺,但不管怎么说都是有益的,即每个分类器都实现一个toString()方法,用于输出一个它自身的文本描述.</P>
<P>本文来自CSDN博客，转载请标明出处：<A href="http://blog.csdn.net/comlc/archive/2007/12/13/1933775.aspx">http://blog.csdn.net/comlc/archive/2007/12/13/1933775.aspx</A></P>]]></description>
</item><item>
<title><![CDATA[（转）利用WEKA编写数据挖掘算法]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45830</link>
<author>reincarnation</author>
<pubDate>2009/6/5 19:22:21</pubDate>
<description><![CDATA[
<DIV>　　WEKA是由新西兰怀卡托大学开发的<FONT color=#ff0000>开源</FONT><FONT color=#ff0000>项目</FONT>。WEKA是<FONT color=#ff0000>由JAVA编写</FONT>的，并且限制在GNU通用公众证书的条件下发布，可以运行在所有的操作系统中。WEKA工作平台包含能处理所有标准数据挖掘问题的方法：<FONT color=#ff0000>回归、分类、聚类、关联规则挖掘以及属性选择</FONT>。作为数据挖掘爱好者自然要对WEKA的源代码进行分析并以及改进，努力写出自己的数据挖掘算法。<BR>下面着重介绍一下如何利用WEKA编写新的数据挖掘算法：</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp;&nbsp; <FONT color=#ff0000>注意</FONT>：WEKA的版本有两个版本：稳定版(STABLE)和开发版(DEVELOP)，不同WEKA版本与不同JDK的版本匹配，稳定版WEKA3-4的与JDK1.4.2匹配，而开发版WEKA3-5与JDK1.5匹配，WEKA3-5新加入了对数据库的数据连接。稳定版直接下载weka-src.jar文件就行了，而开发版需使用CVS连接到sourceForge下载，:pserver:cvs_anon@cvs.scms.waikato.ac.nz:/usr/local/global-cvs/ml_cvs。本文以稳定版为例。</DIV>
<DIV><BR>一、首先从WEKA官方网站（<A href="http://www.cs.waikato.ac.nz/ml/weka">http://www.cs.waikato.ac.nz/ml/weka</A>）下载WEKA程序包。将程序包解压获得weka-src.jar源文件，再将源代码解压缩导入某个JAVA开发工具中（图1），如：JBuilder，Eclipse，Netbeans等。我现在以Netbeans为例。</DIV>
<DIV><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/200965192037730.JPG" border=0></DIV>
<DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图1 ： weka导入Netbeans</DIV>
<DIV><BR>二、为了不与WEKA中已包含的算法相冲突，最好自己建立一个JAVA包，将自己编写的挖掘算法存放在该包内（图2）。我以建立hzm包为例：</DIV>
<DIV><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/20096519217243.JPG" border=0></DIV>
<DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图2 ： 建立新weka包</DIV>
<DIV>&nbsp;</DIV>
<DIV>三、在新的包hzm内建立新的java类，然后双击编写数据挖掘算法程序代码，本人以实现ID3算法为例讲解具体操作过程。</DIV>
<DIV><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/200965192156896.JPG" border=0></DIV>
<DIV>
<DIV>再将weka.classifiers.trees下的id3算法复制到新建的ID3类中（这只是演示，当然最好还是自己写新的挖掘算法），修改一下类中提示的错误，保存就行了。</DIV>
<DIV>四、编写好新的挖掘算法并不能马上在weka中exlorer模式中看到，还要修改weka.gui包中的GenericObjectEditor.props文件。如：我刚才建立的ID3类在weka.classifiers.hzm包中，就要在GenericObjectEditor.props中的# Lists the Classifiers I want to choose from段后添加weka.classifiers.hzm.ID3,\</DIV>
<DIV><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/200965192214397.JPG" border=0></DIV>
<DIV>
<DIV>五、就可以编译整个weka项目，<FONT color=#ff0000>在选择主类时选择weka.gui.GUIChooser这个类</FONT>，就可以运行和调试你编写好的算法了，祝大家都能写出优秀的挖掘算法！</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp;&nbsp; <FONT color=#ff0000>注意：稳定版3-4修改GenericObjectEditor.props文件即可，但开发版3-5还要多修改同目录下的GenericProertiesCreator.props文件。</FONT></DIV></DIV></DIV></DIV></DIV>]]></description>
</item><item>
<title><![CDATA[（转）Weka3.5中使用LibSVM]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45829</link>
<author>reincarnation</author>
<pubDate>2009/6/5 19:17:13</pubDate>
<description><![CDATA[<DIV class=articleContent id=articleBody>Dr. Y.Bao推荐数据试验中最好用上SVM的分类方法，让我们在Weka中使用LibSVM，我在网上差了半天，看到许多相同的被转来转去的帖子都讲得人晕头转向，尤其是像我这种Java基础不牢固的人更是不知所以，弄了半天走了不少弯路，不过最后总算是让我把LibSVM集成进Weka了，下面就以我自己的实际经验介绍一下最简单并且切实可行的方法： 
<P>Weka3.5后增加了libsvm这个选项，在分类器中的functions下面。但是，试图运行的时候，系统提示：Problem uating classifier:libsvm classes not in CLASSPATH。这是因为Weka只是提供了Libsvm的Wrapper调用机制，必须要安装Libsvm后将附带的jar路径添加到Weka的启动路径中。怎么解决呢？我的Weka版本较新（3.5.7），不过我的方法适用于3.5以上的所有版本。</P>
<P>首先，在http://www.cs.iastate.edu/~yasser/wlsvm/上下载wlsvm.zip的压缩包，解压后将WLSVM \ lib 文件夹下的libsvm.jar 和wlsvm.jar 两个文件放到weka的安装目录下。</P>
<P>然后，在weka的安装目录下打开runweka.ini这个文件，把<BR>cmd_default=javaw -Xmx#maxheap# -classpath "%CLASSPATH%;#weka.jar#" #mainclass#<BR>修改为<BR>cmd_default=javaw -Xmx#maxheap# -classpath "%CLASSPATH%;#weka.jar#;wlsvm.jar;libsvm.jar" #mainclass# （注：其实3.4版本是要将wlsvm.jar加进去的，但3.5版本就没有必要了，只用加libsvm.jar就好了）。</P>
<P>最后，直接运行runweka.bat，再打开Explorer，可以在Classify的Classifier-function中找到LibSVM，像使用其它Classifier一样使用它就可以了。这样LibSVM就成功的集成到Weka了。</P>
<P>至于还有帖子教怎么设置libsvm的路径之类的，其实刚刚修改runweka.ini文件时已经完成了这一步了，大可不必再大费周折了，我试过了，不在环境变量里设置ClassPath就按照上面三步设置就完全可以使用LibSVM了。</P>
<P>附：</P>
<P>LIBSVM简介<BR>支持向量机所涉及到的数学知识对一般的化学研究者来说是比较难的，自己编程实现该算法难度就更大了。但是现在的网络资源非常发达，而且国际上的科学研究者把他们的研究成果已经放在网络上，免费提供给用于研究目的，这样方便大多数的研究者，不必要花费大量的时间理解SVM算法的深奥数学原理和计算机程序设计。目前有关SVM计算的相关软件有很多，如LIBSVM、mySVM、SVMLight等，这些软件大部分的免费下载地址和简单介绍都可以在http://www.kernel-machines.org/上获得。<BR>LIBSVM是台湾大学林智仁(Lin Chih-Jen)副教授等开发设计的一个简单、易于使用和快速有效的SVM模式识别与回归的软件包，他不但提供了编译好的可在Windows系列系统的执行文件，还提供了源代码，方便改进、修改以及在其它操作系统上应用；该软件还有一个特点，就是对SVM所涉及的参数调节相对比较少，提供了很多的默认参数，利用这些默认参数就可以解决很多问题；并且提供了交互检验(Cross Validation)的功能。该软件包可以在http://www.csie.ntu.edu.tw/~cjlin/免费获得。该软件可以解决C-SVM分类、-SVM分类、-SVM回归和-SVM回归等问题，包括基于一对一算法的多类模式识别问题。在第2章中我们也介绍了该软件的一些优点，因此通过综合考虑，我们决定采用该软件作为工作软件。SVM用于模式识别或回归时，SVM方法及其参数、核函数及其参数的选择，目前国际上还没有形成一个统一的模式，也就是说最优SVM算法参数选择还只能是凭借经验、实验对比、大范围的搜寻或者利用软件包提供的交互检验功能进行寻优。</P></DIV><!--   -->]]></description>
</item><item>
<title><![CDATA[（转）Matlab遗传算法工具箱函数及实例讲解]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45828</link>
<author>reincarnation</author>
<pubDate>2009/6/5 19:15:59</pubDate>
<description><![CDATA[<SPAN style="FONT-SIZE: 8pt"><FONT style="FONT-SIZE: 14px">核心函数：<BR>(1)function [pop]=initializega(num,bounds,eFN,eOps,options)--初始种群的生成函数<BR>【输出参数】<BR>pop--生成的初始种群<BR>【输入参数】<BR>num--种群中的个体数目<BR>bounds--代表变量的上下界的矩阵<BR>eFN--适应度函数<BR>eOps--传递给适应度函数的参数<BR>options--选择编码形式(浮点编码或是二进制编码)[precision F_or_B],如<BR>precision--变量进行二进制编码时指定的精度<BR>F_or_B--为1时选择浮点编码，否则为二进制编码,由precision指定精度)<BR><BR>(2)function [x,endPop,bPop,traceInfo] = ga(bounds,FN,Ops,startPop,opts,...<BR>termFN,termOps,selectFN,selectOps,xOverFNs,xOverOps,mutFNs,mutOps)--遗传算法函数<BR>【输出参数】<BR>x--求得的最优解<BR>endPop--最终得到的种群<BR>bPop--最优种群的一个搜索轨迹<BR>【输入参数】<BR>bounds--代表变量上下界的矩阵<BR>FN--适应度函数<BR>Ops--传递给适应度函数的参数<BR>startPop-初始种群<BR>opts[epsilon prob_ops display]--opts(1:2)等同于initializega的options参数，第三个参数控制是否输出，一般为0。如[1e-6 1 0]<BR>termFN--终止函数的名称,如['maxGenTerm']<BR>termOps--传递个终止函数的参数,如[100]<BR>selectFN--选择函数的名称,如['normGeomSelect']<BR>selectOps--传递个选择函数的参数,如[0.08]<BR>xOverFNs--交叉函数名称表，以空格分开，如['arithXover heuristicXover simpleXover']<BR>xOverOps--传递给交叉函数的参数表，如[2 0;2 3;2 0]<BR>mutFNs--变异函数表，如['boundaryMutation multiNonUnifMutation nonUnifMutation unifMutation']<BR>mutOps--传递给交叉函数的参数表,如[4 0 0;6 100 3;4 100 3;4 0 0]<BR><BR></FONT><SPAN style="FONT-SIZE: 10pt"><FONT style="FONT-SIZE: 14px" size=3>【问题】求<SPAN lang=EN-US XML:LANG="EN-US">f(x)=x+10*sin(5x)+7*cos(4x)</SPAN>的最大值，其中</FONT><FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US">0&lt;=x&lt;=9<BR></SPAN>【分析】选择二进制编码，种群中的个体数目为<SPAN lang=EN-US XML:LANG="EN-US">10</SPAN>，二进制编码长度为<SPAN lang=EN-US XML:LANG="EN-US">20</SPAN>，交叉概率为<SPAN lang=EN-US XML:LANG="EN-US">0.95,</SPAN>变异概率为</FONT></FONT></FONT><FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US">0.08<BR></SPAN>【程序清单】</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR>%</SPAN>编写目标函数</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR>function[sol,]=fitness(sol,options)<BR>x=sol(1);<BR>=x+10*sin(5*x)+7*cos(4*x);<BR>%</SPAN>把上述函数存储为<SPAN lang=EN-US XML:LANG="EN-US">fitness.m</SPAN>文件并放在工作目录下</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR><BR>initPop=initializega(10,[0 9],'fitness');%</SPAN>生成初始种群，大小为</FONT></FONT></FONT><FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US">10<BR>[x endPop,bPop,trace]=ga([0 9],'fitness',[],initPop,[1e-6 1 1],'maxGenTerm',25,'normGeomSelect',...<BR>[0.08],['arithXover'],[2],'nonUnifMutation',[2 25 3]) %25</SPAN>次遗传迭代</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR><BR></SPAN>运算借过为：</FONT></FONT></FONT><FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US">x =<BR>7.8562 24.8553(</SPAN>当<SPAN lang=EN-US XML:LANG="EN-US">x</SPAN>为<SPAN lang=EN-US XML:LANG="EN-US">7.8562</SPAN>时，<SPAN lang=EN-US XML:LANG="EN-US">f</SPAN>（<SPAN lang=EN-US XML:LANG="EN-US">x</SPAN>）取最大值</FONT></FONT></FONT><FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US">24.8553)<BR><BR></SPAN>注：遗传算法一般用来取得近似最优解，而不是最优解。</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR><BR><BR><BR></SPAN>遗传算法实例</FONT></FONT></FONT><FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US">2<BR><BR></SPAN>【问题】在－<SPAN lang=EN-US XML:LANG="EN-US">5&lt;=Xi&lt;=5,i=1,2</SPAN>区间内，求解</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR>f(x1,x2)=-20*exp(-0.2*sqrt(0.5*(x1.^2+x2.^2)))-exp(0.5*(cos(2*pi*x1)+cos(2*pi*x2)))+22.71282</SPAN>的最小值。</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR></SPAN>【分析】种群大小<SPAN lang=EN-US XML:LANG="EN-US">10</SPAN>，最大代数<SPAN lang=EN-US XML:LANG="EN-US">1000</SPAN>，变异率<SPAN lang=EN-US XML:LANG="EN-US">0.1,</SPAN>交叉率</FONT></FONT></FONT><FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US">0.3<BR></SPAN>【程序清单】</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR></SPAN>％源函数的<SPAN lang=EN-US XML:LANG="EN-US">matlab</SPAN>代码</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR>function []=f(sol)<BR>numv=size(sol,2);<BR>x=sol(1:numv);<BR>=-20*exp(-0.2*sqrt(sum(x.^2)/numv)))-exp(sum(cos(2*pi*x))/numv)+22.71282;<BR>%</SPAN>适应度函数的<SPAN lang=EN-US XML:LANG="EN-US">matlab</SPAN>代码</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR>function [sol,]=fitness(sol,options)<BR>numv=size(sol,2)-1;<BR>x=sol(1:numv);<BR>=f(x);<BR>=-;<BR>%</SPAN>遗传算法的<SPAN lang=EN-US XML:LANG="EN-US">matlab</SPAN>代码</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR>bounds=ones(2,1)*[-5 5];<BR>[p,endPop,bestSols,trace]=ga(bounds,'fitness')<BR><BR></SPAN>注：前两个文件存储为<SPAN lang=EN-US XML:LANG="EN-US">m</SPAN>文件并放在工作目录下，运行结果为</FONT></FONT></FONT> <FONT size=3><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><SPAN lang=EN-US XML:LANG="EN-US"><BR>p =<BR>0.0000 -0.0000 0.0055<BR><BR><BR><BR></SPAN>大家可以直接绘出<SPAN lang=EN-US XML:LANG="EN-US">f(x)</SPAN>的图形来大概看看<SPAN lang=EN-US XML:LANG="EN-US">f</SPAN>（<SPAN lang=EN-US XML:LANG="EN-US">x</SPAN>）的最值是多少，也可是使用优化函数来验证。<SPAN lang=EN-US XML:LANG="EN-US">matlab</SPAN>命令行执行命令：</FONT></FONT></FONT> <SPAN lang=EN-US XML:LANG="EN-US"><FONT style="FONT-SIZE: 18px"><FONT style="FONT-SIZE: 14px"><FONT size=3><BR>fplot('x+10*sin(5*x)+7*cos(4*x)',[0,9])</FONT><BR></FONT></FONT></SPAN></SPAN></SPAN>]]></description>
</item><item>
<title><![CDATA[（转）对Weka中DBSCAN算法的分析以及在C#中的实现]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45827</link>
<author>reincarnation</author>
<pubDate>2009/6/5 19:14:47</pubDate>
<description><![CDATA[
<DIV class=article_c id=fontsize>
<P>　　DBSCAN算法是常用的数据挖掘算法。所有的聚类方法分为若干类型，前面讨论过的KMEANS算法是基于划分的方法进行聚类，而这次提到的DBSCAN算法是基于密度的方法。当然其它的还有基于层次凝聚和分裂的方法、基于模型的方法等。我先对Weka中实现的DBSCAN算法进行一个介绍和分析，然后再分析自己用C#实现的DBSCAN方法。但在这之前要解释几个概念，如果之前没有了解过这个算法的话，最好是先熟悉几个概念：epsilon-邻域、核心对象、（直接）密度可达、密度相连，这些概念可以在《数据挖掘概念与技术》一书中找到，了解这些概念对理解这个算法来说是很重要的。</P>
<P>　　我们先来看看在Weka中是如何实现DBSCAN算法的：</P>
<P><CLK style="FONT-SIZE: 14px; LINE-HEIGHT: 17pt">　　DBSCAN算法的源代码在Weka的weka.clusterers这个包中，文件名为DBScan.<NOBR oncontextmenu="return false" onmousemove=$cE.MoW() id=clickeyekey0 onmouseover=$cE.s(event,0) style="FONT-SIZE: 14px; COLOR: #6600ff; LINE-HEIGHT: 17pt; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick='$cE.c(event,0,"",1)' onmouseout=$cE.OuK()>java</NOBR>。其中buildClusterer和expandCluster这两个方法是最核心的方法。buildClusterer是所有聚类方法的接口方法，而expandCluster是用于扩展样本对象集合的高密度连接区域的。另外还有一个叫epsilonRangeQuery的方法，这个方法位置Database类中，用于查询指定对象在epsilon邻域内的样本对象集合。</CLK></P>
<P>　　在buildClusterer方法中，通过对每个未聚类的样本点调用expandCluster方法进行处理，查找由这个对象开始的密度相连的最大样本对象集合。在这个方法中处理的主要代码如下，当expandCluster方法返回真的时候就说明一个簇已经形成，取下一个聚类标号。</P>
<P><CODE>Weka.DBSCAN<BR>while (iterator.hasNext()) {<BR>　　　 DataObject dataObject = (DataObject) iterator.next();<BR>　　　 if (dataObject.getClusterLabel() == DataObject.UNCLASSIFIED) {<BR>　　　　　　　 if (expandCluster(dataObject)) {<BR>　　　　　　　　　　　 clusterID++;<BR>　　　　　　　　　　　 numberOfGeneratedClusters++;<BR>　　　　　　　　 }<BR>　　　 }<BR>}</CODE></P><CODE>
<DIV class=article_c id=fontsize>
<P>　　buildClusterer方法中的代码比较简单，主要是提供一个处理入口。下面再来看expandCluster方法，这个方法要接收一个样本对象作为参数。在这个方法主要干几件事情：判断这个样本对象是不是核心对象，如果是核心对象再判断这个样本对象的epsilon邻域中的每一个对象，检查它们是不是核心对象，如果是核心对象则将其合并到当前的聚类中。源代码分析如下：</P>
<P><CODE>Weka.DBSCAN<BR>//查找dataObject这个样本对象的epsilon邻域中的所有样本对象并将其存放到一个列表中，这个列表用于存放在密度区域过程扩展中欲处理的样本对象，后面还会用到这个列表<BR>List seedList = database.epsilonRangeQuery(getEpsilon(), dataObject);<BR>//判断dataObject是不是核心对象<BR>if (seedList.size() &lt; getMinPoints()) {<BR>　　//如果不是核心对象则将其设置为噪声点<BR>　　dataObject.setClusterLabel(DataObject.NOISE);<BR>　　//将其设置为噪声点后要返回false以防止聚类编号的增加<BR>　　return false;<BR>}<BR><BR>//如果样本对象dataObject是核心对象，则对其邻域中的每一个对象进行处理<BR>for (int i = 0; i &lt; seedList.size(); i++) {<BR>　　DataObject seedListDataObject = (DataObject) seedList.get(i);<BR>　　<BR>　　//设置dataObject邻域中的每个样本对象的聚类标识，将其归为一个簇<BR>　　seedListDataObject.setClusterLabel(clusterID);<BR>　　<BR>　　//如果邻域中的样本对象与当前这个dataObject是同一个对象那么将其删除，如果在这里不做这个处理将会引起死循环<BR>　　if (seedListDataObject.equals(dataObject)) {<BR>　　　　 　　seedList.remove(i);<BR>　　　　i--;<BR>　　}<BR>}<BR><BR>　　//对dataObject的epsilon邻域中的每一个样本对象进行处理<BR>　　for (int j = 0; j &lt; seedList.size(); j++) {　　　 <BR>　　　　//从邻域中取出一个样本对象seedListDataObject<BR>　　　　DataObject seedListDataObject = (DataObject) seedList.get(j);　　<BR><BR>　　　　//查找seedListDataObject的epsilon邻域并取得其中所有的样本对象<BR>　　　　List seedListDataObject_Neighbourhood =　database.epsilonRangeQuery(getEpsilon(), seedListDataObject);<BR><BR>　　　　//判断seedListDataObject是不是核心对象<BR>　　　　if (seedListDataObject_Neighbourhood.size() &gt;= getMinPoints()) {<BR><BR>　　　　　　for (int i = 0; i &lt; seedListDataObject_Neighbourhood.size(); i++){<BR>　　　　　　　　DataObject p =　(DataObject) seedListDataObject_Neighbourhood.get(i);<BR>　　　　　　　　//如果seedListDataObject样本对象是一个核心对象则将这个样本对象邻域中的所有未被聚类的对象添加到seedList中<BR>　　　　　　　　//并且设置其中未聚类对象或噪声对象的聚类标号为当前聚类标号<BR>　　　　　　　　if (p.getClusterLabel() == DataObject.UNCLASSIFIED ||　p.getClusterLabel() == DataObject.NOISE) {<BR>　　　　　　　　　　if (p.getClusterLabel() == DataObject.UNCLASSIFIED)　{<BR>　　　　　　　　　　//在这里将样本对象添加到seedList列表中的做法是一种广度优先的方法，通过这种方法来逐步扩展当前聚类。<BR>　　　　　　　　　　//这是非常重要的一条语句。如果没有这句就不能形成扩展的查找趋势，不能找到一个完全的密度连接区域。<BR>　　　　　　　　　　seedList.add(p);<BR>　　　　　　　　}<BR>　　　　　　　　p.setClusterLabel(clusterID);<BR>　　　　　　}<BR>　　　　}<BR>　　}<BR>　　//去除当前处理的样本点，其目的与前面一样，为了避免死循环<BR>　　seedList.remove(j);<BR>　　j--;<BR>}<BR><BR>//查找到一个完整的密度连接区域后，返回真完成处理<BR>return true;</CODE></P><CODE>
<DIV class=article_c id=fontsize>
<P>　　上面分析了Weka中DBSCAN算法的执行流程，接下来就是C#版本的DBSCAN算法。C#的实现与Weka中的版本有一些区别。在上面的注释中已经提到过，Weka中的DBSCAN是以广度优先的方法来进行密度连接区域的扩展的，而在本文所提到的C#版本的DBSCAN算法是采用递归的方式以深度优先的方式进行密度连接区域的扩展。下面还是通过代码注释的方式进行分析，在分析之前先对几个自定义类型说明一下：</P>
<P>　　ClusterSample——用于表示样本对象的类</P>
<P>　　SampleStatus——用于表示样本对象状态的类，包含Unclassfied,Classfied,Noise三个枚举值</P>
<P>　　SampleCollection——用于表示样本集合的类，iCollection就是这个类的一个实例</P>
<P>　　代码分析：</P>
<P><CODE>C#.DBSCAN<BR>for (int i = 0; i &lt; iCollection.Count; i++)<BR>{<BR>　　　 ClusterSample sample = iCollection[i] as ClusterSample;<BR><BR>　　　 if (sample != null &amp;&amp; sample.Status == SampleStatus.Unclassfied)<BR>　　　 {<BR>　　　　　　　 RangeExpand(sample);<BR><BR>　　　　　　　 //完成一个簇的扩展后更改聚类标号<BR>　　　　　　　 if (sample.Status == SampleStatus.Classfied)<BR>　　　　　　　 {<BR>　　　　　　　　　　　 K++;<BR>　　　　　　　 }<BR>　　　 }<BR>}</CODE></P>
<P><CODE>Code<BR>IList&lt;ClusterSample&gt; epslionNeighborSamples = new List&lt;ClusterSample&gt;();　　　 <BR>epslionNeighborSamples = FindNeighborObjects(currSample);<BR>currSample.ClusterID = K;<BR><BR>//如果大于iMinPts值则为核心对象(此判断也是递归的结束条件)<BR>//移除当前样本点否则会造成无限递归，导致溢出<BR>epslionNeighborSamples.Remove(currSample);<BR>if (epslionNeighborSamples.Count &gt;= iMinPts)<BR>{<BR>　　　 foreach (ClusterSample item in epslionNeighborSamples)<BR>　　　 {<BR>　　　　　　　 //对于currSample邻域中的每一个样本，检查其是否也是核心对象<BR>　　　　　　　 //如果是核心对象那么从currSample到这个点是直接密度可达的。并且这两个对象之间就是密度相连的<BR>　　　　　　　 //如果不满足这一点，从currSample到item这个点就不是密度相连的，这个点也就不属于当前密度连接区域<BR>　　　　　　　 IList&lt;ClusterSample&gt; item_neighbours = FindNeighborObjects(item);<BR><BR>　　　　　　　 if (item_neighbours.Count &gt;= iMinPts)<BR>　　　　　　　 {<BR>　　　　　　　　　　　 if (item.Status == SampleStatus.Unclassfied || item.Status == SampleStatus.Noise)<BR>　　　　　　　　　　　 {<BR>　　　　　　　　　　　　　　　 item.ClusterID = K;<BR>　　　 <BR>　　　　　　　　　　　　　　　 //递归地查找密度可达的样本对象<BR>　　　　　　　　　　　　　　　 RangeExpand(item);<BR>　　　　　　　　　　　 }<BR>　　　　　　　 }<BR>　　　 }<BR>　　　 epslionNeighborSamples.Clear();<BR>}<BR>else<BR>{<BR>　　　 currSample.Status = SampleStatus.Noise;<BR>}</CODE></P>
<P></P>
<P>　　C#版本的DBSCAN算法的递归实现源于对样本集合分布形态的考虑，即对密度连接区域的搜索扩展总会收敛到某个对象，这个对象的邻域所包含的对象个数不大于参数所指定的个数，那么这个对象就是密度区域的结束位置，这时一轮递归处理结束。当对所有邻域中的对象进行了递归处理后，一个簇的生成就完成了，接着再进行下一个簇的生成，以此类推……</P>
<P>　　DBSCAN的执行过程是一个簇区域不断扩张的过程，所以与KMEANS不同（KMEANS对噪声数据非常敏感，也就是说KMEANS算法可能会因为噪声点而影响其计算结果），DBSCAN可以发现任意形状的聚类，并且可以发现样本集合中的噪声。在DBSCAN中没有被包含在任何簇中的样本对象就是噪声对象。</P></DIV></CODE></DIV></CODE></DIV>]]></description>
</item><item>
<title><![CDATA[（转）如何向weka中添加新算法]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45826</link>
<author>reincarnation</author>
<pubDate>2009/6/5 19:06:48</pubDate>
<description><![CDATA[<P>1.编写新算法，所编写的新算法必须符合Weka 的接口标准。在此以从Weka中文站上下载的一个算法（模糊C均值聚类算法：FuzzyCMeans）的添加为例说明其具体过程。</P>
<P>2.由于FuzzyCMeans是聚类算法，所以直接将FuzzyCMeans.java 源程序考到 weka.clusterers 包下。</P>
<P>3.再修改weka.gui.GenericObjectEditor.props ，在#Lists the Clusterers I want to choose from的weka.clusterers.Clusterer=\下加入：weka.clusterers.FuzzyCMeans。</P>
<P>4.相应的修改weka.gui.GenericPropertiesCreator<WBR>.props ，此去不用修改，因为包weka.clusterers已经存在，若加入新的包时则必须修改这里，加入新的包。<WBR></P>
<P>加入之后，重新编译，运行后，可以在weka的Explorer界面上的Cluster选项卡中的聚类算法中找到刚刚新添加的FuzzyCMeans算法。<WBR></P>
<P>添加过程的关键问题是要弄清楚Weka的内核以及其接口标准，然后编写出符合此规范的新算法。</P>]]></description>
</item><item>
<title><![CDATA[（转）当weka遇到大数据集时]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45784</link>
<author>reincarnation</author>
<pubDate>2009/6/2 20:46:37</pubDate>
<description><![CDATA[<P>用的数据集是Reuters-21578和20个新闻组。结果光是前者，我还只是选择了其中的7个类别，最后生成的训练集的arff文件就有150MB。 <BR>我为此还换了个1G的内存。调整了JVM的大小，居然还是不行。有没有高人指点一下呢。</P>
<P>150M的训练集用WEKA做起来应该比较困难。我想有这么几个办法： </P>
<P>1 增加内存。 其实WEKA不光可以用物理内存，还可以占用虚拟内存。把JAVA的可用内存设置成2G的话，如果机器的物理内存只有1G，操作系统是会在需要时自动在硬盘上划分一块出来作为虚拟内存的。不过这时候一般会处理得比较慢，因此不推荐这个方法。 </P>
<P>2 抽样。从训练集中随机抽取一部分数据来作训练。在二分类的时候，一般样本数量达到几千个时就能预测得比较准确了。如果几千个样本还不怎么准，那要么是所用的分类算法不适合，要么数据中的输入变量根本无法预测目标变量。 <BR>我试过了KDD 99中“kddcup.data_10_percent” 数据集，接近50万条数据，做成ARFF文件后有70多M。在Explorer中10来秒就载入了，抽取1%的样本仅花了几秒钟。 </P>
<P>3 增量学习（Incremental Learning）。所谓增量学习简单的说就是读取一条训练数据就修正一下模型，而不是把全部训练数据都读入之后才得到模型。在WEKA KnowledgeFlow 中支持增量学习算法。目前WEKA中有5种算法可以在这种方式下工作：NaiveBayesUpdateable, IB1, IBk, LWR。另外RacedIncrementalLogitBoost可以让任意的基于回归的算法来增量地学习分类任务。 </P>
<P>要注意的是，有时候数据不是ARFF格式的，而是C45,CSV等格式。这时手动把数据转换成ARFF，会节省很多内存，并且数据集中的错误更容易被检测出来。&nbsp; <BR>&nbsp;</P>]]></description>
</item><item>
<title><![CDATA[（转）由MyEclipse内存不足谈谈JVM内存]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45783</link>
<author>reincarnation</author>
<pubDate>2009/6/2 20:42:54</pubDate>
<description><![CDATA[
<DIV class=storycontent>
<DIV class=declaration>原文出处: <A href="http://www.javatang.com/archives/2007/12/03/1653250.html"><FONT color=#485f93>http://www.javatang.com/archives/2007/12/03/1653250.html</FONT></A><BR>作者: Jet Mah from <A href="http://www.javatang.com/"><FONT color=#485f93>Java堂</FONT></A><BR>声明: <B>可以非商业性任意转载, 转载时请务必以超链接形式标明文章原始出处、作者信息及此声明！</B> </DIV>
<P>如果没有进行设置的话，在使用MyEclipse的经常出现如下图所示内存不足的提示。<BR><IMG alt=myeclipse.png src="http://www.javatang.com/wp-content/myeclipse.png"><BR>提示中说的很明白：“MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) space remains.”意思是说当前只有小于5%的非堆内存是空闲的。所以我们只要将这个值设置大一些就可以了。</P>
<P>提示中给出了设置的参数：</P>
<DIV class=hl-surround>
<OL class="hl-main ln-show" ondblclick=linenumber(this) title="Double click to hide line number.">
<LI class=hl-firstline>-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M</LI></OL></DIV>
<P>这里有几个问题：<BR>1. 各个参数的含义什么？<BR>2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后Eclipse可以启动，而有些机器无法启动？<BR>3. 为何将上面的参数写入到eclipse.ini文件Eclipse没有执行对应的设置？</P>
<P>下面我们一一进行回答</P>
<P><STRONG>1. 各个参数的含义什么？</STRONG></P>
<P>参数中-vmargs的意思是设置JVM参数，所以后面的其实都是JVM的参数了，我们首先了解一下JVM内存管理的机制，然后再解释每个参数代表的含义。</P>
<BLOCKQUOTE>
<LI><STRONG>堆(Heap)和非堆(Non-heap)内存</STRONG><BR>按照官方的说法：“Java 虚拟机具有一个堆，堆是运行时数据区域，所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存：堆和非堆。简单来说堆就是Java代码可及的内存，是留给开发人员使用的；非堆就是JVM留给自己用的，所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。 
<LI><STRONG>堆内存分配</STRONG><BR>JVM初始分配的内存由-Xms指定，默认是物理内存的1/64；JVM最大分配的内存由-Xmx指定，默认是物理内存的1/4。默认空余堆内存小于40%时，JVM就会增大堆直到-Xmx的最大限制；空余堆内存大于70%时，JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。 
<LI><STRONG>非堆内存分配</STRONG><BR>JVM使用-XX:PermSize设置非堆内存初始值，默认是物理内存的1/64；由XX:MaxPermSize设置最大非堆内存的大小，默认是物理内存的1/4。 
<LI><STRONG>JVM内存限制(最大值)</STRONG><BR>首先JVM内存限制于实际的最大物理内存(废话！呵呵)，假设物理内存无限大的话，JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制，这个限制一般是2GB-3GB（一般来说Windows系统下为1.5G-2G，Linux系统下为2G-3G），而64bit以上的处理器就不会有限制了。 </LI></BLOCKQUOTE>
<P><STRONG>2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后Eclipse可以启动，而有些机器无法启动？</STRONG></P>
<P>通过上面对JVM内存管理的介绍我们已经了解到JVM内存包含两种：堆内存和非堆内存，另外JVM最大内存首先取决于实际的物理内存和操作系统。所以说设置VM参数导致程序无法启动主要有以下几种原因：</P>
<BLOCKQUOTE>
<P>1) 参数中-Xms的值大于-Xmx，或者-XX:PermSize的值大于-XX:MaxPermSize；</P>
<P>2) -Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制，比如当前操作系统最大内存限制，或者实际的物理内存等等。说到实际物理内存这里需要说明一点的是，如果你的内存是1024MB，但实际系统中用到的并不可能是1024MB，因为有一部分被硬件占用了。 </P></BLOCKQUOTE>
<P><STRONG>3. 为何将上面的参数写入到eclipse.ini文件Eclipse没有执行对应的设置？</STRONG></P>
<P>那为什么同样的参数在快捷方式或者命令行中有效而在eclipse.ini文件中是无效的呢？这是因为我们没有遵守eclipse.ini文件的设置规则：</P>
<BLOCKQUOTE>
<P>参数形如“项 值”这种形式，中间有空格的需要换行书写，如果值中有空格的需要用双引号包括起来。比如我们使用-vm C:\Java\jre1.6.0\bin\javaw.exe参数设置虚拟机，在eclipse.ini文件中要写成这样：</P>
<DIV class=hl-surround>
<OL class="hl-main ln-show" ondblclick=linenumber(this) title="Double click to hide line number.">
<LI class=hl-firstline>-vm 
<LI>C:\Java\jre1.6.0\bin\javaw.exe</LI></OL></DIV></BLOCKQUOTE>
<P>按照上面所说的，最后参数在eclipse.ini中可以写成这个样子：</P>
<DIV class=hl-surround>
<OL class="hl-main ln-show" ondblclick=linenumber(this) title="Double click to hide line number.">
<LI class=hl-firstline>-vmargs 
<LI>-Xms128M 
<LI>-Xmx512M 
<LI>-XX:PermSize=64M 
<LI>-XX:MaxPermSize=128M</LI></OL></DIV>
<P>实际运行的结果可以通过Eclipse中“Help”-“About Eclipse SDK”窗口里面的“Configuration Details”按钮进行查看。</P>
<P>另外需要说明的是，Eclipse压缩包中自带的eclipse.ini文件内容是这样的：</P>
<DIV class=hl-surround>
<OL class="hl-main ln-show" ondblclick=linenumber(this) title="Double click to hide line number.">
<LI class=hl-firstline>-showsplash 
<LI>org.eclipse.platform 
<LI>--launcher.XXMaxPermSize 
<LI>256m 
<LI>-vmargs 
<LI>-Xms40m 
<LI>-Xmx256m</LI></OL></DIV>
<P>其中–launcher.XXMaxPermSize（注意最前面是两个连接线）跟-XX:MaxPermSize参数的含义基本是一样的，我觉得唯一的区别就是前者是eclipse.exe启动的时候设置的参数，而后者是eclipse所使用的JVM中的参数。其实二者设置一个就可以了，所以这里可以把–launcher.XXMaxPermSize和下一行使用#注释掉。</P>
<P>参考资料：<BR><A href="http://blog.csdn.net/calvinxiu/archive/2007/05/18/1614473.aspx" target=_blank><FONT color=#485f93>JDK5.0垃圾收集优化之–Don’t Pause</FONT></A><BR><A href="http://www.javaeye.com/topic/38142?page=1" target=_blank><FONT color=#485f93>提问：如何超越JVM内存限制？</FONT></A><BR><A href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/management/MemoryMXBean.html" target=_blank><FONT color=#485f93>MemoryMXBean (Java 2 Platform SE 5.0)</FONT></A><BR><A href="http://hi.baidu.com/nickshen3/blog/item/83d89852ba1ee60d0cf3e30b.html" target=_blank><FONT color=#485f93>MyEclipse/Eclipse的内存优化与内存不足的解决办法</FONT></A><BR><A href="http://www.matrix.org.cn/thread.shtml?forumId=25&amp;topicId=c14f5fc6-81c0-11db-babc-9753a314dd4b" target=_blank><FONT color=#485f93>eclipse.ini文件的问题</FONT></A><BR><A href="http://zhidao.baidu.com/question/36893010.html?si=1" target=_blank><FONT color=#485f93>eclipse 为什么报错</FONT></A></P>
<DIV id=crp_related>
<H2>Related Posts:</H2>
<UL>
<LI><A href="http://www.javatang.com/archives/2007/10/30/2016233.html" rel=bookmark><FONT color=#485f93>C++基础之字符串处理函数</FONT></A> 
<LI><A href="http://www.javatang.com/archives/2007/07/04/4045184.html" rel=bookmark><FONT color=#485f93>查找接口实现类的Eclipse插件</FONT></A> 
<LI><A href="http://www.javatang.com/archives/2007/06/08/5540166.html" rel=bookmark><FONT color=#485f93>PHP常见问题及解答</FONT></A> 
<LI><A href="http://www.javatang.com/archives/2007/03/30/1025157.html" rel=bookmark><FONT color=#485f93>Windows下安装zip包版本的MySQL</FONT></A> 
<LI><A href="http://www.javatang.com/archives/2007/03/03/5603105.html" rel=bookmark><FONT color=#485f93>Lucene中文分词 “庖丁解牛”</FONT></A></LI></UL></DIV></DIV>]]></description>
</item><item>
<title><![CDATA[（转）Java虚拟机设置使用的内存[weblogic ,websphere ,jboss,eclipse]]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45782</link>
<author>reincarnation</author>
<pubDate>2009/6/2 20:42:20</pubDate>
<description><![CDATA[可以给Java虚拟机设置使用的内存，但是如果你的选择不对的话，虚拟机不会补偿。可通过命令行的方式改变虚拟机使用内存的大小。如下表所示有两个参数用来设置虚拟机使用内存的大小。 <BR>参数描述 <BR>-Xms JVM初始化堆的大小 <BR>-Xmx JVM堆的最大值 <BR><BR>　　这两个值的大小一般根据需要进行设置。初始化堆的大小执行了虚拟机在启动时向系统申请的内存的大小。一般而言，这个参数不重要。但是有的应用程序在大负载的情况下会急剧地占用更多的内存，此时这个参数就是显得非常重要，如果虚拟机启动时设置使用的内存比较小而在这种情况下有许多对象进行初始化，虚拟机就必须重复地增加内存来满足使用。由于这种原因，我们一般把-Xms和-Xmx设为一样大，而堆的最大值受限于系统使用的物理内存。一般使用数据量较大的应用程序会使用持久对象，内存使用有可能迅速地增长。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出，并且导致应用服务崩溃。因此<FONT color=#ff0000>一般建议堆的最大值设置为可用内存的最大值的80%</FONT>。 <BR>------------------------------------- <BR>　　Tomcat默认可以使用的内存为<FONT color=#ff0000>128MB</FONT>，在较大型的应用项目中，这点内存是不够的，需要调大。 <BR>　　Windows下，在文件{tomcat_home}/bin/catalina.bat，Unix下，在文件{tomcat_home}/bin/catalina.sh的前面，增加如下设置：　　JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】' <BR>　　需要把这个两个参数值调大。例如： <BR>　　JAVA_OPTS='-Xms<FONT color=#ff0000>256m</FONT> -Xmx<FONT color=#ff0000>512m</FONT>' <BR>　　表示初始化内存为256MB，可以使用的最大内存为512MB。 <BR>-------------------------------------- <BR>JBoss默认可以使用的内存为<FONT color=#ff0000>64MB</FONT> <BR><BR>$JBOSSDIR$/bin/run.config <BR><BR>JAVA_OPTS = "-server -Xms<FONT color=#ff0000>128</FONT> -Xmx<FONT color=#ff0000>512</FONT>" <BR>-------------------------------------- <BR>Websphere 进入控制台去设置（暂略） <BR>-------------------------------------- <BR>eclipse <BR>在所在目录下，键入 <BR>eclipse.exe -vmargs -Xms<FONT color=#ff0000>256m</FONT> -Xmx<FONT color=#ff0000>512m</FONT> <BR>256m表示JVM堆内存最小值 <BR>512m表示JVM堆内存最大 <BR>-------------------------------------- <BR>]]></description>
</item><item>
<title><![CDATA[（转）开源机器学习：R Meets Weka]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45781</link>
<author>reincarnation</author>
<pubDate>2009/6/2 20:40:24</pubDate>
<description><![CDATA[<A> 
<P>背景介绍： <BR>1）Weka： <BR>Weka有两种意思：一种不会飞的鸟的名字，一个机器学习开源项目的简称（Waikato Environment for Knowledge Analysis，</A><A href="http://www.cs.waikato.ac.nz/~ml/weka/">http://www.cs.waikato.ac.nz/~ml/weka/</A><A>）。我们这里当然要介绍的是第二种意思啦，Weka项目从1992年开始，由新西兰政府支持，现在已在机器学习领域大名鼎鼎。Weka里有非常全面的机器学习算法，包括数据预处理、分类、回归、聚类、关联规则等。Weka的图形界面对不会写程序的人来说非常方便，而且提供“KnowledgeFlow” 功能，允许将多个步骤组成一个工作流。另外，Weka也允许在命令行执行命令。 <BR>2）R <BR>R就不用我废话了吧，呵呵，越来越受欢迎的统计软件（</A><A href="http://www.r-project.org/">http://www.r-project.org/</A><A>）。 <BR>3）R与Weka： <BR>R里有很多机器学习的函数和包，不过Weka里提供的函数更全面更集中，所以我有时候需要用到Weka。以前我是这样用R和Weka的： <BR>在R中准备好训练的数据（如：提取数据特征……）； <BR>整理成Weka需要的格式（*.arff）； <BR>在Weka里做机器学习（如：特征选择、分类……）； <BR>从Weka的预测结果计算需要的统计量（如：sensitivity, specificity, MCC……）。 <BR>来回捣腾两个软件还是挺麻烦的；为了偷懒，我没学Weka的命令行，只会用图形界面的，在数据量大的时候非常受罪，有时候还会内存不够。现在发现R竟然提供了和Weka的接口函数包RWeka，以后方便多了哦，下面介绍一下RWeka的功能：</P>
<P>RWeka (</A><A href="http://cran.r-project.org/web/packages/RWeka/index.html">http://cran.r-project.org/web/packages/RWeka/index.html</A><A>) ： <BR>1) 数据输入和输出 <BR>WOW()：查看Weka函数的参数。 <BR>Weka_control()：设置Weka函数的参数。 <BR>read.arff()：读Weka Attribute-Relation File Format (ARFF)格式的数据。 <BR>write.arff：将数据写入Weka Attribute-Relation File Format (ARFF)格式的文件。 <BR>2) 数据预处理 <BR>Normalize()：无监督的标准化连续性数据。 <BR>Discretize()：用MDL(Minimum Description Length)方法，有监督的离散化连续性数值数据。 <BR>3) 分类和回归 <BR>IBk()：k最近邻分类 <BR>LBR()：naive Bayes法分类 <BR>J48()：C4.5决策树算法（决策树在分析各个属性时，是完全独立的）。 <BR>LMT()：组合树结构和Logistic回归模型，每个叶子节点是一个Logistic回归模型，准确性比单独的决策树和Logistic回归方法要好。 <BR>M5P()：M5 模型数算法，组合了树结构和线性回归模型，每个叶子节点是一个线性回归模型，因而可用于连续数据的回归。 <BR>DecisionStump()：单层决策树算法，常被作为boosting的基本学习器。 <BR>SMO()：支持向量机分类 <BR>AdaBoostM1()：Adaboost M1方法。-W参数指定弱学习器的算法。 <BR>Bagging()：通过从原始数据取样(用替换方法)，创建多个模型。 <BR>LogitBoost()：弱学习器采用了对数回归方法,学习到的是实数值 <BR>MultiBoostAB()：AdaBoost 方法的改进，可看作AdaBoost 和 “wagging”的组合。 <BR>Stacking()：用于不同的基本分类器集成的算法。 <BR>LinearRegression()：建立合适的线性回归模型。 <BR>Logistic()：建立logistic回归模型。 <BR>JRip()：一种规则学习方法。 <BR>M5Rules()：用M5方法产生回归问题的决策规则。 <BR>OneR()：简单的1-R分类法。 <BR>PART()：产生PART决策规则。 <BR>4) 聚类 <BR>Cobweb()：这是种基于模型方法，它假设每个聚类的模型并发现适合相应模型的数据。不适合对大数据库进行聚类处理。 <BR>FarthestFirst()：快速的近似的k均值聚类算法 <BR>SimpleKMeans()：k均值聚类算法 <BR>XMeans()：改进的k均值法，能自动决定类别数 <BR>DBScan()：基于密度的聚类方法，它根据对象周围的密度不断增长聚类。它能从含有噪声的空间数据库中发现任意形状的聚类。此方法将一个聚类定义为一组“密度连接”的点集。 <BR>5）关联规则 <BR>Apriori()：Apriori是关联规则领域里最具影响力的基础算法，是一种广度优先算法，通过多次扫描数据库来获取支持度大于最小支持度的频繁项集。它的理论基础是频繁项集的两个单调性原则：频繁项集的任一子集一定是频繁的；非频繁项集的任一超集一定是非频繁的。在海量数据的情况下，Apriori 算法的时间和空间成本非常高。 <BR>Tertius()：Tertius算法。 <BR>6）预测和评估： <BR>predict()：根据分类或聚类结果预测新数据的类别 <BR>table()：比较两个因子对象 <BR>evaluate_Weka_classifier()：评估模型的执行，如：TP Rate，FP Rate，Precision，Recall，F-Measure。</P>
<P>来源：</A><A href="http://rbbs.biosino.org/Rbbs/posts/list/196.page">http://rbbs.biosino.org/Rbbs/posts/list/196.page</A><A></P></A>]]></description>
</item><item>
<title><![CDATA[优秀的开源数据挖掘工具]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45777</link>
<author>reincarnation</author>
<pubDate>2009/6/2 17:33:56</pubDate>
<description><![CDATA[<P>转自<A href="http://www.w3china.org/blog/more.asp?name=DMman&amp;id=24009">http://www.w3china.org/blog/more.asp?name=DMman&amp;id=24009</A>和<A href="http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=41774">http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=41774</A></P>
<P>下文对几种流行的开源数据挖掘平台进行了介绍。如果您想找寻更多的开源数据挖掘软件，可以到KDnuggets和Open Directory上查找。</P>
<P>（1）&nbsp;R<BR>R（<A href="http://www.r-project.org">http://www.r-project.org</A>）是用于统计分析和图形化的计算机语言及分析工具，为了保证性能，其核心计算模块是用C、C++和Fortran编写的。同时为了便于使用，它提供了一种脚本语言，即R语言。R语言和贝尔实验室开发的S语言类似。R支持一系列分析技术，包括统计检验、预测建模、数据可视化等等。在CRAN（<A href="http://cran.r-project.org">http://cran.r-project.org</A>）上可以找到众多开源的扩展包。<BR>R软件的首选界面是命令行界面，通过编写脚本来调用分析功能。如果缺乏编程技能，也可使用图形界面，比如使用R Commander（<A href="http://socserv.mcmaster.ca/jfox/Misc/Rcmdr">http://socserv.mcmaster.ca/jfox/Misc/Rcmdr</A>）或Rattle（<A href="http://rattle.togaware.com">http://rattle.togaware.com</A>）。</P>
<P>（2）&nbsp;Tanagra<BR>Tanagra（<A href="http://eric.univ-lyon2.fr/wricco/tanagra">http://eric.univ-lyon2.fr/wricco/tanagra</A>）是使用图形界面的数据挖掘软件，采用了类似Windows资源管理器中的树状结构来组织分析组件。Tanagra缺乏高级的可视化能力，但它的强项是统计分析，提供了众多的有参和无参检验方法。同时它的特征选取方法也很多。</P>
<P>（3）&nbsp;WEKA<BR>WEKA（Waikato Environment for Knowledge Analysis, <A href="http://www.cs.waikato.ac.nz/ml/weka">http://www.cs.waikato.ac.nz/ml/weka</A>）可能是名气最大的开源机器学习和数据挖掘软件。高级用户可以通过Java编程和命令行来调用其分析组件。同时，WEKA也为普通用户提供了图形化界面，称为WEKA Knowledge Flow、WEKA Environment和WEKA Explorer。和R相比，WEKA在统计分析方面较弱，但在机器学习方面要强得多。在WEKA论坛（<A href="http://weka.wiki.sourceforge.net/Related+Projects">http://weka.wiki.sourceforge.net/Related+Projects</A>）可以找到很多扩展包，比如文本挖掘、可视化、网格计算等等。很多其它开源数据挖掘软件也支持调用WEKA的分析功能。</P>
<P>（4）&nbsp;YALE/RapidMiner<BR>YALE（Yet Another Learning Environment, <A href="http://rapid-i.com">http://rapid-i.com</A>）现在已经更名为RapidMiner。并且商业化。它提供了图形化界面，采用了类似Windows资源管理器中的树状结构来组织分析组件，树上每个节点表示不同的运算符（operator）。YALE中提供了大量的运算符，包括数据处理、变换、探索、建模、评估等各个环节。YALE是用Java开发的，基于WEKA来构建，也就是说它可以调用WEKA中的各种分析组件。</P>
<P>（5）&nbsp;Bow<BR>与Weka和Yale不同，Bow（<A href="http://www.cs.cmu.edu/~mccallum/bow">http://www.cs.cmu.edu/~mccallum/bow</A>）是专门为文本处理设计的开源包。Bow包含三个部分：Rainbow（文本分类）、Arrow（文本检索）和Crossbow（文本聚类）。</P>
<P>（6）&nbsp;AlphaMiner<BR>AlphaMiner（<A href="http://www.eti.hku.hk/alphaminer">http://www.eti.hku.hk/alphaminer</A>）是哈工大-香港大学商务智能联合实验室基于WEKA内核开发的一个通用的数据挖掘系统，它能够帮助用户建立一个完整的数据挖掘流程，并提供一系列的功能使得用户可执行其中的任意挖掘步骤。AlphaMiner系统最主要的特点是它能够把开发好的数据挖掘案例保存在它的知识库中以便于日后重用。对于一般的商业管理人员，这个功能显著地提高了AlphaMiner系统的可用性。通过配合其它的数据分析工具，如在小型商业中广泛应用的Excel软件，AlphaMiner系统还提供了除了建立数据挖掘模型以外的一些辅助功能。</P>
<P>（7）&nbsp;KNIME<BR>KNIME（Konstanz Information Miner, <A href="http://www.knime.org">http://www.knime.org</A>）是基于Eclipse开发环境来精心开发的数据挖掘工具。无需安装，方便使用。和YALE一样，KNIME也是用Java开发的，可以扩展使用WEKA中的挖掘算法。和YALE不同点的是，KNIME采用的是类似数据流（data flow）的方式来建立分析挖掘流程。挖掘流程由一系列功能节点（node）组成，每个节点有输入/输出端口（port），用于接收数据或模型、导出结果。<BR>KNIME中每个节点都带有交通信号灯，用于指示该节点的状态（未连接、未配置、缺乏输入数据时为红灯；准备执行为黄灯；执行完毕后为绿灯）。在KNIME中有个特色功能——HiLite，允许用户在节点结果中标记感兴趣的记录，并进一步展开后续探索。</P>
<P>（8）&nbsp;Orange<BR>Orange（<A href="http://www.ailab.si/orange">http://www.ailab.si/orange</A>）是类似KNIME和WEKA Knowledge Flow的数据挖掘工具，它的图形环境称为Orange画布（Orange Canvas），用户可以在画布上放置分析控件（widget），然后把控件连接起来即可组成挖掘流程。这里的控件和KNIME中的节点是类似的概念。每个控件执行特定的功能，但与KNIME中的节点不同，KNIME节点的输入输出分为两种类型（模型和数据），而Orange的控件间可以传递多种不同的信号，比如learners、classifiers、evaluation results、distance matrices、dendrograms等。Orange的控件不象KNIME的节点分得那么细，也就是说要完成同样的分析挖掘任务，在Orange里使用的控件数量可以比KNIME中的节点数少一些。Orange的好处是使用更简单一些，但缺点是控制能力要比KNIME弱。<BR>除了界面友好易于使用的优点，Orange的强项在于提供了大量可视化方法，可以对数据和模型进行多种图形化展示，并能智能搜索合适的可视化形式，支持对数据的交互式探索。<BR>Orange的弱项在于传统统计分析能力不强，不支持统计检验，报表能力也有限。Orange的底层核心也是采用C++编写，同时允许用户使用Python脚本语言来进行扩展开发（参见<A href="http://www.scipy.org">http://www.scipy.org</A>）。</P>
<P>（9）&nbsp;GGobi<BR>数据可视化是数据挖掘的重要组成部分，GGobi（<A href="http://www.ggobi.org">http://www.ggobi.org</A>）就是用于交互式可视化的开源软件，它使用brushing的方法。GGobi可以用作R软件的插件，或者通过Perl、Python等脚本语言来调用。</P>
<P>（10）&nbsp;Lucene<BR>Apache Lucene（<A href="http://lucene.apache.org">http://lucene.apache.org</A>）是一个开放源程序的搜寻器引擎，利用它可以轻易地为Java软件加入全文搜寻功能。Lucene的最主要工作是替文件的每一个字作索引，索引让搜寻的效率比传统的逐字比较大大提高，Lucen提供一组解读，过滤，分析文件，编排和使用索引的API，它的强大之处除了高效和简单外，是最重要的是使使用者可以随时应自已需要自订其功能。</P>
<P>以上介绍的几款软件都是优秀的开源数据挖掘软件，各有所长，同时也各有缺点。读者可以结合自己的需求来进行选择，或者组合使用多个软件。对于普通用户可以选用界面友好易于使用的软件，对于希望从事算法开发的用户则可以根据软件开发工具不同（Java、R、C++、Python等）来选择相应的软件。</P>]]></description>
</item><item>
<title><![CDATA[WEKA源码]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45776</link>
<author>reincarnation</author>
<pubDate>2009/6/2 17:28:42</pubDate>
<description><![CDATA[
<P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<P>到WEKA官网<A href="http://www.cs.waikato.ac.nz/ml/weka/">http://www.cs.waikato.ac.nz/ml/weka/</A>上下载WEKA安装程序。</P>
<P>安装后，把安装目录下的weka-src.jar文件解压后就是WEKA的源文件。 </P></TD></TR></TBODY></TABLE></P>]]></description>
</item><item>
<title><![CDATA[weka学习资料]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45775</link>
<author>reincarnation</author>
<pubDate>2009/6/2 17:24:01</pubDate>
<description><![CDATA[
<P>书籍：</P>
<P>《数据挖掘：实用机器学习技术》第2版</P>
<P>论坛：</P>
<P>WEKA中文论坛<A href="http://bbs.wekacn.org/index.php">http://bbs.wekacn.org/index.php</A></P>
<P>电子书：</P>
<P><A href="http://blogger.org.cn/blog/images/file/zip.gif" target=_blank><IMG onmousewheel="return bbimg(this)" title=点击在新窗口查看原始图片 src="http://blogger.org.cn/blog/images/file/zip.gif" onload="java_script_:if(this.width>500)this.width=500" border=0></A><A href="http://blogger.org.cn/blog/uploadfile/2007414165917393.RAR" target=_blank>ExplorerGuide-3[1].5.5.rar</A><BR><A href="http://blogger.org.cn/blog/images/file/zip.gif" target=_blank><IMG onmousewheel="return bbimg(this)" title=点击在新窗口查看原始图片 src="http://blogger.org.cn/blog/images/file/zip.gif" onload="java_script_:if(this.width>500)this.width=500" border=0></A><A href="http://blogger.org.cn/blog/uploadfile/2007414165951434.RAR" target=_blank>ExperimenterTutorial-3.5.3.rar</A></P>
<P>网上教程：</P>
<P>weka入门教程1 <A href="http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=21854">http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=21854</A><BR>weka入门教程2 <A href="http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=21856">http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=21856</A><BR>weka入门教程3 <A href="http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=21857">http://blogger.org.cn/blog/more.asp?name=idmer&amp;id=21857</A></P>
<P>&nbsp;</P>]]></description>
</item><item>
<title><![CDATA[如何将英文文本数据集转换为ARFF格式]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=reincarnation&amp;id=45774</link>
<author>reincarnation</author>
<pubDate>2009/6/2 17:05:24</pubDate>
<description><![CDATA[
<P>若采用的是英文文本语料库，利用WEKA将英文文本数据转换到ARFF格式中，需要用到以下两个工具：TextDirectoryToArff和TextDirectoryLoader。<BR>TextDirectoryToArff是一个JAVA类（Class），它负责将一个目录文件中的文本数据转换到一个ARFF文件中。<BR>TextDirectoryLoader是一个转换器（Converter），它是基于TextDirectoryToArff类的，并且处于weka.core.converters包中。</P>
<P>在转换之前，我们需要将文本数据集按照TextDirectoryLoader转换器所要求形式布局：</P>
<P>-----------------------------------------------------------<BR>...<BR>&nbsp;|<BR>&nbsp;+- example<BR>&nbsp;&nbsp;&nbsp; |<BR>&nbsp;&nbsp;&nbsp; +- class1<BR>&nbsp;&nbsp;&nbsp; |&nbsp; |<BR>&nbsp;&nbsp;&nbsp; |&nbsp; + file1.txt<BR>&nbsp;&nbsp;&nbsp; |&nbsp; |<BR>&nbsp;&nbsp;&nbsp; |&nbsp; + file2.txt<BR>&nbsp;&nbsp;&nbsp; |&nbsp; |<BR>&nbsp;&nbsp;&nbsp; |&nbsp; ...<BR>&nbsp;&nbsp;&nbsp; |<BR>&nbsp;&nbsp;&nbsp; +- class2<BR>&nbsp;&nbsp;&nbsp; |&nbsp; |<BR>&nbsp;&nbsp;&nbsp; |&nbsp; + another_file1.txt<BR>&nbsp;&nbsp;&nbsp; |&nbsp; |<BR>&nbsp;&nbsp;&nbsp; |&nbsp; + another_file2.txt<BR>&nbsp;&nbsp;&nbsp; |&nbsp; |<BR>&nbsp;&nbsp;&nbsp; |&nbsp; ...<BR>-----------------------------------------------------------<BR>&nbsp;<BR>按照上图所示的目录布局好文本数据后，将example文件夹放置在weka根目录下，我们利用WEKA的命令行界面（Simple CLI）输入以下命令：</P>
<P>java weka.core.converters.TextDirectoryLoader -dir example &gt; example.arff</P>
<P>此时，可以发现在weka根目录下生成了一个example.arff文件，这说明文本数据已经成功转换成了WEKA需要的ARFF文件了。</P>
<P>example.arff文件内容下图所示，从图中可以发现example文件夹下的子文件夹名变成了每个文档的类标记。</P>
<P>-----------------------------------------------------------<BR>@relation D__workspace_weka_example<BR>@attribute text string<BR>@attribute class {class1,class2,class3}<BR>@data<BR>‘文本内容’,class1<BR>‘文本内容’,class3<BR>‘文本内容’,class2<BR>‘文本内容’,class1<BR>‘文本内容’,class3<BR>...<BR>-----------------------------------------------------------</P>
<P>该方法对于中文文本数据不适用，生成的ARFF中的中文会变成乱码，需要修改WEKA的源码才能实现对中文文本数据的处理。</P>
<P>参考文献：<A href="http://weka.wiki.sourceforge.net/Text+categorization+with+Weka">http://weka.wiki.sourceforge.net/Text+categorization+with+Weka</A></P>]]></description>
</item>
</channel>
</rss>