实验二报告

一、题目要求

在Experiment1的基础上实现最基本的Ranked retrieval model

  • Input:a query (like Ron Weasley birthday)
  •Output: Return the top K (e.g., K = 100) relevant tweets.

Use SMART notation: lnc.ltn

  • Document: logarithmic tf (l as first character), no idf and cosine normalization
  • Query: logarithmic tf (l in leftmost column), idf (t in second column),
no normalization

改进Inverted index

  • 在Dictionary中存储每个term的DF
  • 在posting list中存储term在每个doc中的TF with pairs (docID, tf)

选做

  • 支持所有的SMART Notations

二、实验原理与数据结构

原理:

  采用的的权重计算机制是Inc.Itn,即文档向量采用了对数tf的计算方法,没有采用idf因子(同时基于效率和效果的考虑)及余弦归一化方法,而此时查询向量采用了对数tf计算方法,id权重因子及归一化方法
在这里插入图片描述

数据结构

  1. 首先设置共同需要的全局变量,postings(id,tf)、document_frequency(词出现的文档总数)、docunment_numbers(文档总数)、
    document_lengths(每个id对应的文档长度)、avdl(文档平均长度)
  2. 预处理
      首先是对数据集tweets的预处理,与实验一预处理类似,首先将我们需要的tweetid text三部分主要信息,对这三部分信息进行去除无用词、词干还原等操作返回更新后的doc
      对询问数据集queries进行预处理,将需要的queries提取出来,并将处理后的数据集存入queries字典,方便提取查询,对处理后的query统计词频、总文档数、词出现的query数、query的长度等信息,读入每一行时记录每一个query的长度,存入query_lengths,在遍历不同的词时统计词频存入postings1(id,tf),此处的id人为设定,从0开始标号,再输出到文件中q-Invertedtf.txt,遍历完所有的prequeries行后,对postings1进行遍历,统计每个词出现的文档数存入query_frequency,再输出到文件中q-Inverteddtf.txt,处理后的数据如图所示
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  对文档进行统计词频、总文档数、词出现的文档数、文档的长度等信息,读入每一行时记录每一篇文档的长度,存入document_lengths,在遍历不同的词时统计词频存入postings(id,tf),再输出到文件中Invertedtf.txt,遍历完所有的tweets行后,对postings进行遍历,统计每个词出现的文档数存入document_frequency,再输出到文件中Inverteddtf.txt,处理后的数据如图所示
在这里插入图片描述
在这里插入图片描述

  1. 权重计算
      对输入的query进行上述的预处理过程,更新query总数query_numbers,对于query采用公式ltn,对于document,更新query总数query_numbers,采用公式lnc
    在这里插入图片描述

l(logarithm) = 1 + log ⁡ ( t f t , d ) \log(tf_{t,d}) log(tft,d)
t(idf) = l o g ( N d f t ) log(\frac{N}{df_t}) log(dftN)
n(none) = 1
c(cosine) = 1 w 1 2 + w 2 2 + . . . + w n 2 \frac{1}{\sqrt{w_1^2+w_2^2+...+w_n^2}} w12+w22+...+wn2 1
代码实现
在这里插入图片描述

  1. 查找函数
    首先对输入的query进行分词去重词干还原等操作,为了避免遍历所有的tweet,先提取出有相关性的tweetid,tweet中包含查询的关键词之一便可认为相关,之后对权重计算返回的相似性结果进行降序排序,输出前10个最有相关性的结果
    代码实现
    在这里插入图片描述

三、实验结果

  首先是对预处理后的queries进行排序输出前10个最相关的文档之后就可以手动输入自己想要查询的内容,结果如下

对预处理后的queries结果

在这里插入图片描述

对自己输入查询结果

例如输入:Ron Weasley birthday
在这里插入图片描述

从结果中可以看到有多少条是与我们输入的查询是相关的,并且可以看到最相关的10个的tweetid

四、反思与总结

  1. 进行查询权重机制时,发现返回的结果中有负值,这是不正确的,经过排查检错,发现只是定义了文档总数,但是在处理完tweets数据集后没有对其进行更新,导致错误。
  2. 在返回的查询相似度结果排序中,我们应该选择降序排序,输出相似度最大的前10个,所以在调用函数sort后应该将sort后的结果reverse后再输出
  3. 经过这次实验对文档权重和查询权重机制有了更深的了解,还要继续学习,减少错误
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴回答你的问题。在这里给出我的实验报告,希望对你有所帮助。 实验名称:Ubuntu进程与线程实验 实验目的: 1. 了解进程和线程的概念。 2. 掌握在Ubuntu操作系统下创建进程和线程的方法。 3. 掌握进程与线程之间的区别和联系。 实验环境: Ubuntu 18.04 操作系统 实验步骤: 1. 进程的创建与销毁 在Ubuntu系统下,可以使用fork()函数创建一个新的进程。该函数会返回两次,一次在父进程中返回子进程的进程ID,一次在子进程中返回0。下面是一个示例代码: ``` #include <stdio.h> #include <unistd.h> int main() { pid_t pid; pid = fork(); if (pid < 0) { printf("Error: fork failed.\n"); return 1; } else if (pid == 0) { printf("This is child process.\n"); } else { printf("This is parent process.\n"); } return 0; } ``` 运行结果如下: ``` This is parent process. This is child process. ``` 可以看到,父进程和子进程都打印了自己的信息。接下来,我们可以使用exit()函数终止进程的运行: ``` #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { pid_t pid; pid = fork(); if (pid < 0) { printf("Error: fork failed.\n"); return 1; } else if (pid == 0) { printf("This is child process.\n"); exit(0); } else { printf("This is parent process.\n"); wait(NULL); } return 0; } ``` 在子进程中使用exit(0)函数,可以使子进程正常终止。在父进程中使用wait()函数,可以等待子进程终止。 2. 线程的创建与销毁 在Ubuntu系统下,可以使用pthread_create()函数创建一个新的线程。该函数需要传入一个指向函数的指针和一个指向函数参数的指针,下面是一个示例代码: ``` #include <stdio.h> #include <pthread.h> void* thread_func(void* arg) { printf("This is a new thread.\n"); pthread_exit(NULL); } int main() { pthread_t tid; int ret = pthread_create(&tid, NULL, thread_func, NULL); if (ret != 0) { printf("Error: pthread_create failed.\n"); return 1; } pthread_join(tid, NULL); return 0; } ``` 运行结果如下: ``` This is a new thread. ``` 可以看到,新线程打印了自己的信息。接下来,我们可以使用pthread_exit()函数终止线程的运行: ``` #include <stdio.h> #include <pthread.h> void* thread_func(void* arg) { printf("This is a new thread.\n"); pthread_exit(NULL); } int main() { pthread_t tid; int ret = pthread_create(&tid, NULL, thread_func, NULL); if (ret != 0) { printf("Error: pthread_create failed.\n"); return 1; } pthread_join(tid, NULL); return 0; } ``` 在线程中使用pthread_exit()函数,可以使线程正常终止。在主线程中使用pthread_join()函数,可以等待新线程终止。 3. 进程与线程之间的区别和联系 进程和线程都是操作系统中的执行单元,但是它们有着不同的特点。 进程是操作系统中的一个独立的执行单元,它拥有自己的地址空间、文件描述符、信号处理函数等资源。进程之间的通信需要使用IPC机制,如管道、消息队列、共享内存等。 线程是进程中的一个执行单元,它与其他线程共享进程的地址空间、文件描述符、信号处理函数等资源。线程之间的通信可以直接读写共享内存或者使用线程同步机制,如互斥锁、条件变量等。 总的来说,进程和线程都是操作系统中的基本概念,他们各自有着不同的特点和用途。在实际编程中,我们需要根据具体的需求选择使用进程或者线程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值