机器学习算法——信息熵

信息熵(Entropy)

信息是个很抽象的概念。我们常常说信息很多,或者信息较少,但却很难说清楚信息到底有多少。比如一本书中到底有多少信息量。直到 1948 年,香农(C. E. Shannon)提出了信息熵”(shāng) 的概念,才解决了对信息的量化度量问题。熵的概念发展成为信息论、数据压缩等学科的基础,在很多科学研究的领域尤其是计算机科学中有着广泛的应用。

实际上,一条信息的信息量大小和它的不确定性或存在概率有直接的关系。比如说,我们要搞清楚一件非常非常不确定的事,或是我们一无所知的事情,就需要了解大量的信息。相反,如果我们对某件事已经有了较多的了解,我们不需要太多的信息就能把它搞清楚。所以,从这个角度,我们可以认为,信息量的度量就等于不确定性的多少。一个系统越是有序,信息熵就越低;反之,一个系统越是混乱,信息熵就越高。因此可以认为信息熵是系统有序化程度的一个度量。 Shannon 借鉴了热力学的概念,把信息与其存在概率关联起来并称之为信息熵,并给出了计算信息熵的数学表达式:

H = – ∑  Pi * log2 Pi

假设有一个字符串要求它的信息熵,其中Pi是字符i出现的概率(该字符出现次数/所有字符数),然后将所有的Pi乘上取对数后的值log2 Pi后累加,最后取负,得到字符串的信息熵。

本题要求计算给定字符串按照每个字符统计的信息熵。 

输入:

一个字符串,请忽略所有非字母的字符(即只关注a-z, A-Z),且不区分字母的大小写。

提示:可以用StdIn.readAll()读入字符串的所有内容

输出:

对应字符串的熵值,输出请用格式化输出(“%4.2f\n”) 

样例输入:

To be or not To be,

that is the question

样例输出:

3.26

public class Main{
	public static double Entropy(String str){
		double H = .0;
		int sum = 0;
		int[] letter = new int[26];
		
		str = str.toUpperCase(); 					//将小写字母转换成大写     
        for (int i = 0; i < str.length(); i++){    //统计字母个数
            char c = str.charAt(i);   
            if (c >= 'A' && c <= 'Z') {   
                letter[c-'A']++;   
                sum++;   
            }   
        }     
        
        for (int i = 0; i < 26; i++){   
            double p = 1.0*letter[i]/sum;   
            if(p>0)
            	H += -(p*Math.log(p)/Math.log(2));//H = -∑Pi*log2(Pi)   
        }   
        return H;
	}
	
	public static void main(String[] args){
		String str = StdIn.readAll();
		double H = Entropy(str);
		StdOut.printf("%4.2f\n",H);
	}
}

点赞