数据挖掘总介与PageRank

数据挖掘总介与PageRank_第1张图片

说明,记录数据挖掘的博客都来源于coursera的公开课,目的也是为了自己总结,这些PPT都是截取的重要的概率和步骤。如果读者感兴趣可以参考https://class.coursera.org/mmds-001/lecture

上面会有视频资料和一些讲义

一、数据挖掘

数据挖掘包括上面几个分支,而今天集中在应用在Web中横梁网页重要性的pageRank算法。

数据挖掘总介与PageRank_第2张图片

数据挖掘总介与PageRank_第3张图片

二、链接分析

链接分析有如下算法:

数据挖掘总介与PageRank_第4张图片

其中的PageRank首先有两种衡量链接重要性的公式, 流模式和矩阵模式

数据挖掘总介与PageRank_第5张图片

数据挖掘总介与PageRank_第6张图片

AX = 人x, x是特征向量eigenvector, 人是特征值eigenvalue. 所以r是M的特征向量。 并且Mr<=1,因为M的最大特征向量是1.

M也叫转移矩阵,所以他是一个随机矩阵(对于强连通图,某列的和是1),反之,如果某列的和最多是1,即可能是0的转移矩阵称为亚随机矩阵(substochastic)

数据挖掘总介与PageRank_第7张图片

三、随机分布和power iteration

数据挖掘总介与PageRank_第8张图片

数据挖掘总介与PageRank_第9张图片

如何得到最后收敛的重要性衡量值r??使用power iteration. 其定义如下

数据挖掘总介与PageRank_第10张图片

四、PageRank会出现的两个问题

由于我们想要的结果是最后r正常收敛并且收敛的值能够正确的衡量各个网页节点的重要性。

 1.采集器陷阱, 出现的问题一是是不是会正常收敛??

数据挖掘总介与PageRank_第11张图片

    从上面的结构可以看出最后转移矩阵不断的交换重要性,不能停止,不能判定谁更重要。采集器陷阱是一系列节点集合,他们没有出链指向集合之外,最后导致在计算时所有的PageRank都分配到采集器陷阱之内。

    举例如下:这是一个单节点的采集器陷阱,最后他的重要性会收敛为1

数据挖掘总介与PageRank_第12张图片


    上面的例子是是一个单节点的采集器陷阱,最后得到的pageRank值会为1.

2、终止点问题,是不是会正常的收敛??

数据挖掘总介与PageRank_第13张图片

  结果可以看出尽管最后收敛了,可是所有的网页节点的重要性都是0.这样的某个节点没有出链所导致的问题叫做终止点问题。 可以看做所有的冲浪者最终都会来到这个终止节点,然后一起在这里消失,所以其收敛结果已经不能衡量各个网页的重要性了。

   下面继续使用前面的例子来说明一下这两个问题,以及如何解决。

数据挖掘总介与PageRank_第14张图片

五、PageRank问题的解决teleport

数据挖掘总介与PageRank_第15张图片

    最后得到的新的PageRank的估计值如下:


概率随机跳转也能解决终止点的问题。

数据挖掘总介与PageRank_第16张图片

 但是终止点出了可以用概率随机跳转解决还可以用迭代删除终止点的方法,等到最后剩下节点收敛,再来计算删除的节点的PageRank。

六、为什么Teleport可以解决问题

数据挖掘总介与PageRank_第17张图片

数据挖掘总介与PageRank_第18张图片

数据挖掘总介与PageRank_第19张图片

数据挖掘总介与PageRank_第20张图片

数据挖掘总介与PageRank_第21张图片

数据挖掘总介与PageRank_第22张图片

数据挖掘总介与PageRank_第23张图片

最后附上第一周的测试题。

Consider three Web pages with the following links:

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 ab, and c of the three pages A, B, and C, respectively. Then, identify from the list below, the true statement.

Your Answer   Score Explanation
b + c = 2.735      
a + c = 2.745      
a + c = 2.595 Correct 1.00  
a + b = 1.025
我采用编程实现。

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;  
    }  
}  

2. 计算的文件

	
#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;    
}    
可以很容易的通过上上面的代码来实现其他习题。

只是在大数据情况下,矩阵乘法需要分块,需要实现。

    

你可能感兴趣的:(数据挖掘,pagerank)