你有没有遇到过这种情况:在理财平台里放了一笔钱买货币基金,第二天打开收益明细,却发现数字是0.00元,一分钱都没生成。
如果你拿着这个问题去翻平台的基金列表,可能会发现几十只货币基金里,确实有那么一些,无论投多少、放几天,每天收益都上不了“0.01元”这个门槛。6月7日那天,我就把某个微信生态里在售的货币基金拉了一遍,筛出48只“每天没有生成0.01元利息”的产品,然后对这些基金的名字、简介、管理人这些文本信息做了一次词频统计。
别小看这个动作。收益显示为0和基金本身的收益率、计息规则、产品标签都有关系,而词频统计能把一堆产品文本里反复出现的“高频词”挖出来,帮你看清楚这批低收益货基到底长什么样。这篇就用项目复盘的方式,把从数据获取、筛选逻辑、分词处理到词频结果的完整过程整理出来,给想折腾理财产品数据分析的朋友一份能直接抄作业的参考。
这篇内容适合这几类人:对货币基金收益规则好奇的小白、想在某个平台做基金列表横向测评的理财爱好者,以及被“0.01元利息”折磨过、想弄明白原因的操作型用户。
1. 项目背景:为什么“0.01元利息”值得研究
1.1 0.01元背后是两套不同的“低收益逻辑”
货币基金每天的收益是这样算的:每日收益 = 已确认金额 ÷ 10000 × 当日万份收益。
举个直观的例子,某只基金的万份收益是0.5元,那你投10000元,当天收益是0.5元;投1000元,当天收益是0.05元;投100元,当天收益是0.005元,按平台规则分位四舍五入后显示为0.00元。
所以“每天没有生成0.01元利息”至少分两种情况:
- 你的本金太少,导致本来就该有的几分钱被舍入成0.00;
- 基金本身的万份收益实在太低,就算投1万块,一天也赚不到1分钱。
我这次筛的是基金属性,不是个人持仓金额,所以锚定的是第二种情况:选取那些近30天每日万份收益都低于0.01元、或者收益结算记录里持续为0.00的货币基金。这个口径能直接反映基金本身“能不能赚到钱”,而不是用户持仓金额导致的显示问题。
1.2 为什么偏偏是48只
微信理财平台在售的货币基金数量不是固定的,各家代销机构会不定时下架老产品、上架新产品,同一家基金公司也可能发A类、C类等不同份额。6月7日抓取的时候,平台上可申购的货币基金列表一共有几十只,筛除了“暂无收益记录”的新发基金和“暂停申购”的存量份额之后,剩下48只满足“每天没有生成0.01元利息”这个条件。
这个数量并不重要,重要的是48只作为一个有限样本,已经足够做词频统计了。文本分析不是越多样本越好,当样本量在30到100之间时,人工可以复核每一只基金的数据,反而比大规模抓取更可控。后面你会看到,针对48只基金做逐个字段核对,比跑一个几百只基金的大脚本更能发现细节问题。
1.3 标题里的“词频统计”到底要做什么
词频统计不是给48只基金的名字画个词云就完事。我真正要回答的问题是:这些低收益货基,有没有共同特征?它们的名字里是不是都带某些词?基金管理人是不是集中在某几家公司?产品介绍文案里是不是都强调“快速赎回”“随时可取”?
把这些信息拼在一起,能形成一份“低收益货基的语言画像”。虽说文案措辞不直接决定收益,但基金公司对同一类产品的命名习惯、产品定位、营销话术,往往能从词频上看出端倪。这就是词频统计在这个项目里的全部价值。
2. 数据采集与样本筛选
2.1 从哪拿数据、怎么拿
我的数据来源是微信理财平台的基金页面,包括列表页和单只基金的详情页。列表页能看到基金简称、七日年化、万份收益这些核心指标;详情页则有更完整的基金全名、基金管理人、基金类型、成立时间、近一个月收益曲线等。
获取方式有两种。
第一种是纯手动。打开理财页面的货币基金列表,一页页往下翻,把基金代码、名称、万份收益、七日年化抄进Excel。这个方法不推荐,因为列表页默认只展示部分产品,要切换排序方式才能看到全部,而且基金详情页的信息分散,手动抄很容易漏字段。
第二种是用脚本请求接口。微信理财平台的页面背后有标准的数据接口,返回的是JSON格式数据。我自己用Python写了一个抓取脚本,先请求列表页拿到基金代码集合,再逐个请求详情页拿收益数据和文本信息,中间加了随机延时控制访问频率。这里要特别说明一下:个人做数据分析,控制频率、不抓取非公开数据、不用于商业用途,是底线。任何绕过登录验证、高频请求的采集行为都可能违反平台规则,请勿模仿过度行为。
2.2 字段设计与筛选规则
我建的表结构长这样:
| 字段 | 说明 | 示例 |
|---|---|---|
| fund_code | 基金代码 | 000000A(脱敏) |
| fund_name | 基金简称 | 某某货币A |
| fund_fullname | 基金全称 | 某某现金管理货币市场基金A类 |
| manager | 基金管理人 | 某基金公司 |
| mfee_rate | 管理费率 | 0.15% |
| daily_income | 最近一日万份收益 | 0.0039 |
| seven_return | 七日年化收益率 | 0.15% |
筛选规则我设成“连续30天每日万份收益低于0.01元”,也就是满足daily_income < 0.01这个条件。
为什么要定30天?因为货币基金偶尔会出现单日万份收益极低的情况,比如季末、年末资金面紧张导致的短期负收益,或者基金分红除息造成的净值波动。如果只看一天,很容易把正常产品误判成低收益样本。拉长到30天,能过滤掉偶发波动,筛出来的才是“稳定不产生0.01元利息”的基金。实际筛完有48只,占平台在售货基的六成左右,这个比例本身已经说明问题——2026年年中这个时点上,平台里相当一部分货基的收益都处在地板区间。
2.3 清洗过程中的隐蔽问题
第一坑是“万份收益单位不统一”。详情页里有的产品显示“每万份收益:0.50元”,有的显示“万份收益率:0.005%”,脚本解析时单位没统一就会差100倍。我清洗阶段统一转成“元/万元”这个口径,再去做阈值判断。
第二坑是A类和C类份额。同一只基金可能同时有A类和C类份额,名字几乎一样,只是费率结构不同。在列表页里它们会被当成两个独立产品展示,但文本字段高度相似,直接丢进词频统计会造成重复计算。我处理的办法是给每只基金标记分类字段,统计时单独看A类,C类只做参考。
清洗后的数据长这样,一共48行,每一行都经过人工抽查,确保没有解析错位:
合计样本:48只基金 其中A类份额:35只 其中C类份额:13只 日均万份收益低于0.01元的样本:48只(100%)3. 词频统计的完整实操
3.1 工具选型:Python为主,Excel兜底
词频统计的核心工具我选了Python,理由是标准库加上中文分词库就够用,不需要依赖在线服务。
整体技术栈:
- Python 3.10 + pandas 处理表格数据
- jieba 做中文分词
- collections.Counter 做词频计数
- wordcloud 做词云可视化
如果不会写代码,也可以用Excel的替换函数一步步数词频,或者把基金名称粘贴到在线词频工具里跑。但我建议至少用Python跑一遍,因为后面涉及的停用词过滤、自定义词典合并、结果导出,脚本比手动操作省一个小时。
3.2 分词与停用词:中文文本分析的两道门槛
中文和英文不同,英文按空格天然分词,中文必须先把连续字符串切分成一个个有语义的词汇。jieba默认用前缀词典做动态规划,能处理大部分常见词,但“货币基金”这类基金领域的固定搭配容易被拆成“货币”“基金”两个词。这样统计出来的结果会显得很碎。
解决方法是加自定义词典。我在脚本里维护了一个基金专用词表:
货币基金 现金管理 活期理财 快速赎回 零钱理财把这些词设成不可拆分词汇,jieba在分词时会优先把它们当作完整词输出。
停用词表同样重要。我在统计初始结果里看到“的”“了”“是”这类无意义虚词占了好大权重,挤占了关键词的排名。我准备的停用词集合包括常见的中文虚词,以及基金文本里的通用前缀,比如“有限公司”“股份”“简称”这类无信息量词。
3.3 核心代码:从清洗到词频统计
完整流程分四步:读取数据、拼接文本、分词过滤、统计输出。
import jieba import pandas as pd from collections import Counter # 1. 读取清洗后的基金数据 df = pd.read_csv("wechat_currency_funds_20260607.csv") # 2. 拼接每只基金的文本字段 text_data = [] for _, row in df.iterrows(): text = " ".join([ str(row["fund_name"]), str(row["fund_fullname"]), str(row["manager"]), str(row["product_desc"]) ]) text_data.append(text) all_text = " ".join(text_data) # 3. 加载自定义词典和停用词表 jieba.load_userdict("fund_dict.txt") stopwords = set() with open("stopwords.txt", "r", encoding="utf-8") as f: for line in f: stopwords.add(line.strip()) # 4. 分词并过滤停用词 words = jieba.lcut(all_text) filtered_words = [ word for word in words if word.strip() and word not in stopwords and len(word) >= 2 ] # 5. 统计词频 word_counts = Counter(filtered_words) top_20 = word_counts.most_common(20) for word, count in top_20: print(f"{word}\t{count}")运行之后输出会直接打印Top20词和对应次数。为了后续出图,我把结果保存成了表格:
pd.DataFrame(top_20, columns=["word", "count"]).to_csv("word_freq_top20.csv", index=False)3.4 词云生成与基础可视化
词云是直观展示词频分布的好工具,两块代码就够:
from wordcloud import WordCloud import matplotlib.pyplot as plt wc = WordCloud( font_path="C:/Windows/Fonts/msyh.ttc", background_color="white", width=800, height=600, max_words=100 ) wc.generate_from_frequencies(dict(word_counts)) plt.imshow(wc) plt.axis("off") plt.show()注意中文词云必须指定字体,否则输出是方框。我这边用的微软雅黑,Linux环境可以换成思源黑体。
柱状图我也画了一张,展示Top20词的频次对比。柱状图的优点是能看出频次的递减梯度:有些词遥遥领先,有些词半斤八两,这种分布结构比词云更有量化意义。
4. 统计结果解读:从词频看低收益货基特征
4.1 Top20词汇概览
统计完48只基金的名字、全称、管理人和简介,Top20词汇如下(按频次降序排列):
| 排名 | 词汇 | 频次 | 排名 | 词汇 | 频次 |
|---|---|---|---|---|---|
| 1 | 货币 | 48 | 11 | 管理 | 41 |
| 2 | 基金 | 48 | 12 | 现金 | 38 |
| 3 | 有限公司 | 45 | 13 | 保险 | 35 |
| 4 | 证券 | 44 | 14 | 投资 | 33 |
| 5 | 银行 | 44 | 15 | 收益 | 33 |
| 6 | 资产管理 | 43 | 16 | 赎回 | 32 |
| 7 | 快速 | 42 | 17 | 交易 | 30 |
| 8 | A类 | 35 | 18 | 份额 | 29 |
| 9 | C类 | 13 | 19 | 美元 | 20 |
| 10 | 活期 | 42 | 20 | 余额 | 19 |
几个直观结论已经出来了。
结论一,这批低收益货基的名字高度标准化。48只基金全都包含“货币”和“基金”两个词,这不意外,货基的产品类型决定了命名规则。真正有价值的是后面的“证券”“银行”“资产管理”——这说明管理人多是银行系资管和券商系基金公司。
结论二,“快速”“赎回”“活期”这类词频次很高。低收益货基的文案非常强调流动性,“快速赎回”意味着拿钱快,“活期”暗示随取随用。这符合货基的产品定位,但也能看出一个问题:当收益没有竞争力时,产品营销不得不主打便利性,这是基金公司应对收益下行的常用策略。
结论三,“美元”这个词意外进入Top20。这是因为48只基金里有几只QDII货币基金,名字里包含“美元”,这类基金用美元计价,收益结算是另一套体系,把它们混在人民币货基里统计会让词表出现“混血词”。我后来把QDII样本单独拆出来重新跑了一遍,词频排名更干净。
4.2 公司层面:同一管理人旗下多只产品上榜
按manager字段聚合,48只基金只来自7家基金公司。其中一家公司独占14只,另一家独占11只,两家合计超过样本总数的一半。
这个结果有两个解释。
第一,同一公司喜欢发多只货币基金份额。A类、C类,人民币份额、美元份额,产品线拉得很长,导致一家公司有多个基金代码进入列表。第二,当一家公司多只货基同时收益垫底,更说明问题不在单只产品,而在公司整体对流动性、投资标的券种的选择上。
词频统计里“有限公司”的频次高,本质就是因为多家基金公司在文本字段重复出现。这提醒我们:统计词汇时最好把公司名单独拆分,否则“有限公司”这种通用词会掩盖真正的公司词频差异。
4.3 “快速赎回”和“低收益”之间没有因果,但有关联
一开始我以为“快速赎回”只是营销话术,细看数据之后发现没那么简单。快速赎回功能会占用基金公司的垫资额度,管理人为了维持快速赎回的流动性,往往需要保留更多高流动性、低收益的资产,比如银行存款、存单。这些资产安全性高、变现快,但收益率比同业存单、短债要低。
所以词频统计出现“快速”42次、“赎回”32次,低收益与流动性承诺之间存在真实的业务关联。不是说“快速赎回”导致低收益,而是两者往往绑定在同一类产品上:强调极致流动性的货基,更倾向于牺牲收益换取安全资产。
这个洞察是词频表给不了的,得把词频结果和业务规则对照才能得出。
4.4 两个样本的对比拆解
从48只基金里挑两只做脱敏对比,A基金和B基金。
A基金的文本关键词是:货币、现金、活期、快速、赎回、银行、管理。全称是“某某银行现金管理货币市场基金”,看名字就知道是银行系出品,文案强调“活期+收益”,典型的路子是“既能当活期用,又能赚收益”。
B基金的文本关键词是:货币、证券、收益、交易、份额、美元。全称带有“美元”字样,是一只QDII货币基金。它的收益受美元利率影响,统计周期内人民币计价的万份收益被汇率对冲吃掉不少,所以呈现出低收益特征,但它和A基金的低收益原因是完全不同的。
这个对比显示:同样满足“每天没有生成0.01元利息”,产品之间可能毫无相似之处。所以在做词频分析之前,必须先分清楚哪些基金是“人民币货基收益低”,哪些是“外币基金汇率折算后收益低”,否则统计结果会被少数特殊产品干扰。
5. 踩坑实录与后续扩展
5.1 数据采集的坑:动态页面和字段缺失
微信理财平台的列表页是动态加载的,直接用requests抓HTML只会拿到空壳页面。我改成直接请求后端JSON接口才拿到数据,但页面上能看到“万份收益”,接口里对应字段名叫“yieldList”,不核对字段映射表根本对应不上。
另一个坑是部分基金详情页缺失近一月收益曲线,接口返回空数组。如果不对空值做处理,脚本在计算30日平均万份收益时会直接报错。我处理方式是把“空数据”的基金单独标记为“数据不足”,先排除在48只之外,复核后再决定是否纳入。
还有一点,同一只基金在不同平台上的代码可能不同。微信平台展示的“基金代码”用的是基金公司报送代码,而中登登记代码是另一套,采集时需要注意别把两套代码混在一个表里。
5.2 分词统计的坑:词典不全和停用词过猛
分词这事远没有想象中顺利。第一次跑出来的Top词里,“类”字排在第一位,原因是“A类”“C类”全被拆开了。我加进自定义词典后,“A类”“C类”被识别为完整词,但“类”本身又因为停用词列表没包含,仍然占据一定频次,最后还是在停用词表里加了“类”才算干净。
停用词表也不能加得太狠。“收益”和“赎回”这类关键词一旦进了停用词表,后面的洞察就全丢了。我建议分两版跑:第一版只过滤虚词,第二版过滤虚词加基金通用词,对比两版结果的差异,能更清楚看到哪些词是真正的区分词。
5.3 收益口径的坑:0.01元不是绝对阈值
“每天没有生成0.01元利息”这个判断看着简单,实际操作里会遇到边界情况。比如某只基金的万份收益在0.009元到0.012元之间波动,今天看是0.009,过两天可能变成0.011,用0.01做硬阈值会不稳定。
我最后的处理是把判断周期拉长到30天平均,然后剔除掉中间出现过数据断档的基金,总算得到一个相对稳定的分类。如果你也想复现这个分析,建议先定义清楚两个口径:按单日判断还是按周期平均判断,结果会差不少。
5.4 这个分析往后还能做什么
词频统计只是第一步。顺着这个思路,可以做的扩展方向至少有两个。
第一,把词频和结构化收益数据回归。现在只是看“低收益货基”的文本特征,如果拿到全市场货基的收益率和产品文本,就能建立一个文本特征与收益水平的回归模型,直接量化“快速赎回”这四个字对收益的预测能力。
第二,按管理人做聚类。把48只基金按管理人分组后,对每组内的文本做单独词频统计,能看出不同公司的文案策略差异,配合管理规模、投资品种占比,能画出一张货基产品定位图谱。
5.5 个人体会与建议
做完了这个项目,我最大的感受是:0.01元利息这个现象,看起来是平台显示精度问题,实际牵涉产品分类、计息规则、管理人策略、费率结构多个层面。词频统计只是把“看不见的文本噪音”变成“能看见的数字分布”,真正有价值的判断,还得回到业务逻辑上去解释数字。
如果你手上也有类似的问题,我的建议是不要一上来就追求大而全的模型,先把一个具体的、有限的数据集清洗干净,跑通一次词频分析,把每一个高频词都弄明白为什么会出现。48只基金够用了,搞清楚这48只,胜过糊涂分析480只。