说明,记录数据挖掘的博客都来源于coursera的公开课,目的也是为了自己总结,这些PPT都是截取的重要的概率和步骤。如果读者感兴趣可以参考https://class.coursera.org/mmds-001/lecture
上面会有视频资料和一些讲义
数据挖掘包括上面几个分支,而今天集中在应用在Web中横梁网页重要性的pageRank算法。
链接分析有如下算法:
其中的PageRank首先有两种衡量链接重要性的公式, 流模式和矩阵模式
AX = 人x, x是特征向量eigenvector, 人是特征值eigenvalue. 所以r是M的特征向量。 并且Mr<=1,因为M的最大特征向量是1.
M也叫转移矩阵,所以他是一个随机矩阵(对于强连通图,某列的和是1),反之,如果某列的和最多是1,即可能是0的转移矩阵称为亚随机矩阵(substochastic)
如何得到最后收敛的重要性衡量值r??使用power iteration. 其定义如下
由于我们想要的结果是最后r正常收敛并且收敛的值能够正确的衡量各个网页节点的重要性。
从上面的结构可以看出最后转移矩阵不断的交换重要性,不能停止,不能判定谁更重要。采集器陷阱是一系列节点集合,他们没有出链指向集合之外,最后导致在计算时所有的PageRank都分配到采集器陷阱之内。
举例如下:这是一个单节点的采集器陷阱,最后他的重要性会收敛为1
上面的例子是是一个单节点的采集器陷阱,最后得到的pageRank值会为1.
结果可以看出尽管最后收敛了,可是所有的网页节点的重要性都是0.这样的某个节点没有出链所导致的问题叫做终止点问题。 可以看做所有的冲浪者最终都会来到这个终止节点,然后一起在这里消失,所以其收敛结果已经不能衡量各个网页的重要性了。
下面继续使用前面的例子来说明一下这两个问题,以及如何解决。
最后得到的新的PageRank的估计值如下:
概率随机跳转也能解决终止点的问题。
但是终止点出了可以用概率随机跳转解决还可以用迭代删除终止点的方法,等到最后剩下节点收敛,再来计算删除的节点的PageRank。
最后附上第一周的测试题。
Suppose we compute PageRank with a β of 0.7, and we introduce the additional constraint that the sum of the PageRanks of the three pages must be 3, to handle the problem that otherwise any multiple of a solution will also be a solution. Compute the PageRanks a, b, and c of the three pages A, B, and C, respectively. Then, identify from the list below, the true statement.
Your Answer | Score | Explanation | |
---|---|---|---|
1.00 | |||
1.头文件负责计算matirix muliplies
//Matrix矩阵类 #include <iostream> using namespace std; class Matrix { public: Matrix(int mm, int nn)//构造函数 { m=mm; n=nn; int i,j; data=new double*[mm]; for(i=0;i<mm;i++) data[i]=new double[nn]; for(i=0;i<m;i++)//矩阵所有元素清零 for(j=0;j<n;j++) data[i][j]=0.0; } //构造M行N列的矩阵 Matrix(const Matrix &src) //拷贝构造函数 { m=src.m; n=src.n; int i,j; data=new double*[m];//动态建立二维数组 for(i=0;i<m;i++) data[i]=new double[n]; for(i=0;i<m;i++)//动态数组赋值 for(j=0;j<n;j++) data[i][j]=src.data[i][j]; } ~Matrix()//析构函数 { for(int i=0;i<m;i++) delete []data[i]; delete []data; } Matrix& operator=(const Matrix &src);//重载"="运算符 Matrix operator * (const Matrix &m2); //矩阵乘法 Matrix operator +(const Matrix &m2);//矩阵乘法的实现 void display(); void input(double a[][3]); void input(double a[3]); private: double **data; int m,n;//矩阵的行数,列数 };//类定义结束 Matrix& Matrix::operator=(const Matrix &src) //重载"="运算符 { int i,j; for(i=0;i<m;i++) delete []data[i]; delete []data; m=src.m;n=src.n; data=new double*[m];//动态建立二维数组 for(i=0;i<m;i++) data[i]=new double[n]; for(i=0;i<m;i++) for(j=0;j<n;j++) data[i][j]=src.data[i][j]; return *this; } //矩阵*运算符重载 Matrix Matrix::operator *(const Matrix &m2)//矩阵乘法的实现 { Matrix m3(this->m,m2.n); if(this->n!=m2.m) { cout<<"两矩阵无法进行乘法运算.\n"<<endl; exit(0); } int i,j,k,l; for(i=0;i<this->m;i++) for(j=0;j<m2.n;j++) { for(k=0;k<this->n;k++) { m3.data[i][j]+=this->data[i][k]*m2.data[k][j]; } } return m3; } Matrix Matrix::operator +(const Matrix &m2)//矩阵乘法的实现 { Matrix m3(this->m,m2.n); if(this->n!=m2.n && this->m!=m2.m) { cout<<"两矩阵无法进行加法运算.\n"<<endl; exit(0); } for(int i =0;i<m2.m;i++) for(int j=0;j<m2.n;j++) m3.data[i][j] = this->data[i][j]+m2.data[i][j]; return m3; } //输入矩阵元素 void Matrix::input(double a[][3]) { for(int i=0;i<m;i++) for(int j=0;j<n;j++) { data[i][j] = a[i][j]; } } void Matrix::input(double a[3]) { for(int i=0;i<m;i++) { //for(int j=0;j<n;j++) //{ data[i][0] = a[i]; //cout<<"i"<<a[i]<<endl; } //} } //显示矩阵元素 void Matrix::display() { int i,j; for(i=0;i<m;i++) { for(j=0;j<n;j++) { cout<<data[i][j]<<" "; } cout<<endl; } }
#include "bheap.hpp" #include <iostream> #include <vector> #include <stack> #include <queue> using namespace std; const int nodeSize = 3; const double manbuda = 0.7; double M[][nodeSize] = { {0,0,0}, {(double)1/2,0,0}, {(double)1/2,1,1}, };//transfer matrix double add[nodeSize] = {0.3,0.3,0.3};//telport 1* 0.3 double v0[nodeSize] = {(double)1,(double)1,(double)1};//since total is 3 int main () { for(int i = 0;i<nodeSize;i++) for(int j=0;j<nodeSize;j++) M[i][j]= manbuda*M[i][j]; Matrix ma(nodeSize,nodeSize); Matrix add1(nodeSize,1); Matrix v(nodeSize,1); v.input(v0); add1.input(add); ma.input(M); Matrix v2(nodeSize,1); for(int i=0;i<6;i++) { v2 = ma*v+add1; v2.display(); cout<<endl; v = v2; } system("pause"); return 0; }可以很容易的通过上上面的代码来实现其他习题。
只是在大数据情况下,矩阵乘法需要分块,需要实现。