TF-IDF中文可视化

举报
motozilog 发表于 2018/12/27 22:22:56 2018/12/27
【摘要】 TF-IDF算法实现中通常是用词索引(int整型)代替词,虽然该方法效率高,但是对于刚入门NLP的同事存在理解困难。所以,将TF-IDF改用string型,便于理解。

TF-IDF是NLP中较常用的算法

TF:词频,就是做了文本中各个词的出现频率统计,并作为文本特征

IDF:反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低;而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。

但TF-IDF算法实现中通常是用词索引(int整型)代替词,虽然该方法效率高,但是对于刚入门NLP的同事存在理解困难。所以,将TF-IDF改用string型,便于理解。

废话不多说,直接上码


    public class TFIDF
    {
        #region TFIDF
        /// <summary>
        /// 计算文档中的TF-IDF值,(以string形式表示)
        /// 作者:motozilog
        /// 时间:2018-12-26
        /// 需求:由于TF-IDF中计算过程虽然不难,但是全都是int型,非常不直观。故改写成string
        /// <remarks>原始代码参考:http://blog.sciencenet.cn/blog-710509-560574.html 原作者:陈志伟</remarks>
        /// </summary>
        /// <param name="docs"></param>
        public static List<Dictionary<string, double>> CalcTfidfsString(string[][] docs)
        {
            //S1:整理成词表
            Dictionary<string, int> terms = new Dictionary<string, int>();//key为词,value为计次
            foreach (var line in docs)
            {
                foreach (var word in line)
                {
                    if (terms.ContainsKey(word))
                    {
                        terms[word]++;
                    }
                    else
                    {
                        terms.Add(word, 1);
                    }
                }
            }
            //foreach (var x in terms)
            //{
            //    Console.WriteLine(x.Key + ":" + x.Value);
            //}
            //S2:计算每篇文章中各词的比例(TF)
            List<Dictionary<string, double>> tfs = new List<Dictionary<string, double>>();
            foreach (var line in docs)
            {
                Dictionary<string, int> lineWord = new Dictionary<string, int>();//key为词,value为该词在该句中计次
                foreach (var word in line)
                {
                    if (lineWord.ContainsKey(word))
                    {
                        lineWord[word]++;
                    }
                    else
                    {
                        lineWord.Add(word, 1);
                    }
                }
                Dictionary<string, double> tf = new Dictionary<string, double>();//key为词,value为该词在该句中的比重(tf)
                foreach (var x in lineWord)
                {
                    //Console.WriteLine(x.Key+"->"+x.Value+"=>"+ ((decimal)((double)x.Value/(double)lineWord.Count)).ToString());
                    tf.Add(x.Key, ((double)x.Value / (double)lineWord.Count));
                }
                tfs.Add(tf);
                //Console.WriteLine("=========");
            }
            //S3:计算IDF
            double len = (double)docs.Length;
            Dictionary<string, double> idfs = new Dictionary<string, double>(); //key为词,value为idf(总文档数/当前词出现过的文档数
            foreach (var x in terms)
            {
                double idf = Math.Log(len / (double)x.Value, Math.E); //ln(总文档数/当前词出现过的文档数)
                idfs.Add(x.Key, idf);
            }
            //S4:计算TF-IDF
            List<Dictionary<string, double>> tfidfs = new List<Dictionary<string, double>>();
            foreach (var tf in tfs)
            {
                Dictionary<string, double> tfidf = new Dictionary<string, double>();
                foreach (var word in tf)
                {
                    //Console.WriteLine(word.Key + "->" + word.Value * idfs[word.Key]);
                    tfidf.Add(word.Key, word.Value * idfs[word.Key]);
                }
                tfidfs.Add(tfidf);
                //Console.WriteLine("===========");
            }
            return tfidfs;
        }
        #endregion
    }


调用示范(先装jieba库)

            JiebaSegmenter jieba = new JiebaSegmenter();
            string s = tools.ReadStr("docs.txt");
            string[] lines = s.Split('\n');
            string[][] docs = new string[lines.Length][];
            for (int i=0;i<lines.Length;i++)
            {
                docs[i] = jieba.Cut(lines[i]).ToArray();
            }

            List<Dictionary<string, double>> tfidfs = TFIDF.CalcTfidfsString(docs);
            //输出
            StringBuilder sb = new StringBuilder();
            foreach (var tfidf in tfidfs)
            {
                foreach (var word in tfidf)
                {
                    sb.AppendLine(word.Key + "->" + ((decimal)word.Value).ToString());
                }
                sb.AppendLine();
            }

            tools.StrToTxt(sb.ToString(), "tf-idf.txt");


效果:

tf-idf.png


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。