<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>研究研究 &#187; admin</title>
	<atom:link href="http://www.yanjiuyanjiu.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.yanjiuyanjiu.com</link>
	<description>关注互联网和人工智能</description>
	<lastBuildDate>Wed, 04 Jan 2012 04:36:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Hadoop 集群安装详细步骤</title>
		<link>http://www.yanjiuyanjiu.com/2012/01/03/hadoop-cluster-setup/</link>
		<comments>http://www.yanjiuyanjiu.com/2012/01/03/hadoop-cluster-setup/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 14:12:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[集群，安装，配置，Fully distributed mode，setup]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/?p=4226</guid>
		<description><![CDATA[本文所使用的版本是 hadoop 1.0.0，即 2011年12月27日发布的1.0正式版。 详细安装步骤如下，有大步骤，每个步骤里面有小步骤，绝大部分是必选，只有2步是可选的，红色部分表示要特别注意的地方。 1. 用vmware workstation 新建一台ubuntu server，然后用浅拷贝Create a linked clone 克隆出两台作为slave，这样有了三台ubuntu机器。启动三台机器，假设IP分别为192.168.1.131, 192.168.1.132, 192.168.1.133, 131做为master,132为 slave01, 133为slave02。 2. 修改机器名（这一步的作用是让命令行提示看起来好看点，由默认的 dev@bogon变为 dev@master，这步可选，可以跳过） (1)192.168.1.131上执行 dev@bogon:~$ sudo vi /etc/hostname master 重启，会发现命令提示符变为了 dev@master:~$ (2)192.168.1.132上执行 dev@bogon:~$ sudo vi /etc/hostname slave01 重启，会发现命令提示符变为了 dev@slave01:~$ (3)192.168.1.133上执行 dev@bogon:~$ sudo vi /etc/hostname slave02 重启，会发现命令提示符变为了 dev@slave02:~$ 3. 修改master的hosts文件，并拷贝到每台slave上。 (1)dev@master:~$ sudo vi /etc/hosts 添加三行内容 192.168.1.131 [...]]]></description>
			<content:encoded><![CDATA[<p>本文所使用的版本是 hadoop 1.0.0，即 <a href="http://www.iteye.com/news/23874">2011年12月27日发布的1.0正式版</a>。</p>
<p>详细安装步骤如下，有大步骤，每个步骤里面有小步骤，绝大部分是必选，只有2步是可选的，红色部分表示要特别注意的地方。</p>
<p><strong>1. 用vmware workstation 新建一台ubuntu server</strong>，然后用浅拷贝Create a linked clone 克隆出两台作为slave，这样有了三台ubuntu机器。启动三台机器，假设IP分别为192.168.1.131, 192.168.1.132, 192.168.1.133, 131做为master,132为 slave01, 133为slave02。</p>
<p><strong>2. 修改机器名</strong>（这一步的作用是让命令行提示看起来好看点，由默认的 dev@bogon变为 dev@master，这步可选，可以跳过）</p>
<p>(1)192.168.1.131上执行</p>
<p>dev@bogon:~$ sudo vi /etc/hostname</p>
<p>master</p>
<p>重启，会发现命令提示符变为了 dev@master:~$</p>
<p>(2)192.168.1.132上执行</p>
<p>dev@bogon:~$ sudo vi /etc/hostname</p>
<p>slave01</p>
<p>重启，会发现命令提示符变为了 dev@slave01:~$</p>
<p>(3)192.168.1.133上执行</p>
<p>dev@bogon:~$ sudo vi /etc/hostname</p>
<p>slave02</p>
<p>重启，会发现命令提示符变为了 dev@slave02:~$</p>
<p><span id="more-4226"></span></p>
<p><strong>3. 修改master的hosts文件，并拷贝到每台slave上。</strong></p>
<p>(1)dev@master:~$ sudo vi /etc/hosts</p>
<p>添加三行内容</p>
<p>192.168.1.131 master<br />
192.168.1.133 slave01<br />
192.168.1.134 slave02</p>
<p><span style="color: #ff0000;">注意一定要注释掉</span></p>
<p><span style="color: #ff0000;">#127.0.1.1      bogon.localdomain       bogon</span></p>
<p>最后hosts文件内容如下：</p>
<p>127.0.0.1       localhost<br />
#127.0.1.1      bogon.localdomain       bogon<br />
192.168.1.131 master<br />
192.168.1.133 slave01<br />
192.168.1.134 slave02<br />
# The following lines are desirable for IPv6 capable hosts<br />
::1     ip6-localhost ip6-loopback<br />
fe00::0 ip6-localnet<br />
ff00::0 ip6-mcastprefix<br />
ff02::1 ip6-allnodes<br />
ff02::2 ip6-allrouters</p>
<p>(2)将hosts文件拷贝到另外两台台机器上，覆盖原来的hosts文件</p>
<p>dev@master:~$ scp /etc/hosts dev@192.168.1.132:~</p>
<p>dev@master:~$ scp /etc/hosts dev@192.168.1.133:~</p>
<p>(3)在192.168.1.132上执行</p>
<p>dev@slave01:~$ sudo mv hosts /etc/hosts</p>
<p>(4)在192.168.1.133上执行</p>
<p>dev@slave02:~$ sudo mv hosts /etc/hosts</p>
<p><strong>4. 配置 master 无密码登陆到所有机器（<span style="color: #ff0000;">包括本机</span>）</strong></p>
<p>(1)dev@master:~$ ssh-keygen -t rsa</p>
<p>dev@master:~$ cat .ssh/id_rsa.pub &gt;&gt; .ssh/authorized_keys</p>
<p>dev@master:~$ scp .ssh/id_rsa.pub dev@192.168.1.132:~/</p>
<p>dev@master:~$ scp .ssh/id_rsa.pub dev@192.168.1.133:~/</p>
<p>dev@slave01:~$ cat id_rsa.pub &gt;&gt; .ssh/authorized_keys</p>
<p>dev@slave02:~$ cat id_rsa.pub &gt;&gt; .ssh/authorized_keys</p>
<p>(2)测试一下，</p>
<p>dev@master:~$ ssh slav01</p>
<p>如果登陆不上，试试先关闭slave01的防火墙，</p>
<p>dev@slave01:~$ sudo ufw disable</p>
<p><strong>5. 从hadoop.apache.org下载 hadoop-1.0.0-bin.tar.gz，上传到master中，解压，然后复制到其他机器，解压。</strong></p>
<p>dev@master:~$ tar -zxvf hadoop-1.0.0-bin.tar.gz</p>
<p>dev@master:~$ scp hadoop-1.0.0-bin.tar.gz dev@192.168.1.133:~</p>
<p>dev@master:~$ scp hadoop-1.0.0-bin.tar.gz dev@192.168.1.134:~</p>
<p>dev@slave01:~$ tar -zxvf hadoop-1.0.0-bin.tar.gz</p>
<p>dev@slave02:~$ tar -zxvf hadoop-1.0.0-bin.tar.gz</p>
<p><strong>6. 编辑配置文件</strong></p>
<p>dev@master:~$ cd hadoop-1.0.0/etc/hadoop</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$  vi hadoop-env.sh</p>
<p>仅需要设置JAVA_HOME，export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-i386</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$  vi core-site.xml</p>
<p>&lt;configuration&gt;<br />
&lt;name&gt;fs.default.name&lt;/name&gt;<br />
&lt;value&gt;hdfs://192.168.1.131:9000&lt;/value&gt;</p>
<p>&lt;/configuration&gt;</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$  vi mapred-site.xml</p>
<p>&lt;configuration&gt;<br />
&lt;property&gt;<br />
&lt;name&gt;mapred.job.tracker&lt;/name&gt;<br />
&lt;value&gt;192.168.1.131:9001&lt;/value&gt;</p>
<p>&lt;/property&gt;<br />
&lt;/configuration&gt;</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$  vi hdfs-site.xml</p>
<p>&lt;configuration&gt;<br />
&lt;property&gt;<br />
&lt;name&gt;dfs.replication&lt;/name&gt;<br />
&lt;value&gt;3&lt;/value&gt;<br />
&lt;/property&gt;<br />
&lt;/configuration&gt;</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$  vi masters</p>
<p>192.168.1.133</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$  vi slaves</p>
<p>192.168.1.133</p>
<p>192.168.1.134</p>
<p><strong>7. 将配置文件拷贝到各台slave</strong>（master和slaves这2个配置文件可以不拷贝到slave机器上，只在master上保存即可。待验证）</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$ scp hadoop-env.sh core-site.xml hdfs-site.xml mapred-site.xml masters slaves dev@192.168.1.133:~/hadoop-1.0.0/etc/hadoop</p>
<p>dev@master:~/hadoop-1.0.0/etc/hadoop$ scp hadoop-env.sh core-site.xml hdfs-site.xml mapred-site.xml masters slaves dev@192.168.1.134:~/hadoop-1.0.0/etc/hadoop</p>
<p><strong>8. 设置环境变量</strong></p>
<p>(1). 设置master的环境变量</p>
<p>dev@master:~$ vi .bashrc</p>
<p>export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-i386<br />
export CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar<br />
export PATH=$PATH:$JAVA_HOME/bin<br />
export HADOOP_HOME=~/hadoop-1.0.0<br />
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin<br />
export CLASSPATH=$CLASSPATH:$HADOOP_HOME/share/hadoop/hadoop-core-1.0.0.jar</p>
<p>export HADOOP_HOME=~/hadoop-1.0.0</p>
<p>export PATH=$PATH:$HADOOP_HOME/bin</p>
<p>dev@master:~$ source .bashrc</p>
<p>(2) 将master上的.bashrc拷贝到其他机器，并source刷新。</p>
<p>dev@master:~$ scp .bashrc dev@192.168.1.133:~</p>
<p>dev@master:~$ scp .bashrc dev@192.168.1.134:~</p>
<p>dev@slave01:~$ source .bashrc</p>
<p>dev@slave02:~$ source .bashrc</p>
<p><strong>9. 运行 hadoop</strong></p>
<p>dev@master:~$ hadoop  namenode -format  （只需一次，下次启动不再需要格式化，只需 start-all.sh）</p>
<p>dev@master:~$ start-all.sh</p>
<p><strong>10. 检查是否运行成功</strong></p>
<p>dev@master:~$ jps</p>
<p>2615 NameNode<br />
2767 JobTracker<br />
2874 Jps</p>
<p>dev@slave01:~$ jps</p>
<p>3415 DataNode<br />
3582 TaskTracker<br />
3499 SecondaryNameNode<br />
3619 Jps</p>
<p>dev@slave02:~$ jps</p>
<p>3741 Jps<br />
3618 DataNode<br />
3702 TaskTracker</p>
<p><strong>11. 停止 hadoop集群</strong></p>
<p>dev@master:~$ stop-all.sh</p>
<p>让 slave 节点也 可以启动 整个hadoop集群</p>
<p>&nbsp;</p>
<p><span style="font-size: small;"><strong><span style="color: #ff0000;">注意</span></strong> </span></p>
<p>1. stat-all.sh 启动后，刚刚开始，namenode的日志里有些异常，是正常的，过一两分钟就好了，如果两分钟后，还有异常不断在打印，就有问题了。datanode的日志，从一开始，正常情况下，就没有异常，如果报了异常，说明有异常，要去排除。</p>
<p>2. masters文件，这个文件很容易被误解，它实际上存放的是secondarynamenode，而不是namenode。<span style="color: #a5a5a5;">An HDFS instance is started on a cluster by logging in to the NameNode machine and running$HADOOP_HOME/bin/start-dfs.sh (orstart-all.sh ). This script. starts a local instance of the NameNode process, logs into every machine listed in theconf/slaves file and starts an instance of the DataNode process, and logs into every machine listed in theconf/masters file and starts an instance of the SecondaryNameNode process. Themasters file does not govern which nodes become NameNodes or JobTrackers; those are started on the machine(s) </span><span style="color: #a5a5a5;">wherebin/start-dfs.sh andbin/start-mapred.sh are executed. A more accurate filename might be “secondaries,” but that’s not currently the case.</span></p>
<p>参考以下三篇文章<br />
<a href="http://www.cloudera.com/blog/2009/02/multi-host-secondarynamenode-configuration/">Multi-host SecondaryNameNode Configuration</a><br />
<a href="http://blog.csdn.net/dajuezhao/article/details/5987580">SecondaryNamenode应用摘记</a><br />
<a href="http://blog.csdn.net/AE86_FC/article/details/5284181">hadoop下运行多个SecondaryNameNode的配置</a></p>
<p>3. 一定要注释掉 hosts里面的 #127.0.1.1      bogon.localdomain       bogon，参考 <a href="http://blog.sina.com.cn/s/blog_631ffec50100w700.html">Hadoop集群机器命名机制</a>，<a href="http://blog.csdn.net/singno116/article/details/6298995">hadoop集群环境安装中的hosts 配置问题</a>。</p>
<p>4. 当测试ssh是否能连通时，如果连接不上，先记得要关闭防火墙，sudo ufw disable，参考<a href="http://blog.csdn.net/make19830723/article/details/6230074">hadoop集群安装步骤</a>。</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000; font-size: small;"><strong>未解决的疑惑</strong></span></p>
<p>1. 有的很多文章，比如这篇，<a href="http://blog.csdn.net/cuishi0/article/details/6824884">Hadoop集群安装</a>，在core-site.xml, mapred-site.xml，直接写上ip:port，这样就不用修改hosts文件了。可是我这样配置，老是不成功。为此我还<a href="http://stackoverflow.com/questions/8702637/hadoop-conf-fs-default-name-cant-be-setted-ipport-format-directly">在stackoverflow上发了帖子</a>，。<a href="http://51mst.iteye.com/blog/1152439">有的文章</a>又说只能用host:port的形式。因此ip:port的格式是否能成功还待验证。如果有高手用ip:port配置成功过，请在下面留言或给我发email，一起交流:)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2012/01/03/hadoop-cluster-setup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用javac命令行编译多个java文件</title>
		<link>http://www.yanjiuyanjiu.com/2011/06/23/javac-mutiple-files/</link>
		<comments>http://www.yanjiuyanjiu.com/2011/06/23/javac-mutiple-files/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 07:21:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[语言与算法]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/?p=4204</guid>
		<description><![CDATA[1. CLASSPATH一定要具体到jar路径，例如 export CLASSPATH=/usr/lib/jvm/java-6-sun/lib/commons-codec.jar:/usr/lib/jvm/java-6-sun/lib/commons-httpclient-3.1.jar:/usr/lib/jvm/java-6-sun/lib/commons-logging-1.1.jar:/usr/lib/jvm/java-6-sun/lib/dt.jar:/usr/lib/jvm/java-6-sun/lib/htmlconverter.jar:/usr/lib/jvm/java-6-sun/lib/jconsole.jar:/usr/lib/jvm/java-6-sun/lib/junit-4.1.jar:/usr/lib/jvm/java-6-sun/lib/mysql-connector-java-5.1.16-bin.jar:/usr/lib/jvm/java-6-sun/lib/sa-jdi.jar:/usr/lib/jvm/java-6-sun/lib/tools.jar 2. 每个java文件给出路径，最常见的是用通配符*，不支持目录递归。 3. 最好加上 -d，这样会在这个目录下生成class文件，而不会和java文件混在一起 看我的一个具体的例子 javac -d /home/dfq/crawler/bin crawler/*.java weibo4j/*.java weibo4j/org/json/*.java weibo4j/*.java weibo4j/util/*.java weibo4j/http/*.java 运行时用如下命令： cd /home/dfq/crawler/bin java -cp .:$CLASSPATH crawler.ManagerThread]]></description>
			<content:encoded><![CDATA[<p>1. CLASSPATH一定要具体到jar路径，例如<br />
export CLASSPATH=/usr/lib/jvm/java-6-sun/lib/commons-codec.jar:/usr/lib/jvm/java-6-sun/lib/commons-httpclient-3.1.jar:/usr/lib/jvm/java-6-sun/lib/commons-logging-1.1.jar:/usr/lib/jvm/java-6-sun/lib/dt.jar:/usr/lib/jvm/java-6-sun/lib/htmlconverter.jar:/usr/lib/jvm/java-6-sun/lib/jconsole.jar:/usr/lib/jvm/java-6-sun/lib/junit-4.1.jar:/usr/lib/jvm/java-6-sun/lib/mysql-connector-java-5.1.16-bin.jar:/usr/lib/jvm/java-6-sun/lib/sa-jdi.jar:/usr/lib/jvm/java-6-sun/lib/tools.jar</p>
<p>2. 每个java文件给出路径，最常见的是用通配符*，不支持目录递归。</p>
<p>3. 最好加上 -d，这样会在这个目录下生成class文件，而不会和java文件混在一起</p>
<p>看我的一个具体的例子<br />
javac  -d /home/dfq/crawler/bin crawler/*.java weibo4j/*.java weibo4j/org/json/*.java weibo4j/*.java weibo4j/util/*.java weibo4j/http/*.java</p>
<p>运行时用如下命令：<br />
cd /home/dfq/crawler/bin<br />
java -cp .:$CLASSPATH crawler.ManagerThread</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2011/06/23/javac-mutiple-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于朴素贝叶斯的文本分类算法</title>
		<link>http://www.yanjiuyanjiu.com/2010/05/28/naive-bayes-text-classification/</link>
		<comments>http://www.yanjiuyanjiu.com/2010/05/28/naive-bayes-text-classification/#comments</comments>
		<pubDate>Fri, 28 May 2010 08:37:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[naive bayes]]></category>
		<category><![CDATA[text classification]]></category>
		<category><![CDATA[文本分类]]></category>
		<category><![CDATA[朴素贝叶斯]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/2010/05/28/%e5%9f%ba%e4%ba%8e%e6%9c%b4%e7%b4%a0%e8%b4%9d%e5%8f%b6%e6%96%af%e7%9a%84%e6%96%87%e6%9c%ac%e5%88%86%e7%b1%bb%e7%ae%97%e6%b3%95-4/</guid>
		<description><![CDATA[基于朴素贝叶斯的文本分类算法 作者: 灵魂机器 联系方式：soulmachine@gmail.com 作者博客：www.yanjiuyanjiu.com 摘要：常用的文本分类方法有支持向量机、K-近邻算法和朴素贝叶斯。其中朴素贝叶斯具有容易实现，运行速度快的特点，被广泛使用。本文详细介绍了朴素贝叶斯的基本原理，讨论了两种常见模型：多项式模型（MM）和伯努利模型（BM），实现了可运行的代码，并进行了一些数据测试。 关键字：朴素贝叶斯；文本分类 Text Classification Algorithm Based on Naive Bayes Author: soulmachine Email：soulmachine@gmail.com Blog：www.yanjiuyanjiu.com Abstract:Usually there are three methods for text classification: SVM、KNN and Naïve Bayes. Naïve Bayes is easy to implement and fast, so it is widely used. This article introduced the theory of Naïve Bayes and discussed two popular [...]]]></description>
			<content:encoded><![CDATA[<p><strong>基于朴素贝叶斯的文本分类算法</strong><strong> </strong></p>
<p>作者: 灵魂机器</p>
<p>联系方式：<a href="mailto:soulmachine@gmail.com">soulmachine@gmail.com</a></p>
<p>作者博客：<a href="http://www.yanjiuyanjiu.com">www.yanjiuyanjiu.com</a></p>
<p><strong>摘要</strong>：常用的文本分类方法有支持向量机、K-近邻算法和朴素贝叶斯。其中朴素贝叶斯具有容易实现，运行速度快的特点，被广泛使用。本文详细介绍了朴素贝叶斯的基本原理，讨论了两种常见模型：多项式模型（MM）和伯努利模型（BM），实现了可运行的代码，并进行了一些数据测试。</p>
<p><strong>关键字</strong>：朴素贝叶斯；文本分类</p>
<p><strong>Text Classification Algorithm Based on Naive Bayes</strong></p>
<p>Author: soulmachine</p>
<p>Email：<a href="mailto:soulmachine@gmail.com">soulmachine@gmail.com</a></p>
<p>Blog：<a href="http://www.yanjiuyanjiu.com">www.yanjiuyanjiu.com</a></p>
<p><strong>Abstract</strong>:Usually there are three methods for text classification: SVM、KNN and Naïve Bayes. Naïve Bayes is easy to implement and fast, so it is widely used. This article introduced the theory of Naïve Bayes and discussed two popular models: multinomial model(MM) and Bernoulli model(BM) in details, implemented runnable code and performed some data tests.</p>
<p><strong>Keywords</strong>: naïve bayes; text classification</p>
<h3>第1章 贝叶斯原理</h3>
<h4>1.1 贝叶斯公式</h4>
<p>设A、B是两个事件，且P(A)&gt;0，称</p>
<p><a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image002.gif"><img style="display: inline; border-width: 0px;" title="clip_image002" src="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image002_thumb.gif" border="0" alt="clip_image002" width="117" height="36" /></a></p>
<p>为在事件A发生的条件下事件B发生的<strong>条件概率</strong>。</p>
<p><strong>乘法公式</strong> P(XYZ)=P(Z|XY)P(Y|X)P(X)</p>
<p><strong>全概率公式</strong> P(X)=P(X|Y<sub>1</sub>)+ P(X|Y<sub>2</sub>)+…+ P(X|Y<sub>n</sub>)</p>
<p><strong>贝叶斯公式</strong><a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image004.gif"><img style="display: inline; border-width: 0px;" title="clip_image004" src="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image004_thumb.gif" border="0" alt="clip_image004" width="240" height="40" /></a></p>
<p>在此处，贝叶斯公式，我们要用到的是<a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image006.gif"><img style="display: inline; border-width: 0px;" title="clip_image006" src="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image006_thumb.gif" border="0" alt="clip_image006" width="195" height="43" /></a></p>
<p>以上公式，请读者参考<a href="http://book.douban.com/subject/1231189/">《概率论与数理统计（第五版）》</a>的1.4节“条件概率”（这里将原书中的A换成了X，B换成了Y），获得更深的理解。</p>
<h4>1.2贝叶斯定理在分类中的应用</h4>
<p>在分类（classification）问题中，常常需要把一个事物分到某个类别。一个事物具有很多属性，把它的众多属性看做一个向量，即x=(x<sub>1</sub>,x<sub>2</sub>,x<sub>3</sub>,…,x<sub>n</sub>)，用x这个向量来代表这个事物。类别也是有很多种，用集合Y={y<sub>1</sub>,y<sub>2</sub>,…y<sub>m</sub>}表示<a name="_GoBack"></a>。如果x属于y1类别，就可以给x打上y1标签，意思是说x属于y1类别。这就是所谓的<strong>分类</strong><strong>(Classification)</strong>。</p>
<p>x的集合记为X，称为属性集。一般X和Y的关系是不确定的，你只能在某种程度上说x有多大可能性属于类y1，比如说x有80%的可能性属于类y1，这时可以把X和Y看做是随机变量，P(Y|X)称为Y的<strong>后验概率</strong>（posterior probability），与之相对的，P(Y)称为Y的<strong>先验概率</strong>（prior probability）<sup>[2]</sup>。</p>
<p>在训练阶段，我们要根据从训练数据中收集的信息，对X和Y的每一种组合学习后验概率P(Y|X)。分类时，来了一个实例x，在刚才训练得到的一堆后验概率中找出所有的P(Y|x)， 其中最大的那个y，即为x所属分类。根据贝叶斯公式，后验概率为</p>
<p><a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image008.gif"><img style="display: inline; border-width: 0px;" title="clip_image008" src="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image008_thumb.gif" border="0" alt="clip_image008" width="184" height="43" /></a></p>
<p>在比较不同Y值的后验概率时，分母P(X)总是常数，因此可以忽略。先验概率P(Y)可以通过计算训练集中属于每一个类的训练样本所占的比例容易地估计。</p>
<p>我们来举个简单的例子，让读者对上述思路有个形象的认识<sup>[3]</sup>。</p>
<p>考虑一个医疗诊断问题，有两种可能的假设：（1）病人有癌症。（2）病人无癌症。样本数据来自某化验测试，它也有两种可能的结果：阳性和阴性。假设我们已经有先验知识：在所有人口中只有0.008的人患病。此外，化验测试对有病的患者有98%的可能返回阳性结果，对无病患者有97%的可能返回阴性结果。</p>
<p>上面的数据可以用以下概率式子表示：</p>
<p>P(cancer)=0.008,P(无cancer)=0.992</p>
<p>P(阳性|cancer)=0.98,P(阴性|cancer)=0.02</p>
<p>P(阳性|无cancer)=0.03，P(阴性|无cancer)=0.97</p>
<p>假设现在有一个新病人，化验测试返回阳性，是否将病人断定为有癌症呢？</p>
<p>在这里，Y={cancer，无cancer}，共两个类别，这个新病人是一个样本，他有一个属性阳性，可以令x=(阳性)。</p>
<p>我们可以来计算各个类别的后验概率：</p>
<p>P(cancer | 阳性) = P(阳性 | cancer)p(cancer)=0.98*0.008 = 0.0078</p>
<p>P(无cancer | 阳性) =P(阳性 | 无cancer)*p(无cancer)=0.03*0.992 = 0.0298</p>
<p>因此，应该判断为无癌症。</p>
<p>在这个例子中，类条件概率，P(cancer|阳性)和P(无cancer|阳性)直接告诉了我们。</p>
<p>一般地，对<strong>类条件概率</strong>P(X|Y)的估计，有朴素贝叶斯分类器和贝叶斯信念网络两种方法，这里介绍朴素贝叶斯分类器。<span id="more-4162"></span></p>
<h4>1.3朴素贝叶斯分类器</h4>
<p><strong>1</strong><strong>、条件独立性</strong><strong> </strong></p>
<p>给定类标号y，朴素贝叶斯分类器在估计类条件概率时假设属性之间条件独立。条件独立假设可以形式化的表达如下：</p>
<p><a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image010.gif"><img style="display: inline; border-width: 0px;" title="clip_image010" src="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image010_thumb.gif" border="0" alt="clip_image010" width="200" height="45" /></a></p>
<p>其中每个训练样本可用一个属性向量X=(x<sub>1</sub>,x<sub>2</sub>,x<sub>3</sub>,…,x<sub>n</sub>)表示，各个属性之间条件独立。</p>
<p>比如，对于一篇文章，</p>
<p>Good good study,Day day up.</p>
<p>可以用一个<strong>文本特征向量</strong>来表示，x=(Good, good, study, Day, day , up)。一般各个词语之间肯定不是相互独立的，有一定的上下文联系。但在朴素贝叶斯文本分类时，我们假设个单词之间没有联系，可以用一个文本特征向量来表示这篇文章，这就是“朴素”的来历。</p>
<p><strong>2</strong><strong>、朴素贝叶斯如何工作</strong><strong> </strong></p>
<p>有了条件独立假设，就不必计算X和Y的每一种组合的类条件概率，只需对给定的Y，计算每个xi的条件概率。后一种方法更实用，因为它不需要很大的训练集就能获得较好的概率估计。</p>
<p><strong>3</strong><strong>、估计分类属性的条件概率</strong><strong> </strong></p>
<p>P(x<sub>i</sub>|Y=y)怎么计算呢？它一般根据类别y下包含属性xi的实例的比例来估计。以文本分类为例，xi表示一个单词，P(x<sub>i</sub>|Y=y)=包含该类别下包含单词的xi的文章总数/ 该类别下的文章总数。</p>
<p><strong>4</strong><strong>、贝叶斯分类器举例</strong><strong> </strong></p>
<p>假设给定了如下训练样本数据，我们学习的目标是根据给定的天气状况判断你对PlayTennis这个请求的回答是Yes还是No。</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="95" valign="top">Day</td>
<td width="95" valign="top">Outlook</td>
<td width="95" valign="top">Temperature</td>
<td width="95" valign="top">Humidity</td>
<td width="95" valign="top">Wind</td>
<td width="95" valign="top">PlayTennis</td>
</tr>
<tr>
<td width="95" valign="top">D1</td>
<td width="95" valign="top">Sunny</td>
<td width="95" valign="top">Hot</td>
<td width="95" valign="top">High</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">No</td>
</tr>
<tr>
<td width="95" valign="top">D2</td>
<td width="95" valign="top">Sunny</td>
<td width="95" valign="top">Hot</td>
<td width="95" valign="top">High</td>
<td width="95" valign="top">Strong</td>
<td width="95" valign="top">No</td>
</tr>
<tr>
<td width="95" valign="top">D3</td>
<td width="95" valign="top">Overcast</td>
<td width="95" valign="top">Hot</td>
<td width="95" valign="top">High</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D4</td>
<td width="95" valign="top">Rain</td>
<td width="95" valign="top">Mild</td>
<td width="95" valign="top">High</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D5</td>
<td width="95" valign="top">Rain</td>
<td width="95" valign="top">Cool</td>
<td width="95" valign="top">Normal</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D6</td>
<td width="95" valign="top">Rain</td>
<td width="95" valign="top">Cool</td>
<td width="95" valign="top">Normal</td>
<td width="95" valign="top">Strong</td>
<td width="95" valign="top">No</td>
</tr>
<tr>
<td width="95" valign="top">D7</td>
<td width="95" valign="top">Overcast</td>
<td width="95" valign="top">Cool</td>
<td width="95" valign="top">Normal</td>
<td width="95" valign="top">Strong</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D8</td>
<td width="95" valign="top">Sunny</td>
<td width="95" valign="top">Mild</td>
<td width="95" valign="top">High</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">No</td>
</tr>
<tr>
<td width="95" valign="top">D9</td>
<td width="95" valign="top">Sunny</td>
<td width="95" valign="top">Cool</td>
<td width="95" valign="top">Normal</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D10</td>
<td width="95" valign="top">Rain</td>
<td width="95" valign="top">Mild</td>
<td width="95" valign="top">Normal</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D11</td>
<td width="95" valign="top">Sunny</td>
<td width="95" valign="top">Mild</td>
<td width="95" valign="top">Normal</td>
<td width="95" valign="top">Strong</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D12</td>
<td width="95" valign="top">Overcast</td>
<td width="95" valign="top">Mild</td>
<td width="95" valign="top">High</td>
<td width="95" valign="top">Strong</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D13</td>
<td width="95" valign="top">Overcast</td>
<td width="95" valign="top">Hot</td>
<td width="95" valign="top">Normal</td>
<td width="95" valign="top">Weak</td>
<td width="95" valign="top">Yes</td>
</tr>
<tr>
<td width="95" valign="top">D14</td>
<td width="95" valign="top">Rain</td>
<td width="95" valign="top">Mild</td>
<td width="95" valign="top">High</td>
<td width="95" valign="top">Strong</td>
<td width="95" valign="top">No</td>
</tr>
</tbody>
</table>
<p>可以看到这里样本数据集提供了14个训练样本，我们将使用此表的数据，并结合朴素贝叶斯分类器来分类下面的新实例：</p>
<p>x = (Outlook = Sunny,Temprature = Cool,Humidity = High,Wind = Strong)</p>
<p>在这个例子中，属性向量X=(Outlook, Temperature, Humidity, Wind)，类集合Y={Yes, No}。我们需要利用训练数据计算后验概率P(Yes|x)和P(No|x)，如果P(Yes|x)&gt;P(No|x)，那么新实例分类为Yes，否则为No。</p>
<p>为了计算后验概率，我们需要计算先验概率P(Yes)和P(No)和类条件概率P(xi|Y)。</p>
<p>因为有9个样本属于Yes，5个样本属于No，所以P(Yes)=9/14, P(No)=5/14。</p>
<p>类条件概率计算如下：</p>
<p>P(Outlook = Sunny|Yes)=2/9 P(Outlook = Sunny|No)=3/5</p>
<p>P(Temprature = Cool |Yes) =3/9 P(Temprature = Cool |No) =1/5</p>
<p>P(Humidity = High |Yes) =3/9 P(Humidity = High |No) =4/5</p>
<p>P(Wind = Strong |Yes) =3/9 P(Wind = Strong |No) =3/5</p>
<p>后验概率计算如下：</p>
<p>P(Yes | x)= P(Outlook = Sunny|Yes)×P(Temprature = Cool |Yes)×P(Humidity = High |Yes)×P(Wind = Strong |Yes)×P(Yes)=2/9×3/9×3/9×3/9×3/9×9/14=2/243=9/1701≈0.00529</p>
<p>P(No | x)= P(Outlook = Sunny|No)×P(Temprature = Cool |No)×P(Humidity = High |No)× P(Wind = Strong |No)×P(No)=3/5×1/5×4/5×3/5×5/14=18/875≈0.02057</p>
<p>通过计算得出P(No | x)&gt; P(Yes | x)，所以该样本分类为No[3]。</p>
<p><strong>5</strong><strong>、条件概率的</strong><strong>m</strong><strong>估计</strong><strong></strong></p>
<p>假设有来了一个新样本 x1= (Outlook = Cloudy,Temprature = Cool,Humidity = High,Wind = Strong)，要求对其分类。我们来开始计算，</p>
<p>P(Outlook = Cloudy|Yes)=0/9=0 P(Outlook = Cloudy |No)=0/5=0</p>
<p>计算到这里，大家就会意识到，这里出现了一个新的属性值，在训练样本中所没有的。如果有一个属性的类条件概率为0，则整个类的后验概率就等于0，我们可以直接得到后验概率P(Yes | x1)= P(No | x1)=0，这时二者相等，无法分类。</p>
<p>当训练样本不能覆盖那么多的属性值时，都会出现上述的窘境。简单的使用样本比例来估计类条件概率的方法太脆弱了，尤其是当训练样本少而属性数目又很大时。</p>
<p>解决方法是使用m估计(m-estimate)方法来估计条件概率：</p>
<p><a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image012.gif"><img style="display: inline; border-width: 0px;" title="clip_image012" src="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image012_thumb.gif" border="0" alt="clip_image012" width="129" height="41" /></a></p>
<p>n是类y<sub>j</sub>中的样本总数，n<sub>c</sub>是类y<sub>j</sub>中取值x<sub>i</sub>的样本数，m是称为等价样本大小的参数，而p是用户指定的参数。如果没有训练集（即n=0），则P(x<sub>i</sub>|y<sub>j</sub>)=p, 因此p可以看作是在类yj的样本中观察属性值xi的先验概率。等价样本大小决定先验概率和观测概率n<sub>c</sub>/n之间的平衡[2]。</p>
<h3>第2章 朴素贝叶斯文本分类算法</h3>
<p>现在开始进入本文的主旨部分：如何将贝叶斯分类器应用到文本分类上来。</p>
<h4>2.1文本分类问题</h4>
<p>在文本分类中，假设我们有一个文档d∈X，X是文档向量空间(document space)，和一个固定的类集合C={c1,c2,…,cj}，类别又称为标签。显然，文档向量空间是一个高维度空间。我们把一堆打了标签的文档集合&lt;d,c&gt;作为训练样本，&lt;d,c&gt;∈X×C。例如：</p>
<p>&lt;d,c&gt;={Beijing joins the World Trade Organization, China}</p>
<p>对于这个只有一句话的文档，我们把它归类到 China，即打上china标签。</p>
<p>我们期望用某种训练算法，训练出一个函数γ，能够将文档映射到某一个类别：</p>
<p>γ:X→C</p>
<p>这种类型的学习方法叫做有监督学习，因为事先有一个监督者（我们事先给出了一堆打好标签的文档）像个老师一样监督着整个学习过程。</p>
<p>朴素贝叶斯分类器是一种有监督学习，常见有两种模型，多项式模型(multinomial model)和伯努利模型(Bernoulli model)。</p>
<h4>2.2多项式模型</h4>
<p><strong>1</strong><strong>、基本原理</strong><strong></strong></p>
<p>在多项式模型中， 设某文档d=(t<sub>1</sub>,t<sub>2</sub>,…,t<sub>k</sub>)，t<sub>k</sub>是该文档中出现过的单词，允许重复，则</p>
<p>先验概率P(c)= 类c下单词总数/整个训练样本的单词总数</p>
<p>类条件概率P(t<sub>k</sub>|c)=(类c下单词t<sub>k</sub>在各个文档中出现过的次数之和+1)/(类c下单词总数+|V|)</p>
<p>V是训练样本的单词表（即抽取单词，单词出现多次，只算一个），|V|则表示训练样本包含多少种单词。在这里，m=|V|, p=1/|V|。</p>
<p>P(t<sub>k</sub>|c)可以看作是单词t<sub>k</sub>在证明d属于类c上提供了多大的证据，而P(c)则可以认为是类别c在整体上占多大比例(有多大可能性)。</p>
<p><strong>2</strong><strong>、伪代码</strong><strong></strong></p>
<p>//C，类别集合，D，用于训练的文本文件集合</p>
<p>TrainMultiNomialNB(C,D) {</p>
<p>// 单词出现多次，只算一个</p>
<p>V←ExtractVocabulary(D)</p>
<p>// 单词可重复计算</p>
<p>N←CountTokens(D)</p>
<p>for each c∈C</p>
<p>// 计算类别c下的单词总数</p>
<p>// N和Nc的计算方法和Introduction to Information Retrieval上的不同，个人认为</p>
<p>//该书是错误的，先验概率和类条件概率的计算方法应当保持一致</p>
<p>Nc←CountTokensInClass(D,c)</p>
<p>prior[c][/c]←Nc/N</p>
<p>// 将类别c下的文档连接成一个大字符串</p>
<p>text<sub>c</sub>←ConcatenateTextOfAllDocsInClass(D,c)</p>
<p>for each t∈V</p>
<p>// 计算类c下单词t的出现次数</p>
<p>T<sub>ct</sub>←CountTokensOfTerm(text<sub>c</sub>,t)</p>
<p>for each t∈V</p>
<p>//计算P(t|c)</p>
<p>condprob[t][c][/c]←<a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image014.gif"><img style="display: inline; border-width: 0px;" title="clip_image014" src="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/clip_image014_thumb.gif" border="0" alt="clip_image014" width="98" height="64" /></a></p>
<p>return V,prior,condprob</p>
<p>}</p>
<p>ApplyMultiNomialNB(C,V,prior,condprob,d) {</p>
<p>// 将文档d中的单词抽取出来，允许重复，如果单词是全新的，在全局单词表V中都</p>
<p>// 没出现过，则忽略掉</p>
<p>W←ExtractTokensFromDoc(V,d)</p>
<p>for each c∈C</p>
<p>score[c][/c]←prior[c][/c]</p>
<p>for each t∈W</p>
<p>if t∈Vd</p>
<p>score[c][/c] *= condprob[t][c][/c]</p>
<p>return max(score[c][/c])</p>
<p>}</p>
<p><strong>3</strong><strong>、举例</strong><strong></strong></p>
<p>给定一组分类好了的文本训练数据，如下：</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="64" valign="top">docId</td>
<td width="236" valign="top">doc</td>
<td width="126" valign="top">类别</p>
<p>In c=China?</td>
</tr>
<tr>
<td width="64" valign="top">1</td>
<td width="236" valign="top">Chinese Beijing Chinese</td>
<td width="126" valign="top">yes</td>
</tr>
<tr>
<td width="64" valign="top">2</td>
<td width="236" valign="top">Chinese Chinese Shanghai</td>
<td width="126" valign="top">yes</td>
</tr>
<tr>
<td width="64" valign="top">3</td>
<td width="236" valign="top">Chinese Macao</td>
<td width="126" valign="top">yes</td>
</tr>
<tr>
<td width="64" valign="top">4</td>
<td width="236" valign="top">Tokyo Japan Chinese</td>
<td width="126" valign="top">no</td>
</tr>
</tbody>
</table>
<p>给定一个新样本Chinese Chinese Chinese Tokyo Japan，对其进行分类。</p>
<p>该文本用属性向量表示为d=(Chinese, Chinese, Chinese, Tokyo, Japan)，类别集合为Y={yes, no}。</p>
<p>类yes下总共有8个单词，类no下总共有3个单词，训练样本单词总数为11，因此P(yes)=8/11, P(no)=3/11。类条件概率计算如下：</p>
<p>P(Chinese | yes)=(5+1)/(8+6)=6/14=3/7</p>
<p>P(Japan | yes)=P(Tokyo | yes)= (0+1)/(8+6)=1/14</p>
<p>P(Chinese|no)=(1+1)/(3+6)=2/9</p>
<p>P(Japan|no)=P(Tokyo| no) =(1+1)/(3+6)=2/9</p>
<p>分母中的8，是指yes类别下text<sub>c</sub>的长度，也即训练样本的单词总数，6是指训练样本有Chinese,Beijing,Shanghai, Macao, Tokyo, Japan 共6个单词，3是指no类下共有3个单词。</p>
<p>有了以上类条件概率，开始计算后验概率，</p>
<p>P(yes | d)=(3/7)<sup>3</sup>×1/14×1/14×8/11=108/184877≈0.00058417</p>
<p>P(no | d)= (2/9)<sup>3</sup>×2/9×2/9×3/11=32/216513≈0.00014780</p>
<p>因此，这个文档属于类别china。</p>
<h4>2.3伯努利模型</h4>
<p><strong>1</strong><strong>、基本原理</strong><strong></strong></p>
<p>P(c)= 类c下文件总数/整个训练样本的文件总数</p>
<p>P(t<sub>k</sub>|c)=(类c下包含单词t<sub>k</sub>的文件数+1)/(类c下单词总数+2)</p>
<p>在这里，m=2, p=1/2。</p>
<p>后验概率的计算，也有点变化，见下面的伪代码。</p>
<p><strong>2</strong><strong>、伪代码</strong><strong></strong></p>
<p>//C，类别集合，D，用于训练的文本文件集合</p>
<p>TrainBernoulliNB(C, D) {</p>
<p>// 单词出现多次，只算一个</p>
<p>V←ExtractVocabulary(D)</p>
<p>// 计算文件总数</p>
<p>N←CountDocs(D)</p>
<p>for each c∈C</p>
<p>// 计算类别c下的文件总数</p>
<p>Nc←CountDocsInClass(D,c)</p>
<p>prior[c][/c]←Nc/N</p>
<p>for each t∈V</p>
<p>// 计算类c下包含单词t的文件数</p>
<p>Nct←CountDocsInClassContainingTerm(D,c,t)</p>
<p>//计算P(t|c)</p>
<p>condprob[t][c][/c]←(Nct+1)/(Nct+2)</p>
<p>return V,prior,condprob</p>
<p>}</p>
<p>ApplyBernoulliNB(C,V,prior,condprob,d) {</p>
<p>// 将文档d中单词表抽取出来，如果单词是全新的，在全局单词表V中都没出现过，</p>
<p>// 则舍弃</p>
<p>V<sub>d</sub>←ExtractTermsFromDoc(V,d)</p>
<p>for each c∈C</p>
<p>score[c][/c]←prior[c][/c]</p>
<p>for each t∈V</p>
<p>if t∈V<sub>d</sub></p>
<p>score[c][/c] *= condprob[t][c][/c]</p>
<p>else</p>
<p>score[c][/c] *= (1-condprob[t][c][/c])</p>
<p>return max(score[c][/c])</p>
<p>}</p>
<p><strong>3</strong><strong>、举例</strong><strong></strong></p>
<p>还是使用前面例子中的数据，不过模型换成了使用伯努利模型。</p>
<p>类yes下总共有3个文件，类no下有1个文件，训练样本文件总数为11，因此P(yes)=3/4, P(Chinese | yes)=(3+1)/(3+2)=4/5</p>
<p>P(Japan | yes)=P(Tokyo | yes)=(0+1)/(3+2)=1/5</p>
<p>P(Beijing | yes)= P(Macao|yes)= P(Shanghai |yes)=(1+1)/(3+2)=2/5</p>
<p>P(Chinese|no)=(1+1)/(1+2)=2/3</p>
<p>P(Japan|no)=P(Tokyo| no) =(1+1)/(1+2)=2/3</p>
<p>P(Beijing| no)= P(Macao| no)= P(Shanghai | no)=(0+1)/(1+2)=1/3</p>
<p>有了以上类条件概率，开始计算后验概率，</p>
<p>P(yes | d)=P(yes)×P(Chinese|yes) ×P(Japan|yes) ×P(Tokyo|yes)×(1-P(Beijing|yes)) ×(1-P(Shanghai|yes))×(1-P(Macao|yes))</p>
<p>=3/4×4/5×1/5×1/5×(1-2/5) ×(1-2/5)×(1-2/5)=81/15625≈0.005</p>
<p>P(no | d)= 1/4×2/3×2/3×2/3×(1-1/3)×(1-1/3)×(1-1/3)=16/729≈0.022</p>
<p>因此，这个文档不属于类别china。</p>
<h4>2.4两个模型的区别</h4>
<p>二者的计算粒度不一样，多项式模型以单词为粒度，伯努利模型以文件为粒度，因此二者的先验概率和类条件概率的计算方法都不同。</p>
<p>计算后验概率时，对于一个文档d，多项式模型中，只有在d中出现过的单词，才会参与后验概率计算，伯努利模型中，没有在d中出现，但是在全局单词表中出现的单词，也会参与计算，不过是作为“反方”参与的。</p>
<h3>第3章 代码详解</h3>
<p>本文附带了一个eclipse工程，有完整的源代码，以及一个微型文本训练库。</p>
<p>ChineseSpliter用于中文分词，StopWordsHandler用于判断一个单词是否是停止词，ClassifyResult用于保存结果，IntermediateData用于预处理文本语料库，TrainnedModel用于保存训练后得到的数据，NaiveBayesClassifier是基础类，包含了贝叶斯分类器的主要代码，MultiNomialNB是多项式模型，类似的，BernoulliNB是伯努利模型，二者都继承自NaiveBayesClassifier，都只重写了父类的计算先验概率，类条件概率和后验概率这3个函数。</p>
<h4>3.1中文分词</h4>
<p>中文分词不是本文的重点，这里我们直接使用第三方工具，本源码使用的是<a href="http://www.jesoft.cn/">极易中文分词组件</a>，你还可以使用<a href="http://chtsai.org/">MMSEG</a>，中科院的<a href="http://ictclas.org/">ICTCLAS</a>等等。</p>
<p>/**</p>
<p>* 对给定的文本进行中文分词.</p>
<p>*</p>
<p>* <strong>@param</strong> text</p>
<p>* 给定的文本</p>
<p>* <strong>@param</strong> splitToken</p>
<p>* 用于分割的标记,如”|”</p>
<p>* <strong>@return</strong> 分词完毕的文本</p>
<p>*/</p>
<p><strong>public</strong> String split(<strong>final</strong> String text, <strong>final</strong> String splitToken) {</p>
<p>String result = <strong>null</strong>;</p>
<p><strong>try</strong> {</p>
<p>result = analyzer.segment(text, splitToken);</p>
<p>} <strong>catch</strong> (IOException e) {</p>
<p>e.printStackTrace();</p>
<p>}</p>
<p><strong>return</strong> result;</p>
<p>}</p>
<h4>3.2停止词处理</h4>
<p>停止词(Stop Word)是指那些无意义的字或词，如“的”、“在”等。去掉文档中的停止词也是必须的一项工作,这里简单的定义了一些常见的停止词，并根据这些常用停止词在分词时进行判断。</p>
<p>/** 常用停用词. */</p>
<p><strong>private</strong> <strong>static</strong> String[] <em>stopWordsList</em> = {</p>
<p>// 来自 c:\Windows\System32\NOISE.CHS</p>
<p>“的”, “一”, “不”, “在”, “人”, “有”, “是”, “为”, “以”, “于”, “上”, “他”, “而”,</p>
<p>“后”, “之”, “来”, “及”, “了”, “因”, “下”, “可”, “到”, “由”, “这”, “与”, “也”,</p>
<p>“此”, “但”, “并”, “个”, “其”, “已”, “无”, “小”, “我”, “们”, “起”, “最”, “再”,</p>
<p>“今”, “去”, “好”, “只”, “又”, “或”, “很”, “亦”, “某”, “把”, “那”, “你”, “乃”,</p>
<p>“它”,</p>
<p>// 来自网络</p>
<p>“要”, “将”, “应”, “位”, “新”, “两”, “中”, “更”, “我们”, “自己”, “没有”, ““”, “””,</p>
<p>“，”, “（”, “）”, “” };</p>
<p>/**</p>
<p>* 判断一个词是否是停止词.</p>
<p>*</p>
<p>* <strong>@param</strong> word</p>
<p>* 要判断的词</p>
<p>* <strong>@return</strong> 是停止词，返回true，否则返回false</p>
<p>*/</p>
<p><strong>public</strong> <strong>static</strong> <strong>boolean</strong> isStopWord(<strong>final</strong> String word) {</p>
<p><strong>for</strong> (<strong>int</strong> i = 0; i &lt; <em>stopWordsList</em>.length; ++i) {</p>
<p><strong>if</strong> (word.equalsIgnoreCase(<em>stopWordsList</em>[i])) {</p>
<p><strong>return</strong> <strong>true</strong>;</p>
<p>}</p>
<p>}</p>
<p><strong>return</strong> <strong>false</strong>;</p>
<p>}</p>
<h4>3.3预处理数据</h4>
<p>我们这里使用<a href="http://www.sogou.com/labs/dl/c.html">搜狗的文本分类语料库</a>作为训练样本，把SogouC.reduced.20061102.tar.gz解压到D盘，目录结构为</p>
<p>D:\Reduced</p>
<p>|&#8211; C000008</p>
<p>|&#8211; C000010</p>
<p>|&#8211; C000013</p>
<p>|&#8211; C000014</p>
<p>|&#8211; C000016</p>
<p>|&#8211; C000020</p>
<p>|&#8211; C000022</p>
<p>|&#8211; C000023</p>
<p>|&#8211; C000024</p>
<p>IntermediateData.java主要用于处理文本数据，将所需要的信息计算好，存放到数据库文件中。</p>
<p>中间数据文件主要保存了如下信息，</p>
<p>/** 单词X在类别C下出现的总数. */</p>
<p><strong>public</strong> <span style="text-decoration: underline;">HashMap</span>[] filesOfXC;</p>
<p>/** 给定分类下的文件数目. */</p>
<p><strong>public</strong> <strong>int</strong>[] filesOfC;</p>
<p>/** 根目录下的文件总数. */</p>
<p><strong>public</strong> <strong>int</strong> files;</p>
<p>/** 单词X在类别C下出现的总数 */</p>
<p><strong>public</strong> <span style="text-decoration: underline;">HashMap</span>[] tokensOfXC;</p>
<p>/** 类别C下所有单词的总数. */</p>
<p><strong>public</strong> <strong>int</strong>[] tokensOfC;</p>
<p>/** 整个语料库中单词的总数. */</p>
<p><strong>public</strong> <strong>int</strong> tokens;</p>
<p>/** 整个训练语料所出现的单词. */</p>
<p><strong>public</strong> HashSet&lt;String&gt; vocabulary;</p>
<p>我们使用命令</p>
<p>IntermediateData d:\Reduced\ gbk d:\reduced.db</p>
<p>将文本训练库的信息计算好，保存到中间文件中。以后的阶段，我们都不再需要文本语料库了，只需要reduced.db。</p>
<h4>3.3训练</h4>
<p>基本的框架代码都在NaiveBayesClassifier中，MultiNomialNB和BernoulliNB都只是重新实现(override)了</p>
<p>/** 计算先验概率P(c). */</p>
<p><strong>protected</strong> <strong>void</strong> calculatePc() {</p>
<p>}</p>
<p>/** 计算类条件概率P(x|c). */</p>
<p><strong>protected</strong> <strong>void</strong> calculatePxc() {</p>
<p>}</p>
<p>/**</p>
<p>* 计算文本属性向量X在类<span style="text-decoration: underline;">Cj</span>下的后验概率P(<span style="text-decoration: underline;">Cj</span>|X).</p>
<p>*</p>
<p>* <strong>@param</strong> x</p>
<p>* 文本属性向量</p>
<p>* <strong>@param</strong> cj</p>
<p>* 给定的类别</p>
<p>* <strong>@return</strong> 后验概率</p>
<p>*/</p>
<p><strong>protected</strong> <strong>double</strong> calcProd(<strong>final</strong> String[] x, <strong>final</strong> <strong>int</strong> cj) {</p>
<p><strong>return</strong> 0;</p>
<p>}</p>
<p>这三个函数。</p>
<p>训练函数如下：</p>
<p><strong>public</strong> <strong>final</strong> <strong>void</strong> train(String intermediateData, String modelFile) {</p>
<p>// 加载中间数据文件</p>
<p>loadData(intermediateData);</p>
<p>model = <strong>new</strong> TrainnedModel(db.classifications.length);</p>
<p>model.classifications = db.classifications;</p>
<p>model.vocabulary = db.vocabulary;</p>
<p>// 开始训练</p>
<p>calculatePc();</p>
<p>calculatePxc();</p>
<p>db = <strong>null</strong>;</p>
<p><strong>try</strong> {</p>
<p>// 用序列化，将训练得到的结果存放到模型文件中</p>
<p>ObjectOutputStream out = <strong>new</strong> ObjectOutputStream(</p>
<p><strong>new</strong> FileOutputStream(modelFile));</p>
<p>out.writeObject(model);</p>
<p>out.close();</p>
<p>} <strong>catch</strong> (IOException e) {</p>
<p>e.printStackTrace();</p>
<p>}</p>
<p>}</p>
<p>我们使用命令：</p>
<p>MultiNomialNB –t d:\reduced.db d:\reduced.mdl</p>
<p>开始训练，得到的模型文件保存在reduced.mdl中。</p>
<h4>3.4分类</h4>
<p>有了模型文件，就可以用它来进行分类了。</p>
<p>可以使用命令</p>
<p>MultiNomialNB d:\reduced.mdl d:\temp.txt gbk</p>
<p>对文本文件temp.txt进行分类。</p>
<p>还可以将当初训练出这个模型文件的文本库，进行分类，看看正确率有多少，即“吃自己的狗食”，命令行如下</p>
<p>MultiNomialNB -r d:\reduced\ gbk d:\reduced.mdl</p>
<p>分类函数如下：</p>
<p>/**</p>
<p>* 对给定的文本进行分类.</p>
<p>*</p>
<p>* <strong>@param</strong> text</p>
<p>* 给定的文本</p>
<p>* <strong>@return</strong> 分类结果</p>
<p>*/</p>
<p><strong>public</strong> <strong>final</strong> String classify(<strong>final</strong> String text) {</p>
<p>String[] terms = <strong>null</strong>;</p>
<p>// 中文分词处理(分词后结果可能还包含有停用词）</p>
<p>terms = textSpliter.split(text, ” “).split(” “);</p>
<p>// 去掉停用词，以免影响分类</p>
<p>terms = ChineseSpliter.<em>dropStopWords</em>(terms);</p>
<p><strong>double</strong> probility = 0.0;</p>
<p>// 分类结果</p>
<p>List&lt;ClassifyResult&gt; crs = <strong>new</strong> ArrayList&lt;ClassifyResult&gt;();</p>
<p><strong>for</strong> (<strong>int</strong> i = 0; i &lt; model.classifications.length; i++) {</p>
<p>// 计算给定的文本属性向量terms在给定的分类<span style="text-decoration: underline;">Ci</span>中的分类条件概率</p>
<p>probility = calcProd(terms, i);</p>
<p>// 保存分类结果</p>
<p>ClassifyResult cr = <strong>new</strong> ClassifyResult();</p>
<p>cr.classification = model.classifications[i]; // 分类</p>
<p>cr.probility = probility; // 关键字在分类的条件概率</p>
<p>System.<em>out</em>.println(“In process&#8230;.”);</p>
<p>System.<em>out</em>.println(model.classifications[i] + “：” + probility);</p>
<p>crs.add(cr);</p>
<p>}</p>
<p>// 找出最大的元素</p>
<p>ClassifyResult maxElem = (ClassifyResult) java.util.Collections.<em>max</em>(</p>
<p>crs, <strong>new</strong> Comparator() {</p>
<p><strong>public</strong> <strong>int</strong> compare(<strong>final</strong> Object o1, <strong>final</strong> Object o2) {</p>
<p><strong>final</strong> ClassifyResult m1 = (ClassifyResult) o1;</p>
<p><strong>final</strong> ClassifyResult m2 = (ClassifyResult) o2;</p>
<p><strong>final</strong> <strong>double</strong> ret = m1.probility &#8211; m2.probility;</p>
<p><strong>if</strong> (ret &lt; 0) {</p>
<p><strong>return</strong> -1;</p>
<p>} <strong>else</strong> {</p>
<p><strong>return</strong> 1;</p>
<p>}</p>
<p>}</p>
<p>});</p>
<p><strong>return</strong> maxElem.classification;</p>
<p>}</p>
<p>测试正确率的函数getCorrectRate()，核心代码就是对每个文本文件调用classify()，将得到的类别和原始的类别比较，经过统计后就可以得到百分比。</p>
<p>更多细节请读者阅读源代码。</p>
<h3>参考文献</h3>
<p>[1] Christopher D. Manning, Prabhakar Raghavan, Hinrich Schütze, <a href="http://nlp.stanford.edu/IR-book/"><em>Introduction to Information Retrieval</em></a>, Cambridge University Press, 2008, chapter 13, <em>Text classification and Naive Bayes</em>.</p>
<p>[2]Pang-Ning Tan, Michael Steinbach, Vipin Kumar, <a href="http://book.douban.com/subject/1786120/">《数据挖掘导论》</a>，北京：人民邮电出版社，2007，第140~145页。</p>
<p>[2] 石志伟, 吴功宜, “<a href="http://d.wanfangdata.com.cn/Conference_5615512.aspx">基于朴素贝叶斯分类器的文本分类算法</a>”, 第一届全国信息检索与内容安全学术会议，2004</p>
<p>[3] 洞庭散人，“<a href="http://www.cnblogs.com/phinecos/archive/2008/10/21/1315948.html">基于朴素贝叶斯分类器的文本分类算法（上）</a>”，“<a href="http://www.cnblogs.com/phinecos/archive/2008/10/21/1316044.html">基于朴素贝叶斯分类器的文本分类算法（下）</a>”，2008</p>
<p>[4]DL88250, “<a href="http://blog.csdn.net/DL88250/archive/2008/02/20/2108164.aspx">朴素贝叶斯中文文本分类器的研究与实现（1）</a>”，“<a href="http://blog.csdn.net/DL88250/archive/2008/03/27/2224126.aspx">朴素贝叶斯中文文本分类器的研究与实现（2）</a>”，2008</p>
<p>由于笔者水平有限，本文出现错误在所难免，欢迎读者批评指正，请到原文发表评论或给我发email，谢谢 <img src='http://www.yanjiuyanjiu.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<strong><a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/基于朴素贝叶斯的文本分类算法.pdf">PDF版本</a></strong> <strong><a href="http://www.yanjiuyanjiu.com/wp-content/uploads/2010/05/NaiveBayesClassifier.zip">源代码下载</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2010/05/28/naive-bayes-text-classification/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>推荐给TeX新手的电子书和书籍</title>
		<link>http://www.yanjiuyanjiu.com/2010/04/17/newbie-to-latex/</link>
		<comments>http://www.yanjiuyanjiu.com/2010/04/17/newbie-to-latex/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 10:23:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开源工具]]></category>
		<category><![CDATA[ctex]]></category>
		<category><![CDATA[latex]]></category>
		<category><![CDATA[tex]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/?p=4128</guid>
		<description><![CDATA[CTEX自带的文档： 1、安装好CTEX后，c:\CTEX\CTeX\ctex\doc\下的两个文档，ctex-faq.pdf和lshort-cn.pdf（即93 分钟学会 LaTeX2e） 2、ftp://ftp.ctex.org/pub/tex/documents/bible/ 下的 LaTeX_manual.zip 对于初学者，上面3个文档足够了，在c:\CTEX\CTeX\ctex\doc\目录下的其他几个文档也非常好。 如果想进一步学习，推荐下面一本书。 3、《LaTeX入门与提高》，陈志杰，2008，高等教育出版社，卓越上有卖的。这里有个PDF扫描版。 网上的免费电子书： 4、A Guide to LaTeX 5、the latex companion，和第2个文档 LaTeX_manual 在同一个ftp目录下,还有另一个下载地址。 6、LaTeX2e使用手册 7、LaTeX2e插图指南 参考资料： 陈志杰老师的《latex入门与提高》这本书怎么样啊？ 中国LaTeX 新用户，LaTeX中文必读教程]]></description>
			<content:encoded><![CDATA[<p><strong>CTEX自带的文档：</strong><br />
1、安装好CTEX后，c:\CTEX\CTeX\ctex\doc\下的两个文档，ctex-faq.pdf和lshort-cn.pdf（即93 分钟学会 LaTeX2e）<br />
2、ftp://ftp.ctex.org/pub/tex/documents/bible/ 下的 LaTeX_manual.zip<br />
对于初学者，上面3个文档足够了，在c:\CTEX\CTeX\ctex\doc\目录下的其他几个文档也非常好。</p>
<p><strong>如果想进一步学习，推荐下面一本书。</strong><br />
3、<a href="http://www.amazon.cn/mn/detailApp/ref=sr_1_1?_encoding=UTF8&amp;s=books&amp;qid=1271499096&amp;asin=B00114JYBU&amp;sr=8-1">《LaTeX入门与提高》</a>，陈志杰，2008，高等教育出版社，卓越上有卖的。<a href="http://ishare.iask.sina.com.cn/f/7485622.html">这里有个PDF扫描版</a>。</p>
<p><strong>网上的免费电子书：</strong><br />
4、<a href="http://gigapedia.com/items/104415/a-guide-to-latex--document-preparation-for-beginners-and-advanced-users--3rd-edition-">A Guide to LaTeX</a><br />
5、the latex companion，和第2个文档 LaTeX_manual 在同一个ftp目录下,还有<a href="http://gigapedia.com/items/3842/the-latex-companion--tools-and-techniques-for-computer-typesetting-">另一个下载地址</a>。<br />
6、<a href="http://ftp.ctex.org/pub/tex/documents/texguru/homepage/guide.html">LaTeX2e使用手册</a><br />
7、<a href="ftp://ftp.ctex.org/pub/tex/documents/bible/LaTeX_graphics.zip">LaTeX2e插图指南</a></p>
<p>参考资料：<br />
<a href="http://bbs.ctex.org/redirect.php?tid=31930&amp;goto=lastpost">陈志杰老师的《latex入门与提高》这本书怎么样啊？</a><br />
<a href="http://bbs.ctex.org/viewthread.php?&amp;tid=1023">中国LaTeX 新用户，LaTeX中文必读教程</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2010/04/17/newbie-to-latex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于Ubuntu Jeos打造自己的精简版Linux服务器</title>
		<link>http://www.yanjiuyanjiu.com/2010/04/14/ubuntu-jeos/</link>
		<comments>http://www.yanjiuyanjiu.com/2010/04/14/ubuntu-jeos/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 14:52:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开源工具]]></category>
		<category><![CDATA[jeos]]></category>
		<category><![CDATA[ubunt]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/?p=4112</guid>
		<description><![CDATA[1. 下载 Ubuntu Server 官网的地址是：http://www.ubuntu.com/getubuntu/download-server 在这里下载的是标准的服务器版Ubuntu。为什么呢？因为 Ubuntu Jeos 现在已经并入了 Ubuntu Server 的ISO中了，这里有提到： Now part of the standard server ISO image 2. 下载并安装VMware Workstation 当前最新版本是 7.0.1 build-227600 3. 安装 Ubuntu Jeos虚拟机 一般选择默认，直接一路next即可，需要注意的地方本文会给出说明。 这里一定要选择 “I will install the operating system later”，因为如果选择前面两个，就会启用 “Easy Install”功能，即VMWare会很智能的识别这是Ubuntu，自动给你安装，你待会儿就没机会选择选项了。 注意：这里最为关键，按F4，选择 “Install a minimal virtual machine” 一连串的“NO”，一般会探测出你的键盘类型是”us”即美国键盘。 计算机名字，随便取 格式化硬盘 用户的显示名字，随便取 用户名和密码就不能随便取了，不能忘了，否则进不了系统你就杯具了。我一般就把用户名和密码设置为： Hostname:ubuntu-10.04 Full name [...]]]></description>
			<content:encoded><![CDATA[<p><strong>1. 下载 Ubuntu Server </strong></p>
<p>官网的地址是：<a href="http://www.ubuntu.com/getubuntu/download-server">http://www.ubuntu.com/getubuntu/download-server</a></p>
<p>在这里下载的是标准的服务器版Ubuntu。为什么呢？因为 Ubuntu Jeos 现在已经并入了 Ubuntu Server 的ISO中了，<a href="http://www.ubuntu.com/products/whatisubuntu/serveredition/jeos">这里</a>有提到：</p>
<p>Now part of the standard server ISO image</p>
<p><strong>2. 下载并安装VMware Workstation</strong></p>
<p>当前最新版本是 7.0.1 build-227600</p>
<p><strong>3. 安装 Ubuntu Jeos虚拟机</strong></p>
<p>一般选择默认，直接一路next即可，需要注意的地方本文会给出说明。</p>
<p><img src="/images/ubuntu_jeos/1.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap1.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap2.jpg" alt="" /></p>
<p>这里一定要选择 “I will install the operating system later”，因为如果选择前面两个，就会启用 “Easy Install”功能，即VMWare会很智能的识别这是Ubuntu，自动给你安装，你待会儿就没机会选择选项了。<span id="more-4112"></span></p>
<p><img src="/images/ubuntu_jeos/Snap3.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap4.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap5.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap6.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap7.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap8.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap9.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap10.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap11.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap12.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap13.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap14.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap15.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap16.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap17.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap18.jpg" alt="" /></p>
<p><span style="color: #ff0000;">注意：这里最为关键，按F4，选择 “Install a minimal virtual machine” </span></p>
<p><img src="/images/ubuntu_jeos/Snap19.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap20.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap21.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap22.jpg" alt="" /><br />
一连串的“NO”，一般会探测出你的键盘类型是”us”即美国键盘。<br/><br />
<img src="/images/ubuntu_jeos/Snap23.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap24.jpg" alt="" /></p>
<p>计算机名字，随便取</p>
<p><img src="/images/ubuntu_jeos/Snap25.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap26.jpg" alt="" /></p>
<p>格式化硬盘</p>
<p><img src="/images/ubuntu_jeos/Snap27.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap28.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap29.jpg" alt="" /></p>
<p><img src="./images/ubuntu_jeos/Snap30.jpg" alt="" /></p>
<p>用户的显示名字，随便取</p>
<p><img src="/images/ubuntu_jeos/Snap32.jpg" alt="" /></p>
<p>用户名和密码就不能随便取了，不能忘了，否则进不了系统你就杯具了。我一般就把用户名和密码设置为：<br/><br />
Hostname:ubuntu-10.04<br/><br />
Full name for the new user:developer<br/><br />
Username for your account:developer<br/><br />
Chose a password for the new user:developer123<br/><br />
Re-enter password to verify:admin<br/><br />
New password for the MySQL “root” user: root<br/></p>
<p><img src="/images/ubuntu_jeos/Snap33.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap34.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap35.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap36.jpg" alt="" /></p>
<p><span style="color: #ff0000;">选一个国内的源，待会儿下载一些包速度比较快，这里用的地址<a href="http://wiki.ubuntu.org.cn/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E6%88%91%E4%BB%AC%E6%8E%A8%E8%8D%90%E7%9A%84%E6%BA%90">来自这里</a>。</span></p>
<p><img src="/images/ubuntu_jeos/Snap37.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap38.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap39.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap40.jpg" alt="" /></p>
<p>选择需要安装的服务器软件，我选择了4个，<span style="color: #ff0000;">按空格选择</span>。注意，<span style="color: #ff0000;">不要选samba</span>，后面会安装vmware-tools，比samba方便多了。</p>
<p>Ubuntu JDK 默认路径为 /usr/lib/jvm/java-1.6.0-openjdk。</p>
<p><img src="/images/ubuntu_jeos/Snap41.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap42.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap43.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap44.jpg" alt="" /></p>
<p>大公告成，重启！</p>
<p>给刚安装好的机器创建一个快照，免得后面的操作不成功是可以退回。</p>
<p><img src="/images/ubuntu_jeos/Snap59.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap60.jpg" alt="" /></p>
<p><strong>4. 在真机上安装一个SSH客户端</strong></p>
<p>推荐 <a href="http://www.onlinedown.net/soft/20089.htm">SSH Secure Shell Client 3.2.9</a>，下载，安装好后，登陆</p>
<p><img src="/images/ubuntu_jeos/Snap46.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap47.jpg" alt="" /></p>
<p><strong>启动SSH Secure File Transfer</strong>，待会儿传输文件要用到。</p>
<p><img src="/images/ubuntu_jeos/Snap49.jpg" alt="" /></p>
<p><strong>5.升级一下系统，然后清理一下，再建一个快照，命名为 “updated”。</strong></p>
<p>备份源列表：</p>
<p><span style="background-color: #d9d9d9;">hadoop@soulmachine:~$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bk</span></p>
<p>将 /etc/apt/sources.list 下载到本地 d:/tmp/sources.list</p>
<p><img src="/images/ubuntu_jeos/Snap61.jpg" alt="" /></p>
<p>用记事本或UltralEdit打开，清空其中内容，然后用如下内容替换，保存。这个APT源来自<a href="http://wiki.ubuntu.org.cn/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E6%88%91%E4%BB%AC%E6%8E%A8%E8%8D%90%E7%9A%84%E6%BA%90">这里</a>，速度比较快。</p>
<p><span style="background-color: #d9d9d9;"><br />
deb http://ubuntu.srt.cn/ubuntu/ karmic main restricted universe multiverse</span></p>
<p>deb http://ubuntu.srt.cn/ubuntu/ karmic-security main restricted universe multiverse</p>
<p>deb http://ubuntu.srt.cn/ubuntu/ karmic-updates main restricted universe multiverse</p>
<p>deb http://ubuntu.srt.cn/ubuntu/ karmic-proposed main restricted universe multiverse</p>
<p>deb http://ubuntu.srt.cn/ubuntu/ karmic-backports main restricted universe multiverse</p>
<p>deb-src http://ubuntu.srt.cn/ubuntu/ karmic main restricted universe multiverse</p>
<p>deb-src http://ubuntu.srt.cn/ubuntu/ karmic-security main restricted universe multiverse</p>
<p>deb-src http://ubuntu.srt.cn/ubuntu/ karmic-updates main restricted universe multiverse</p>
<p>deb-src http://ubuntu.srt.cn/ubuntu/ karmic-proposed main restricted universe multiverse</p>
<p>deb-src http://ubuntu.srt.cn/ubuntu/ karmic-backports main restricted universe multiverse</p>
<p>上传文件到 /home/hadoop/下，因为直接上传到 /etc/apt/不行，没有权限。</p>
<p><img src="/images/ubuntu_jeos/Snap62.jpg" alt="" /></p>
<p>覆盖系统中的源列表：</p>
<p><span style="background-color: #d9d9d9;">hadoop@soulmachine:~$ sudo cp sources.list /etc/apt/sources.list</span></p>
<p>刷新列表：</p>
<p><span style="background-color: #d9d9d9;">hadoop@soulmachine:~$ sudo apt-get update</span></p>
<p><span style="color: #ff0000;">注意：一定要执行刷新</span></p>
<p>更新已安装的包，这一步要花一点时间。</p>
<p><span style="background-color: #d9d9d9;">hadoop@soulmachine:~$ sudo apt-get upgrade</span></p>
<p>清理无用的包：</p>
<p><span style="background-color: #d9d9d9;"><br />
hadoop@soulmachine:~$ sudo apt-get clean &amp;&amp; sudo apt-get autoclean</span></p>
<p>hadoop@soulmachine:~$ rm sources.list<br />
// 删除用户目录下的这个文件，可选</p>
<p>新建一个快照，取名为”upgraded”。</p>
<p><img src="/images/ubuntu_jeos/Snap63.jpg" alt="" /></p>
<p><strong>6.在ubuntu中安装 vmware-tools</strong></p>
<p>找到 C:\Program Files\VMware\VMware Workstation\linux.iso，解压，得到一个 VMWARETO.TGZ，把它上传到Ubuntu中。</p>
<p><img src="/images/ubuntu_jeos/Snap51.jpg" alt="" /></p>
<p><img src="/images/ubuntu_jeos/Snap52.jpg" alt="" /></p>
<p>解压，命令为 tar -zxvf VMWARETO.TGZ</p>
<p><span style="background-color: #d9d9d9;">hadoop@soulmachine:~$ tar -zxvf VMWARETO.TGZ </span></p>
<p>解压好后，执行 vmware-tools-distrib/vmware-install.pl</p>
<p><img src="/images/ubuntu_jeos/Snap54.jpg" alt="" /></p>
<p>一路回车，YES下去就行了</p>
<p><span style="background-color: #d9d9d9;"><br />
Installing VMware Tools.</span></p>
<p>In which directory do you want to install the binary files?</p>
<p>[/usr/bin]</p>
<p>What is the directory that contains the init directories (rc0.d/ to rc6.d/)?</p>
<p>[/etc]</p>
<p>What is the directory that contains the init scripts?</p>
<p>[/etc/init.d]</p>
<p>In which directory do you want to install the daemon files?</p>
<p>[/usr/sbin]</p>
<p>In which directory do you want to install the library files?</p>
<p>[/usr/lib/vmware-tools]</p>
<p>The path “/usr/lib/vmware-tools” does not exist currently. This program is</p>
<p>going to create it, including needed parent directories. Is this what you want?</p>
<p>[yes] yes</p>
<p>In which directory do you want to install the documentation files?</p>
<p>[/usr/share/doc/vmware-tools]</p>
<p>The path “/usr/share/doc/vmware-tools” does not exist currently. This program</p>
<p>is going to create it, including needed parent directories. Is this what you</p>
<p>want? [yes] yes</p>
<p>The installation of VMware Tools 8.1.4 build-227600 for Linux completed</p>
<p>successfully. You can decide to remove this software from your system at any</p>
<p>time by invoking the following command: “/usr/bin/vmware-uninstall-tools.pl”.</p>
<p>Before running VMware Tools for the first time, you need to configure it by</p>
<p>invoking the following command: “/usr/bin/vmware-config-tools.pl”. Do you want</p>
<p>this program to invoke the command for you now? [yes]</p>
<p>接下来这一处默认是NO，我们也输入NO</p>
<p><span style="background-color: #d9d9d9;"><br />
[EXPERIMENTAL] The VMware FileSystem Sync Driver (vmsync) is a new feature that</span></p>
<p>creates backups of virtual machines. Please refer to the VMware Knowledge Base</p>
<p>for more details on this capability. Do you wish to enable this feature?</p>
<p>[no] no</p>
<p>安装好了，删除安装包，然后关机，因为我们需要设置一个东西，下一步就会看到。</p>
<p><span style="background-color: #d9d9d9;"><br />
hadoop@soulmachine:~/vmware-tools-distrib$ cd ..</span></p>
<p>hadoop@soulmachine:~$ ls</p>
<p><span style="color: #0000ff;">vmware-tools-distrib</span> VMWARETO.TGZ</p>
<p>hadoop@soulmachine:~$ rm -rf ./vmware-tools-distrib/</p>
<p>hadoop@soulmachine:~$ ls</p>
<p>VMWARETO.TGZ</p>
<p>hadoop@soulmachine:~$ rm ./VMWARETO.TGZ</p>
<p>新建一个快照，取名为 “vmware-tools-installed”，然后关机。</p>
<p><span style="background-color: #d9d9d9;">hadoop@soulmachine:~$ sudo shutdown -h now </span></p>
<p><strong>7.设置文件夹共享</strong></p>
<p>点击 Edit virtual machine settings，激活文件夹共享，</p>
<p><img src="/images/ubuntu_jeos/Snap55.jpg" alt="" /></p>
<p>添加本机上的一个文件夹，Name 为linux上显示的名字，</p>
<p><img src="/images/ubuntu_jeos/Snap56.jpg" alt="" /></p>
<p>其他默认，点击“Finish”，然后点击”Power on this virtual machine”，开机，可以在linux里访问这个文件夹了，windows上的这个文件夹会被vmware-tools自动映射 (mount) 到linux下的 <span style="color: #ff0000;">/mnt/hgfs/xpshare </span>。</p>
<p><span style="background-color: #d9d9d9;">hadoop@soulmachine:~$ ls /mnt/hgfs/</span></p>
<p><span style="background-color: #007f00;">xpshare</span></p>
<p><strong>8.将本虚拟机打包。</strong></p>
<p>右击本虚拟机标签，选择 “clone”。</p>
<p><img src="/images/ubuntu_jeos/Snap64.jpg" alt="" /></p>
<p>这一步默认，</p>
<p><img src="/images/ubuntu_jeos/Snap65.jpg" alt="" /></p>
<p>选择 “create full clone”，</p>
<p><img src="/images/ubuntu_jeos/Snap66.jpg" alt="" /></p>
<p>选择存放路径。</p>
<p><img src="/images/ubuntu_jeos/Snap67.jpg" alt="" /></p>
<p>注意：没必要删除之前创建的快照再克隆，因为克隆时不会把快照考虑进去。</p>
<p>接下来可以把这个文件夹用WinRAR压缩，大小大约500M多，我的是 514M。</p>
<p><strong>9.使用别人打包好的虚拟机</strong></p>
<p>如何使用这个打包好后的虚拟机呢？很简单，解压，然后再VMWare Workstation里点击”File-&gt;Open”，浏览到此文件夹，打开.vmx后缀的文件即可。</p>
<p>当打开一个vmx文件时，会跳出一个对话框，一般选择”I copied it”。</p>
<p><img src="/images/ubuntu_jeos/Snap68.jpg" alt="" /></p>
<p><strong>10.VMWare克隆后Ubuntu的 “No such device eth0&#8243; 错误 </strong></p>
<p>其实克隆后的虚拟机，第一个碰到的问题，便是不能上网。用ifconfig命令发现机器没有获得IP，只有一个 127.0.0.1。Google了一下，找到了答案。</p>
<p><strong>原因：</strong></p>
<p>新克隆的虚拟机镜像的网卡mac地址已经变更。打开虚拟机的.vmx文件，ethernet0.generatedAddress项记录了该虚拟机的 mac地址。</p>
<p>查看所有适配器信息</p>
<p>ifconfig -a</p>
<p>发现除了原来的eth0外，Ubuntu已经将新网卡命名为eth1。</p>
<p>Ubuntu保存网卡mac地址和设备名的配置文件在</p>
<p>/etc/udev/rules.d/70-persistent-net.rules</p>
<p>网卡的网络配置保存在</p>
<p>/etc/network/interfaces</p>
<p>该配置文件中只有原来eth0的配置信息。</p>
<p><strong>解决方案：</strong>移动/删除rules文件。（已验证）</p>
<p><span style="background-color: #d9d9d9;"><br />
sudo mv /etc/udev/rules.d/70-persistent-net.rules /etc/udev/rules.d/70-persistent-net.rules.old</span></p>
<p>重启后Ubuntu会创建新的rules文件，将新网卡辨认为eth0，沿用原eth0 的网络配置。</p>
<p><strong>参考资料</strong></p>
<p><a href="http://www.ubuntu.com/products/whatisubuntu/serveredition/jeos"> Ubuntu Server Edition JeOS</a></p>
<p><a href="http://fanqiang.chinaunix.net/a1/b1/20020130/21030661.html"> Linux关机命令详解</a></p>
<p><a href="http://wiki.ubuntu.org.cn/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E6%88%91%E4%BB%AC%E6%8E%A8%E8%8D%90%E7%9A%84%E6%BA%90">如何使用我们推荐的源 </a></p>
<p><a href="http://blog.csdn.net/willand1981/archive/2010/04/06/5455521.aspx">Ubuntu Linux系统下apt-get命令详解</a></p>
<p><a href="http://blog.csdn.net/man8848/archive/2009/04/30/4138415.aspx"> Ubuntu 安装VMware-Tools </a></p>
<p><a href="http://blog.csdn.net/dctfjy/archive/2009/06/01/4233284.aspx">VMWare克隆后Ubuntu的 “No such device eth0&#8243; 错误 </a></p>
<p><a href="http://www.yanjiuyanjiu.com/upload/ubuntu_jeos.pdf"><span style="font-size: large;">下载PDF版本</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2010/04/14/ubuntu-jeos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java 读写图像</title>
		<link>http://www.yanjiuyanjiu.com/2010/04/01/java-image-io/</link>
		<comments>http://www.yanjiuyanjiu.com/2010/04/01/java-image-io/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 04:08:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开源工具]]></category>
		<category><![CDATA[image]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/?p=4110</guid>
		<description><![CDATA[Java中进行图像I/O（即读图片和写图片，不涉及到复杂图像处理）有三个方法： 1. Java Image I/O API，支持常见图片，从Java 2 version 1.4.0开始就内置了。 主页：http://java.sun.com/javase/6/docs/technotes/guides/imageio/index.html 2. JAI 中的 Image I/O Tools，支持更多图片类型，例如JPEG-LS, JPEG2000, 和 TIFF。 主页：https://jai-imageio.dev.java.net/。JAI 是一个关于图像处理的框架，很庞大， 其中仅仅jai-imageio是关于图像I/O的，其他的可以不看。 3. JAI的com.sun.media.jai.codec 也有一定的图像解码能力 当然，还有众多的java开源工具包可以读写图像，例如JIMI, JMagic等，但JDK目前本身能 够读写图片，就用JDK的，开发和部署方便，不需要额外下载jar包。 由于JAI是Java新加入的，很多组件不是正式规范，JDK不自带，因此开发和部署需要额外 安装，安装文件在官网https://jai.dev.java.net/下载得到。 如果你仅仅想读取常见格式的图片，不需要用JAI这么高级这么庞大的东西， 用Java Image I/O API即可。 下面重点介绍 Java Image I/O API。 Java Image I/O API 主要在 javax.imageio 下面。JDK已经内置了常见图片格式的插件， 但它提供了插件体系结构，第三方也可以开发插件支持其他图片格式。 下面这段代码可以展示，JDK内置支持的图片格式。 import javax.imageio.*; import java.util.Arrays; public class [...]]]></description>
			<content:encoded><![CDATA[<p>Java中进行图像I/O（即读图片和写图片，不涉及到复杂图像处理）有三个方法：<br />
1. Java Image I/O API，支持常见图片，从Java 2 version 1.4.0开始就内置了。<br />
主页：<a href="http://java.sun.com/javase/6/docs/technotes/guides/imageio/index.html" target="_blank">http://java.sun.com/javase/6/docs/technotes/guides/imageio/index.html</a><br />
2. JAI 中的 Image I/O Tools，支持更多图片类型，例如JPEG-LS, JPEG2000, 和 TIFF。<br />
主页：<a href="https://jai-imageio.dev.java.net/" target="_blank">https://jai-imageio.dev.java.net/</a>。JAI 是一个关于图像处理的框架，很庞大，<br />
其中仅仅jai-imageio是关于图像I/O的，其他的可以不看。<br />
3. JAI的com.sun.media.jai.codec 也有一定的图像解码能力</p>
<p>当然，还有众多的java开源工具包可以读写图像，例如JIMI, JMagic等，但JDK目前本身能<br />
够读写图片，就用JDK的，开发和部署方便，不需要额外下载jar包。</p>
<p>由于JAI是Java新加入的，很多组件不是正式规范，JDK不自带，因此开发和部署需要额外<br />
安装，安装文件在官网<a href="https://jai.dev.java.net/" target="_blank">https://jai.dev.java.net/</a>下载得到。</p>
<p>如果你仅仅想读取常见格式的图片，不需要用JAI这么高级这么庞大的东西，<br />
用Java Image I/O API即可。</p>
<p>下面重点介绍 Java Image I/O API。</p>
<p>Java Image I/O API 主要在 javax.imageio 下面。JDK已经内置了常见图片格式的插件，<br />
但它提供了插件体系结构，第三方也可以开发插件支持其他图片格式。</p>
<p>下面这段代码可以展示，JDK内置支持的图片格式。<br />
import javax.imageio.*;<br />
import java.util.Arrays;</p>
<p>public class HelloWorld {<br />
public static void main(String args[]) {<br />
String readFormats[] = ImageIO.getReaderFormatNames();<br />
String writeFormats[] = ImageIO.getWriterFormatNames();<br />
System.out.println(“Readers:  ” + Arrays.asList(readFormats));<br />
System.out.println(“Writers:  ” + Arrays.asList(writeFormats));<br />
}<br />
}</p>
<p>主页上有一个文档，<a href="http://java.sun.com/javase/6/docs/technotes/guides/imageio/spec/title.fm.html" target="_blank"><strong>Java Image I/O API Guide</strong></a>，很通俗易懂，可以让你快速上手。以下<br />
内容主要来自这个文档的第3章。</p>
<p><strong>第3章 编写图像I/O程序</strong><br />
<strong>3.1 读写图片</strong><br />
javax.imageio.ImageIO类提供了一组静态方法进行最简单的图像I/O操作。<br />
读取一个标准格式(GIF, PNG, or JPEG)的图片很简单：<br />
File f = new File(“c:\images\myimage.gif”);<br />
BufferedImage bi = ImageIO.read(f);</p>
<p>Java Image I/O API 会自动探测图片的格式并调用对应的插件进行解码，当安装了一个新<br />
插件，新的格式会被自动理解，程序代码不需要改变。</p>
<p>写图片同样简单：<br />
BufferedImage bi;<br />
File f = new File(“c:\images\myimage.png”);<br />
ImageIO.write(im, “png”, f);</p>
<p><strong>3.2 更进一步</strong><br />
上一节谈到的方法对于简单程序已经足够了。不过，Java Image I/O API 提供了为编写复<br />
杂程序的能力。为了利用API的高级特性，应用程序应当直接使用类ImageReader 和<br />
ImageWriter。</p>
<p><strong>3.3 ImageReader 类</strong><br />
与其用ImageIO类来进行所有的解码操作，不如用ImageIO类去得到一个ImageReader对象，<br />
再用这个对象去进行读操作：<br />
Iterator readers = ImageIO.getImageReadersByFormatName(“gif”);<br />
ImageReader reader = (ImageReader)readers.next();</p>
<p>ImageReader对象也可以基于文件内容、文件后缀或MIME类型获得。这个用于查找和初始<br />
化ImageReader对象的机制用到了javax.imageio.spi.ImageReaderSpi类，它可以在不用初<br />
始化插件的情况下获得插件的信息。”service provider interfaces” (SPIs)将会在下一<br />
章详细讨论。一旦获得了一个ImageReader对象，必须给它是指一个输入源。大部分<br />
ImageReader对象可以从ImageInputStream类输入源读取数据，ImageInputStream是Image<br />
I/O API定义的专用输入源。</p>
<p>获得一个ImageInputStream 是简单的。给定一个File或InputStream，一个<br />
ImageInputStream对象可以通过调用如下函数产生：<br />
Object source; // File or InputStream<br />
ImageInputStream iis = ImageIO.createImageInputStream(source);</p>
<p>一旦有了输入源，可以把它与一个ImageReader对象关联起来：<br />
reader.setInput(iis, true);</p>
<p>如果输入源文件包含多张图片，而程序不保证按顺序读取时，第二个参数应该设置为<br />
false。对于那些只允许存储一张图片的文件格式，永远传递true是合理的。</p>
<p>当ImageReader对象有了输入源后，我们就可以获取图片信息而不用把整张图片数据都读入<br />
内存。例如，调用reader.getImageWidth(0)可以让我们获得文件中第一张图片的宽度。一<br />
个好的插件会试图解码文件的必要部分，去获得图片的宽度，而不用读取任何一个像素。</p>
<p>为读取图片，可以调用reader.read(imageIndex), imageIndex是文件（当包含多张图片时）<br />
中图片的索引。这与上一节调用ImageIO.read()产生的结果相同。</p>
<p><strong>3.3.1 ImageReadParam</strong><br />
如果需要更多的控制，可以向read()方法传递一个ImageReadParam类型的参数。一个<br />
ImageReadParam对象可以让程序更好的利用内存。它不仅允许指定一个感兴趣的区域，还<br />
可以指定一个抽样因子，用于向下采样。</p>
<p>例如，为了只解码图片的左上角的1/4，程序可以先获取一个合适的ImageReadParam对象：<br />
ImageReadParam param = reader.getDefaultReadParam();</p>
<p>接下来，指定图片区域：<br />
import java.awt.Rectangle;<br />
int imageIndex = 0;<br />
int half_width = reader.getImageWidth(imageIndex)/2;<br />
int half_height = reader.getImageHeight(imageIndex)/2;<br />
Rectangle rect = new Rectangle(0, 0, half_width, half_height);<br />
param.setSourceRegion(rect);</p>
<p>最后，读取图片：<br />
BufferedImage bi = reader.read(imageIndex, param);</p>
<p>结果是一张新图片，宽和高都只有原图片的一半。</p>
<p>另一个例子，为了读取每三个像素中的一个，产生一个原图片1/9大小的图片，可以用<br />
ImageReadParam指定抽样因子：<br />
param = reader.getDefaultImageParam();<br />
param.setSourceSubsampling(3, 3, 0, 0);<br />
BufferedImage bi3 = reader.read(0, param);</p>
<p><strong>3.3.2 IIOParamController</strong><br />
插件有时会提供一个IIOParamController类，这是可选的。略。</p>
<p><strong>3.3.3 读多图片文件</strong><br />
ImageReader 中所有与图片打交道的方法都有一个imageIndex 参数，这个参数用于读取多<br />
图片文件中的一张。</p>
<p>ImageReader.getNumImages()返回多图片文件中的图片个数。这个方法有一个boolean参数，<br />
allowSearch。有的图片格式，典型的GIF，没有提供任何获取文件中的图片个数方法，除<br />
非读取整个进行解析。这样代价很高，因此设置allowSearch为false可以让方法直接返回<br />
-1，而不是实际的图片个数。如果此参数是true，则该方法总会返回文件中实际的图片个<br />
数。</p>
<p>即使在不知道文件中图片个数的情况下，仍可以调用read(imageIndex); 如果索引值过大，<br />
该方法会抛出IndexOutOfBoundsException异常。因此，程序可以递增索引去获取图片，<br />
直到异常。</p>
<p><strong>3.3.4 读缩略图 </strong><br />
有的图片格式允许一个（或多个）小的预览图，与主图片一起存储在文件中。这些<br />
“缩略图”对于快速识别图片很有用，不用解码整个图片。</p>
<p>程序可以调用如下代码，探测一张图片有多少张缩略图：<br />
reader.getNumThumbnails(imageIndex);</p>
<p>如果存在缩略图，可以调用如下代码获取：<br />
int thumbailIndex = 0;<br />
BufferedImage bi;<br />
bi = reader.readThumbnail(imageIndex, thumbnailIndex);</p>
<p><strong>3.4 ImageWriter 类 </strong><br />
就像我们可以用ImageIO 的一个方法获取某种图片格式的ImageReader对象一样，我们也可<br />
以获取ImageWriter对象：<br />
Iterator writers = ImageIO.getImageWritersByFormatName(“png”);<br />
ImageWriter writer = (ImageWriter)writers.next();</p>
<p>一旦获取了一个ImageWriter对象，必须给它设置一个输出源ImageOutputStream。<br />
File f = new File(“c:\images\myimage.png”);<br />
ImageOutputStream ios = ImageIO.createImageOutputStream(f);<br />
writer.setOutput(ios);</p>
<p>最后，可以把图片写入到输出源：<br />
BufferedImage bi;<br />
writer.write(bi);</p>
<p><strong>3.4.1 写多图片文件</strong><br />
IIOImage类用于存储图片，缩略图或元信息的引用。下一节将讨论Metadata，目前，我们<br />
简单地给Metadata相关参数传递null。<br />
ImageWriter 类有一个方法write()，用于从IIOImage创建一个新文件，还有一个方法<br />
writeInsert()，用于向一个已存在文件添加一个IIOImage对象。通过调用这两者，可以创<br />
建一个多图片文件：<br />
BufferedImage first_bi, second_bi;<br />
IIOImage first_IIOImage = new IIOImage(first_bi, null, null);<br />
IIOImage second_IIOImage = new IIOImage(second_bi, null, null);<br />
writer.write(null, first_IIOImage, null);<br />
if (writer.canInsertImage(1)) {<br />
writer.writeInsert(1, second_IIOImage, null);<br />
} else {<br />
System.err.println(“Writer can&#8217;t append a second image!”);<br />
}</p>
<p><strong>3.5  处理 Metadata </strong><br />
所有与像素无关的信息，都属于在Metadata。javax.imageio.metadata 包含了用于访问<br />
Metadata的类和接口。</p>
<p>Image I/O API 将stream metadata 和image metadata区别对待。stream metadata与一个<br />
文件中存储了多张图片有关，image metadata只与单个图片有关。如果一个文件只包含一张<br />
图片，那么就只存在image metadata。</p>
<p>可以通过调用ImageReader.getStreamMetadata 和 getImageMetadata(int imageIndex)来<br />
获取metadata。这些方法会返回一个实现了IIOMetadata接口的对象，该对象会被向上转化<br />
为ImageReader类型，</p>
<p><strong>3.6 编码转换</strong><br />
略</p>
<p><strong>3.7 事件监听</strong><br />
略</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2010/04/01/java-image-io/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java质量检测评估工具</title>
		<link>http://www.yanjiuyanjiu.com/2010/03/31/java-qa-tools/</link>
		<comments>http://www.yanjiuyanjiu.com/2010/03/31/java-qa-tools/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 09:17:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开源工具]]></category>
		<category><![CDATA[QA]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/?p=4102</guid>
		<description><![CDATA[Java代码质量检测评估工具 “五大” 代码分析领域： * 编码风格 * 冗余代码 * 代码覆盖率 * 依赖项分析 * 复杂度监控 一下列举了一些目前比较流行的工具。网址后面列出了其PR值，可以反映此工具的流行度。 1、编码风格 CheckStyle Home page: http://checkstyle.sourceforge.net/ (6) 对应的eclipse插件有多个，其中eclipsecs最常用 Home page: http://eclipse-cs.sourceforge.net/ (6) eclipse插件URL：http://eclipse-cs.sf.net/update/ 2、冗余代码 Simian http://www.redhillconsulting.com.au/products/simian/ (5) PMD 的 CPD http://pmd.sourceforge.net/cpd.html (5) 3、代码覆盖率 EMMA  http://emma.sourceforge.net/ (6) Cobertura  http://cobertura.sourceforge.net/ (6) EclEmma http://update.eclemma.org/ (5) Coverlipse http://coverlipse.sourceforge.net/ (3) 4、依赖项分析 JDepend http://clarkware.com/software/JDepend.html (6) 5、复杂度监控 Metrics http://metrics.sourceforge.net/ [...]]]></description>
			<content:encoded><![CDATA[<p>Java代码质量检测评估工具<br />
“五大” 代码分析领域：<br />
* 编码风格<br />
* 冗余代码<br />
* 代码覆盖率<br />
* 依赖项分析<br />
* 复杂度监控</p>
<p>一下列举了一些目前比较流行的工具。网址后面列出了其PR值，可以反映此工具的流行度。<br />
1、编码风格<br />
CheckStyle<br />
Home page: <a href="http://checkstyle.sourceforge.net/" target="_blank">http://checkstyle.sourceforge.net/</a> (6)<br />
对应的eclipse插件有多个，其中eclipsecs最常用<br />
Home page: <a href="http://eclipse-cs.sourceforge.net/" target="_blank">http://eclipse-cs.sourceforge.net/</a> (6)<br />
eclipse插件URL：<a href="http://eclipse-cs.sf.net/update/" target="_blank">http://eclipse-cs.sf.net/update/</a></p>
<p>2、冗余代码<br />
Simian <a href="http://www.redhillconsulting.com.au/products/simian/" target="_blank">http://www.redhillconsulting.com.au/products/simian/</a> (5)<br />
PMD 的 CPD <a href="http://pmd.sourceforge.net/cpd.html" target="_blank">http://pmd.sourceforge.net/cpd.html</a> (5)</p>
<p>3、代码覆盖率<br />
EMMA  <a href="http://emma.sourceforge.net/" target="_blank">http://emma.sourceforge.net/</a> (6)<br />
Cobertura  <a href="http://cobertura.sourceforge.net/" target="_blank">http://cobertura.sourceforge.net/</a> (6)<br />
EclEmma <a href="http://update.eclemma.org/" target="_blank">http://update.eclemma.org/</a> (5)<br />
Coverlipse <a href="http://coverlipse.sourceforge.net/" target="_blank">http://coverlipse.sourceforge.net/</a> (3)</p>
<p>4、依赖项分析<br />
JDepend <a href="http://clarkware.com/software/JDepend.html" target="_blank">http://clarkware.com/software/JDepend.html</a> (6)</p>
<p>5、复杂度监控<br />
Metrics <a href="http://metrics.sourceforge.net/" target="_blank">http://metrics.sourceforge.net/</a> (4)</p>
<p>具有以上两项或两项以上的综合工具（也称为静态分析工具）：<br />
1、PMD<br />
Home page: <a href="http://pmd.sourceforge.net/cpd.html" target="_blank">http://pmd.sourceforge.net/</a> (6)<br />
eclipse插件URL：<a href="http://pmd.sourceforge.net/eclipse" target="_blank">http://pmd.sourceforge.net/eclipse</a></p>
<p>2、FindBugs <a href="http://findbugs.sourceforge.net/" target="_blank">http://findbugs.sourceforge.net/</a> (6)<br />
eclipse插件URL：<a href="http://findbugs.cs.umd.edu/eclipse" target="_blank">http://findbugs.cs.umd.edu/eclipse</a></p>
<p>FindBugs 检查程序生成的class文件，即分析字节码<br />
PMD 检查源码，分析源代码</p>
<p>3、Jtest <a href="http://www.parasoft.com/jtest" target="_blank">http://www.parasoft.com/jtest</a></p>
<p>4、Jlint <a href="http://artho.com/jlint/" target="_blank">http://artho.com/jlint/</a> (5)</p>
<p>5、Lint4j <a href="http://www.jutils.com/" target="_blank">http://www.jutils.com/</a> (4)</p>
<p>参考资料：<a href="http://blog.csdn.net/cb_121/archive/2009/05/22/4208792.aspx" target="_blank">http://blog.csdn.net/cb_121/archive/2009/05/22/4208792.aspx</a></p>
<p>我个人平时最常用的是Checkstyle，其次是PMD，读者可以参考一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2010/03/31/java-qa-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用pdfbox 抽取PDF文件中的文本</title>
		<link>http://www.yanjiuyanjiu.com/2010/03/28/extrac-text-from-pdf-using-pdfbox/</link>
		<comments>http://www.yanjiuyanjiu.com/2010/03/28/extrac-text-from-pdf-using-pdfbox/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 11:54:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开源工具]]></category>
		<category><![CDATA[pdfbox]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/?p=4090</guid>
		<description><![CDATA[[code lang="java"] package com.yanjiuyanjiu.search; import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.util.PDFTextStripper; /** * 抽去PDF文件中的文本. * @author soulmachine * */ public final class PDFboxTest { /** 禁止创建对象. */ private PDFboxTest() { } /** * 抽取PDF中的文本. * @param f PDF文件 * @return PDF对应的文本字符串 */ public static String getText(final File f) { String text = &#34;&#34;; try [...]]]></description>
			<content:encoded><![CDATA[<pre><strong></strong>[code lang="java"]
package com.yanjiuyanjiu.search;

import java.io.File;
import java.io.IOException;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;

/**
 * 抽去PDF文件中的文本.
 * @author soulmachine
 *
 */
public final class PDFboxTest {
 /** 禁止创建对象. */
 private PDFboxTest() {
 }
 /**
 * 抽取PDF中的文本.
 * @param f PDF文件
 * @return PDF对应的文本字符串
 */
 public static String getText(final File f) {
 String text = &quot;&quot;;
 try {
 PDDocument pdfdocument = PDDocument.load(f);
 PDFTextStripper stripper = new PDFTextStripper();
 stripper.setStartPage(1); // 只抽取第1页和第2页
 stripper.setEndPage(2);
 text = stripper.getText(pdfdocument);
 pdfdocument.close();

 } catch (IOException e) {
 e.printStackTrace();
 }

 return text;
 }

 /** 测试.
 *
 * @param args PDF文件路径
 */
 public static void main(final String[]  args) {
 File file = new File(args[0]);
 System.out.println(PDFboxTest.getText(file));
 }
}

[/code]

<strong><a href="upload/PDFExtractor.zip" target="_blank">eclipse工程文件下载</a></strong>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2010/03/28/extrac-text-from-pdf-using-pdfbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java命令行下运行class文件</title>
		<link>http://www.yanjiuyanjiu.com/2010/02/15/run-java-class-in-console/</link>
		<comments>http://www.yanjiuyanjiu.com/2010/02/15/run-java-class-in-console/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 08:16:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[语言与算法]]></category>

		<guid isPermaLink="false">http://www.yanjiuyanjiu.com/archives/4072.html</guid>
		<description><![CDATA[今天碰到了一个很变态的问题，写了一个很简单的HelloWord.java，内容如下： package com.yanjiuyanjiu; public class HelloWorld { public static void main(String args[]) { System.out.println(“Hello World!”); } } 在eclipse中运行是可以的，但是在命令行下运行总是失败。我的工程位置为 d:\workspace\HelloWorld\。 尝试了很多次，如下 d:\workspace\HelloWorld\bin\com\yanjiuyanjiu\&#62;java HelloWorld Exception in thread “main” java.lang.NoClassDefFoundError: HelloWorld (wrong name: com/yanjiuyanjiu/HelloWorld) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(Unknown Source) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) [...]]]></description>
			<content:encoded><![CDATA[<p>今天碰到了一个很变态的问题，写了一个很简单的HelloWord.java，内容如下：<br />
package com.yanjiuyanjiu;</p>
<p>public class HelloWorld {<br />
public static void main(String args[]) {<br />
System.out.println(“Hello World!”);<br />
}<br />
}</p>
<p>在eclipse中运行是可以的，但是在命令行下运行总是失败。我的工程位置为 d:\workspace\HelloWorld\。</p>
<p>尝试了很多次，如下</p>
<p><span style="color: #808080;">d:\workspace\HelloWorld\bin\com\yanjiuyanjiu\&gt;java HelloWorld</span></p>
<p><span style="color: #808080;">Exception in thread “main” java.lang.NoClassDefFoundError: HelloWorld (wrong name: com/yanjiuyanjiu/HelloWorld)<br />
at java.lang.ClassLoader.defineClass1(Native Method)<br />
at java.lang.ClassLoader.defineClassCond(Unknown Source)<br />
at java.lang.ClassLoader.defineClass(Unknown Source)<br />
at java.security.SecureClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.access$000(Unknown Source)<br />
at java.net.URLClassLoader$1.run(Unknown Source)<br />
at java.security.AccessController.doPrivileged(Native Method)<br />
at java.net.URLClassLoader.findClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
Could not find the main class: HelloWorld.  Program will exit.<br />
Exception in thread “main”</span></p>
<p><span style="color: #808080;">d:\workspace\HelloWorld\bin\com\yanjiuyanjiu\&gt;java -classpath .; HelloWorld<br />
Exception in thread “main” java.lang.NoClassDefFoundError: HelloWorld (wrong name: com/yanjiuyanjiu/HelloWorld)<br />
at java.lang.ClassLoader.defineClass1(Native Method)<br />
at java.lang.ClassLoader.defineClassCond(Unknown Source)<br />
at java.lang.ClassLoader.defineClass(Unknown Source)<br />
at java.security.SecureClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.access$000(Unknown Source)<br />
at java.net.URLClassLoader$1.run(Unknown Source)<br />
at java.security.AccessController.doPrivileged(Native Method)<br />
at java.net.URLClassLoader.findClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
Could not find the main class: HelloWorld.  Program will exit.<br />
Exception in thread “main”</span></p>
<p><span style="color: #808080;">d:\workspace\HelloWorld\bin\com\yanjiuyanjiu\&gt;cd..</span></p>
<p><span style="color: #808080;">d:\workspace\HelloWorld\bin\com\&gt;cd..</span></p>
<p><span style="color: #808080;">d:\workspace\HelloWorld\bin\&gt;java -classpath .; com/yanjiuyanjiu/HelloWorld    <span style="color: #ff0000;">只有这个成功</span></span></p>
<p><span style="color: #808080;">Hello World!</span></p>
<p><span style="color: #808080;">d:\workspace\HelloWorld\bin\&gt;java -classpath .; com\yanjiuyanjiu\HelloWorld    <span style="color: #ff0000;">换了个斜杠就不行了</span></span></p>
<p><span style="color: #808080;">Exception in thread “main” java.lang.NoClassDefFoundError: com\yanjiuyanjiu\HelloWorld (wrong name: com/yanjiuyanjiu/HelloWorld)<br />
at java.lang.ClassLoader.defineClass1(Native Method)<br />
at java.lang.ClassLoader.defineClassCond(Unknown Source)<br />
at java.lang.ClassLoader.defineClass(Unknown Source)<br />
at java.security.SecureClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.access$000(Unknown Source)<br />
at java.net.URLClassLoader$1.run(Unknown Source)<br />
at java.security.AccessController.doPrivileged(Native Method)<br />
at java.net.URLClassLoader.findClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
Could not find the main class: com\yanjiuyanjiu\HelloWorld.  Program will exit.<br />
Exception in thread “main”</span></p>
<p><span style="color: #808080;">d:\workspace\HelloWorld\bin\&gt;java -classpath ./com/yanjiuyanjiu/; HelloWorld</span></p>
<p><span style="color: #808080;">Exception in thread “main”java.lang.NoClassDefFoundError: HelloWorld (wrong name: com/yanjiuyanjiu/HelloWorld)<br />
at java.lang.ClassLoader.defineClass1(Native Method)<br />
at java.lang.ClassLoader.defineClassCond(Unknown Source)<br />
at java.lang.ClassLoader.defineClass(Unknown Source)<br />
at java.security.SecureClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.defineClass(Unknown Source)<br />
at java.net.URLClassLoader.access$000(Unknown Source)<br />
at java.net.URLClassLoader$1.run(Unknown Source)<br />
at java.security.AccessController.doPrivileged(Native Method)<br />
at java.net.URLClassLoader.findClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)<br />
at java.lang.ClassLoader.loadClass(Unknown Source)<br />
Could not find the main class: HelloWorld.  Program will exit.<br />
Exception in thread “main”</span></p>
<p>在网上搜索了大半天，大部分说是环境 变量，classpath或JDK 版本的问题，还有执行时文件名 class后缀不要。我一一试过，都没有解决。最后无意中换了一下命令符的位置，成功了。总结如下：<br />
1. 环境变量，CLASSPATH当然要设置好，执行时不要带class后缀；<br />
2. 路径中的斜杠用“/”而不是“\”；<br />
3. 命令符的当前目录要在包的起点。比如这里应该在 d:\workspace\HelloWorld\bin\&gt;，如果在 d:\workspace\HelloWorld\bin\com\yanjiuyanjiu\&gt;，反而不行，有点“近水楼台不得月”的意思，不知 道为什么，还请高手解释一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2010/02/15/run-java-class-in-console/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>godaddy 域名 301 重定向</title>
		<link>http://www.yanjiuyanjiu.com/2009/07/21/godaddy-301/</link>
		<comments>http://www.yanjiuyanjiu.com/2009/07/21/godaddy-301/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 10:09:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[互联网]]></category>
		<category><![CDATA[godaddy]]></category>

		<guid isPermaLink="false">/2009/07/21/godaddy-301.html</guid>
		<description><![CDATA[为了将域名不带 WWW 的前缀指向带前缀的，一般使用 301重定向，操作步骤如下： 1. 将如下代码粘贴在记事本，保存为 .htaccess ： RewriteEngine onRewriteCond %{HTTP_HOST} ^yanjiuyanjiu.com [NC]RewriteRule ^(.*)$ http://www.yanjiuyanjiu.com/$1 [L,R=301] 2. 登录 godaddy，开启免费空间，这个要耗费一点时间。 3. 等空间开启了，就把这个文件上传到 空间个目录下。 4.  等待一会儿，再次访问 yanjiuyanjiu.com ，会自动跳转到 www.yanjiuyanjiu.com。 注意：有两个地方需要耐心等待一段时间，一个是开启免费空间，另一个是上传 ..htaccess 文件之后。   参考资料：通过.htaccess实现GoDaddy域名Apache 301重定向 .htaccess和500 Internal Server Error的解决之道！    ]]></description>
			<content:encoded><![CDATA[<p>为了将域名不带 WWW 的前缀指向带前缀的，一般使用 301重定向，操作步骤如下：</p>
<p>1. 将如下代码粘贴在记事本，保存为 .htaccess ：</p>
<p>RewriteEngine on<br />RewriteCond %{HTTP_HOST} ^yanjiuyanjiu.com [NC]<br />RewriteRule ^(.*)$ http://www.yanjiuyanjiu.com/$1 [L,R=301]</p>
<p>2. 登录 godaddy，开启免费空间，这个要耗费一点时间。</p>
<p>3. 等空间开启了，就把这个文件上传到 空间个目录下。</p>
<p>4.  等待一会儿，再次访问 <a href="http://yanjiuyanjiu.com" target="_blank">yanjiuyanjiu.com</a> ，会自动跳转到 <a href="http://www.yanjiuyanjiu.com" target="_blank">www.yanjiuyanjiu.com</a>。</p>
<p><strong>注意</strong>：有两个地方需要耐心等待一段时间，一个是开启免费空间，另一个是上传 ..htaccess 文件之后。</p>
<p> </p>
<p><strong>参考资料</strong>：<a href="http://www.imguangyao.com/archives/270" target="_blank">通过.htaccess实现GoDaddy域名Apache 301重定向</a></p>
<p><a href="http://www.cnwebmasters.com/thread-15949-1-1.html" target="_blank"> .htaccess和500 Internal Server Error的解决之道！</a></p>
<p> </p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.yanjiuyanjiu.com/2009/07/21/godaddy-301/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

