加载中…
个人资料
破破的桥
破破的桥 新浪个人认证
  • 博客等级:
  • 博客积分:0
  • 博客访问:2,876
  • 关注人气:6,890
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

用于韩寒文章分析的PCA matlab代码

(2012-01-26 02:47:31)
标签:

杂谈

由于本文是微博回复摘选,可能前后有词义不搭之处。大家看个大概就行了。

觉得文科生真的好容易被忽悠啊。随便用点手法吓吓就全投降了。

下文是一个matlab代码。X是特征矩阵,可以取文章的虚词以及数量构成一个矩阵。dimnum是通过PCA转换后的目标矩阵维数。Xpca是转换后的矩阵,Loss是信息丢失率。(我当年做硬件时写的,熟悉matlab软件的朋友可以直接用princomp函数)。

为了让文科朋友看懂,我仔细讲讲。(估计还是看不懂,唉)
比如:的,地,得,了,在文章里分别出现了1400,200,400,5000次,那么X矩阵是1:1400,2:200,3:400,4:5000。原始dimension是4,目标dimnum必须小于等于4。
虚词的选取应该挑选特征词,具体怎么挑选我不是很清楚,总之不要太多也不要太少,需要有区分度。然后把所有文章的矩阵用PCA压缩一下,放上一些clustering软件自己跑就行了。识别率看来估计在七八成的样子(五个错一两个),也可能更差,因为相关实验我没有做过。我这里推荐用linear classifier,因为比较快,文档比较全。(还有不少其它的聚类方案,但是往往会手选距离值、相似度上限等,可能造成人为干扰,比如选取对自己结果有利的值,当然这个干扰也可以用其它方法解决,不多谈。Linear Classifier完全没有手选余地,都由算法完成,比较中立。唯一的弱点在于特征值选择,比如一组虚词可能是一个结果,另一组可能是另一个结果。特征虚词词组还是人来手选的。)

最后算出的结果可以写成大矩阵,下载Linear Classifier软件,先跑一个training,让电脑记住整个大矩阵特征值,然后用clustering做出多维超平面对文本相似度进行区分。我不是很懂文本分析,但大致是这样做,识别率只能呵呵呵。大家可以自己随机选择文本测试。防忽悠的方法就是自己动手。

我简单讲讲本文所针对原文(不转载了,纯属典型伪科学作品)中的统计问题:1.是把韩寒博客集去掉了,预估杂文和其它问题的词频统计肯定有不同,不知道会影响总统计的判别性还是为了获得一个局部的判别性。总之这不是一件有道理的事情。2.选取的对比作者和作品的标准不明,如果不是随机选取,而是刻意摘选,很容易选出最容易区分的几个和韩寒放在一起。然后再把韩寒文章中摘选和韩仁均最不容易区分的几篇放在一起,就能突出对比度。然而这种手法除了忽悠人以外,一点意义也没有。3.如果做不到随机,就应该用全文本。4.纯粹从classifier的角度来说,也忽视了如下步骤:训练组和测试组没有分开,协方差取样不对,有效性测试都完全没做过。我认为不一定有效。5.从原文PCA的结果看,有一个低级失误,正交化以后两维的取样就涵盖了97.9%的信息,说明选取的关键词完全不是独立的,没有区分度。等于是用两个完全独立的关键词的出现频率就确定了几百万字的小说的归属,这靠谱么?(也可能是算法本身使用出错)最终结果也很可笑,变成了按文章长度的聚类。霸唱的长篇被聚在一起,郭敬明的两个中篇被聚在一起,韩寒的中短篇聚在一起。韩寒和他老爸的几个短篇聚在一起。然后说他和他老爸是同一个人写的,这不纯粹坑爹么。(不说取样的问题,我对该结果本身的数据都非常怀疑,不会是忘了做normalization步骤吧?是不是词频统计时忘了除以文章长度了?把总量代替频率错用作原始数据?

我的建议是,大家想得到正确的“数学”结论(注意只是数学结论),可以尝试用这个步骤自我分析。但是在样本选取上,要严格遵循统计学的方法。韩仁均的样本量要扩展,太小了,各种访谈、未发表版本都可以加进来。而作家的分布考虑各年龄段,各体裁的,查看区分度。作品要随机选取。随机选取很重要。因为对作品很多很杂的作家来说,精心选两个匹配文本太容易了,还能打扮得跟无意中选的一样。

基本步骤:
1.随机挑选样本。挑选韩仁均,韩寒,以及其他你认为疑似的代笔者,再挑选年龄段、文章体裁(因为虚词在长文章中的分布很可能和短文不同,在小说中的分布也很可能和杂文不同)平均分布的作家作品。
2.每个作品用关键词区分后,PCA压缩,算出特征值(eigenvalue)与特征矩阵。
3.将已知的每个作家的特征矩阵用1,2,3等标记标出类别,比如韩仁均为1,韩寒为2,郭敬明为3……,然后用classifier工具做出多维超平面划分。这个叫training步骤。
4.训练步骤做完以后,用不在上文中的韩寒作品,使用linear classifier工具,这个分类工具会自动将该作品分到training中的某个类别里。此时你可以看一下,韩寒的作品有多大几率落在他自己的类别里。如果韩寒的作品会平均地落在韩仁均和韩寒两个组里,那么就表示其文风(指的是数理统计中使用虚词出现的比例而不是那种通常意义上的“文风”)相似,反之文风不相似。

最后提醒一下,使用特征值分析人脸、地理位置的相似度,精确度会比较大,大概有七八成甚至更高,但分析“文风”,是不是伪科学我还不知道,个人认为属于伪科学(仅具备数学意义并无确切的文本考据意义,也就是只能证明两个作品的虚词使用频率相似但不能证明两者为同一人所写)。

这套方法很可能本身就是不成立的,验证有效性时可以采取如下方法:在第3步骤聚类完成后,找一个training阶段未使用的已知作家作品,用同样聚类法进行归类,如果能准备匹配到聚类空间中该作家所在的组别,说明这是一个有效样例,否则是无效样例,然后尝试多个样例后计算有效率。我个人怀疑该方法的有效率很低。

%author: bridgeduan

function [ Xpca, Loss] = PCA_auto( X, dimnum)

[d,n] = size(X);  % get the size of the input matrix, d is the number of rows and n is the number of columns

mPca = mean(X, 2);   % mPCA is the mean value of each rows, it is a column vector which has d elements

Y = X - kron(ones(1,n), mPca); % each element in X will subtract the mean value of its row and save it to Y

St = Y * Y';   % St is the scatter Matrix of Y

[V,D] = eig(St);   % eig() will return a vector of eigenvalues of input scatter Matrix St

Ddiag = diag(D);
Ddiag = Ddiag';   % transform eigenvalue to a row 
[Ddiag, Index] = sort(Ddiag, 'descend');
[Loss,d1] = DestDim2(Ddiag, dimnum); % return dimensions after compression, 0<dimPara<1, percentage of reserved information

Wpca = zeros(d1,d); % initialization
Xpca = zeros(d1,n);
Wpca = V(:, Index(1:d1))'; % choose the most d1 important dimensions 
Wpca = Wpca ./ (sqrt(sum(Wpca.^2, 2))*ones(1,size(Wpca,2))); % standardization.
Xpca = Wpca * Y;


end

------------------------------------------------------------

2012年1月27日补充:该流程已有人跑过,证实利用虚词分析的这套方法,对作品无区分能力。请大家忽略本文。


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有