每日一贴,今天的内容关键字为矩阵特征
大学时我的线性代数老师寿继麟,事先六十多岁带着一副金丝眼镜精力矍铄,传说是我最尊敬的余德鴻副校长的老师。上课的课本是寿老师写的打印出来给大家,很便宜。我虽然不好好学习,但是在好老师的率领下,也不至于学的太差。余校长隔段时光总会给我们上一堂课,虽然没有说过我们什么,但总能让我们羞愧进而耐劳上一段时光。记得他说过这样一个问题,会场人声嘈杂,给你两个麦克风,怎么在一无所知的情况下分离出你想听到的那个人的声音。十年后的今年我才真正开始考虑这个问题,余校长提出的问题,原来寿老师事先就帮我们处理了。
非负矩阵因式分解,非负是说矩阵的元素都是正数或者零,因式分解就是对矩阵A,寻觅矩阵B和C,使得A=B*C。这样分解有什么用呢?还是为了处理分类的问题。区别人声,也是一个分类问题。分类的问题在之前《集体伶俐编程学习之分类系统》中提到了贝叶斯和费舍尔,在《集体伶俐编程学习之聚类系统》中提到了K-均值聚类,贝叶斯和费舍尔需要事前定义好分类,然后训练模型,K-均值聚类的计算量还是蛮大的。而非负矩阵因式分解可以一次把所有的相关性计算出来,还是很有必要好好学习的。
矩阵因式分解的目标呢,就是把矩阵B拆分成为两个矩阵相乘,比如矩阵F和矩阵W,这样B=W*F。矩阵的乘法事先寿老师教的很清晰,第一个矩阵(比如W)的列必须于第二个矩阵(比如F)的行数相称才能相乘,乘积矩阵(比如B)的每一个元素的取值,是通过将矩阵W中雷同行的值与矩阵F中雷同列的值相乘,然后将乘积相加所得。(这里我不举例子了,随便Google就有了)。这里将B拆分为F和W的乘积,F代表特征矩阵,W代表权值矩阵,下面具体说说这两个货色。
F特征矩阵:在该矩阵中,每一个特征对应一行,每一个单词对应一列,矩阵中的数字代表了某个单词相对于某个特征的重要程度;
W权值矩阵:在改矩阵中,每一行对应一本书,每一列对应一个特征,矩阵中的数字代表了将某个特征应用于某篇文章的程度;
这样W*F就可以重构出B,一行对应一本书,一列对应一个单词。
通过计算最好的特征矩阵和权值矩阵,算法实验尽可能大地来从新结构文章矩阵。这里我们先定义一种方法来衡量最终结果与幻想结果的接近程度:
def difcost(a,b): dif=0 for i in range(shape(a)[0]): for j in range(shape(a)[1]): # Euclidean Distance dif+=pow(a[i,j]-b[i,j],2) return dif
函数difcost针对两个同样大小的矩阵遍历其中的每一个值,并将两者的间差值的平方累加起来。
下面我们需要一种方法能够逐渐地更新矩阵,以使本钱函数的计算值逐步降低。《集体伶俐编程学习之优化系统》里的退火法和遗传算法都能满足要求。这里我来学习一种更为的方法,乘法更新矩阵规律。规律的具体道理先不学习,先直接拿来用。有兴趣的看这篇论文《Algorithms for Non-negative Matrix Factorization》
这个规律发生四个新的更新矩阵:
hn:转置后的权重矩阵与数据矩阵相乘而来;
hd:转置后的权重矩阵与原权重矩阵相乘,再与特征矩阵相乘而来;
wn:数据矩阵与转置后的特征矩阵相乘而来;
wd:权重矩阵与特征矩阵相乘,再与转置后的特征矩阵相乘而来;
更新特征矩阵和权重矩阵,我们将特征矩阵中的每一个值与hn中的对应值相乘,并除以hd中的对应值;再将权重矩阵中的每一个值与wn中的对应值相乘,并除以wd中的对应值下面看用python的算法实现:
def factorize(v,pc=10,iter=50): ic=shape(v)[0] fc=shape(v)[1] # Initialize the weight and feature matrices with random values w=matrix([[random.random() for j in range(pc)] for i in range(ic)]) h=matrix([[random.random() for i in range(fc)] for i in range(pc)]) # Perform operation a maximum of iter times for i in range(iter): wh=w*h # Calculate the current difference cost=difcost(v,wh) if i%10==0: print cost # Terminate if the matrix has been fully factorized if cost==0: break # Update feature matrix hn=(transpose(w)*v) hd=(transpose(w)*w*h) h=matrix(array(h)*array(hn)/array(hd)) # Update weights matrix wn=(v*transpose(h)) wd=(w*h*transpose(h)) w=matrix(array(w)*array(wn)/array(wd)) return w,h
参数pc指定我们希望找到的特征数,iter是最多执行次数。
来看看我机器执行的测试:
测试数据还是用之前的例子:每一行都是一本书,每一列都代表一个词,数组中的数字代表这个词在这本书中涌现的次数或者TF-IDF值:
books = [ [2, 3, 3, 12, 13, 12], [3, 3, 1, 13, 12, 11], [1, 10, 3, 5, 11, 13], [13, 12, 11, 1, 3, 3], [12, 13, 12, 3, 2, 2], [5, 11, 13, 3, 1, 10] ]
>>> from numpy import * >>> v=matrix(nnmf.books) >>> w,f=nnmf.factorize(v,2) 2352.23524582 130.308626905 125.555272626 125.540256481 125.540046063 >>> w matrix([[ 1.01861466, 0.11646996], [ 0.99224682, 0.07461746], [ 0.80748193, 0.400123 ], [ 0.04713232, 1.2421583 ], [ 0.04119911, 1.27694878], [ 0.27820173, 1.02855868]]) >>> f matrix([[ 0.21984673, 3.29533888, 0.77713346, 10.7432405 , 12.31672543, 12.3422249 ], [ 8.44995405, 10.06321664, 9.81092778, 0.6161926 , 0.65151678, 2.88313112]]) >>> w*f matrix([[ 1.20810496, 4.52874298, 1.93427795, 11.01499022, 12.62187925, 12.90776943], [ 0.84865631, 4.02068115, 1.50317469, 10.70592492, 12.26984613, 12.46166529], [ 3.5585432 , 6.68745101, 4.55309905, 8.92152545, 10.20622012, 11.1197307 ], [ 10.50654247, 12.65542508, 12.2233535 , 1.27176259, 1.38980281, 4.16302294], [ 10.79921601, 12.98597723, 12.56006946, 1.22945829, 1.33939163, 4.1900994 ], [ 8.75243536, 11.26737784, 10.30731484, 3.6225783 , 4.09665751, 6.39909782]])
我测试用的特征数选择为2。
先来看看权值矩阵w:
book1,特征一显著(1.0),特征二不显著(0.1);
book2,特征一显著(0.9),特征二不显著(0.0);
book3,特征一显著(0.8),特征二不显著(0.4);
book4,特征一不显著(0.0),特征二显著(1.2);
book5,特征一不显著(0.0),特征二显著(1.2);
book6,特征一不显著(0.2),特征二显著(1.0);
再看看特征矩阵:
特征一:word1不显著(0.2),word2不太显著(3.2),word3不显著(0.7),word4显著(10.7),word5显著(12.3),word6显著(12.3)
特征二:word1挺显著(8.4),word2显著(10.0),word3显著(9.8),word4不显著(0.6),word5不显著(0.6),word6不显著(2.8)
实现还是很简单的,主要是这类思惟,再次得成论断最NB的还是算法。上次听博士说一年要读100多篇论文,这才是学术研究,这才会发明核心技术。
文章结束给大家分享下程序员的一些笑话语录: 一条狗在街上闲逛,看见橱窗里一张告示:「招聘程序员。会编程,有团队精神,至少精通两种语言。均等机会。」
那条狗就进去申请,但是被拒绝了。
「我不能雇一条狗在公司里做事。」经理说。
狗不服气,指着告示上「均等机会」几字抗议。
经理没法,叹了口气,不屑地问道:「你会编程吗?」
那条狗默默地走到电脑前,编了个程序,运作准确。
「你有团队精神吗?」经理问。
那条狗掉头看了看门外,一大群野狗在外面虎视耽耽。
「我真的不能雇狗做这份工作。」经理气急败坏地说。
「就算会编程、有团队精神,但是我需要的雇员至少要能精通两种语言。」
那条狗抬头看着经理说:「喵-噢。」
--------------------------------- 原创文章 By
矩阵和特征
---------------------------------