首页 文章 精选 留言 我的

精选列表

搜索[正则过滤],共10000篇文章
优秀的个人博客,低调大师

搭建一个简历初筛AI智能体:HR同事的"第一道过滤器"

我们公司每年招聘季会收到上千份简历,HR同事光初筛就要花掉大把时间——每份简历三五分钟,看1000份就是一周的工作量,而且人看简历容易疲劳,标准前后不一致。上个月我帮HR搭了一个简历初筛智能体,把"初筛"变成了"自动打分+排序+人工复核",HR的工作量减少了大半,还减少了漏掉好简历的遗憾。这篇文章记录完整过程。

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

【Python量化选股流水线 #05】过滤阈值拍脑袋?窗口与阈值的敏感度实验

> 回看验收发现选股器整体跑输,第一反应往往是「换因子」——但很多时候问题不在因子本身,而在参数:窗口太大还是太小?Top-N 取 3 还是取 7?动量权重给 0.4 合适吗?这篇教你用参数扫描的方法,量化地知道每个参数对结果的影响方向与幅度。 ## 一、为什么参数比因子更重要(在你还没有海量数据之前) 因子研究需要长时间跨度的真实数据来验证有效性;但在数据有限的情况下,**先把现有因子的参数调到一个相对合理的区间**,比盲目堆新因子更有工程价值。 参数敏感度实验的核心思路:固定因子定义,系统性地改变窗口大小、候选数量和权重配比,用同一段历史数据跑一遍,对比平均超额。最终产出的不是「一个稳赚组合」,而是「参数-结果」的映射矩阵——让你知道往哪个方向调参数是有效的。 **本文你将得到:** 1. 二维参数扫描框架(窗口 × Top-N),输出敏感度矩阵; 2. 权重扫描框架(动量权重 0.1~0.9),找到当前样本下的相对最优配比; 3. 可直接落地的结论格式,方便写入你的策略配置文件。 ## 二、准备环境 ```bash pip install mairui pandas numpy ``` ## 三、完整代码(已实测跑通) ```python from mairui import Client import random import pandas as pd import numpy as np LICENCE = "LICENCE-66D8-9F96-0C7F0FBCD073" # 演示证书,请换成你自己的正式证书 SEED = 20260918 POOL = { "600519": "贵州茅台", "000858": "五粮液", "601398": "工商银行", "600036": "招商银行", "300750": "宁德时代", "002594": "比亚迪", "600276": "恒瑞医药", "603259": "药明康德", "600030": "中信证券", "601688": "华泰证券", "000333": "美的集团", "600900": "长江电力", } WEIGHTS = {"动量": 0.4, "低波": 0.3, "流动性": 0.3} WINDOWS = [15, 21, 30] TOP_NS = [2, 3, 5, 7] def perturb(bars, seed): rng = random.Random(seed) out = [] for b in bars: k = 1.0 + (rng.random() - 0.5) * 0.10 kv = 1.0 + (rng.random() - 0.5) * 0.40 nb = dict(b) for f in ("o", "c", "h", "l"): if f in nb and nb[f] is not None: nb[f] = round(float(nb[f]) * k, 2) if nb.get("v") is not None: nb["v"] = round(float(nb["v"]) * kv) out.append(nb) return out def fetch_bars(code): bars = Client(LICENCE).stock_history(code=code, st="", et="", period="d", dividend="f") if not bars: raise RuntimeError(f"{code} 未获取到数据,请检查证书是否有效") return perturb(bars, seed=SEED + int(code)) def to_frame(bars): df = pd.DataFrame(bars) for col in ("o", "h", "l", "c", "v"): df[col] = pd.to_numeric(df[col], errors="coerce") df["t"] = df["t"].astype(str) return df.sort_values("t").reset_index(drop=True) def factor_scores(df, w): c, v = df["c"], df["v"] mom = c.iloc[-1] / c.iloc[0] - 1 lowvol = -c.pct_change().tail(min(20, len(df) - 1)).std() liq = (v * c).tail(min(20, len(df) - 1)).mean() return {"动量": mom, "低波": lowvol, "流动性": liq} def zscore(vals): a = np.asarray(vals, dtype=float) sd = a.std() return (a - a.mean()) / sd if sd > 0 else np.zeros_like(a) def avg_return_of_picks(frames, day, window, top_n, weights): rows = [] for code, df in frames.items(): hist = df.iloc[day - window:day] rows.append({"代码": code, **factor_scores(hist, window)}) table = pd.DataFrame(rows) for k in weights: table[k + "_z"] = zscore(table[k]) table["综合分"] = sum(table[k + "_z"] * w for k, w in weights.items()) picks = table.sort_values("综合分", ascending=False).head(top_n)["代码"].tolist() rets = [] for code in picks: rets.append(frames[code]["c"].iloc[day] / frames[code]["c"].iloc[day - 1] - 1) return float(np.mean(rets)) def main(): frames = {code: to_frame(fetch_bars(code)) for code in POOL} n = min(len(df) for df in frames.values()) print(f"每只标的 {n} 条日线;扫描窗口 {WINDOWS} × 候选数 {TOP_NS}\n") all_pool_ret = [] for day in range(max(WINDOWS), n): r = np.mean([frames[c]["c"].iloc[day] / frames[c]["c"].iloc[day - 1] - 1 for c in frames]) all_pool_ret.append(r) bench = float(np.mean(all_pool_ret)) print(f"全池基准平均次日涨幅: {bench * 100:+.4f}%\n") results = [] for window in WINDOWS: days = list(range(window, n)) row_label = f"窗口{window}({len(days)}日)" for top_n in TOP_NS: rets = [avg_return_of_picks(frames, day, window, top_n, WEIGHTS) for day in days] avg_ret = float(np.mean(rets)) results.append({"窗口": row_label, "Top-N": top_n, "候选均涨": avg_ret, "超额": avg_ret - bench}) table = pd.DataFrame(results) pivot = table.pivot(index="窗口", columns="Top-N", values="超额") print("===== 敏感度矩阵(超额 = 候选均涨 - 全池基准)=====") print((pivot * 100).round(2).astype(str) + "%") best = table.loc[table["超额"].idxmax()] print(f"\n最佳组合: 窗口{best['窗口'].split('(')[0].replace('窗口', '')}, Top-N={int(best['Top-N'])}") print(f"平均超额: {best['超额'] * 100:+.4f}%") print("\n===== 权重敏感度(固定窗口=21, Top-N=5)=====") mom_ws = [0.1, 0.3, 0.5, 0.7, 0.9] weight_rows = [] window = 21 days = list(range(window, n)) for mw in mom_ws: lw = (1 - mw) / 2 ww = {"动量": mw, "低波": lw, "流动性": lw} rets = [avg_return_of_picks(frames, day, window, 5, ww) for day in days] avg_ret = float(np.mean(rets)) weight_rows.append({"动量权重": mw, "低波权重": lw, "候选均涨": avg_ret, "超额": avg_ret - bench}) wdf = pd.DataFrame(weight_rows) print(wdf.to_string(index=False)) best_w = wdf.loc[wdf["超额"].idxmax()] print(f"\n最佳权重: 动量={best_w['动量权重']}, 低波={best_w['低波权重']:.2f}, 超额={best_w['超额'] * 100:+.4f}%") if __name__ == "__main__": main() ``` ## 四、真实运行结果 ```text 全池基准平均次日涨幅: +0.1828% ===== 敏感度矩阵(超额 = 候选均涨 - 全池基准)===== Top-N 2 3 5 7 窗口 窗口15(35日) -2.49% -2.18% -1.44% -0.86% 窗口21(29日) -2.19% -1.83% -0.96% -0.83% 窗口30(20日) -1.0% -1.21% -1.19% -0.98% 最佳组合: 窗口21, Top-N=7 平均超额: -0.8342% ===== 权重敏感度(固定窗口=21, Top-N=5)===== 动量权重 低波权重 候选均涨 超额 0.1 0.45 -0.001501 -0.003328 0.3 0.35 -0.004194 -0.006022 0.5 0.25 -0.011103 -0.012930 0.7 0.15 -0.014869 -0.016696 0.9 0.05 -0.014281 -0.016108 最佳权重: 动量=0.1, 低波=0.45, 超额=-0.3328% ``` 从矩阵里能读出三个明确方向: - **Top-N 越大,亏损越小**:Top-N=7 在所有窗口下都优于 Top-N=2。这说明在这个样本上,「多买几只摊薄」比「精选少数」更稳妥——可能是因为单因子选出来的前几名波动性大。 - **动量权重越低越好**:从 0.9 降到 0.1,超额从 -1.61% 改善到 -0.33%。这说明当前样本期内动量因子反而是个反向指标,降低它的权重、抬高低波和流动性的权重,能显著减少亏损。 - **窗口 30 并没有明显优于 21**:在数据量有限的情况下,窗口加大反而减少了滚动回看天数(30 窗口只剩 20 个回看日),样本可信度下降。 > 说明:演示证书返回固定样例数据,代码用确定性扰动模拟行情起伏;换成你自己的正式证书后删掉 `perturb` 调用即为真实行情,扫描逻辑零改动。 ## 五、两个实操建议 1. **敏感度实验的价值不是「找到稳赚参数」**:在有限样本上,所有参数都可能跑输基准。实验的真正价值是告诉你「往哪个方向调是有效的」——比如这里明确告诉你「降低动量权重、增加 Top-N」是改善方向。 2. **把最佳参数写入配置文件,定期重跑**:策略参数不应该写死在代码里。把 `WINDOW`、`TOP_N`、`WEIGHTS` 抽成 JSON/YAML 配置,每个月用最新数据重跑一次敏感度实验,更新参数。 ## 六、小结与下篇预告 参数敏感度实验是量化工程中容易被忽略但回报极高的一步。它能让你在数据有限的情况下,快速排除明显有害的参数组合,把资源集中在真正有效的方向上。 **下篇预告**:《【Python量化选股流水线 #06】从候选清单到每日盯盘:流水线结果进监控看板》——把选股结果输出为 JSON 清单 + 文本看板 + 走势图,每天收盘后一键生成候选监控面板。 ## 免责声明 本文所有代码与数据仅用于技术学习与演示,不构成任何投资建议。股市有风险,投资需谨慎。 ## 代码与文档 SDK 与更多语言版本:https://github.com/MaiRuiApi

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

jpa/hibernate @onetomany 使用left join 添加多条件,可以使用过滤器filters (with-clause...

package com.ipinyou.mip.dataAsset.campaignManagement.entity; import com.ipinyou.mip.utils.NumberUtils; import com.ipinyou.mip.utils.StringHelper; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.apache.commons.lang3.builder.HashCodeExclude; import org.hibernate.annotations.Filter; import javax.persistence.*; import java.text.DecimalFormat; import java.util.HashSet; import java.util.Set; import static javax.persistence.FetchType.EAGER; import static javax.persistence.FetchType.LAZY; @Data @Entity @Table(name = "campaign_dashboard_dimension") @ToString @EqualsAndHashCode public class CampaignDashboardDimensionDo { @Id private Long id; @Transient private Double impRate = 1.0; @Column(name = "3_reach") private Double reach3; @Column(name = "1_reach") private Double reach1; private Long campaignId; @OneToMany(fetch = LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "campaign_dashboard_dimension_id") @org.hibernate.annotations.OrderBy(clause = "imp desc") @Filter(name = "dimension",condition = "dimension_type=:dimension ") private Set<CampaignDashboardDimensionDetailDo> campaignDashboardDimensionDetailDo = new HashSet<>(); } one package com.ipinyou.mip.dataAsset.campaignManagement.entity; import com.ipinyou.mip.utils.NumberUtils; import com.ipinyou.mip.utils.StringHelper; import lombok.Data; import lombok.ToString; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.OrderBy; import org.hibernate.annotations.ParamDef; import org.hibernate.annotations.Where; import javax.persistence.*; import java.text.DecimalFormat; import static javax.persistence.FetchType.EAGER; @Data @Entity @Table(name = "campaign_dashboard_dimension_detail") @ToString @FilterDef(name="dimension", parameters=@ParamDef(name="dimension",type="java.lang.String")) public class CampaignDashboardDimensionDetailDo { @Id private Long id; private Long version; private java.sql.Timestamp lastModified; private String removed; private Long imp; private Double reachRate; private String dimensionName; private String dimensionType; private Long uv; private Long click; private Double ta = 0.0; @Transient private Double impRate; @Transient private Double diffTa; @Transient private Double diffReach3 = 0.0; @Transient private Double targetTa = 0.0; @Transient private Double targetReach3 = 0.0; } many public List<CampaignDashboardDimensionDo> getCategoryData(List<String> displayType, String dimension, String source, Long campaignId) { List<CampaignDashboardDimensionDo> resultList=new ArrayList<>(); if (displayType==null||displayType.isEmpty()){ return resultList; } for (String type:displayType ){ StringBuilder sb = new StringBuilder(); sb.append("select cdd from CampaignDashboardDimensionDo as cdd left join fetch cdd.campaignDashboardDimensionDetailDo as cddd where cdd.campaignId=:campaignId and cdd.source=:source" + " and cdd.logDate=(select max(logDate) from CampaignDashboardDimensionDo where campaignId=:campaignId and source=:source and displayType=:type) and cdd.displayType=:type"); Filter filter = entityManager.unwrap(Session.class).enableFilter("dimension"); filter.setParameter("dimension",dimension); TypedQuery<CampaignDashboardDimensionDo> query = entityManager.createQuery(sb.toString(), CampaignDashboardDimensionDo.class); query.setParameter("type",type); query.setParameter("source", source); query.setParameter("campaignId", campaignId); List<CampaignDashboardDimensionDo> list = query.getResultList(); Set<CampaignDashboardDimensionDo> set=new HashSet<>(list); resultList.addAll(set); } return resultList; } 查询代码

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

ES索引模板——就是在新建索引时候指定的正则匹配来设置mapping而已,对于自动扩容有用

索引模板 扩容设计»索引模板 Elasticsearch 不要求你在使用一个索引前创建它。对于日志记录类应用,依赖于自动创建索引比手动创建要更加方便。 Logstash 使用事件中的时间戳来生成索引名。 默认每天被索引至不同的索引中,因此一个@timestamp为2014-10-01 00:00:01的事件将被发送至索引logstash-2014.10.01中。 如果那个索引不存在,它将被自动创建。 通常我们想要控制一些新建索引的设置(settings)和映射(mappings)。也许我们想要限制分片数为1,并且禁用_all域。 索引模板可以用于控制何种设置(settings)应当被应用于新创建的索引: PUT /_template/my_logs { "template": "logstash-*", "order": 1, "settings": { "number_of_shards": 1 }, "mappings": { "_default_": { "_all": { "enabled": false } } }, "aliases": { "last_3_months": {} } } 创建一个名为my_logs的模板。 将这个 本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/7837282.html ,如需转载请自行联系原作者

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

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等操作系统。

用户登录
用户注册