写一个TF-IDF模型

这个小项目是跟一位广工的小伙伴一起完成的,他负责提供数据和这个模型的理论,没办法,谁让咱数学底子薄呢,我就是负责一下代码实现就完事了

  1. 模型理论
    这个模型的基础理论其实不难
    假设我有一千篇论文,通过数据清洗,分词等操作,我得到了关键词数据。
    然后从这些关键词中,再次去找关键词。常理来说,一个词出现的频率越高那么这个词就越关键。然如果只有这一篇论文出现了这么一个词,而且满篇都是这一个词,这个词被恶意刷屏了,怎么办。那么我们就在引入一个量,log(总文章/总文章中含有这个词的文章数),咱也不晓得这个模型的大佬是怎么想的用这个方法,可能这就是奇才吧。然后我们把这个词频和那个数相乘,那么就得到了我们需要的量 TF-IDF模型量,通过这个量,我们得知哪个关键字最关键。

  2. 代码实验
    来来来,直接代码搞一波
    首先做个声明,所有的数据已经清洗,分词完毕,统一放在一个txt文件中,那么有人问了,都放在了同一个文件中,那怎么算后面那个量呢。很简单,我们可以把获取的这个大数组分成若干个小数组,模拟有这么多篇论文,因为是实验,总有些不严谨的地方。


```python
from collections import Counter

import math
import operator

"""
读取txt函数
path:txt路径
encod:编码
"""
def read_txt(path,encod):
    file = open(path, 'r',encoding = encod)
    return file

"""
将已经分好词的文本文件转换成数组
"""
def txtToList(file):
    list = []
    num = 0
    contents = file.readlines()
    for content in contents:
        content = content.split(',')
        for word in content:
            list.append(word)
            num = num + 1
    print("当前文本词汇个数: ",num)
    return list,num

"""
将list数据存入txt文件中
"""
def listToTxt(put_list,fileName):
    f = open(fileName, "w",encoding="utf-8")
    for list_mem in put_list:
        f.write(list_mem + ",")
    f.close()


"""
将数组按照等量划分
"""
def arr_size(arr,size):
    s=[]
    for i in range(0,len(arr)+1,size):
        c=arr[i:i+size]
        s.append(c)
    return s


# 计算词频
def func_counter(word_list):
    count_result = Counter(word_list)
    return count_result


# 寻找某个关键词的词数
def fidc_wf(word,wfs_Dict):
    word_num = wfs_Dict[word]
    return word_num
#关键词在这篇文章中是否出现
def findw_article(word,article):
    for str in article:
        if( word == str):
            return True
    return False


# 查出包含该词的文档数
def wordinfilecount(i_word, put_lists):
    count = 0  # 计数器
    for train_list in put_lists:
        if (findw_article(i_word, train_list)):
            count = count + 1
    #print("关键字在" + str(count) + "篇q文章中出现过")
    return count


# 计算TF-IDF,并返回字典
def tf_idf(dataList,putLists,num):
    tf = 0
    idf = 0
    dic = func_counter(dataList) #获取每个关键词的出现次数
    outdic = dic
    for word in dic.keys():
        tf = fidc_wf(word,dic)/num #计算关键词词频
        idf = math.log(len(putLists)/(wordinfilecount(word,putLists)+1)) #计算idf
        tfidf = tf * idf # 计算综合
        outdic[word] = tfidf #写入键值对
    orderdic = sorted(outdic.items(), key=operator.itemgetter(1), reverse=True)  # 给字典排序
    return orderdic



# 读取文件
file = read_txt(自己的文件路径,'utf-8')
# 将文件转化为list数组
list,num = txtToList(file)
# 将数组按照1000的个数划分成若干个小数组
put_lists = arr_size(list,1000)

#调用主函数
print(tf_idf(list,put_lists,num))

namespace ServiceRanking { /// <summary> /// Summary description for TF_IDFLib. /// </summary> public class TFIDFMeasure { private string[] _docs; private string[][] _ngramDoc; private int _numDocs=0; private int _numTerms=0; private ArrayList _terms; private int[][] _termFreq; private float[][] _termWeight; private int[] _maxTermFreq; private int[] _docFreq; public class TermVector { public static float ComputeCosineSimilarity(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFER LENGTH"); float denom=(VectorLength(vector1) * VectorLength(vector2)); if (denom == 0F) return 0F; else return (InnerProduct(vector1, vector2) / denom); } public static float InnerProduct(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFFER LENGTH ARE NOT ALLOWED"); float result=0F; for (int i=0; i < vector1.Length; i++) result += vector1[i] * vector2[i]; return result; } public static float VectorLength(float[] vector) { float sum=0.0F; for (int i=0; i < vector.Length; i++) sum=sum + (vector[i] * vector[i]); return (float)Math.Sqrt(sum); } } private IDictionary _wordsIndex=new Hashtable() ; public TFIDFMeasure(string[] documents) { _docs=documents; _numDocs=documents.Length ; MyInit(); } private void GeneratNgramText() { } private ArrayList GenerateTerms(string[] docs) { ArrayList uniques=new ArrayList() ; _ngramDoc=new string[_numDocs][] ; for (int i=0; i < docs.Length ; i++) { Tokeniser tokenizer=new Tokeniser() ; string[] words=tokenizer.Partition(docs[i]); for (int j=0; j < words.Length ; j++) if (!uniques.Contains(words[j]) ) uniques.Add(words[j]) ; } return uniques; } private static object
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值