首页 文章 精选 留言 我的

精选列表

搜索[自动发现],共10000篇文章
优秀的个人博客,低调大师

在 LangChain 尝试了 N 种可能后,我发现了分块的奥义!

分块(Chunking)是构建检索增强型生成(RAG)应用程序中最具挑战性的问题。分块是指切分文本的过程,虽然听起来非常简单,但要处理的细节问题不少。根据文本内容的类型,需要采用不同的分块策略。 在本教程中,我们将针对同一个文本采用不同的分块策略,探索不同分块策略的效果。访问链接获取本文中涉及的代码。 01.LangChain 分块简介 LangChain 是一个 LLM 协调框架,内置了一些用于分块以及加载文档的工具。本次分块教程主要围绕设置分块参数,并最小限度地使用 LLM。简而言之,通过编写一个函数并设置其参数来加载文档并对文档进行分块,该函数打印结果为分块后的文本块。在下述实验中,我们会在这个函数中运行多个参数值。 LangChain 分块代码导入和设置 代码第一部分主要是导入和设置工具。下面代码有很多导入语句,os 和dotenv都比较常用。它们仅用于环境变量。 接下来,我们深入讲解一下有关 LangChain 和 pymilvus 部分的代码。 首先是用于获取文档的三个导入: NotionDirectoryLoader用于加载含有 markdown/Notion 文档的目录。然后,MarkdownHeader 和 RecursiveCharacter 文本分割器会根据标题(标题分割器)或一组预先选定的字符分隔符(递归分割器)分割 markdown 文档中的文本。 接下来,是检索器导入。我们用 Milvus 、OpenAIEmbeddings 模型和 OpenAI 大语言模型(LLM)。SelfQueryRetriever 是 LangChain 原生检索器,允许向量数据库“查询自身”。 最后一个 LangChain 导入是AttributeInfo,它将一个带有信息的属性传入 SelfQueryRetriever。 至于 pymilvus 导入,通常我只将这些导入在结束时用于清理数据库。 编写函数之前的最后一步是加载环境变量并声明一些常量。headers_to_split_on 变量列出了我们希望在 markdown 中分割的所有标题;path 用于帮助 LangChain 了解在哪里找到 Notion 文档。 import osfrom langchain.document_loaders import NotionDirectoryLoader from langchain.text_splitter import MarkdownHeaderTextSplitter, RecursiveCharacterTextSplitter from langchain.vectorstores import Milvus from langchain.embeddings import OpenAIEmbeddings from langchain.llms import OpenAI from langchain.retrievers.self_query.base import SelfQueryRetriever from langchain.chains.query_constructor.base import AttributeInfo from pymilvus import connections, utility from dotenv import load_dotenv load_dotenv() zilliz_uri = os.getenv("ZILLIZ_CLUSTER_01_URI") zilliz_token = os.getenv("ZILLIZ_CLUSTER_01_TOKEN") headers_to_split_on = [ ("##", "Section"), ] path='./notion_docs' 构建一个分块实验函数 构建分块实验函数是本教程中最关键的部分。如前所述,此函数需要一些参数用于档导入和分块。我们需要提供文档的路径、要分割的标题(分割器)、分块大小、分块重叠(chunk overlap)以及我们是否希望通过删除 Collection 来清理数据库。默认情况下,将该参数设置为 True,即删除 Collection 清理数据库。 注意,要尽可能少地创建和删除 Collection,从而避免不必要的开销。 函数第一部分通过 Notion 目录加载器(Notion Directory Loader)从路径加载文档,此处只抓取第一页的内容。 接下来,获取分割器。首先,使用 markdown 分割器根据上面传入的标题进行分割。然后,用递归分割器根据分块大小和 overlap 来分割。 分割完成后,使用环境变量、OpenAI embedding、分块工具以及 Collection名 称初始化一个 LangChain Milvus 实例。此外,我们还通过 AttributeInfo 对象创建了一个元数据字段列表,帮助 SelfQueryRetriever 了解文本块所属的“章节”。 完成所有上述设置后,获取 LLM 并将其传递给 SelfQueryRetriever。当我们针对文档提出问题时,检索器开始发挥作用。我还设置了函数从而了解其正在测试哪种分块策略。最后,可以按需删除 Collection。 def test_langchain_chunking(docs_path, splitters, chunk_size, chunk_overlap, drop_collection=True): path=docs_path loader = NotionDirectoryLoader(path) docs = loader.load() md_file=docs[0].page_content # Let's create groups based on the section headers in our page markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=splitters) md_header_splits = markdown_splitter.split_text(md_file) # Define our text splitter text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap) all_splits = text_splitter.split_documents(md_header_splits) test_collection_name = f"EngineeringNotionDoc_{chunk_size}_{chunk_overlap}" vectordb = Milvus.from_documents(documents=all_splits, embedding=OpenAIEmbeddings(), connection_args={"uri": zilliz_uri, "token": zilliz_token}, collection_name=test_collection_name) metadata_fields_info = [ AttributeInfo( name="Section", description="Part of the document that the text comes from", type="string or list[string]" ), ] document_content_description = "Major sections of the document" llm = OpenAI(temperature=0) retriever = SelfQueryRetriever.from_llm(llm, vectordb, document_content_description, metadata_fields_info, verbose=True) res = retriever.get_relevant_documents("What makes a distinguished engineer?") print(f"""Responses from chunking strategy: {chunk_size}, {chunk_overlap}""") for doc in res: print(doc) # this is just for rough cleanup, we can improve this# lots of user considerations to understand for real experimentation use cases thoughif drop_collection: connections.connect(uri=zilliz_uri, token=zilliz_token) utility.drop_collection(test_collection_name) 02.LangChain 分块实验和结果 接下来就是激动人心的时刻了!让我们来看看分块实验的结果。 测试 LangChain 分块 以下代码块展示了如何运行我们的实验函数。我添加了五个实验,这个教程测试的分块长度从 32 到 64、128、256、512 不等,分块 overlap 从 4 到 8、16、32、64 不等的分块策略。为了测试,我们遍历元组列表并调用上面写的函数。 chunking_tests = [(32, 4), (64, 8), (128, 16), (256, 32), (512, 64)]for test in chunking_tests: test_langchain_chunking(path, headers_to_split_on, test[0], test[1]) 以下为输出结果。接着让我们来仔细观察每一组实验的输出结果。我们使用的测试问题是“What makes a distinguished engineer?” 分块长度 32,重叠 4 显而易见,32 的长度太短了,这种分块策略完全无效。 分块长度 64,重叠 8 这种策略一开始效果也不理想,但最终也给出了问题的答案—— Werner Vogels,亚马逊(Amazon)首席技术官(CTO)。 分块长度 128,重叠 16 长度变为 128 时,答案出现了更多完整句,更少“工程师”类型的回答。这个策略的效果还不错,能够提取出 Werner Vogel 相关文本片段。但是这个策略的一个劣势是答案中会出现 \xa0和 \n 这种特殊字符。也许我们分块长度过长了。 分块长度 256,重叠 32 虽然答案会返回相关内容,但这个分块长度过长。 分块长度 512,重叠 64 已知 256 的分块长度已经过长了。但是将长度设置为 512 时,会提取出整个 section 的内容。这时候就要思考:我们到底是想要结果中返回单独的一行文字,还是整个 section 内容?这就需要根据使用场景进行判断。 03.总结 本教程探索了 5 种不同分块策略的效果。选择分块策略时,我们要根据期望获得的返回结果来确定最合适的分块长度,后续我们将测试不同分块 overlap 的效果。敬请期待! 如果在使用 Milvus 或 Zilliz 产品有任何问题,可添加小助手微信 “zilliz-tech” 加入交流群。 欢迎关注微信公众号“Zilliz”,了解最新资讯。

优秀的个人博客,低调大师

最近最火的《大秦赋》,用Python抓取相关数据,发现了秘密

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。 以下文章来源于数据分析与统计学之美 ,作者黄伟呢 Python 数据分析入门案例讲解 https://www.bilibili.com/video/BV18f4y1i7q9/ 前言 最近,最火的电视剧莫过于《大秦赋》了,自12月1日开播后,收获了不错的口碑。然而随着电视剧的跟新,该剧在网上引起了激烈的讨论,不仅口碑急剧下滑,颇有高开低走的趋势,同时该剧的评分也由最初的8.9分,下降到了现在的6.5分。 虽然我还没有看过这个新剧,但是对于小伙伴们讨论的内容,却颇有兴趣(主要还是大家老是讨论这个剧)。 因此,我用Python爬取了《大秦赋》的相关数据,进行了一波分析。 数据爬取 巧妇难为无米之炊,做数据分析之前最重要的就是“数据获取”。于是,我准备用Python爬取豆瓣上的短评数据以及一些评论时间信息、评价星级信息。 关于数据的爬取主要说以下几个内容: 1)关于翻页操作 第一页: https://movie.douban.com/subject/26413293/comments?status=P 第二页: https://movie.douban.com/subject/26413293/comments?start=20&limit=20&status=P&sort=new_score 第三页: https://movie.douban.com/subject/26413293/comments?start=40&limit=20&status=P&sort=new_score 上面我们分别展示了第1-3页的页面链接,我们主要是观察其中的规律,其中start是获取评论的起始位置,limit代表获取多少条评论数据。观察结果:3个链接的不同在于这个start的不同,在后续翻页时,我们只需要修改start参数即可。 2)关于反扒说明 对于豆瓣的爬取,其实找到真实的短评链接,是极其容易的。但是这里有一点我必须说明,你可以不登陆爬取数据,但是只能是操作一段时间,过一段时间,会检测到你是爬虫。因此,你一定要登陆后,携带cookie去进行数据的爬取。如果你有时候不知道请求头中,该放一些什么,那么就请都加上,等有空再慢慢总结。 headers={ "Accept":"application/json,text/plain,*/*", "Accept-Language":"zh-CN,zh;q=0.9", "Connection":"keep-alive", "Host":"movie.douban.com", "User-Agent":'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/87.0.4280.88Safari/537.36', "Cookie":'这里是你自己的cookie' } cookie有些人可能又不知道在哪里,还是告诉你一下吧!好多参数都在下面呢,如果你想学好爬虫,那么这些参数代表什么,你总应该需要知道吧。 最终再补充一点:我本来打算把豆瓣上的《大秦赋》短评,全部爬下来作为分析的素材。然而并没有成功爬取到所有的短评,一波三折,最终只爬到了500条,当然我觉得这也是豆瓣的一种反扒措施,最大可见短评数就500条,多的不给你看。(有大神的话,可以下去研究一下) 数据处理 爬取后的数据,再怎么规整,也和用于分析的数据之间,有一定的差距。因此在分析之前,一定的数据清洗是很有必要的。在数据清洗之前,我们简单看看数据是什么样子的。 df=pd.read_csv("final_all_comment.csv",index_col=0) df.head(10) 结果如下: 其实数据还是挺漂亮的,但是我们还是需要做如下处理: 1)剔除重复值 我们认为:如果'评论时间'和'评论内容'完全一致的话,就认为他是同一条评论,需要将其剔除。 print("删除之前的记录数:",df.shape) df.drop_duplicates(subset=['评论时间','评论内容'],inplace=True,keep='first') print("删除之前的记录数:",df.shape) 2)评论时间处理 因为《大秦赋》是2020年12月1号开播的,现在是12月16号晚,因此所有的评论数据肯定都是2020年12月开始有的,因此我们只保留有用的“日期”数据(哪一天)。而对于时分秒来说,我们只保留“小时”数据。 df["评论天数"]=df["评论时间"].str[8:-9].astype(int) df["小时"]=df["评论时间"].str[11:-6].astype(int) 3)评论星级说明 观察原页面的评论星级,可以看到所有的星级并不是以数字展示的,而是用星星进行前端渲染出来的,但是页面的源代码,却展示的是星级数。 对应到页面源代码中,我们看看又是怎么样子的呢? 可以看到:3星的数字是30,其它的以此类推,1星的数字是10,2星的数字是20......我看着就是很不爽,因此我在爬取数据的时候,已经将这些数字,全都除以10后计算。 4)评论内容机械压缩去重 对于一条评论来说,有些人可能手误,或者凑字数,会出现将某个字或者词语,重复说多次,因此在进行分词之前,需要做“机械压缩去重”操作。下面是我很早之前写的一段代码,大家可以去看我的CSDN博客,里面有很好的解释。 deffunc(st): foriinrange(1,int(len(st)/2)+1): forjinrange(len(st)): ifst[j:j+i]==st[j+i:j+2*i]: k=j+i whilest[k:k+i]==st[k+i:k+2*i]andk<len(st): k=k+i st=st[:j]+st[k:] returnst st="我爱你我爱你我爱你好你好你好哈哈哈哈哈" func(st) 结果如下: 利用上述函数,我们可以对爬取到的数据,应用此操作。 deffunc(st): foriinrange(1,int(len(st)/2)+1): forjinrange(len(st)): ifst[j:j+i]==st[j+i:j+2*i]: k=j+i whilest[k:k+i]==st[k+i:k+2*i]andk<len(st): k=k+i st=st[:j]+st[k:] returnst df["评论内容"]=df["评论内容"].apply(func) 数据可视化操作 俗话说:“字不如表,表不如图”。爬取到的数据,最终做可视化的呈现,才能够让大家对数据背后的规律,有一个清晰的认识。下面我们从以下几个方面来进行数据可视化分析。 评论数随时间的变化趋势 二十四小时内的评论数的变化趋势 星级评分的饼图 大家主要都在评论一些啥 关于数据可视化工具,我就不用pyecharts了,我还是回归原始,用最原始的matplotlib库进行数据可视化的展示。毕竟我们没有什么复杂的展示,代码越简短越好。 1)评论数随时间的变化趋势 从图中可以看出:短评数量在12月4日之前,一直处于上升趋势,在12月4日达到顶峰。和文章最开始的说明一致,前面几天观众对于该剧的期待值较高,但是在12月4日后,突然出现断崖式下降,说明随着该剧的更新,大家有所失望了。 2)二十四小时内的评论数的变化趋势 最近总听到周围有人在讨论这部剧,下面就来看看大家都是在啥时候追剧呢?从24小时图中可以看出:晚上7-24点,评论急剧上升,大多数人都是6点下班,可能吃个饭到7点左右,或者直接在下班过程中,就开始了一天的追剧。这里还有一波早高峰5-8点,难道睡不着?早上还要起来刷刷据,然后上班。这里还有两个时间段:上午10-11点,中午12-15点,大家可以分析下,肯定有相当一部分小伙伴,正在摸鱼工作呀 3)星级评分的饼图 剧究竟好不好,看看观众的评分少不了,这也是观众最直观的想法。 1星:很差 2星:较差 3星:还行 4星:推荐 1星:力荐 从下图中可以看出:大家对于该剧的哦=评价还是很低的,1星和2星基本占据了整个饼图,也就是说该剧并没有得到大家的认可。 4)大家主要都在评论一些啥 其实大家对于该剧最大的争论点,还是由张鲁一饰演的嬴政。40岁的张鲁一,竟然饰演13岁的少年嬴政,然后向36岁朱珠饰演的赵姬分享喜讯,这个角色显色很不协调。很多人直呼:难道请不起小演员吗? 还有一部分人,对该剧的剧情和台词很是吐槽,嬴政称如果吕不韦是自己的生父,愿意跟他一起离开秦国浪迹天涯,这真的是少年老成的嬴政能说出来的话吗? 《大秦赋》是“大秦帝国”系列的第四部,原名为《大秦帝国之天下》,播出时改为了《大秦赋》。于是很多人将这部剧和2009年播出的《大秦帝国》作比较,以此来讽刺该剧。 本文同步分享在 博客“松鼠爱吃饼干”(CSDN)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

收发现金红包——alipay.fund.coupon.order.disburse(红包打款接口)

接口名称:红包打款接口 英文名称:alipay.fund.coupon.order.disburse 产品首页:[url]https://openclub.alipay.com/read.php?tid=12180&fid=72[/url] 上一步:[url]https://openclub.alipay.com/read.php?tid=13602&fid=72[/url] 下一步:[url]https://openclub.alipay.com/read.php?tid=13610&fid=72[/url] 一、注意事项 1、用户领取红包,通过打款接口实现。 2、若是想实现拆分红包用户分别领取(领取红包A+领取红包B+……+领取红包n<=总红包)。 3、打款接口调用频次:每秒要小于100次; 4、打款接口的发送的异

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册