首页 文章 精选 留言 我的

精选列表

搜索[数据处理],共9358篇文章
优秀的个人博客,低调大师

初探IBM大数据处理平台BigInsights(1)

之前的文章《IBM BigInsights -- 基于 Hadoop 的数据分析平台》介绍了IBM大数据分析平台BigInsights,在Hadoop的基础上IBM增加了额外的模块提供更广泛的数据分析。对于想了解下BigInsight是个什么东西?能做什么的同学,IBM也提供了BigInsights的虚拟机版本。对于那些想大概了解Hadoop,但又不想手动去搭建Hadoop平台的同学来说,BigInsight虚拟机也是个不错的选择。 首先到IBM官网下载https://www-01.ibm.com/marketing/iwm/iwm/web/reg/download.do?source=swg-beta-iibob&S_PKG=dl&lang=en_US&cp=UTF-8&dlmethod=http, 下载“iibi3002_QuickStart_Single_VMware.7z”,用VMware Workstation打开,开机后如下界面,可以看到是基于SUSE的。 第一次启动时会做文件系统检查 选择语言 同意License 输入用户名密码,默认的用户名密码及端口号如下 之后会看到如下界面 双击桌面的Start Biginsights,启动BigInsight服务,或者使用脚本启动 biadmin@bivm:~>/opt/ibm/biginsights/bin/start-all.sh [INFO] DeployCmdline - [ IBM InfoSphere BigInsights Quickstart Edition ] [INFO] Progress - Start hdm [INFO] @bivm.ibm.com - hdm started, pid 4363 [INFO] Progress - 8% [INFO] Progress - Start zookeeper [INFO] HdmUtil - Install configuration has changed in the system, reloading... [INFO] @bivm.ibm.com - zookeeper started, pid 4618 [INFO] Deployer - zookeeper service started [INFO] Progress - 17% [INFO] Progress - Start hadoop [INFO] @bivm.ibm.com - namenode started, pid 4829 [INFO] @bivm.ibm.com - secondarynamenode started, pid 5363 [INFO] @bivm.ibm.com - datanode started, pid 5713 [INFO] Progress - 19% [INFO] Deployer - Waiting for Namenode to exit safe mode... [INFO] Deployer - Waiting another 5 seconds for namenode to exit safemode. Check the namenode log for details. [INFO] Deployer - HDFS cluster started successfully [INFO] Progress - 20% [INFO] Progress - 21% [INFO] @bivm.ibm.com - jobtracker started, pid 6468 [INFO] @bivm.ibm.com - tasktracker started, pid 6888 [INFO] Progress - 25% [INFO] Deployer - MapReduce cluster started successfully [INFO] Progress - Start catalog [INFO] DB2Operator - Starting DB2 Instance db2inst1 on node bivm.ibm.com. Database to be activated BIDB [INFO] DB2Operator - DB2 node bivm.ibm.com is started with process ID 7672 [INFO] DB2Operator - Database BIDB has been activated [INFO] Progress - 33% [INFO] Progress - Start hbase [INFO] Deployer - check zookeeper services, make sure zookeeper service is started before start hbase service [INFO] @bivm.ibm.com - hbase-master(active) started [INFO] @bivm.ibm.com - hbase-regionserver started [INFO] Deployer - hbase service started [INFO] Progress - 42% [INFO] Progress - Start hive [INFO] DB2Operator - Starting DB2 Instance db2inst1 on node bivm.ibm.com. Database to be activated BIDB [INFO] DB2Operator - DB2 Instance db2inst1 is already running on node bivm.ibm.com with process ID 7672 [INFO] DB2Operator - Database BIDB has already been activated [INFO] @bivm.ibm.com - hive-web-interface started, pid 10001 [INFO] @bivm.ibm.com - hive-server2 started, pid 10587 [INFO] Progress - 49% [INFO] Progress - 50% [INFO] Progress - Start bigsql [INFO] Deployer - Starting Big SQL Scheduler : OK Starting Big SQL : OK Starting Big SQL v1 : OK (pid 17836) [INFO] @bivm.ibm.com - scheduler started [INFO] @bivm.ibm.com - bigsql-server started [INFO] @bivm.ibm.com - bigsql-server-v1 started, pid 17836 [INFO] Deployer - FMP pids file written [INFO] Progress - 58% [INFO] Progress - Start oozie [INFO] Deployer - Run oozie command as:oozie [INFO] @bivm.ibm.com - oozie started, pid 19082 [INFO] Progress - 67% [INFO] Progress - Start console [INFO] Deployer - starting pigserver, logging to /var/ibm/biginsights/sheets/logs/bigsheets-console-pigserver.out [INFO] Deployer - Server waslp-server is not running. [INFO] Deployer - Starting server waslp-server. [INFO] Deployer - Server waslp-server started with process ID 19488. [INFO] Deployer - BigInsights Management Console started, pid 19488 [INFO] Progress - 75% [INFO] Progress - Start httpfs [INFO] @bivm.ibm.com - httpfs-server started, pid 19975 [INFO] Deployer - httpfs service started [INFO] Progress - 83% [INFO] Progress - Start monitoring [INFO] Deployer - Start monitoring... [INFO] Deployer - Starting monitoring agent on bivm.ibm.com as user monitoring [INFO] @bivm.ibm.com - monitoring started, pid 21613 [INFO] Deployer - monitoring service started [INFO] Progress - 92% [INFO] Progress - Start alert [INFO] Deployer - start alert management service... [INFO] Deployer - Server waslp-server is not running. [INFO] Deployer - Starting server waslp-server. [INFO] Deployer - Server waslp-server start failed. Check server logs for details. [INFO] Progress - 100% [INFO] DeployManager - Start; SUCCEEDED components: [hdm, zookeeper, hadoop, catalog, hbase, hive, bigsql, oozie, console, httpfs, monitoring, alert]; Consumes : 2148290ms 大概10分钟后启动完毕,然后可以使用命令行查看BigInsight各项服务的状态 biadmin@bivm:~>/opt/ibm/biginsights/bin/status.sh 另外,桌面上还有BigInsight Shell, 比如双击桌面的HBase Shell,就可以直接进入shell 用浏览器打开BigInsight Web界面,http://192.168.133.135:8080/ 分布式文件系统HDFS的web界面 接下来的文章我们会通过几个实验来了解BigInsight具体是怎么工作的。 BigInsight Knowledge Center 更多内容请参考: http://www-01.ibm.com/support/knowledgecenter/SSPT3X_3.0.0/com.ibm.swg.im.infosphere.biginsights.product.doc/doc/using.html%23task_edc_xhj_3n?lang=zh 本文转自 taojin1240 51CTO博客,原文链接:http://blog.51cto.com/taotao1240/1734755,如需转载请自行联系原作者

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

0基础搭建Hadoop大数据处理-环境

由于Hadoop需要运行在Linux环境中,而且是分布式的,因此个人学习只能装虚拟机,本文都以VMware Workstation为准,安装CentOS7,具体的安装此处不作过多介绍,只作需要用到的知识介绍。 VMware的安装,装好一个虚拟机后利用复制虚拟机的方式创建后面几个虚拟机,省时省力,需要注意的是需要修改每个虚拟机的IP与主机名。 所有虚拟机采用NAT模式上网,而且要保证与物理主机的IP互相能访问。 需要注意的几个问题。nat如果上网首先需要查看物理机(pc机)这个服务器已经启动。上网的原理:流量是走的物理网卡,但是它的ip,却是和物理机没有关系的。也就是说,无论你怎么更换网络环境,你的虚拟机都不需要做改变。这就是它的优点。 首先在安装VMware之后,我们会看到多了两个网卡 这个如果经过网络配置的折磨,应该能找到着两个网卡:vmnet1和vmnet8,这里讲的是vmnet8。 重点看右侧第三图你会看到ip地址,这个ip地址,因个人而异,也就是说不同网络,不同环境,这个ip变化的概率是很大的。可能是192.168.0.1等等。这里也相当于我们编程的一个变量,这里是需要你根据你的环境来赋值的,建议vmnet1到vmnet8分别设置192.168.10.1到192.168.80.1,好作区分。 上面我们通过看到的虚拟机网卡的ip,为了避免混肴,上面的虚拟网卡和本地网络适配器处于同一界面。如下图 而下面则是在打开虚拟机之后,通过菜单弹出 弹出之后,我们在看一下虚拟机的(交换机)vmnet8. 可以看到vmnet8子网ip和虚拟机网卡是出于同一个网段的。 同时在右侧net设置界面,我们可以看到网关为:192.168.106.2,改成192.168.80.2虚拟机的设置会用到。 Linux基础知识 Linux的学习也是一个过程,因为可能你连最简单的开机和关机命令都不会,更不要谈配置网络。这里面给大家提供刚开始学习所查阅的资料和经验总结。首先我们需要使用一些命令,进行网络配置,但是在网络配置中,这里面又必须懂得虚拟机的一些知识,所以前面的虚拟机知识需要掌握扎实一些。 在此注意CentOS7与CentOS6的命令有些不同,会一些常用命令是必备,每次开机或启动解压安装授权都是最基本的知识,其它的可以暂时不用学。 具体常用命令可参考常备Linux命令 CentOS中安装java环境 下载对应32或64位jdk,设置好JDK环境变量PATH,具体的配置可自行Google。 环境准备 修改机器名,每个系统中都要修改成这样。 打开终端,切换到root用户下修改机器名称。 $ sudo su $ vim /etc/sysconfig/network 在其中添加“HOSTNAME=H32” 添加每个服务器IP对应的机器名 三个ip地址都添加到各自的/etc/hosts文件中 每个系统中都要修改成这样 #编辑hosts vim /etc/hosts 关闭SELinux #编辑 SELinux 配置文件 vim /etc/selinux/config #改状态 SELINUX=disabled SSH设置 进入H30,查看ssh是否安装,如果有,继续,没有安装下。 rpm -qa|grep ssh 关于ssh的安装参考 : 如何实现两台服务器间无密码的传输数据和操作 时间服务器安装 这里需要安装时间服务器,其他的服务器通过这个来进行多机器时间的同步,分布式部署时机器时间不一致会导致数据错误或组件内通讯错误。 安装httpd服务 httpd是Apache超文本传输协议(HTTP)服务器的主程序。被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池。 安装yum-utils yum install yum-utils 用于在线yum安装 它是基於RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。(需要机器能访问外网) 准备资源和环境 下载Centos 7.2 的iso安装镜像,jdk1.8 for Linux压缩包,hadoop2.7.3压缩包(本来用hadoop3,发现后面不兼容hive的最新版本) Java基础知识 由于Hadoop框架源码都是以java来写,因此最好都以java作为开发的最佳语言,虽然说有些用C#做了封装,但性能已大打折扣。(这就是为什么说Java的学大数据有很大的优势,其它语言的还需要重新学习Java) Eclipse IDE使用 Linux和Windows下源码编译技术 还有最重要的是你的网速要好,因为安装过程中会下载依赖包,网不好会卡到你怀疑人生。 最后还需要有耐心,每台机子的环境都不一样,而且每个人下载的包的版本也有可能不一样 会导致各种问题,此时就需要耐心的去看日志,不停的尝试和仔细的对比安装步骤,可能就是少了个变量 或大小写错误或是要重启。 环境准备就这么多,下一章开始讲如何安装Hadoop集群。

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

除权因子在量化数据处理中有什么作用?

**一句话回答:** 除权因子用于处理股票分红、送股、拆股等公司行动对历史价格序列的影响,帮助量化系统在统一的价格口径下计算收益率、动量和技术指标。使用 QuantDash Python SDK 获取历史 K 线时,可以通过 **adjust** 参数选择前复权、后复权或不复权,减少自行维护复权逻辑的工作。 ### 为什么需要除权因子 / 传统做法有什么问题? 假设一只股票昨天收盘价为 100 元,今天因为公司行动发生除权,除权后的参考价格变为 50 元。 如果程序直接计算: **收益率 = 50 / 100 - 1 = -50%** 策略就可能认为这只股票当天大跌了 50%。 但如果价格变化主要来自拆股等公司行动,这个结果就不能直接解释为投资者的实际亏损。 问题出在哪里? 原始行情记录的是实际市场价格,而量化策略经常需要比较不同时点的价格变化。两者的用途不同。 如果不处理公司行动,历史价格序列就可能出现非市场因素造成的跳变,进而影响以下计算: - **动量因子:** 将除权导致的价格变化误判为趋势变化。 - **均线指标:** 历史价格与最新价格的口径不一致,造成指标异常。 - **历史收益率:** 将公司行动造成的价格调整误认为市场涨跌。 - **策略回测:** 价格收益与包含股数变化、现金分红的真实持仓收益出现偏差。 传统做法是自行收集公司行动数据,再计算调整系数,逐只股票处理历史行情。 这种方式并非不可行,但需要持续维护事件数据、复权公式、基准日期和累计调整逻辑。对于多标的量化系统而言,维护成本并不低。 因此,在数据接入阶段明确复权方式,通常比让每个策略重复处理历史价格更容易维护。 ### 分步骤解决:使用 QuantDash 获取不同复权口径的 K 线 #### 第 1 步:安装 Python SDK 先安装 QuantDash SDK: ```python pip install quantdash ``` 如果后续需要使用 DataFrame 进行数据分析,还需要确保环境中安装了 pandas。 #### 第 2 步:配置 API Key 建议通过环境变量管理密钥,避免将敏感信息直接写入代码。 Linux 或 macOS 环境可以执行: ```python export QUANTDASH_API_KEY="你的API_KEY" ``` 然后初始化客户端: ```python import os from quantdash import QuantDash api_key = os.getenv("QUANTDASH_API_KEY") if not api_key: raise RuntimeError( "请先设置 QUANTDASH_API_KEY 环境变量" ) qd = QuantDash(api_key=api_key) ``` 这里显式检查环境变量,主要是为了让配置错误尽早暴露,而不是等到请求行情时才发现密钥缺失。 #### 第 3 步:获取前复权历史 K 线 以 A 股贵州茅台为例,标的代码使用 **600519.SH**。 通过 K 线接口获取最近 100 条日线: ```python df = qd.klines.get( "600519.SH", period="1d", count=100, adjust="forward", to_dataframe=True, ) if df is None or df.empty: raise ValueError("没有获取到有效的历史 K 线数据") print(df.tail()) ``` 这里的关键参数是 **adjust="forward"**。 它指定使用前复权方式获取历史行情,便于在相应的价格口径下计算历史收益率和技术指标。 如果策略主要关注历史价格趋势,可以在明确复权基准和数据服务规则后,使用前复权数据开展分析。 不过,需要注意:前复权价格是经过调整的研究价格,不应直接当作历史真实成交价格使用。 #### 第 4 步:比较前复权、后复权和不复权数据 QuantDash 的 K 线接口支持多种复权方式。 为了理解不同价格口径的区别,可以分别请求三组数据: ```python import os import pandas as pd from quantdash import QuantDash def main(): api_key = os.getenv("QUANTDASH_API_KEY") if not api_key: raise RuntimeError( "请先设置 QUANTDASH_API_KEY 环境变量" ) qd = QuantDash(api_key=api_key) symbol = "600519.SH" adjustment_methods = [ "forward", "backward", "none", ] results = {} for method in adjustment_methods: try: df = qd.klines.get( symbol, period="1d", count=100, adjust=method, to_dataframe=True, ) if df is None or df.empty: print(f"{method}: 返回数据为空") continue if "close" not in df.columns: print(f"{method}: 缺少 close 字段") continue data = df.copy() data["close"] = pd.to_numeric( data["close"], errors="coerce", ) data = data.dropna(subset=["close"]) if data.empty: print(f"{method}: 没有有效收盘价") continue results[method] = data print(f"\n复权方式:{method}") print(data[["close"]].tail()) except Exception as exc: print( f"{method}: 获取失败," f"{type(exc).__name__}: {exc}" ) if not results: raise RuntimeError("所有复权方式均未获取到有效数据") # 分别计算每种价格序列的简单价格收益率。 for method, data in results.items(): data["price_return"] = data["close"].pct_change() print(f"\n{method} 最近的价格收益率:") print(data[["close", "price_return"]].tail()) if __name__ == "__main__": main() ``` 这段代码做了三件事: 1. 使用相同的标的和日线周期,分别获取前复权、后复权和不复权数据。 2. 检查返回结果是否为空,并验证 **close** 字段是否存在。 3. 基于每组价格序列分别计算简单价格收益率,便于观察不同价格口径的差异。 这里有一个重要前提:示例没有假定三次请求一定返回完全相同的日期集合。如果要逐日比较不同复权方式的价格,应进一步使用实际返回的交易日期字段进行对齐,并检查日期覆盖范围。 另外,**三种复权方式计算出的价格收益率不一定完全相同**。实际结果取决于公司行动、复权基准和数据服务采用的计算规则。 #### 第 5 步:利用复权价格计算动量因子 拿到复权后的历史 K 线后,就可以在研究层计算简单的动量指标。 例如,使用过去 20 个交易日的价格变化构建 20 日动量: **20 日动量 = 当前收盘价 / 20 个交易日前的收盘价 - 1** 代码如下: ```python def calculate_momentum(df, window=20): if df is None or df.empty: raise ValueError("输入的行情数据为空") if "close" not in df.columns: raise ValueError("行情数据缺少 close 字段") result = df.copy() result["close"] = pd.to_numeric( result["close"], errors="coerce", ) result = result.dropna(subset=["close"]) if len(result) <= window: raise ValueError( f"有效行情不足,至少需要超过 {window} 条记录" ) result["momentum"] = ( result["close"] / result["close"].shift(window) - 1 ) return result # 示例:df 为前面获取的前复权 K 线 DataFrame momentum_df = calculate_momentum(df, window=20) print(momentum_df[["close", "momentum"]].tail()) ``` 这个指标只是演示复权行情的常见用途,不构成完整的选股策略。 实际使用时,还需要处理停牌、缺失交易日、异常行情以及股票池变化等问题。 对于历史回测,还应保证因子使用的信息在对应决策时点已经可用,不能直接将事后才知道的信息用于历史信号。 ### 关键坑与注意事项 - **前复权不等于原始价格。** 前复权调整历史价格,适合部分历史价格分析场景,但不能替代真实成交记录。 - **后复权和前复权的基准不同。** 两者生成的价格序列可能不同,计算出的历史价格水平也不能直接混用。 - **不复权不代表数据错误。** 如果需要还原当时的市场成交价格,原始行情反而是必要的数据来源。 - **复权价格不等于真实持仓收益。** 真实收益还可能涉及股数变化、现金分红、交易费用和税费。 - **不能仅凭价格差异判断除权因子错误。** 还需要核对公司行动记录、复权基准和数据服务的调整规则。 - **历史复权结果可能随基准变化。** 为保证回测可复现,应保存行情快照、复权方式和数据版本。 - **不要在已复权的数据上重复应用相同调整。** 重复调整可能造成价格和收益率失真。 ### 常见问题(FAQ) **Q:除权因子和复权价格有什么区别?** A:除权因子是用于调整价格的系数或调整依据;复权价格是根据相应规则处理后得到的价格序列。两者相关,但不是同一个概念。 **Q:量化选股应该使用前复权还是后复权?** A:没有适用于所有策略的统一答案。对于需要比较历史价格走势的动量和趋势研究,可以考虑前复权;其他研究也可能选择后复权。关键是明确复权基准,保持计算口径一致,并验证结果。 **Q:什么时候应该使用不复权数据?** A:还原历史市场价格、核对实际成交、处理订单价格及构建交易账本时,通常需要保留原始行情。涉及分红和股数变化时,还应结合公司行动记录计算实际持仓收益。 **Q:使用 QuantDash 获取复权数据,还需要自己计算除权因子吗?** A:如果使用的接口已经按照指定规则返回复权后的 K 线,通常不需要在策略层重复计算相同的价格调整。但对于需要审计公司行动、独立验证复权结果或还原历史持仓现金流的系统,仍然需要保留相应数据和校验逻辑。 **Q:为什么同一只股票的历史价格在不同时间获取时可能发生变化?** A:可能与复权基准变化、公司行动信息更新或历史数据修订有关。建议记录获取时间、复权参数和数据版本,并在重要回测中保留实际使用的数据快照。 ### 小结 除权因子的核心作用,是帮助量化系统正确处理公司行动对历史价格序列的影响,避免价格口径不一致进一步影响收益率、动量因子和回测结果。 在工程实现上,可以通过 QuantDash Python SDK 的 **qd.klines.get()** 接口获取历史 K 线,并使用 **adjust** 参数选择相应复权方式。这样可以减少策略层重复维护复权逻辑的工作。 但接口统一只是第一步。要让研究结果可靠,还需要区分原始价格与复权价格,明确复权基准,保留数据版本,并将研究价格收益与真实持仓收益分开处理。 ### 参考 QuantDash Python SDK 文档:https://docs.quantdash.net/zh-Hans/sdk/python-quickstart

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

Elasticsearch 高级 RAG 技术第 1 部分:数据处理

作者:来自 ElasticHan Xiang Choong 这是我们探索高级 RAG 技术的第 1 部分。单击此处查看第 2 部分! 最近的论文《寻找检索增强生成的最佳实践》通过实证评估了各种 RAG 增强技术的有效性,目的是汇集一套 RAG 的最佳实践。 我们将实施其中一些建议的最佳实践,即旨在提高搜索质量的实践(句子分块/sentence chunking、HyDE、反向打包/reverse packing)。 为简洁起见,我们将省略那些专注于提高效率的技术(查询分类和摘要)。 我们还将实施一些未涉及但我个人认为有用且有趣的技术(元数据包含/Metadata inclusion、复合多字段嵌入/Composite multi-field embeddings、查询丰富/Query enrichment)。 最后,我们将进行一个简短的测试,看看我们的搜索结果和生成的答案的质量与基线相比是否有所提高。让我们开始吧! 概述 RAG 旨在通过从外部知识库检索信息来丰富生成的答案,从而增强 LLMs。通过提供特定领域的信息,LLM 可以快速适应其训练数据范围之外的用例;比微调便宜得多,而且更容易保持最新状态。 提高 RAG 质量的措施通常侧重于两个方面: 提高知识库的质量和清晰度。 提高搜索查询的覆盖率和特异性。 这两项措施将实现提高 LLM 获得相关事实和信息的可能性的目标,从而不太可能产生幻觉或利用自己的知识 —— 这些知识可能已经过时或不相关。 方法的多样性很难用几句话来阐明。让我们直接进入实施阶段,让事情更清楚。 设置 所有代码都可以在 Searchlabs 仓库中找到。 首先,你需要以下内容: Elastic Cloud 部署 LLM API - 我们在此笔记本中使用 Azure OpenAI 上的 GPT-4o 部署 Python 版本 3.12.4 或更高版本 我们将运行 main.ipynb 笔记本中的所有代码。 继续 git clone 仓库,导航到 supporting-blog-content/advanced-rag-techniques,然后运行以下命令: # Create a new virtual environment named 'rag_env' python -m venv rag_env # Activate the virtual environment (for Unix-based systems) source rag_env/bin/activate # (For Windows) .\rag_env\Scripts\activate # Install packages listed in requirements.txt pip install -r requirements.txt 完成后,创建一个 .env 文件并填写以下字段(参考 env.example )。感谢我的合著者 Claude-3.5 提供的有益评论。 # Elastic Cloud: Found in the 'Deployment' page of your Elastic Cloud # console ELASTIC_CLOUD_ENDPOINT="" ELASTIC_CLOUD_ID="" # Elastic Cloud: Created during deployment setup or in 'Security' # settings ELASTIC_USERNAME="" ELASTIC_PASSWORD="" # Elastic Cloud: The name of the index you created in Kibana or via API ELASTIC_INDEX_NAME="" # Azure AI Studio: Found in 'Keys and Endpoint' section of your Azure # OpenAI resource AZURE_OPENAI_KEY_1="" AZURE_OPENAI_KEY_2="" AZURE_OPENAI_REGION="" AZURE_OPENAI_ENDPOINT="" # Azure AI Studio: Found in 'Deployments' section of your Azure OpenAI # resource AZURE_OPENAI_DEPLOYMENT_NAME="" # Using BAAI/bge-small-en-v1.5 because I think it is a good balance of # resource efficiency and performance. HUGGINGFACE_EMBEDDING_MODEL="BAAI/bge-small-en-v1.5" 接下来,我们将选择要提取的文档,并将其放在文档文件夹中。在本文中,我们将使用 Elastic N.V. 2023 年年度报告。这是一份相当具有挑战性且内容丰富的文档,非常适合对我们的 RAG 技术进行压力测试。 现在一切就绪,让我们开始提取。打开 main.ipynb 并执行前两个单元以导入所有包并初始化所有服务。 提取、处理和嵌入文档 数据提取 个人笔记:LlamaIndex 的便利性让我震惊。在 LLMs 和 LlamaIndex 出现之前的旧时代,提取各种格式的文档是一个痛苦的过程,需要从各个地方收集深奥的软件包。现在它简化为一个函数调用。太疯狂了! SimpleDirectoryReader 将加载 directory_path 中的每个文档。对于 .pdf 文件,它返回一个文档对象列表,我将其转换为 Python 字典,因为我发现它们更容易使用。 # llamaindex_processor.py from llama_index.core import SimpleDirectoryReader class LlamaIndexProcessor: def __init__(self): pass def load_documents(self, directory_path): ''' Load all documents in directory ''' reader = SimpleDirectoryReader(input_dir=directory_path) return reader.load_data() # main.ipynb llamaindex_processor=LlamaIndexProcessor() documents=llamaindex_processor.load_documents('./documents/') documents=[dict(doc_obj) for doc_obj in documents] 每个词典都包含在text 字段中的关键内容。它还包含有用的元数据,例如页码、文件名、文件大小和类型。 { 'id_': '5f76f0b3-22d8-49a8-9942-c2bbab14f63f', 'metadata': {'page_label': '5', 'file_name': 'Elastic_NV_Annual-Report-Fiscal-Year-2023.pdf', 'file_path': '/Users/han/Desktop/Projects/truckasaurus/documents/Elastic_NV_Annual-Report-Fiscal-Year-2023.pdf', 'file_type': 'application/pdf', 'file_size': 3724426, 'creation_date': '2024-07-27', 'last_modified_date': '2024-07-27'}, 'text': 'Table of Contents\nPage\nPART I\nItem 1. Business 3\n15 Item 1A. Risk Factors\nItem 1B. Unresolved Staff Comments 48\nItem 2. Properties 48\nItem 3. Legal Proceedings 48\nItem 4. Mine Safety Disclosures 48\nPART II\nItem 5. Market for Registrant’s Common Equity, Related Stockholder Matters and Issuer Purchases of \nEquity Securities49\nItem 6. [Reserved] 49\nItem 7. Management’s Discussion and Analysis of Financial Condition and Results of Operations 50\nItem 7A. Quantitative and Qualitative Disclosures About Market Risk 64\nItem 8. Financial Statements and Supplementary Data 66\nItem 9. Changes in and Disagreements With Accountants on Accounting and Financial Disclosure 100\n100\n101Item 9A. Controls and Procedures\nItem 9B. Other Information\nItem 9C. Disclosure Regarding Foreign Jurisdictions That Prevent Inspections 101\nPART III\n102\n102\n102\n102Item 10. Directors, Executive Officers and Corporate Governance\nItem 11. Executive Compensation\nItem 12. Security Ownership of Certain Beneficial Owners and Management, and Related Stockholder Matters \nItem 13. Certain Relationships and Related Transactions, and Director Independence\nItem 14. Principal Accountant Fees and Services 102\nPART IV\n103\n105Item 15. Exhibits and Financial Statement Schedules \nItem 16. Form 10-K Summary\nSignatures 106\ni', ... } 句子级、标记式分块 首先要做的是将文档缩减为标准长度的块(以确保一致性和可管理性)。嵌入模型具有唯一的标记(token)限制(它们可以处理的最大输入大小)。标记是模型处理的基本文本单位。为了防止信息丢失(截断或遗漏内容),我们应该提供不超过这些限制的文本(通过将较长的文本拆分为较小的段)。 分块对性能有重大影响。理想情况下,每个块都代表一个独立的信息,捕获有关单个主题的上下文信息。分块方法包括单词级分块(按字数拆分文档)和语义分块(使用 LLM 识别逻辑断点)。 单词级分块便宜、快速且简单,但存在拆分句子从而破坏上下文的风险。语义分块变得缓慢且昂贵,尤其是在处理像 116 页的 Elastic 年度报告这样的文档时。 让我们选择一种折中方法。句子级分块仍然很简单,但可以比单词级分块更有效地保留上下文,同时成本更低、速度更快。此外,我们将实现一个滑动窗口来捕获一些周围的上下文,并减轻拆分段落的影响。 # chunker.py import uuid import re class Chunker: def __init__(self, tokenizer): self.tokenizer = tokenizer def split_into_sentences(self, text): """Split text into sentences.""" return re.split(r'(?<=[.!?])\s+', text) def sentence_wise_tokenized_chunk_documents(self, documents, chunk_size=512, overlap=20, min_chunk_size=50): ''' 1. Split text into sentences. 2. Tokenize using the provided tokenizer method. 3. Build chunks up to the chunk_size limit. 4. Create an overlap based on tokens - to preserve context. 5. Only keep chunks that meet the minimum token size requirement. ''' chunked_documents = [] for doc in documents: sentences = self.split_into_sentences(doc['text']) tokens = [] sentence_boundaries = [0] # Tokenize all sentences and keep track of sentence boundaries for sentence in sentences: sentence_tokens = self.tokenizer.encode(sentence, add_special_tokens=True) tokens.extend(sentence_tokens) sentence_boundaries.append(len(tokens)) # Create chunks chunk_start = 0 while chunk_start < len(tokens): chunk_end = chunk_start + chunk_size # Find the last complete sentence that fits in the chunk sentence_end = next((i for i in sentence_boundaries if i > chunk_end), len(tokens)) chunk_end = min(chunk_end, sentence_end) # Create the chunk chunk_tokens = tokens[chunk_start:chunk_end] # Check if the chunk meets the minimum size requirement if len(chunk_tokens) >= min_chunk_size: # Create a new document object for this chunk chunk_doc = { 'id_': str(uuid.uuid4()), 'chunk': chunk_tokens, 'original_text': self.tokenizer.decode(chunk_tokens), 'chunk_index': len(chunked_documents), 'parent_id': doc['id_'], 'chunk_token_count': len(chunk_tokens) } # Copy all other fields from the original document for key, value in doc.items(): if key != 'text' and key not in chunk_doc: chunk_doc[key] = value chunked_documents.append(chunk_doc) # Move to the next chunk start, considering overlap chunk_start = max(chunk_start + chunk_size - overlap, chunk_end - overlap) return chunked_documents # main.ipynb # Initialize Embedding Model HUGGINGFACE_EMBEDDING_MODEL = os.environ.get('HUGGINGFACE_EMBEDDING_MODEL') embedder=EmbeddingModel(model_name=HUGGINGFACE_EMBEDDING_MODEL) # Initialize Chunker chunker=Chunker(embedder.tokenizer) Chunker 类采用嵌入模型的分词器来对文本进行编码和解码。我们现在将构建每个包含 512 个标记的块,其中重叠 20 个标记。为此,我们将文本拆分成句子,对这些句子进行分词,然后将标记后的句子添加到我们当前的块中,直到我们无法添加更多句子而不会超出我们的标记限制。 最后,将句子解码回原始文本以进行嵌入,并将其存储在名为 original_text 的字段中。块存储在名为 chunk 的字段中。为了减少噪音(即无用文档),我们将丢弃长度小于 50 个标记的任何文档。 让我们在我们的文档上运行它: chunked_documents=chunker.sentence_wise_tokenized_chunk_documents(documents, chunk_size=512) 并返回如下大段文本: print(chunked_documents[4]['original_text']) [CLS] the aggregate market value of the ordinary shares held by non - affiliates of the registrant, based on the closing price of the shares of ordinary shares on the new york stock exchange on october 31, 2022 ( the last business day of the registrant ’ s second fiscal quarter ), was approximately $ 6. 1 billion. [SEP] [CLS] as of may 31, 2023, the registrant had 97, 390, 886 ordinary shares, par value €0. 01 per share, outstanding. [SEP] [CLS] documents incorporated by reference portions of the registrant ’ s definitive proxy statement relating to the registrant ’ s 2 023 annual general meeting of shareholders are incorporated by reference into part iii of this annual ... ... 元数据的包含和生成 我们已经对文档进行了分块。现在是时候丰富数据了。我想生成或提取额外的元数据。这些额外的元数据可用于影响和增强搜索性能。 我们将定义一个 DocumentEnricher 类,其作用是接收文档列表(Python 字典)和处理器函数列表。这些函数将在文档的 original_text 列上运行,并将其输出存储在新字段中。 首先,我们使用 TextRank 提取关键短语(keyphrases)。TextRank 是一种基于图(graph-based)的算法,它通过根据单词之间的关系对关键短语和句子的重要性进行排序,从文本中提取关键短语和句子。 接下来,我们将使用 GPT-4o 生成潜在问题。 最后,我们将使用 Spacy 提取实体。 由于每个代码都相当冗长且复杂,因此我将避免在此处重现它。如果你有兴趣,文件已在下面的代码示例中进行了标记。 让我们运行数据丰富: # documentenricher.py from tqdm import tqdm class DocumentEnricher: def __init__(self): pass def enrich_document(self, documents, processors, text_col='text'): for doc in tqdm(documents, desc="Enriching documents using processors: "+str(processors)): for (processor, field) in processors: metadata=processor(doc[text_col]) if isinstance(metadata, list): metadata='\n'.join(metadata) doc.update({field: metadata}) # main.ipynb # Initialize processor classes nltkprocessor=NLTKProcessor() // nltk_processor.py entity_extractor=EntityExtractor() // entity_extractor.py gpt4o = LLMProcessor(model='gpt-4o') // llm.py # Initialize LLM documentenricher=DocumentEnricher() # Create new fields in the documents - These are the outputs of the processor functions. processors=[ (nltkprocessor.textrank_phrases, "keyphrases"), (gpt4o.generate_questions, "potential_questions"), (entity_extractor.extract_entities, "entities") ] # .enrich_document() will modify chunked_docs in place. # To view the results, we'll print chunked_docs in the next few cells! documentenricher.enrich_document(chunked_docs, text_col='original_text', processors=processors) 看一下结果: TextRank 提取的关键短语 这些关键短语代表了区块的核心主题。如果查询与网络安全有关,则该区块的得分会提高。 print(chunked_documents[25]['keyphrases']) 'elastic agent stop', 'agent stop malware', 'stop malware ransomware', 'malware ransomware environment', 'ransomware environment wide', 'environment wide visibility', 'wide visibility threat', 'visibility threat detection', 'sep cl key', 'cl key feature' GPT-4o 生成的潜在问题 这些潜在问题可能与用户查询直接匹配,从而提高得分。我们提示 GPT-4o 生成可以使用当前块中找到的信息来回答的问题。 print(chunked_documents[25]['potential_questions']) 1. What are the primary functions that Elastic Agent provides in terms of cybersecurity? 2. Describe how Logstash contributes to data management within an IT environment. 3. List and explain any key features of Logstash mentioned in the document. 4. How does Elastic Agent enhance environment-wide visibility in threat detection? 5. What capabilities does Logstash offer for handling data beyond simple collection? 6. In what ways does the document suggest that Elastic Agent stops malware and ransomware? 7. Can you identify any relationships between the functionalities of Elastic Agent and Logstash in an integrated environment? 8. What implications might the advanced threat detection capabilities of Elastic Agent have for organizational security policies? 9. Compare and contrast the roles of Elastic Agent and Logstash based on their described functions. 10. How might the centralized collection ability of Logstash support the threat detection capabilities of Elastic Agent? Spacy 提取的实体 这些实体的作用与关键短语类似,但会捕获组织和个人的名称,而关键短语提取可能会遗漏这些名称。 print(chunked_documents[29]['entities']) 'appdynamics', 'apm data', 'azure sentinel', 'microsoft', 'mcafee', 'broadcom', 'cisco', 'dynatrace', 'coveo', 'lucidworks' 复合多字段嵌入 现在我们已经用额外的元数据丰富了我们的文档,我们可以利用这些信息来创建更强大、更能感知上下文的嵌入。 让我们回顾一下我们目前在流程中的要点。每个文档都有四个感兴趣的字段。 { "chunk": "...", "keyphrases": "...", "potential_questions": "...", "entities": "..." } 每个字段代表文档上下文的不同视角,有可能突出显示 LLM 需要关注的关键领域。 计划是嵌入每个字段,然后创建嵌入的加权和,称为复合嵌入(Composite Embedding)。 幸运的是,除了引入另一个可调节的超参数来控制搜索行为之外,这种复合嵌入还将使系统能够更好地感知上下文。 首先,让我们使用在 main.ipynb 笔记本开头导入的本地定义的嵌入模型嵌入每个字段并就地更新每个文档。 # EmbeddingModel defined in embedding_model.py embedder=EmbeddingModel(model_name=HUGGINGFACE_EMBEDDING_MODEL) cols_to_embed=['keyphrases', 'potential_questions', 'entities'] embedding_cols=[] for col in cols_to_embed: # Works on text input embedding_col=embedder.embed_documents_text_wise(chunked_documents, text_field=col) embedding_cols.append(embedding_col) # Works on token input embedding_col=embedder.embed_documents_token_wise(chunked_documents, token_field="chunk") embedding_cols.append(embedding_col) 每个嵌入函数都会返回嵌入的字段,该字段只是带有 _embedding 后缀的原始输入字段。 现在让我们定义复合嵌入的权重: embedding_cols=[ 'keyphrases_embedding', 'potential_questions_embedding', 'entities_embedding', 'chunk_embedding'] combination_weights=[ 0.1, 0.15, 0.05, 0.7 ] 权重允许你根据用例和数据质量为每个组件分配优先级。直观地说,这些权重的大小取决于每个组件的语义值。由于块文本本身是迄今为止最丰富的,因此我分配了 70% 的权重。由于实体是最小的,只是组织或人名列表,因此我为其分配了 5% 的权重。这些值的精确设置必须根据用例逐一根据经验确定。 最后,让我们编写一个函数来应用权重,并创建我们的复合嵌入。我们还将删除所有组件嵌入以节省空间。 from tqdm import tqdm def combine_embeddings(objects, embedding_cols, combination_weights, primary_embedding='primary_embedding'): # Ensure the number of weights matches the number of embedding columns assert len(embedding_cols) == len(combination_weights), "Number of embedding columns must match number of weights" # Normalize weights to sum to 1 weights = np.array(combination_weights) / np.sum(combination_weights) for obj in tqdm(objects, desc="Combining embeddings"): # Initialize the combined embedding combined = np.zeros_like(obj[embedding_cols[0]]) # Compute the weighted sum for col, weight in zip(embedding_cols, weights): combined += weight * np.array(obj[col]) # Add the new combined embedding to the object obj.update({primary_embedding:combined.tolist()}) # Remove the original embedding columns for col in embedding_cols: obj.pop(col, None) combine_embeddings(chunked_documents, embedding_cols, combination_weights) 至此,我们完成了文档处理。我们现在有一个文档对象列表,如下所示: { 'id_': '7fe71686-5cd0-4831-9e79-998c6dbeae0c', 'chunk': [2312, 14613, ...], 'original_text': 'if an emerging growth company, indicate by check mark if the registrant has elected not to use the extended ...', 'chunk_index': 3, 'chunk_token_count': 399, 'metadata': {'page_label': '3', 'file_name': 'Elastic_NV_Annual-Report-Fiscal-Year-2023.pdf', ... 'keyphrases': 'sep cl unk\ncheck mark registrant\ncl unk indicate\nunk indicate check\nindicate check mark\nprincipal executive office\naccelerate filer unk\ncompany unk emerge\nunk emerge growth\nemerge growth company', 'potential_questions': '1. What are the different types of registrant statuses mentioned in the document?\n2. Under what section of the Sarbanes-Oxley Act must registrants file a report on the effectiveness of their internal ...', 'entities': 'the effe ctiveness of\nsection 13\nSEP\nUNK\nsection 21e\n1934\n1933\nu. s. c.\nsection 404\nsection 12\nal', 'primary_embedding': [-0.3946287803351879, -0.17586839850991964, ...] } 索引到 Elasticsearch 让我们将文档批量上传到 Elasticsearch。为此,我很久以前在 elastic_helpers.py 中定义了一组 Elastic Helper 函数。这是一段非常冗长的代码,因此我们继续查看函数调用。 es_bulk_indexer.bulk_upload_documents 可与任何字典对象列表配合使用,充分利用 Elasticsearch 便捷的动态映射。 # Initialize Elasticsearch ELASTIC_CLOUD_ID = os.environ.get('ELASTIC_CLOUD_ID') ELASTIC_USERNAME = os.environ.get('ELASTIC_USERNAME') ELASTIC_PASSWORD = os.environ.get('ELASTIC_PASSWORD') ELASTIC_CLOUD_AUTH = (ELASTIC_USERNAME, ELASTIC_PASSWORD) es_bulk_indexer = ESBulkIndexer(cloud_id=ELASTIC_CLOUD_ID, credentials=ELASTIC_CLOUD_AUTH) es_query_maker = ESQueryMaker(cloud_id=ELASTIC_CLOUD_ID, credentials=ELASTIC_CLOUD_AUTH) # Define Index Name index_name=os.environ.get('ELASTIC_INDEX_NAME') # Create index and bulk upload index_exists = es_bulk_indexer.check_index_existence(index_name=index_name) if not index_exists: logger.info(f"Creating new index: {index_name}") es_bulk_indexer.create_es_index(es_configuration=BASIC_CONFIG, index_name=index_name) success_count = es_bulk_indexer.bulk_upload_documents( index_name=index_name, documents=chunked_documents, id_col='id_', batch_size=32 ) # Initialize Elasticsearch ELASTIC_CLOUD_ID = os.environ.get('ELASTIC_CLOUD_ID') ELASTIC_USERNAME = os.environ.get('ELASTIC_USERNAME') ELASTIC_PASSWORD = os.environ.get('ELASTIC_PASSWORD') ELASTIC_CLOUD_AUTH = (ELASTIC_USERNAME, ELASTIC_PASSWORD) es_bulk_indexer = ESBulkIndexer(cloud_id=ELASTIC_CLOUD_ID, credentials=ELASTIC_CLOUD_AUTH) es_query_maker = ESQueryMaker(cloud_id=ELASTIC_CLOUD_ID, credentials=ELASTIC_CLOUD_AUTH) # Define Index Name index_name=os.environ.get('ELASTIC_INDEX_NAME') # Create index and bulk upload index_exists = es_bulk_indexer.check_index_existence(index_name=index_name) if not index_exists: logger.info(f"Creating new index: {index_name}") es_bulk_indexer.create_es_index(es_configuration=BASIC_CONFIG, index_name=index_name) success_count = es_bulk_indexer.bulk_upload_documents( index_name=index_name, documents=chunked_documents, id_col='id_', batch_size=32 ) 前往 Kibana 并验证所有文档是否都已编入索引。应该有 224 个文档。对于如此大的文档来说还不错! 猫咪休息一下 让我们休息一下,我知道这篇文章有点沉重。看看我的猫咪: 看看她有多生气 恭喜你取得如此大的成就 :) 加入我的第二部分,测试和评估我们的 RAG 管道! 附录 定义 句子分块 一种在 RAG 系统中用于将文本划分为较小且有意义单位的预处理技术。 过程: 输入: 大段文本(如文档、段落) 输出: 较小的文本片段(通常是句子或几句的组合) 目的: 创建细粒度的、特定于上下文的文本片段 允许更精确的索引和检索 提高 RAG 系统中检索信息的相关性 特征: 分段具有语义意义 可以独立索引和检索 通常保留一些上下文以确保独立的可理解性 好处: 增强检索精度 在 RAG 流程中实现更集中的增强 HyDE(Hypothetical Document Embedding - 假设文档嵌入) 一种在 RAG 系统中使用 LLM 生成假设文档来扩展查询的技术。 过程: 将输入查询提交给 LLM LLM 生成回答查询的假设文档 为生成的文档生成嵌入 使用嵌入进行向量搜索 关键区别: 传统 RAG: 将查询与文档匹配 HyDE: 将文档与文档匹配 目的: 提高检索性能,特别是针对复杂或模糊的查询 捕捉比简短查询更丰富的语义上下文 好处: 利用 LLM 的知识扩展查询 可能提高检索文档的相关性 挑战: 需要额外的 LLM 推理,增加延迟和成本 性能取决于生成的假设文档的质量 反向打包 - reverse packing 一种用于在将搜索结果传递给 LLM 之前重新排序的技术。 过程: 搜索引擎(如 Elasticsearch)按相关性降序返回文档。 排序被反转,将最相关的文档放在最后。 目的: 利用 LLM 的近期偏好,它们往往更关注上下文中最新的信息。 确保最相关的信息在 LLM 的上下文窗口中是 “最新的”。 示例: 原始顺序: [最相关,次相关,第三相关,...] 反转顺序: [...,第三相关,次相关,最相关] 查询分类 -Query Classification 一种通过确定查询是否需要 RAG 处理或可以由 LLM 直接回答来优化 RAG 系统效率的技术。 过程: 开发针对使用的 LLM 的自定义数据集 训练一个专门的分类模型 使用模型对传入查询进行分类 目的: 提高系统效率,避免不必要的 RAG 处理 将查询定向到最适合的响应机制 要求: LLM 特定的数据集和模型 持续改进以保持准确性 好处: 减少简单查询的计算开销 可能改善非 RAG 查询的响应时间 摘要 -Summarization 一种在 RAG 系统中将检索到的文档压缩的技术。 过程: 检索相关文档 生成每个文档的简明摘要 在 RAG 流程中使用摘要代替完整文档 目的: 通过关注重要信息提高 RAG 性能 减少不相关内容带来的噪音和干扰 好处: 可能提高 LLM 响应的相关性 允许在上下文限制内包含更多文档 挑战: 摘要可能导致重要细节丢失 生成摘要的计算开销增加 元数据包含 -Metadata Inclusion 一种通过额外的上下文信息丰富文档的技术。 元数据类型: 关键短语 标题 日期 作者详情 简介 目的: 增加 RAG系统可用的上下文信息 为 LLM 提供更清晰的文档内容和相关性的理解 好处: 可能提高检索精度 增强 LLM 评估文档有用性的能力 实施: 可以在文档预处理期间完成 可能需要额外的数据提取或生成步骤 复合多字段嵌入 -Composite Multi-Field Embeddings 一种用于 RAG 系统的高级嵌入技术,为不同的文档组件创建单独的嵌入。 过程: 确定相关字段(如标题、关键短语、简介、主要内容) 为每个字段生成单独的嵌入 结合或存储这些嵌入以供检索使用 与标准方法的区别: 传统方法: 整个文档的单一嵌入 复合方法: 不同文档方面的多个嵌入 目的: 创建更细致入微且具上下文意识的文档表示 从文档的更多来源捕获信息 好处: 可能提高对模糊或多面查询的表现 允许在检索中更灵活地对文档不同方面加权 挑战: 嵌入存储和检索过程的复杂性增加 可能需要更复杂的匹配算法 查询扩展 -Query Enrichment 一种通过与查询相关的词汇扩展原始查询以提高搜索覆盖范围的技术。 过程: 分析原始查询 生成同义词和语义相关短语 使用这些额外的词汇扩展查询 目的: 增加文档库中潜在匹配的范围 改善对具有特定或技术语言的查询的检索性能 好处: 可能检索与原始查询词不完全匹配的相关文档 有助于克服查询与文档之间的词汇不匹配 挑战: 如果未仔细实施,可能导致查询漂移 可能增加检索过程中的计算开销 准备好自己尝试了吗?开始免费试用吧。 Elasticsearch 集成了 LangChain、Cohere 等工具。加入我们的高级语义搜索网络研讨会,构建你的下一个 GenAI 应用程序! 原文:Advanced RAG Techniques Part 1: Data Processing — Search Labs

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

数据处理的那些事「GitHub 热点速览」

撇开一屏占四分之三屏幕的 AI 相关项目之外,本周剩下的热榜项目就是同数据有关的数据库项目,比如 CockroachDB 团队开源的 kv 存储数据库 pebble,旨在提供高性能的消息队列 blazingmq。 其他项目则比较通用,像帮你学外文的语法校对器 languagetool,提高你阅读体验的等宽字体 FiraCode,还有提供数字签名服务的 docuseal,以及用来跟踪 issue 做项目管理的 plane。 最好玩的当属 HG 热门项目 habitica,让你在完成 todo 事项,培养某个习惯之余,也能练好你的游戏号。 以下内容摘录自微博@HelloGitHub 的 GitHub Trending 及 Hacker News 热帖(简称 HN 热帖),选项标准:新发布 | 实用 | 有趣,根据项目 release 时间分类,发布时间不超过 14 day 的项目会标注 New,无该标志则说明项目 release 超过半月。由于本文篇幅有限,还有部分项目未能在本文展示,望周知 🌝 本文目录 1. 本周特推 1.1 语法校对:languagetool 1.2 免费等宽字体:FiraCode 2. GitHub Trending 周榜 2.1 消息队列:blazingmq 2.2 KV 数据库:pebble 2.3 更快的连结器:mold 2.4 数字签名:docuseal 2.5 产品管理:plane 3. HelloGitHub 热评 3.1 习惯养成:habitica 3.2 内存管理应用:memreduct 4. 往期回顾 1. 本周特推 1.1 语法校对:languagetool 主语言:Java 一个开源的词法校对器,它会自动校对你输入文字的语法以及拼写,能有效地检测出拼写错误,以及语法问题。如果你对日常外文书写不是很有信心,可以试试 LanguageTool,支持英文、德语、西班牙语、法语等等 25+ 外文。在线体验:https://languagetool.org/ GitHub 地址→https://github.com/languagetool-org/languagetool 1.2 免费等宽字体:FiraCode 主语言:Clojure Fira Code 一款免费的等宽字体,包含常用的编程语言中多种字符组合的连字。它只是做了字体的呈现,底层代码仍然与 ASCII 兼容。下图展示了左侧:Fira Code 中呈现的连字。右侧:没有连字的相同字符序列。 GitHub 地址→https://github.com/tonsky/FiraCode 2. GitHub Trending 周榜 2.1 消息队列:blazingmq 本周 star 增长数:450+,主语言:C++ New 高性能的消息队列系统,具有高效、可靠、功能丰富的特性。BlazingMQ 的核心功能是提供持久化、高容错、高性能和高可用的队列,同时,它具备了消息路由策略(例如:工作队列、优先级、fan-out、广播等等)、压缩、强一致性等功能。 GitHub 地址→https://github.com/bloomberg/blazingmq 2.2 KV 数据库:pebble 本周 star 增长数:150+,主语言:Golang 受 RocksDB、LevelDB 启发的 KV 存储数据库,采用 Golang 编写而成,主要优化 CockroachDB 的性能。它继承了 RocksDB 的文件格式,并添加了一些扩展功能:范围删除墓碑、表级的布隆过滤器、MANIFEST 格式的更新。 GitHub 地址→https://github.com/cockroachdb/pebble 2.3 更快的连结器:mold 本周 star 增长数:650+,主语言:C++ mold 是现有 Unix 链接器(连结器)的替代品,因为它更快:它比第二快的开源链接器 LLVM lld 快几倍,mold 旨在通过缩短构建时间来提高开发者的生产力,特别是在快速调试-编辑-重建循环中。 GitHub 地址→https://github.com/rui314/mold 2.4 数字签名:docuseal 本周 star 增长数:700+,主语言:Ruby DocuSeal 是一个开源平台,提供安全高效的数字文档签名和处理功能。有了它,你可以创建 / 编辑 PDF,在文件上进行签名(网络数字签名),并邮件到邮箱。 GitHub 地址→https://github.com/docusealco/docuseal 2.5 产品管理:plane 本周 star 增长数:1,000+,主语言:TypeScript JIRA、Linear 之类项目管理器的开源替代品,可以方便地跟踪 issue、产品开发进度等等。特性: issue 规划和追踪:支持富文本,可快速创建 issue; issue 附件:支持文件上传,作为附件附属在对应 issue 中; 自定义布局; 模块化:方便拆解大任务为小任务,快速推进项目开展; 可与 GitHub 同步; GitHub 地址→https://github.com/makeplane/plane 3. HelloGitHub 热评 在这个章节,我们将会分享下本周 HelloGitHub 网站上的热评项目,HG 开源项目评价体系刚上线不久,期待你的评价。 3.1 习惯养成:habitica 主语言:JavaScript 这是一款养成类 RPG 游戏,当你完成一个现实中的待办事项后,会获得相应的经验和金币。随着你的等级提升,将会开启更多的玩法,比如购买装备、孵化宠物、职业、专属技能、组队打副本等。 HG 评价地址→https://hellogithub.com/repository/9cb771c1667940f9a92bf3942b2a702e 3.2 内存管理应用:memreduct 主语言:C 这是一款 Windows 内存管理工具,可以实时监控计算机内存和清理系统缓存。它体积小(6MB)、内存释放效果明显,兼容 Windows XP 及更高版本。 HG 评价地址→https://hellogithub.com/repository/fb96589af4c04b02872c66d0fbf32469 4. 往期回顾 往期回顾: 懒人的百宝箱「GitHub 热点速览」 效率回归,工具库之美「GitHub 热点速览」 以上为 2023 年第 30 个工作周的 GitHub Trending 🎉如果你 Pick 其他好玩、实用的 GitHub 项目,来 HelloGitHub 和大家一起分享下哟 🌝

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

在MaxCompute中利用bitmap进行数据处理

很多数据开发者使用bitmap技术对用户数据进行编码和压缩,然后利用bitmap的与/或/非的极速处理速度,实现类似用户画像标签的人群筛选、运营分析的7日活跃等分析。本文给出了一个使用MaxCompute MapReduce开发一个对不同日期活跃用户ID进行bitmap编码和计算的样例。供感兴趣的用户进一步了解、分析,并应用在自己的场景下。 import com.aliyun.odps.OdpsException; import com.aliyun.odps.data.Record; import com.aliyun.odps.data.TableInfo; import com.aliyun.odps.mapred.JobClient; import com.aliyun.odps.mapred.MapperBase; im

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

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

用户登录
用户注册