新年快乐!!
小卒祝大家新年快乐!!
有时新的一年,祝大家的美好心愿都能成真!哈哈…
小卒祝大家新年快乐!!
有时新的一年,祝大家的美好心愿都能成真!哈哈…
今天通识案例课中央电视台的记者讲了中国的江河十年的变化。
有些悲观。而且代价惨重。有趣的是一条河上到处建电站。密密麻麻,结果中国还是缺电。很明显,这电站和手工作坊差不多。
增加了些环保意识。于是写此篇文章以纪念。
而后又有了新的想法:去当官,而且要当大官!
不过…我是没有要去参政的想法。
我在图书馆——自习中…
近日在图书馆里上自习。想事情想得烦了,晃动双脚摩擦着地面期待灵感的显现。这瞬间突然
发现有个人与自己很像——马克思。不过很可惜自己不姓马,所以即使克思也不是马克思…当年马克思是不是在为资本论而发愁呢?想想自己在图书馆自习室某个位置坐久了,
会不会也磨出个脚印呢?想到这里,又用脚狠狠的磨了下地板。
近来听说要抵制法国货,于是有些人把各种产品列上了:
香奈儿 家乐福 路易威登LV 欧莱雅 卡地亚 空中客车 鳄鱼服饰 兰蔻 纪梵希 梦特娇 巴黎世家 人头马 马爹利 轩尼诗 碧欧泉 宝姿 达能 皮尔卡丹
圣罗兰 爱马仕 薇姿 都彭 艾格 依尼 兰姿 米欧 艾瑞娜 露得清 娇兰 歌非乔 卓丹 百宝力 卡纷 非罗伦斯 希巴杜 那可可 姿妮华 雷诺 乐飞叶 雅漾
迪莱 圣戈班 所罗门 迪梵 克里斯提鲁布托 库克香槟 凯歌香槟 雪铁龙 标致 凯芙兰 阿尔卡特 夜巴黎香水 米其林 啄木鸟 娇韵诗 迪卡侬 王朝葡萄酒
这些东西的确很多,当然法国货还不止这些:
1 法国空客(大家请坐波音)
2 《巴黎圣母院》、《悲惨世界》、《哲学原理》、《哲学通信》、《人间喜剧》、《鼠疫》、《基督山伯爵》、《社会契约论》、《论法的精神》、《茶花女》、《约翰;克
利斯朵夫》、《基督山伯爵》、《包法利夫人》、《思想录》、《西方哲学史》、《存在与虚无》、《论美国的民!主》、《忏悔录》、《三个火枪手》、《爱弥儿》、《新爱洛
伊丝》、《人间喜剧》、《羊脂球》、《红与黑》、《巨人传》
3不使用直角坐标系,算极限的时候不用罗必塔法则,不用傅里叶变换,不用泊松方程和泊松积分,不用拉格朗日中值定理,拉格朗日插值多项式。
为了民族的振兴,这些都不要用了。让我们来点极端的。特别是数学…其实我很不喜欢当今的数学体系…不知道中国人谁有兴趣再建立一套?
俺的SVM,牛mm说太口语化,另外加的都是句号,说我语文没有学好。于是她给我改写了一下。我发现我真的很喜欢句号,句号表示一句话终结了。很显然,我喜欢把每件事
情都终结了。
不多说了,因为牛mm可能不希望别人知道她真名,所以我只好先用牛mm代替了。因为她很牛,而且又是mm,所以就叫牛mm。原文:
http://blog.csdn.net/cctt_1/archive/2008/11/17/3321185.aspx
废话完毕,下面粘贴改进后的版本:
第一步,资料和代码查找。在 Google 上搜索各种 SVM 相关代码和使用方法,经过可行性试验和筛选,选定了 libsvm 的 c
版本,使用 vs2005 编译生成 svm-train.exe ,svm-predict.exe, 和 svm-scale.exe
。关于这些类库文件的使用方法,可以参照 http://www.csie.ntu.edu.tw/~piaip/ docs/svm/ 。
第二步,确定文件存储格式。通过下载和阅读 heart.scale 了解到,其文件格式是
< 类号 > < 词号 > : < 词个数 > < 词号 > : < 词个数 >…
但是这里有一点要注意:最后一行数据必须敲一个回车。就是说以空行做结束。否则程序就不会终止。另外偶然发现 svm 可以直接处理字符串,文件格式是: 类号
字符串。我心想这个不正适合我的文本分类吗?而且我根本就不需要做分词就可将整个 content 当作一个字符串。我试了下作者给的其他的 svm
版本都不支持。我看了下这个作者给的 svm 的源代码 libsvm-2.88-string
中其实是含有这段代码的,但是没有使用宏进行编译,所以要使用这个 libsvm 来处理字符串,需要对代码进行宏编译。
第三步,宏编译? -D … 后面还有一大堆看不懂的参数。作者给了 makefile 文件,可以选择两种编译环境:一是 windows
环境;二是 linux 等操作系统。考虑到数据文件大小在 3G 左右, linux 下并没有足够大的空间来存放这些文件,所以只有在
windows 下了。下载一个 windows 下的 g++ ,安装后,打开作者所给的 makefile 文件,去掉 CXX?=g++
中的 ?. 然后生成成功。
第四步,研究 java 如何调用 libsvm 的 exe 文件。找了几段网上的代码,发现均不满足要求;于是写了
http://blog.csdn.net/cctt_1/archive/2008/11/14/3300789.aspx
。不过这篇文章里只是说
exe 运行正确的情况下可以正常退出;如果 exe 抛出异常,那么程序就会终止。所以你还有在得到一个类似 error 的输入输出流,这个也是
Process 的函数。然后反复试验就知道是把 error 流放在前面还是正常输入输出放在前面了。
第五步,初步测试。使用十几个 content 做测试,发现效果不错;然后用了 26000 多个 content
再做测试,发现运行了几个小时依旧没有结果。其实之前就不抱有什么期望,因为 libsvm 对字符串的处理是采用子串匹配算法,效率比较低。
第六步,重新使用正常的 libsvm ,采用类号 词号:词个数 … 作为文件存储方式。这时看到了 libsvm-2.88 有 java
的代码,于是采用之;但是在 libsvm 中抛了 Outofmemory 异常。我按网上的做法,将 eclipse 的 eclipse.ini
文件中的 xmx 的大小改为 1024m ,重启之,还是不行。于是再搜索,结果还是没有啥新发现,于是还是使用了调用 exe
的方式。(后来才知道这里的 1024m 是对于 eclipse 来说的。如果 eclipse 运行程序的话,要在 Run… 这个选项中的
jvm 参数中设置 -xmx1024m 才可以。)
第七步,一切 ok ,进行测试,发现正确率偏低达到 28% 。后来看到有 scale 的 exe
,想着可以找到训练的最好参数。但是我看着我的硬盘一点点的被吃掉,那个生成 scale 的程序还没有终止。一个 30M 的小文件耗费了我 6G
左右的硬盘 … 而且还没有将 scale 生成完毕, scale 方法就此作罢。如果只有几百个 content 使用 -c
的参数竟然达到了 100% ;但是交叉训练还是 25% 左右。
第八步,检查了自己的程序,发现竟然词号那里有错误。每统计一个文件,重新生成了一个词号 …
这怎么可能是对的,重新改正,生成新的数据文件。再跑一遍,发现这次 svm-train.exe 抛异常了,竟然是 status_access_valid
。查了下是共享内存出了问题,但是我这个是单线程的,于是把几乎所有能关的程序全部关闭再跑,依旧同样的错误。给作者发信, 作者竟然很快给我回信了,说
libsvm 可以跑出结果呀,又把他的 log 给了我。
第九步,和同组成员一起分析原因。为啥人家就能跑出来,自己却跑不出来呢?再看 libsvm 的异常信息,上面有 stack 的信息,再分析了下作者给的
log ,发现我没有跑出来的那个 log ,其迭代次数达到了 3000 多次;而之前的最高次数也就是 1000 次。难道是 stack
溢出?于是使用 vs 打开源代码,将工程中的 properties->system->stack commit size 调为 10 ,意为
10M ,再各个编译、运行,果然成功。
第十步,训练 26000 个 content 需要 1 个小时,但是需要训练的 content 数量是 26000*7
以上的。以实际经验来看 svm 的训练不是线性的,而是指数或多项式级的;所以训练如此大的文件,我的机器我的时间是根本不允许的。
SVM 虽然部署完毕,但是在运行过程仍然存在着种种问题,下面是一些想法:
1 )如何解决正确率不高,训练时间长的问题。因为没有时间这样去跑,所以得另想它法,能不能将几篇文档整合?于是将全部的文档按照 doc 个数为 n
进行整合,然后最后再除以 n. 所以现在维数据不是词个数(整数),而是浮点数,然后将测试文档放入预测,发现全为 0
了,根本预测不出。可能是因为这样除 n 不具有一般意义,比如一个词只出现 1 次,但是再除以 n ,那就是 0.0001
或者更小;而预测文档中此词就是 1 ,所以根本不可能匹配。另外一种方法:如果 n 个文档不匹配,那么如果是全部的文档,是否符合统计的规律?结果测试说
明,还是不匹配,原因相同。这里其实还有一个想法,就是将这个统计得到的训练文档中维数据整理成整数,如果此时维数据是 0.0001 ,还有的维数据是
0.002 ,那么如果真实测试文档中有这两个词,那么必定至少是 1 。如果每个维数据都乘以一个代价常数,变为一个大于等于 1
的维数据,这样做就有可能得到正确的预测。另外还要考虑到有些词是偶尔出现在此类中,也就是基本与此类无关。那么的它的维数据中可能有更小的例如
0.000001. 那么这样的数据怎么考虑?还有如果全部的维数据都乘以一个相同的代价常数。那么当维数据 0.0001 变为 1 时,(假设)维数据
1 (表示这个词与此类有极大的关联),将变为 10000 ,在一篇文档中不可能有一个词个数是 10000
的。即使这个词在每个文档中都出现,所以我们还是不能这样直接乘以一个相同代价的常数。这里因为时间关系,并没有做一个代价函数。
2 )试图采用所有的数据进行训练。 26000 个 doc
不一定能说明什么问题,当数据量极大的时候,或许能产生一个好结果;但是这是我们希望发生的事情。借用了别人实验室中的机器,发现虽然他的机器是 4 核 4G
的,但是跑 svm 依旧很慢。原因在于 svm 是一个单线程单进程的程序,所以和一个核去跑本质上没有啥区别。另外也发现一个问题,就是 libsvm
在测试 2.57G 的数据时, crash
了,这真的不是内存或者是其他的错误,因为产生的向量维数太大,以至于申请一个向量空间时访问到了操作系统的保护段数据,被操作系统拒绝了,所以可能要进行 “
缩水 ” 。
我这里说的“缩水”是一种自己的算法,我认为每个文档在训练集中的地位不是一样的。那么可能有些文档没有必要存在于训练集中,或者说每个文档存在于训练集中的概率是不
同的,所以我这里做一个“缩水”,将大文档尽可能的排除,设为 20% 概率保留;小文档尽可能的保留,设为 80% ;中等大小的文档 50%
保留。这样做完后,只剩下 500M 左右的数据。我希望这些数据可能保持原来的特性,并且训练速度要提高,可惜结果还是一样的差。
3 )想到可以查询相关论文资料。(这一步感觉应该提前去做。竟然因为时间关系忘记了,因为一直以为这是一个工程的活,和研究没有太多的关联。谁知道在数据量如此大
时候,这些工程的方法都不起作用。)找到很多论文,发现论文之间的一致性:降维,找特征值。可是这个矩阵太大了。另外还有一种方法,就是在这个类中找出很多感觉上一定
相关的词(人肉的方法),然后用这些词进行筛选。当然这个方法是可行的,可惜没有时间和精力去每个类找这么多相关的词。
我觉得 svm 不得不暂时放弃了。毕竟数据量太大的时候,效果很不好,这也是各个 svm
论文中提到的一点;而且至今没有很好的解决方案。另外即使是降维,最后还是要调节参数,看了各个文献,发现调参数也是很有讲究的 ( 使用人工智能等等方法 )
。
最后的总结: svm 的确是可以运行了,但是训练时间太长;另外数据集太大, svm 显得太笨重;还有正确率必须用参数调优,而调优的前提是必须生成
scale 文件。大数据量所生成的 scale 文件太大了,所以就不可能去调优(对于我的机器而言)。这样比较起来还是朴素贝叶斯较好,简单、而且速度快。
线性级排序算法
需求:需要找到前 m 个大数,这 m 个数必须有序。现在有 n 个数( n>>m )。可以使用大空间但是空间远小于 n
。这里的含义是连同这 n 个数都不要占用 n 的空间。因为数据量太大了。 N 个数是一个一个生成的。
思考:
1. 这 m 个数有序,这当然不是一个排序问题,或者是一个部分排序问题。已知的排序是冒泡,插入,选择,归并,快速和基数排序。
2. 冒泡效率低。选择排序的要求是这 n 个数已经存在,并且需要的空间(包括这 n 个数的存储空间)肯定大于 n 。快排,虽然在找第 k
的数是 klogk 的复杂度也就是线性级 O(n) 。但是它还是需要 O(n) 的空间。归并排序,基数排序也是同样如此。
3. 插入排序要求,元素是要移动的。所以插入的移动数据复杂度是 O(n 2 ) 。所以这里要改进下插入排序。要将插入变为 O(1)
。那么就要使用链表。而且数据是一个一个生成的,那么小的数据插入在大的数据后面。这样就完成了排序任务。
4. 另外设置固定长度为 l, 可以认为即使是大数据量 n ,也有 cl=n/l, 其中 cl 为较小常数。
部分伪代码:
public static void Sort (LinkedList lsort ,double num)
{
if(lsort.size() == 0 )
{
lsort.add(0, num);
return;
}
for(int i = 0; i < m && i< lsort.size(); i++)
{
if(num > lsort.get(i))
{
lsort.add(i,num);
break;
}
}
// remove no used sort object
if(lsort.size() == maxSize)
{
int startIndex = maxSize - fileSetNum;
while(startIndex – != 0)
{
lsort.removeLast();
}
}
}
我们下面对上面的这段代码进行分析 , 因为使用链表,所以插入删除的复杂度为 O(1), 查找的复杂度为 O(m) 但是会包含在第二段代码中:
if(lsort.size() == 0 )
{
lsort.add(0, num);
return;
}
这段代码的时间复杂度明显是 O(1)
for(int i = 0; i < m && i< lsort.size(); i++)
{
if(num > lsort.get(i))
{
lsort.add(i,num);
break;
}
}
这段代码中 m 个数为常数。所以这个进行比较的时间复杂度最差为 O(m) ,即只与前 m 个数进行比较。
// remove no used sort object
if(lsort.size() == l)
{
int startIndex = l – m;
while(startIndex – != 0)
{
lsort.removeLast();
}
}
这段代码是为了减少存储空间。当空间达到 l 时,将会释放 l-m 个空间。使得存储空间不会到达 n 。这段代码的时间复杂度为 O(l-m)
。 但是因为这段代码不是经常执行 , 要在链表长度到达 l 时才会执行,所以分摊到各个执行上其复杂度为 O((l-m)*l/n).
当此段代码需要访问 n 次。
所以总复杂度为各个复杂度加和再乘 n 为: n*(O(1)+ O(m)+O((1-m)*l/n)) = O(n+mn+(1-m)*l)=O(mn),
因为 m 为常数,所以故为 O(n)
总结:
根据已有的算法知识,做出符合需求的算法。并且这个算法的时间复杂度也很理想。在实际运行过程中达到了很好的效果。使用 java 测试。在 290000
条待排序的数据中,时间消耗在 700ms 左右。
1. 安装 SQL Server 2000 analysis service
2. 安装 analysis service sp3,这里要注意一定要安装同样语言版本的。如果你安装的 SQL Server 2000
analysis service是简体中文版,那就到微软那里网站上选择语言为简体中文版,然后再下载该 analysis service sp3。 [
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-
cn&FamilyID=90dcd52c-0488-4e46-afbf-acace5369fa3
](http://www.microsoft.com/downloads/details.aspx?displaylang=zh-
cn&FamilyID=90dcd52c-0488-4e46-afbf-acace5369fa3) 那里的名字叫做chs_sql2kasp3.exe
3. 使用 analysis manager 建立多维数据集
“mdataset”。这里要新建立一个数据库,然后选中你在ODBC中的数据源。(连接程序选择Microsoft OLE DB provider for
ODBC drivers)然后再去建立数据集。如果不知道如何在ODBC中建立数据源可以参见
http://blog.csdn.net/cctt_1/archive/2008/11/20/3339526.aspx
。
4. 打开 Brio 软件,新建一个连接,连接软件和数据库类型都选择 OLE DB ,下一步
5. OLE DB 提供者选择 Microsoft OLE DB Provider for Olap Services 8.0 ,下一步
6. 选择分析服务器 ,输入服务器为localhost ,下一步
7.你可以看到你的多维数据集…选中它即可。
8。ok
其实我是想连接sql server 2005的,但是brio只支持2000,无奈。
1. 启动sqlserver2000,在控制面板中点击管理工具。然后再选中服务,在弹出的窗口中选择MSSQLSERVER,点右捡查看属性。选择自动后,然后
点击启动。(在下放会有小图标,并有绿色箭头,如果没有就在开始菜单中选择Microsoft SQL
server->服务管理器,在弹出的窗口下服务器中选择你的完整计算机名)
2.查看我的电脑的属性,然后再选中计算机名,记住你的完整计算机名。
3.再管理工具中点击数据源(ODBC),然后在系统DSN选项卡中点击添加,选中最后的sql
server.输入一个名称test,然后再你想要连接那个服务器的选项中 选择你的完整计算机名。下一步,再下一步,一直到完成。
4.在Microsoft SQL Server中选择企业管理器。然后建立你自己的数据库
5.在brio中选择使用哪种连接软件->ODBC,然后连接到何种数据库类型->Microsoft Sql server 7/2000,然后勾上显示数据库名。
6.下一步,主机选择test,然后下一步,数据库选择你新建的数据库…
7. ok
开始接到SVM的研究任务,心里其实感觉svm是够难的。因为我大学在人脸识别项目中曾经研究过一段时间。但是因为不知道为何matlab中svm类库有点小问题,就
被迫终止了研究。所以心里一直发憷。
当然这件事如果我不做,估计没有人去做。为了自己的信息检索大作业(文本分类)。还是要好好的努力下。
之后在google上搜索各种svm相关的代码和使用方法。(这估计是我研究的第一步,收集大量资料)
第二步,找到可能有关的类库文件或者代码保存下来。这时我搜索到libsvm,其实还有各种关于svm的matlab版。
第三步,决定使用那个svm。1.libsvm当时只搜到c版本。2.svm的matlab版本也有。这时我的项目使用的是java语言。虽然语言具有无关性。但是还
是要看看各种语言之间是怎么调用。matlab版本说要使用一个tooljar文件。但是这个文件在我的matlab中没有找到。所以先搁置一下。libsvm的c版
本用vs2005打开,发现竟然编译不通过。于是在网上查为啥不通过。后来解决。然后生成svm-train.exe ,svm-predict.exe,和svm-
scale.exe.但是这个怎么用?还是在网上搜索下。
第四步,搜索如何使用libsvm类库。这里可以说研究的对象更加明确了。应该使用什么类库也比较清楚。然后搜到了一篇写的很好的libsvm如何使用的文章。
_ http://www.csie.ntu.edu.tw/~piaip/docs/svm/ _
感觉写的很不错。我这里就不重复写了。
第五步,确定文件存储格式。那个使用简介上说要下一个heart.scale,最后历经千辛万苦终于在libsvm的网站上找到了。 _
http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/ _
这里有很多数据文件,找到classification的download下来看看就知道了。其实文件是由
类号 词号:词个数 词号:词个数…但是这里有一点要注意:最后一行数据必须敲一个回车。就是说以空行做结束。否则程序就不会终止。另外偶然发现svm可以直接
处理字符串,文件格式是: 类号 字符串。我心想这个不正适合我的文本分类吗?而且我根本就不需要做分词就可将整个content当作一个字符串。我试了下作者给的其
他的svm版本。都不支持。我看了下这个作者给的svm的源代码libsvm-2.88-string中其实是含有这段代码的。但是没有使用宏进行编译。所以要使用这
个libsvm来处理字符串,需要对代码进行宏编译。
第六步。宏编译? -D …而且后面还有一大堆看不懂的参数。作者倒是给了makefile文件。下面采用两个方向:
1.在windows下进行编译。2。在linux等操作系统下编译。但但是我的数据文件3个G左右,linux下并没有足够大的空间来放这些文件。所以只有在win
dows下了。然后又在google上搜索了如何使用vs的编译器来执行makefile文件。搜到几个网页。发现vs的编译器就是cl.exe文件。但是它依旧不支
持这个makefile。无奈打开makefile文件。看到makefile中第一行CXX? = g++。改为CXX = cl.exe
依旧不行。(其实我是乱改的。)
2.下一个windows下的g++,安装后,去掉CXX?=g++中的?.然后生成成功。
(其实这两步没有这么麻烦的。作者在libsvm-2.88中给了makefile.win就可以用cl.exe来生成windows下的exe。但是还是要改动一下
才能用于处理字符串的svm,要加-D _STRING
才可以。但是libsvm-2.88的代码可能不含处理字符串的代码。用的时候看看源代码中是否包含宏定义_STRING )
第七步。研究下java是如何调用exe的?找了几段网上的代码…发现均不满足要求。于是写了 _
http://blog.csdn.net/cctt_1/archive/2008/11/14/3300789.aspx _
不过这篇文章里只是说exe运行
正确的情况下可以正常退出。如果exe抛出异常。那么程序就会卡死。所以你还有在得到一个类似error的输入输出流。这个也是Process的函数。然后你反复试试
就知道error流放前还是正常输入输出放前了。:)当做练习吧
第八步。我使用十几个content做了测试。效果不错。然后用了26000多个content再做测试。发现运行了几个小时依旧没有啥结果。前面其实就不抱有什么期
望。因为这个libsvm对字符串的串的处理是用的字符串子串匹配算法。效率能高才怪了。但是我的content不只26000个。大概有1500000个左右…那
需要跑多久呀…所以只得放弃。
第九步。重新使用正常的libsvm。采用类号 词号:词个数…作为文件存储方式。这时看到了libsvm-2.88,哈哈竟然有java的代码。于是采用之。但
是在libsvm中抛了Outofmemory异常。我按网上的做法,将eclipse的eclipse.ini文件中的xmx的大小改为1024m。重启之。还是不
行。于是再搜索…结果还是没有啥新发现。(后来才知道这里的1024m是对于eclipse来说的。如果eclipse运行程序的话,要在Run
…这个选项中的jvm的参数中设置-xmx1024m才可以。网上的教材不可轻信呀!)当时我还是使用了调用exe的方式。
第十步。一切ok,测试…发现正确率偏低最好达到28%。后来看到有scale的exe。想着可以找到训练的最好参数。但是我看着我的硬盘一点点的被吃掉,那个生
成scale的程序还没有终止。一个30M的小文件耗费了我6G左右的硬盘…而且还没有将scale生成完毕。scale这个方法就不能用来
。如果只有几百个content使用-c的参数竟然达到了100%。但是交叉训练还是25%左右。
第11步。检查了自己的程序。发现竟然词号那里有错误。每统计一个文件,重新生成了一个词号…这怎么可能是对的。(唉,估计自己的当时脑子不清醒)重新改正,生成新
的数据文件。再跑一遍。发现这次svm-train.exe抛异常了。竟然是status_access_valid。。查了下是共享内存出了问题。但是我这个是单线
程的。于是把几乎所有能关的程序全部关闭。再跑。依旧同样的错误。
第12步。给作者发信。因为作者是熟悉英文者。虽然是台湾的,但是我还是给他发英文。谁知道他有没有台
独倾向呢?询问我这个问题,为啥他的那个鬼东东没有跑出结果,却报了异常。当然说话要含蓄。
第13步。作者竟然给我回信了。说这个libsvm可以跑出结果呀。又把他的log给了我。我发现确实跑出来了。这里要发点感慨,你看人家那教授。一天内必回信,而且
还将整个data都训练一下。我想应该有一个小时吧。在想想大陆的教授…无限感慨!
第14步。和同组成员一起分析原因。为啥这个东西人家就能跑出来,自己却跑不出来呢?再看libsvm的异常信息,上面有stack的信息。我再分析了下作者给的lo
g。发现我没有跑出来的那个log,其迭代次数达到了3000多次。而之前的最高次数也就是1000次。难道是stack溢出?(真是佩服自己的运气,啥情况都碰上了
)于是使用vs打开源代码,将工程中的properties->system->stack commit size
调为10,意为10M。再各个编译。再运行,果然成功。
第15步。26000个content需要1个小时。我还要训练26000*7以上的content。并且我以我刚刚的经验来看这个svm的训练不是线性的。是指数的
,或者是多项式级的。所以训练如此大的文件…我的机器我的时间是根本不允许的。因为没有那个精力。而且还面临着调优。
第16步。向信息检索老师argue一下。结果老师说你就这样吧。算工作量,正确率不高没有关系。
第17步。正确率不高…我估计也没有时间这样去跑呀…所以另想它法,能不能将几篇文档整合?于是将全部的文档按照doc个数为n进行整合,然后最后再除以n.所以
现在维数据不是词个数(整数),而是浮点数。然后将测试文档放入预测。发现全为0了,根本预测不出。可能是因为这样除n不具有一般意义。比如一个词只出现1次,但是再
除以n,那就是0.0001或者更小。而预测文档中此词就是1,所以根本不可能匹配。另外一种方法。如果n个文档不匹配。那么如果是全部的文档,是否符合统计的规律?
结果测试说明,还是不匹配。原因相同。这里其实还有一个想法。就是将这个统计得到的训练文档中维数据整理成整数。就是如果此时维数据是0.0001,还有的维数据是0
.002,那么如果真实测试文档中有这两个词,那么必定至少是1。如果每个维数据都乘以一个代价常数,变为一个大于等于1的维数据。这样做就有可能得到正确的预测。另
外还要考虑到有些词是偶尔出现在此类中,也就是基本与此类无关。那么的它的维数据中可能有更小的例如0.000001.那么这样的数据怎么考虑?还有如果全部的维数据
都乘以一个相同的代价常数。那么当维数据0.0001变为1时,(假设)维数据1(表示这个词与此类有极大的关联),将变为10000,在一篇文档中不可能有一个词个
数是10000的。即使这个词在每个文档中都出现。所以我们还是不能这样直接乘以一个相同代价的常数。这里因为时间关系,并没有做一个代价函数。
第18步。采用所有的数据进行训练。26000个doc不一定能说明什么问题。当数据量极大的时候。或许能产生一个好结果。但是这是我们希望发生的事情。借用了别人实
验室中的机器。发现虽然他的机器是4核4G的。但是跑svm依旧很慢。原因在于svm是一个单线程单进程的程序。所以和一个核去跑本质上没有啥区别。另外也发现一个问
题。就是libsvm在测试2.57G的数据时,crash了。这真的不是内存或者是其他的错误。因为生产的向量维数太大。以至于申请一个向量空间就被操作系统拒绝了
。因为访问到了操作系统的保护段数据。所以可能要进行“缩水”。
第19步。我这里说的“缩水”是一种自己的算法。我认为每个文档在训练集中的地位不是一样的。那么可能有些文档没有必要存在在训练集中。或者说每个文档存在在训练集中
的概率是不同的。所以我这里做一个“缩水”。将大文档尽可能的排除,设为20%概率保留。小文档尽可能的保留,设为80%,中等大小的文档50%保留。这样做完后,只
剩下500M左右的数据。我希望这些数据可能保持原来的特性。并且训练速度要提高。可惜结果还是一样的差。
第20步。查询相关论文资料。(这一步感觉应该提前去做。竟然因为时间关系忘记了,因为一直以为这是一个工程的活,和研究没有太多的关联。谁知道在数据量如此大时候,
这些工程的方法都不起作用。)找到很多论文。同时也发现了这些论文之间的一致性:降维,找特征值。可是这个矩阵太大了。这方法有问题。另外还有一种方法,就是在这个类
中找n多感觉上一定相关的词(人肉的方法)。然后用这些词进行筛选。当然这个方法是可行的。可惜没有时间和精力去每个类找这么多相关的词。
第21步。我觉得我还是暂时放弃它好了。毕竟数据量太大的时候,效果很不好,这也是各个svm论文中提到的一点。而且至今没有很好的解决方案。另外即使是降维,最后还
是要调节参数。看了各个文献,发现调参数也是很有讲究的(使用人工智能等等方法)。
最后的总结:
svm地区是能跑了,但是训练时间太长了。另外数据集太大,svm就显得太笨重了。还有正确率必须用参数调优。要调优的前提就必须生成scale文件。大数据量所生成
的scale文件太大了。所以就不可能去调优(对于我那机器而言)。这样比较起来还是朴素贝叶斯方法较好。简单,而且速度快。