【完结】cyのMemo(20231231~20240208)

序言

最终,无事发生,我的跨年是在图书馆(因为我忘带卡打不开实验室门),和去年一样。其实我并不想去图书馆,但是觉得在床上跨年太颓废,找个好点的处所,至少说得过去些。人嘛,体面些,不磕碜。

我对2023年基本满意,至少比前两年要好很多,在经历越来越多事情后,对世间事物的运行规律更加清楚,对自己的未来更加明晰。大家都是资深成年人,跨不跨年又有何谓?正如我现在认为的那样,拼死拼活,爬到多高的位置,无非是换了个圈子,总有比你更强的人,如果给我重来的机会,或许本科毕业就找个活干。不如养生。



20231231

  • 吃惊地发现SXY在31日凌晨两点多竟然在淮海中路云海大厦的一间酒吧,灯红酒绿。我不是对酒吧有何偏见,但是至少在我的印象里,SXY不像是那种会去酒吧到深夜的人,我不清楚为什么,但人或许总是会变。之前跟宝玺、剑仙一起吃饭时,宝玺问你们喝酒都是为了什么,剑仙说当然是精神解脱,我不以为然,因为我喝酒都是跟最好的朋友一起吃饭才会喝。或许酒的确是有那些用途的吧。
  • 然而,LXY不仅没有感冒,而且生龙活虎地在31日清晨七点,去操场跑23.24km跨年(用时2:00:55,平均配速5’12"/km,汗颜),瞋目结舌。我知道她很猛,但没想到会这么猛。我自己最长也不曾跑过半马以上的距离,更不用说是在场地。而且31号早晨重度污染,好多跑团的活动都临时取消,真是早起的鸟儿有霾吸。我撺掇LXY一起报锡马,她要是能去,我们四五个兄弟绝对不追求成绩,主线任务就是破风带路。
  • 旧岁到此结束,无论喜怒哀乐,相信新年将有无限可能。——To you all

df.applybroadcast参数,布尔型的可选参数。当为NoneFalse时,会返回一个与原dataframe的column或index长度相同的Series。 当为True时,会返回一个index和column跟原dataframe相同的dataframe(当然结果进行了广播)。

还有一个很重要的参数raw: 布尔型。默认为False。当为False时,会将dataframe中的每一个column或每一个index上以Series的形式传到函数中(这也是常规的做法,此时逻辑是循环,通常很慢)。当为True时,则会把数据以np.ndarray的形式传到函数中,如果这个时候func用的就是numpy的函数,则执行效率会非常高。

在0.23版本以后,这个参数会被替换成result_type='broadcast',可选值包括以下几种:expandreducebroardcastNone。确定返回形式。(0.23.0以后版本才有并且只有当axis=1时这个参数才能发挥作用)

此外,apply支持位置参数agrs,和关键词参数**kwds

另外,假定X是dataframe的一列,比如每行的数值是一个列表或者np.ndarray,可以使用np.array(X)是无法将它变成一个矩阵的,得用np.stack或者np.vstack才行。


20240101

  • Happy New Year! Wish you all the best!
  • 万能的LXY终于倒下,早上说膝盖崩了,问我疼没疼,说实话,不算去年4月初意外扭脚,我已经一年半腿脚没有疼痛过了,得益于前掌跑法和力量训练(我目前的看法,不以达二级运动员为目标的跑步训练,对身体一定是利大于弊,损伤可以忽略不计,前提是训练是科学的)。
  • 我觉得现在这样也挺好,把LXY当作目标去追求,让自己能够做事更努力些,能不能追得到又有何所谓?今早打开微信想回消息时,才发现认识的这两年多,我竟只跟她单聊过三句话,第一句是默认的打招呼语句,第二句是2022年春节贺喜(我没有回复),第三句是2023年春节贺喜(我有回复),尴尬得不行,王凯再三嘱托我不要在群里聊,一定要单聊,但是你这让我怎么开得了口,唉,两年前刚认识的时候,我就知道她很NB,学习运动全能选手,所以早有自知之明,但是两年后我觉得自己似乎也可以,高低现在也能算个业余精英跑者,学习也勉强说得过去,就有些蠢蠢欲动了。
  • 我总觉得,那些单身很久的人,必定会有很突出的性格缺陷,我自己在关键问题上缺乏主见,患得患失,常为小事焦虑。因此相处需要的是理解,而不是冲动。
  • 下午场地万米,41’07"(平均心率167bpm)。似乎平常的例训,但前5000米我是穿着外套慢摇,脱了之后,后5000米用时19’50"(4’05"+4’05"+4’01"+3’57"+3’42"),顶了一波心肺强度(190bpm)。很满意的结果,至少我现在可以轻松地把5000米跑进20分,这就足够了。
    在这里插入图片描述

df = df.loc[df["列名"].str.contains("需要筛选的字符串"),:]

如果字段df["列名"]存在缺失,此法会报错。

解决方案是:在筛选中加上"na=False",这意思是:遇到非字符串的情况,直接忽略。

df = df.loc[df["列名"].str.contains("需要筛选的字符串", na=False),:]

之前说df["列名"].map有一个参数na_action可以用来简便处理缺失:

>>> a = pd.DataFrame({"a": [np.nan, "1", "2"]})
>>> a["b"] = a["a"].map(int, na_action="ignore")
>>> a["b"]
0    NaN
1    1.0
2    2.0

这是ok的,但是比如有时候你需要筛选带有特定字符串的,NaN并不能作为False处理,还是得用最一开始提到的方法。


20240102~20240103

  • 嘉伟昨晚居然一个人去听维也纳皇家乐团的跨年演出,竟然如此上流,认识这么久我都不知道。我一直觉得下半年嘉伟沉寂是因为失恋,我也有些事情想问他,所以就约了今晚一起训练。
  • 很久没有这种感觉,一天听不到消息就会些许失落,但又不肯主动去cue,昨晚快12点时LXY才冒了泡。
  • 昨晚回来去操场慢跑5000米(均配4’35"),追加20kg负重的30×8组箭步,最后冲了一个400米(1’15"),练完力量适合接一组爆发,最后放松拉伸,拉了会儿单杠,状态不错。
  • 今晚按计划约嘉伟跑课表,6k+6k节奏跑,间隔3~4分钟,嘉伟带的3’50"左右的配速(我跟嘉伟实力悬殊,嘉伟目标是帮我顶到极限,但不可否认跑前我确实觉得自己状态很好),第一组顶到5000米力竭,用时19’30"(表漂了,距离不准),当时觉得不可能坚持完第二组,第二组开始时跟嘉伟说,估计要跑一圈停一圈,结果第二组一直坚持到5000米才停下,用时19’08",比第一组还要快,我自己都震惊了,状态好的离谱,如果是全盛状态下,我极有可能破开19分。4分配终于被我彻底跨过,可以更轻松地腾跃以扩大步幅,现在就算是3’50"的配速,跑起来也相当稳,这就是腿部力量与核心力量强大后立竿见影的效果。
  • 练完我问嘉伟有没有接着谈的打算(主要一直觉得他和濛麓走的很近,他觉得濛麓很好,但听下来他似乎另有所思),我告诉他佩瑶已有新任,嘉伟很吃惊,我说新任就一棒子脸根本比不上你,她眼光真差,嘉伟估计是受刺激了,跟我分开后他居然又折道回操场干了3个1000米间歇,唉,人呐,这就是我不愿意再去触碰恋爱的原因。其实我是想顺着引出想追LXY的事,想听听嘉伟的看法,但是时间太短我没能说出口,但我觉得自己可能也真的说不出口,我不知道自己到底在想什么,自相矛盾,却又放弃不下,我觉得自己错过了一个又一个人,难道还要这样继续错过吗?我已经没有时间了。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

pandas dataframe绘图参数

DataFrame.plot(x=None, y=None, kind='line', ax=None, subplots=False, 
                sharex=None, sharey=False, layout=None, figsize=None, 
                use_index=True, title=None, grid=None, legend=True, 
                style=None, logx=False, logy=False, loglog=False, 
                xticks=None, yticks=None, xlim=None, ylim=None, rot=None, 
                fontsize=None, colormap=None, position=0.5, table=False, yerr=None, 
                xerr=None, stacked=True/False, sort_columns=False, 
                secondary_y=False, mark_right=True, **kwds)

x和y:表示标签或者位置,用来指定显示的索引,默认为None
kind:表示绘图的类型,默认为line,折线图
line:折线图
bar/barh:柱状图(条形图),纵向/横向
pie:饼状图
hist:直方图(数值频率分布)
box:箱型图
kde:密度图,主要对柱状图添加Kernel 概率密度线
area:区域图(面积图)
scatter:散点图
hexbin:蜂巢图
ax:子图,可以理解成第二坐标轴,默认None
subplots:是否对列分别作子图,默认False
sharex:共享x轴刻度、标签。如果ax为None,则默认为True,如果传入ax,则默认为False
sharey:共享y轴刻度、标签
layout:子图的行列布局,(rows, columns)
figsize:图形尺寸大小,(width, height)
use_index:用索引做x轴,默认True
title:图形的标题
grid:图形是否有网格,默认None
legend:子图的图例
style:对每列折线图设置线的类型,list or dict
logx:设置x轴刻度是否取对数,默认False
logy
loglog:同时设置x,y轴刻度是否取对数,默认False
xticks:设置x轴刻度值,序列形式(比如列表)
yticks
xlim:设置坐标轴的范围。数值,列表或元组(区间范围)
ylim
rot:轴标签(轴刻度)的显示旋转度数,默认None
fontsize : int, default None#设置轴刻度的字体大小
colormap:设置图的区域颜色
colorbar:柱子颜色
position:柱形图的对齐方式,取值范围[0,1],默认0.5(中间对齐)
table:图下添加表,默认False。若为True,则使用DataFrame中的数据绘制表格
yerr:误差线
xerr
stacked:是否堆积,在折线图和柱状图中默认为False,在区域图中默认为True
sort_columns:对列名称进行排序,默认为False
secondary_y:设置第二个y轴(右辅助y轴),默认为False
mark_right : 当使用secondary_y轴时,在图例中自动用“(right)”标记列标签 ,默认True
x_compat:适配x轴刻度显示,默认为False。设置True可优化时间刻度的显示


20240104

  • 后来下班我在群里说今晚诚信慢跑,嘉伟考完最后一门要聚餐,AK要加班,宋某直接失联,我想着这周前三天都是大强度,四五可以放松跑。但我真实目的是想试探LXY来不来跑,但是等了会儿一直没有想要的答复,只好鼓起勇气去单聊约她出来,原来她下午已经打过球(看来膝盖是真的好了),她说明天可以,但是生理期,只能诚信慢跑,这就触及我的知识盲区了,为了让她信服我的诚信,今晚特地去跑了一个5’34"/km配速的6.66km(平均心率142bpm,说实话,这么慢的跑着真累),顺带打电话跟医生老妈请教了一下这个生理期的问题,老妈非常耐心地给我科普了一下常识,说我真是个睿智,生理期都不懂,白活这么大。
  • 李乐康元旦去日本,为的是第100回箱根驿传,他到现场观战,人非常多。发了几张照片给我们看,热血沸腾,日本高校长跑精英的那种极致力量感,要知道中国的万米和半马国家记录放在日本这些前十的高校里,连它们参赛队伍的平均水平都比不上(人均万米28分台),这还只是他们的大学生,并非最顶尖的职业选手。今年青学(不是网球王子的青学)刷新大会新,以及5区的区间新被两次刷新(山神降临),10年7冠,重回王座,往路3个区间赏,1个区间新,也算是第100回箱根驿传之圆满,要知道复路的7区天降暴雨,极其恶劣的条件下都刷新大会记录,抛开民族情节不谈,小日本真的令人震撼。
    在这里插入图片描述

Seaborn绘图记录:散点图

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid") #这是seaborn默认的风格

#scatterplot参数
seaborn.scatterplot(x=None, y=None, hue=None, style=None, size=None, 
data=None, palette=None, hue_order=None, hue_norm=None, sizes=None, 
size_order=None, size_norm=None, markers=True, style_order=None,
 x_bins=None, y_bins=None, units=None, estimator=None, ci=95, n_boot=1000, 
 alpha='auto', x_jitter=None, y_jitter=None, legend='brief', ax=None, **kwargs)

x,y:横纵轴数据
hue:具体用以做分类的列,如'event', 'day'
data:是你的数据集,可选;
style:绘图的风格,如'time', ''event'
size:绘图的大小,可以直接设置为'size'
palette:调色板,如可以设置为palette=["b", "r"]
markers:绘图的形状,如可以设置为['o', 'x'],其实就是点的形状
ci:允许的误差范围(空值误差的百分比,0-100之间),可为‘sd’,则采用标准差(默认95);
n_boot(int):计算置信区间要使用的迭代次数;
alpha:透明度;
x_jitter,y_jitter:设置点的抖动程度。


20230105

  • 晚上按约定陪跑LXY,12.38km,1小时5分,均配5’18"。从头聊到尾(很难想象女生能这种配速跑这种距离,还是生理期,还特么能说话,我因为要克制住速度,跑到最后都僵硬了,累得不行),出于隐私考量,我就不写具体内容,因为以她的性格,真的可能只是无意地说出那些暗示性极强的话。我并没有流露太多信号,依然是站在普通朋友的立场上说话做事,因为我并没有真的下定决心,虽然我很想更进一步,最后在学校已经没有多少时间,想还能留下一段回忆。
  • 跑完回实验室打了个电话给妈妈,想到经年种种,难以置信地,我竟然哭了出来。等我开始写这段话的时候,又觉得自己很幼稚得可笑。
  • 都说爱的是一个,成家立业的又是另一个,但这并不意味着前者是没有意义的。我跑了4年步,被父辈祖辈质疑了4年,从当年体测1000米在及格线上挣扎的人,到如今万米破40分,5000米19分台(预计可破19分),勉强也算个业余精英,结识了一群志同道合的朋友和一两个能交心的挚友,前几天我在回翻自己之前的朋友圈,几乎全部都是跑步,尽管我第一个10km就跑到了49’50",那时觉得自己多么厉害,但现在看起来又多么弱小。坚持许多年做一件事情怎么会没有意义呢?这些年,它本身就是意义。
  • 我不知道,我真的不知道,但我真的很想知道。罢了。

小技巧:发现函数的参数定义可以这样写:

def f(*a, b, c, d, **e):
	print(a)
	print(b)
	print(c)
	print(d)
	print(e)
f(1, 2, 3, b=1, c=2, d=3, e=123, f=342, h=324)

如果想禁用位参(即强制调用时必须注明名参的名字),可以这样写:

def g(*, a, b, c): ...

这样的情况调用函数g必须使用:g(a=1,b=2,c=3)的形式,如果写成g(1, 2, 3)则会抛出异常

TypeError: g() takes 0 positional arguments but 3 was given

20240106

  • 早上AK五点半去世纪公园进行NIKE黑马训练营的训练,3’43"均配跑了20km,太可怕了,今早上海全境重霾,肉眼可见的污染。
  • 下午按计划与嘉伟进行20km拉练(预定配速4分整),没想到嘉伟竟然6000米就不行了,很罕见(4分配对他来说就是很简单的有氧跑)。他下场后我顶到8000米,平均配速3’58",很吃力,感觉可以顶到10km,但绝对坚持不到20km。还好LXY过来(昨晚她是说要来凑个热闹),准备跟她摇完最后12km。
  • 我本以为LXY昨晚跟我跑12km,而且是生理期,今天怎么也不至于还能跑这么多。结果今天跑的比昨天还猛,我4’57"的配速跑了10km,腿已经完全抬不动,她却依然游刃有余,最后几圈她看出我体力不支(确切地说,是腿力不支,心率都掉到135bpm了,体能是绝对够的,现在的短板是大腿力量),提出让她来跑外道,我跑内道,我一脸???,最后她又是一共跑了12km,均配5分整,真给我整不会了。
    在这里插入图片描述
  • 这两天跑的太多,约定明天就不跑了,下周再约。跑完拿两个垫子一起拉伸会儿,女生身体是真的很柔软,脸都能压到腿面上。离开后跟着走了一段,今天比昨晚走得长些(再往前应该就没有一起走过路)。年纪大了,不想像年轻人那样搞些幼稚俗气的操作,在这个互相试探的过程中逐渐摸索,但自己还是处于信息的劣势方,她问了我一些,包括我的恋爱史(我只是说自己是分手后才加入田径队),我也主动说了一些,我却似乎问得很少,该从何问起,如何问起,感觉上她很有可能到现在都没有过一次恋爱,这让我极其费解,可能就像胡哥跟我说的那样,女生太优秀就是这样吧。如果真是第一个吃螃蟹的人,我也怕被夹到舌头,唉。

关于tokenizer添加special_token的问题:

from transformers import BertConfig
from transformers import BertTokenizer
from transformers import BertModel

model_name = "hfl/chinese-roberta-wwm-ext/"
model_dir = "models/pretrain_models/" + model_name

config = BertConfig.from_pretrained(model_dir)
model = BertForMaskedLM.from_pretrained(model_dir)
tokenizer = BertTokenizer.from_pretrained(model_dir)

add_tokens = ["[desc]", "[title]"]
tokenizer.add_tokens(add_tokens)                                #返回一个数,表示加入的新词数量(2)

special_tokens_dict = {'additional_special_tokens': add_token}. # add_special_tokens 传入是一个key为additional_special_tokens的dict
tokenizer.add_special_tokens(special_tokens_dict)               # 效果与add_tokens等价

model.resize_token_embeddings(len(tokenizer))                   # 关键步骤,重新调整所有的向量数量,即vocab size
tokenizer.save_pretrained(model_dir)                            # 将当前tokenizer保存本地,实现保留增加[token]。

20240107~20240108

  • 凯爹问我要SXY的wx,我有些不解,他说为了扩大社交圈,中金那边认识的人太少了,我觉得也没啥不方便的,只是已经一个多月没联系过。凯爹叮嘱我不要去联系SXY,我思来想去,他们搞行研的自己扯吧,我也不掺和啥了。我也吃不准SXY,保不齐她还在看我写的东西。
  • 昨天去小姨家大补,七点到实验楼陪AK爬楼3组(1~15层,他干了10组,我因为前两日量太大,走路都累,休一日)。回实验室后突然觉得烦躁,因为一天没有听到LXY的消息,不平静,在日记本上划拉好久,暗示自己平复下来,拖到最后直到零点把论文投掉才离开。心真乱了,太差劲太差劲,这么多年一点长进都没有,还是这个老样子。
  • 万幸没失眠(把自己逼到极限,就不会失眠),一觉醒来依然精力充沛,九点整打个早卡,本想晚上早些回去,可是下午下雨,LXY说七号楼11~23点停水,所以下午去健身房跑步顺带洗个澡窝宿舍里了,不过晚上回来操场也不开放,只是连食堂都不开是真难受。只得出去觅食,回来到实验楼负1层3000个跳绳+200个双摇,回去再补核心训练,群里大伙儿也没闲着(除了已经躺了半个月的宋某),雨天也有三位都在环校跑步。
  • 真好,以前我们只是各自在跑,现在将这些水平尚可的人聚集起来(可惜女生太少,但苛求女生跑步确实很难),相互激励,这个冬天过去,整体实力一定会有进步,现在连zjc都能4’26"配速跑完16km,开春万米跑进42分应该问题不大。我现在对自己的目标是开春万米破39分,5000米破18分半(自以为是可以达到的,因为我现在比之前训练要科学规律得多)。一定要控制饮食,保证高质量睡眠,每年年后水平都是暴跌,今年难得有正当理由挨到除夕再回家,七天之后就可以返回上海,一定要把过年这个发福期扛过去,以最全盛的状态迎接上半年比赛。

余弦学习率(torch文档—余弦相似度衰减学习率torch文档—余弦相似度衰减学习率):

转自:https://zhuanlan.zhihu.com/p/261134624

torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=-1, verbose=False)
optimizer (Optimizer) – Wrapped optimizer.
T_max (int) – Maximum number of iterations.
eta_min (float) – Minimum learning rate. Default: 0.
last_epoch (int) – The index of last epoch. Default: -1.
verbose (bool) – If True, prints a message to stdout for each update. Default: False.

CosineAnnealingLR比较简单,只对其中的最关键的Tmax参数作一个说明,这个可以理解为余弦函数的半周期.如果max_epoch=50次,那么设置T_max=5则会让学习率余弦周期性变化5次.

在这里插入图片描述
max_opoch=50, T_max=5👆


20240109

  • 为了和LXY更进一步,我让老妈把我三年前买的羽毛球拍寄过来(这当时买来想跟前任打的,结果一次没打苟在角落吃灰,如今物是人非)。晚上下班去取球拍,回来和LXY先约跑10km(今天有电灯泡,虽然是大一小朋友,但也使我没能说上几句话),跑完我提议让她教我打会儿羽毛球(我说公司明天有羽球社团的活动,说实话,我这句话99%都是真的,周三真的羽球社活动,但我并不去参加,虽然之前颜烨确实邀请过我),她没有拒绝,便一同前往羽毛球房练了会儿。
  • 还好,我的羽球技术比想象得要稍好些,之前是真碰不到球,但这次打了两三回后反手基本上都能接到,但是正手真的拉胯,一直打到最后都很难连续接到两个正手,根本碰不到球,掌握不到要领。
  • 后来分别后,我返回操场取水杯,嘉伟和AK刚下班回来练,我拦住嘉伟,赏了他一片苹果,并向他透露我想追LXY的事,嘉伟似乎早已了然,我知道瞒不过他,所以只告诉他一人(也是跑圈里我最信任的兄弟),让他帮我保守秘密,这样可以避免一些不必要的麻烦,最重要的是,让我不是孤军奋战,能多架僚机。
  • 嘉伟告诉我,LXY前天刚拉了一个四人小群去打羽毛球(嘉伟、韬哥、古丽),我回想那天是周日,确实是约定不跑,这样看起来她最近也找不到人打球。但怎么说呢,今晚也有让我很失落的时段,人的心态每一秒都会发生变化,最忌急于求成,一定要沉住气,凡事缓图,太容易得到也难以学会珍惜,慢慢来吧,没有什么事会一帆风顺,一定一定平常心。

CosineAnnealingWarmRestarts

torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0, T_mult=1, eta_min=0, last_epoch=-1, verbose=False)

这个最主要的参数有两个:

T_0:学习率第一次回到初始值的epoch位置
T_mult:这个控制了学习率变化的速度
如果T_mult=1,则学习率在T_0,2T_0,3T_0,…,i*T_0,…处回到最大值(初始学习率)
5,10,15,20,25,…处回到最大值
如果T_mult>1,则学习率在T_0,(1+T_mult)T_0,(1+T_mult+T_mult**2)T_0,…,(1+T_mult+T_mult2+…+T_0i)*T0,处回到最大值
5,15,35,75,155,…处回到最大值

在这里插入图片描述
T_0=5, T_mult=1👆

在这里插入图片描述
T_0=5, T_mult=2👆

所以可以看到,在调节参数的时候,一定要根据自己总的epoch合理的设置参数,不然很可能达不到预期的效果,经过我自己的试验发现,如果是用那种等间隔的退火策略(CosineAnnealingLR和Tmult=1的CosineAnnealingWarmRestarts),验证准确率总是会在学习率的最低点达到一个很好的效果,而随着学习率回升,验证精度会有所下降.所以为了能最终得到一个更好的收敛点,设置T_mult>1是很有必要的,这样到了训练后期,学习率不会再有一个回升的过程,而且一直下降直到训练结束。


20240110

  • 早上不到七点,LXY又在群里摇人晚上跑(起的真早,昨天还在群里唠嗑到11点半之后),我知道晚上很冷,希望她下午有太阳时去跑,会舒服些。不是我不想晚上回来陪她跑,也不是想偷懒(周三本来是就是跟嘉伟跑课表),而是,一来我觉得没必要每天跑10km,这太伤身,何况女生(当然今天跑完我觉得她可能真的是身体比我还好,这话我收回),二来就是没必要每天都见面,因为总有一天会见不到的,浇些冷水对我是好事,得到时有多欣喜,失去后就有多失落,何况八字还没一撇,根本就未开始。
  • 后来晚上我下地铁给LXY发消息,外面真的很冷,没必要勉强出来跑,但她坚持要跑,还要拉上古丽,我说人家必不可能出来,没人会跟你一样发神经(这么冷的天跑步不是发神经?),最后古丽确实没来,当然我也不希望她来。
  • 所以今晚跑得很舒服,一来跑得很慢,5’37"配速的10.65km,也没电灯泡,可以轻松聊天,我连风衣都没脱,聊了学校很多过去的事情(作为这个学校的老住客,很怀念过去的生活),各自导师派的烂活,以及最近有趣的事,不涉及敏感话题,说起来就很轻松。她下周四就要回家,回家之前要先跟同学出去玩两天,我说你去哪儿玩,她说去合肥,我说去合肥也能叫出去玩嘛,就像我去南京,那不就串个门,好像没出省,但又好像出了省,所以我很少去南京。
  • 跑完拉伸,前两天没拉伸搞得我小腿胀,今天拉完一下子好多了。一起走到七号楼分别,LXY问我明天还跑吗,我说你来我就来,她说那就老时间。
  • 那就一起呗,趁你还在学校,一周时间,我也不知道会发生些什么。这辈子最错误的事,就是在2021年5月1日丧失理智,Bad End,乃至消沉数月,而最正确的事,是在2021年10月2日加入田径队,收获如此多朋友,以及交心的挚友,我不知道还能否收获学生时代尾声上的伴侣,但是无论成败,或许那天我只是心血来潮,但如今回看,一切又是那么命中注定。

所以可以看到,在调节参数的时候,一定要根据自己总的epoch合理的设置参数,不然很可能达不到预期的效果,经过我自己的试验发现,如果是用那种等间隔的退火策略(CosineAnnealingLRTmult=1CosineAnnealingWarmRestarts),验证准确率总是会在学习率的最低点达到一个很好的效果,而随着学习率回升,验证精度会有所下降.所以为了能最终得到一个更好的收敛点,设置T_mult>1是很有必要的,这样到了训练后期,学习率不会再有一个回升的过程,而且一直下降直到训练结束。

import torch
from torch.optim.lr_scheduler import CosineAnnealingLR,CosineAnnealingWarmRestarts,StepLR
import torch.nn as nn
from torchvision.models import resnet18
import matplotlib.pyplot as plt
#
model=resnet18(pretrained=False)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
mode='cosineAnnWarm'
if mode=='cosineAnn':
    scheduler = CosineAnnealingLR(optimizer, T_max=5, eta_min=0)
elif mode=='cosineAnnWarm':
    scheduler = CosineAnnealingWarmRestarts(optimizer,T_0=5,T_mult=1)
    '''
    以T_0=5, T_mult=1为例:
    T_0:学习率第一次回到初始值的epoch位置.
    T_mult:这个控制了学习率回升的速度
        - 如果T_mult=1,则学习率在T_0,2*T_0,3*T_0,....,i*T_0,....处回到最大值(初始学习率)
            - 5,10,15,20,25,.......处回到最大值
        - 如果T_mult>1,则学习率在T_0,(1+T_mult)*T_0,(1+T_mult+T_mult**2)*T_0,.....,(1+T_mult+T_mult**2+...+T_0**i)*T0,处回到最大值
            - 5,15,35,75,155,.......处回到最大值
    example:
        T_0=5, T_mult=1
    '''
plt.figure()
max_epoch=50
iters=200
cur_lr_list = []
for epoch in range(max_epoch):
    for batch in range(iters):
        '''
        这里scheduler.step(epoch + batch / iters)的理解如下,如果是一个epoch结束后再.step
        那么一个epoch内所有batch使用的都是同一个学习率,为了使得不同batch也使用不同的学习率
        则可以在这里进行.step
        '''
        #scheduler.step(epoch + batch / iters)
        optimizer.step()
    scheduler.step()
    cur_lr=optimizer.param_groups[-1]['lr']
    cur_lr_list.append(cur_lr)
    print('cur_lr:',cur_lr)
x_list = list(range(len(cur_lr_list)))
plt.plot(x_list, cur_lr_list)
plt.show()

最后,对scheduler.step(epoch + batch / iters)的一个说明,这里的个人理解:一个epoch结束后再.step, 那么一个epoch内所有batch使用的都是同一个学习率,为了使得不同batch也使用不同的学习率 ,则可以在这里进行.step(将离散连续化,或者说使得采样得更加的密集),下图是以20个epoch,每个epoch5个batchT0=2,Tmul=2画的学习率变化图


20240111

  • 昨晚LXY在群里口无遮拦(我跟胡哥说我这个冬天跑得多些是因为今年想干个全马,她回复我满足你,直到下周四我回家,天天缠着你10k),虽然她行事作风一向不把自己当女生,但是落在我身上还是很胃疼(在我和她圈子的交集里,除AK我是没有竞争对手的,但AK是95年的,又是云南人,而且AK的圈子可太大了,我觉得不太可能;她也一样,除非她觉得婷玉姐是对手,但LTY那段位我根本不敢碰,但更多的可能是她仅仅想找个人跑步而已),她前脚在群里说完,住隔壁的胡哥就跟我说,这不得和妹子有点情况,还跑啥锡马,找个半马带她冲啊!我本想瞒着,但是毕竟男人太懂男人,何况还是扬州老乡,当面我也扯不下脸撒谎,只能实话实说。
  • 胡哥说他一眼就看出我想追LXY,说我表现得太明显,最早最早听我提到LXY时就感觉到了(说实话,那时只是仰慕,并没有想过追),当时刚过零点,我也要睡了,不想深夜跟胡哥掰扯太久,想等下次有机会再细说。
  • 我依然没有十足的把握,但我还是决定抽时间写封情书,虽然很俗套,但我喜欢这么做,讲道理我们这个年纪,说喜欢二字多少显得有些幼稚,但能怎么办呢?除此以外我也不知道该说些啥。如果要出手,就只有这个周末,因为下周四LXY就要回家,错过就要等到年后,我怕的不是夜长梦多(她能母胎solo到现在,就能solo得更久),而是她若无意,毕竟跟她交集的圈子里有这么多人在看着,虽然现在已知的只有嘉伟和胡哥知道,我怕自己再也混不下去了。
  • 后来晚上下班,LXY跟我说被导师薅去干活,但这是好事,最近一周几乎每天的活动消耗都到了1000卡以上,腿真有些受不了,而且浇点冷水也好。回来之后到底还是有些失落,想找人陪我去练羽毛球,问了胡哥、安迪、嘉伟、宋某都不方便,悻悻然去羽毛球馆拦了两个男的折磨,第一个我特意给他先送了瓶果汁,防止他嫌我菜,还是陪我打了好久,第二个觉得我实在太菜,打了四五个就走了,太真实了。看到大家都打的那么上手,我一个人去馆后的空排球场,对着视频教程练接球,练发球。我一定要把羽毛球练好[苦涩]。
  • 我想着下学期能白天陪她打打球多好,唉,我根本就是个体育白痴,身体协调性从小就差,运动会永远的观众,广播体操天天被老师留下来纠正,只有从2020年初开始跑步,靠日复一日的碰壁、反省、改进,花了整整四年才达到如今的水平,我以为自己能做到一切,但我已经没有时间了。

torch自定义反向传播:https://zhuanlan.zhihu.com/p/359524837

我们实现一个 a + b a+b a+b的tensor求和cuda算子,于是我们可以利用它来实现 L = a 2 + b 2 \mathcal{L}=a^2+b^2 L=a2+b2,最终训练收敛后 a a a b b b都会趋近于 0 0 0,模型没有输入,只有两个可训练的参数 a a a b b b

功能是搭建了一个PyTorch模型,并且调用了自定义的cuda算子,实现了自定义的反向传播函数,最终完成训练。

首先定义模型

class AddModel(nn.Module):
    def __init__(self, n):
        super(AddModel, self).__init__()
        # tensor长度
        self.n = n
        # 定义可训练参数a和b
        self.a = nn.Parameter(torch.Tensor(self.n))
        self.b = nn.Parameter(torch.Tensor(self.n))
        # 正态分布初始化参数a和b
        self.a.data.normal_(mean=0.0, std=1.0)
        self.b.data.normal_(mean=0.0, std=1.0)

    def forward(self):
        # 求a^2与b^2
        a2 = torch.square(self.a)
        b2 = torch.square(self.b)
        # 调用自定义cuda算子对两个平方数求和
        c = AddModelFunction.apply(a2, b2, self.n)
        return c

20240112

  • 六点醒来,失眠,是近几个月来第一次失眠。昨晚10.55离开实验室时,给LXY发消息,直到我睡下都没收到回复,我突然有些担心,因为不至于这么早睡觉,也不至于在导师家忙到通宵,害怕是否在路上出事。我醒来就看到她六点回复的消息,虚惊一场。
  • 昨晚回三门路,还是把情书写完(现在字写得勉强还说得过去),不管用得到用不到,先备在身上。结果LXY早上继续约我晚上七点跑,而且她一大早环校跑5km,把昨天的量补了,是真的恐怖。
  • 后来我想到她很喜欢吃栗子,我五点溜出去买了一袋,发现路边摊的真不行,糖炒栗子竟然不够甜,还是上美团又点了一份,把情书直接塞进去。我决心不当懦夫,懦夫了这么多年,必须莽一回,炸就炸了,今晚就出手,不折磨自己了。
  • 大约是搞砸了吧…[哭泣]
星雨:

已识二年有余 却似如初见

两年前 你是完全陌生
一年前 你是令我仰慕
而如今 你是无法言说

其实我很孤僻 囚生 笼中鸟 八年未改
直至进队许久 与人熟络 方豁然开朗

我知晓 在此年岁 枉言喜欢 难免些许幼稚

然 慢热如我 八年财大 繁花落尽
直至与我一同走过的 都一一离去

我不愿再错过 写下此页 谨表吾意

阳

20240113

  • 今天下午约了嘉伟进行1600米×6的间歇,预定配速是340,结果嘉伟第一组冲到330,第一组即力竭,最后我一共跑了3组1600米和3组1000米,间歇4分钟,其中第5组1000米顶到3’23",估计现在体测1000米的是能跑到满分线3’15"的。
  • 昨晚之后一直没有消息,其实我并不急,感觉还是做得太草率了,每次都是这样,后知后觉,莽起来没脑子,怂起来没血性。后来在实验室跟朋友扯到快12点才走,朋友跟我扯了半天倒是让我轻松了许多,我知道昨晚不会有结果,我估计LXY应该会今天过来给我当面审判,死猪不怕开水烫,回去洗洗早睡了。
  • 结果还是太尴尬,下午跑完一起去吃了饭,回来路上还是没有说出口,我估计她也没有准备好,到最后还是在版聊解决问题(srds,我算是被发了张好人卡吧…),女生总是要更理智一些(虽然算半个工科男,但我感觉自己很多时候是很感性的),脑袋一拍就容易草率。但今天唯一的遗憾,是按道理周六我要去蜀地源大吃一顿,结果只是跟吃了碗牛肉刀削,没过瘾,但也吃不下更多了,罢了,就当这周省个饭钱呗。
  • 结局:normal end,无事发生,这样也挺好,谈恋爱确实很累,彼此都轻松些也是好的,正如12月9日那天的想法,多个朋友总是比多个npy好。

实现自定义cuda算子前向和反向传播
下面就是如何实现AddModelFunction.apply()函数了,我们先来看一下具体代码:

class AddModelFunction(Function):
    @staticmethod
    def forward(ctx, a, b, n):
        c = torch.empty(n).to(device="cuda:0")

        if args.compiler == 'jit':
            cuda_module.torch_launch_add2(c, a, b, n)
        elif args.compiler == 'setup':
            add2.torch_launch_add2(c, a, b, n)
        elif args.compiler == 'cmake':
            torch.ops.add2.torch_launch_add2(c, a, b, n)
        else:
            raise Exception("Type of cuda compiler must be one of jit/setup/cmake.")

        return c

    @staticmethod
    def backward(ctx, grad_output):
        return (grad_output, grad_output, None)

这个类继承的是torch.autograd.Function类,我们可以用它来实现一下无法自动求导的操作,比如arxmax这种不可导的函数。


20240114

  • 中午找嘉伟陪我练球,免费陪练,还不嫌我菜。嘉伟先花20分钟喂我正手发高远球,我连续六七次碰不到,嘉伟没疯我都快疯了。后来发现,得有个参照物,把左手举起来瞄准球,就能比较好的正手打中,虽笨但管用;然后发现反手又碰不到球,又花20分钟喂我反手。太稳了,每周末找练一次,争取速成。
  • 晚上跟LXY跑完10k,浓雾加大风,现在我竟然觉得一天一个10k是很普通的事,有人一起确实轻松许多,可惜这样的好日子无多。消耗很大,所以我还是出去把昨晚没吃的蜀地源补了,468g肉+370g菜,外加2碗饭,再一瓶可乐,每周一次放纵,反正吃不胖,就硬造。
  • 很纠结,我有些后悔让更多人知道这个地方。以前也有这种情况,那时我会选择不写,但是过一段时间又憋得慌。我本意是在清净之处留下些活过的痕迹,但后来发现这也是一种很重要的潜在沟通渠道,但是不再想让更多的人知道此处。
  • 我越来越觉得自己最近一段时间变了许多,变成自己以前讨厌的样子,对如今的行事风格很陌生,但又不想再变回去,唉。

把之前积累的7000多条GPT4响应的HotpotQA多跳问题的回答过了一遍,还是有明显错误的结果。

但是我发现有明显的问题答案给错了,比如5a879ba55542993e715abfc3,5ae1f596554299234fd04372,而且这种都是典型的错误,即打标注的人被混淆了,比如后者:

context:
    "2008 Summer Olympics": "The 2008 Summer Olympic Games, officially known as the Games of the XXIX Olympiad () and commonly known as Beijing 2008, was a major international multi-sport event that took place in Beijing, China, from 7 to 24 August 2008.
	A total of 10,942 athletes from 204 National Olympic Committees (NOCs) competed in 28 sports and 302 events (a total of one event more than the schedule of the 2004 Games).
	China became the 22nd nation to host the Olympic Games and the 18th to hold a Summer Olympic Games.\n It was the third time that the Summer Olympic Games were held in East Asia and Asia, after Tokyo, Japan, in 1964 and Seoul, South Korea, in 1988.",
	
    "Summer Olympic Games": "The Summer Olympic Games (French: \"Jeux olympiques d'\u00e9t\u00e9\" ) or the Games of the Olympiad, first held in 1896, is an international multi-sport event that is hosted by a different city every four years.

	The most recent Olympics were held in Rio de Janeiro, Brazil.

	The International Olympic Committee organizes the games and oversees the host city's preparations.

	In each Olympic event, gold medals are awarded for first place, silver medals are awarded for second place, and bronze medals are awarded for third; this tradition began in 1904.

	The Winter Olympic Games were created due to the success of the Summer Olympics.",

question: When did the game which held three times in  in East Asia first held 

label: 1896
gpt4: The game which held three times in East Asia was first held in 1964.
cot: The context mentions that the 2008 Summer Olympics was the third time the Summer Olympic Games were held in East Asia and Asia, after Tokyo in 1964 and Seoul in 1988. Therefore, the first instance of the game being held in East Asia was in Tokyo, 1964.

这个明显就是标签打错了,大模型的结果和论据都是完全正确的。

就目前来看,几乎可以认为gpt4的输出结果就是黄金标准,看下来hotpot还是太脏了,这是dev集上的案例,检查发现gpt4至少有5%的结果和给的答案不匹配,但这里面绝大多数都是答案本身有问题。

另一个问题就是hotpot几乎是强制的extractive形式的回答,这个并不好,因为很多时候答案未必是可以抽出来的。23年ACL还有人在做同时输出答案和推理过程(还只是很简单的推理过程,即论据发现)的工作,之前肯定是有人做过的,所以如果真的能做出输出cot的小型生成模型,一定是巨大的创新。‘


20240115

  • 算了,该写啥写啥,我不能因为有人可能会看,就刻意改变自己的内容。
  • 晚上状态很好,因为今天慧悦不在,中午实打实地睡了一个小时,我有点想一个人好好练会儿,最近几乎全是慢跑,量比以前多,但强度太低。后来还是被LXY叫去一起跑了会儿,我当然很高兴,只是担心她是照顾我的情绪所以叫我一起跑,其实没啥必要,想打球就去打呗,每个人都应该有自己隐私的空间,何况现在也并没有所谓约束。
  • 她俩走后,我自己冲了5圈4分配,回实验室后,还是决定不去羽毛球馆了,一来实在没必要给自己找不自在,眼不见心不烦,二来在实验室吹空调不香嘛,非要出去挨冻。本来我是真想跟DGL菜鸡互啄一下,毕竟能找个水平相当的对手不容易(不过实际情况很有可能是我比DGL还要菜…),最后还是打消了这个念头,以前总给自己找不自在,现在多一事不如少一事,明智些,少做无意义的事,好好跟嘉伟把球练起来就完了。
  • 看到WXY新发的pyq,总觉得他是消沉许久,近期又幸福了起来。多年不见,依然很羡慕他这样干净清澈的眼神。
  • 明天我亲爱的宋某终于回来,已有20多天没见,还以为年前再不能一睹芳容,但是,作为见面礼,我要趁他初愈,好好拿捏一下,以后不一定有机会[奸笑]。

https://zhuanlan.zhihu.com/p/666671956

LinearFunction反向传播源码详解

class LinearFunction(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input: Tensor, weight: Tensor, bias: Tensor) -> Tensor:
        # input -- [B, M]  weight -- [N, M]  bias -- [N]
        output = input @ weight.T + bias[None, ...]
        ctx.save_for_backward(input, weight)
        return output  # [B, N]
    
    @staticmethod
    def backward(ctx, grad_output: Tensor) -> Tuple[Tensor, Tensor, Tensor]:
        # grad_output -- [B, N]
        input, weight = ctx.saved_tensors
        grad_input = grad_output @ weight
        grad_weight = grad_output.T @ input
        grad_bias = grad_output.sum(0)
        return grad_input, grad_weight, grad_bias

# 对LinearFunction进行封装
class MyLinear(torch.nn.Module):
    def __init__(self, in_features: int, out_features: int, dtype: torch.dtype) -> None:
        super().__init__()
        self.in_features = in_features
        self.out_features = out_features
        self.weight = torch.nn.Parameter(torch.empty((out_features, in_features), dtype=dtype))
        self.bias = torch.nn.Parameter(torch.empty((out_features,), dtype=dtype))
        self.reset_parameters()

    def reset_parameters(self) -> None:
        torch.nn.init.uniform_(self.weight)
        torch.nn.init.uniform_(self.bias)
    
    def forward(self, input: Tensor) -> Tensor:
        return LinearFunction.apply(input, self.weight, self.bias)  # 在此处使用
  1. LinearFunction需要继承自torch.autograd.Function,并且需要实现forward和backward两个静态方法,注意是静态方法!
  2. forward输入的第一个参数都是ctx,后跟前向传播所需要的一个或多个输入,可以是任意类型的参数。输出也可以是一个或多个的任意类型结果。
  3. backward的输入输出类型的要求也和forward一样,但是数量是和forward有对应关系的,不能随便想怎么写就怎么写。上面代码中,backward的输入grad_output,对应了forward的输出output的梯度;输出grad_input, grad_weight, grad_bias则分别对应了forward的输入input、weight、bias的梯度。这很容易理解,因为是在做链式求导,LinearFunction是这条链上的某个节点,输入输出的数量和含义刚好相反且对应。
  4. ctx就是在此处只承担的一个功能(当然还可以有其他功能,详见官方文档),通过ctx.save_for_backward在forward中保存下来backward需要的变量,然后通过ctx.saved_tensors在backward中提取出这些变量。
  5. LinearFunction的使用不是直接调用forward,backward,而是调用LinearFunction.apply(input, weight, bias)。推荐如以上代码所示,封装进torch.nn.Module的子类。

20240116

  • 到胃的一晚,3k@3’54" + 5k@5’00" + 4k@3’55" + 30个×8组箭步(20kg负重),其实不算累,感觉上休息得很好,但今天回来身体电量只剩33,最后的力量做得还是很极限,虽然又被宋某鸽,也算是很尽兴。最近强度一直不够,接下来又要连日下雨,趁着这两天天气好,赶紧把强度堆点儿起来。
  • 中间5k是在陪胡哥慢跑,按约,把最近的事说了些,胡哥也谈了自己的经历,听来也是一番波折。胡哥毕竟长我两岁,都是以结婚为目的去谈,而我潜意识里可能没有那么强的目的性,尤其是在经历过一次之后,一谈就成几乎是童话中的桥段,但别人或许并不这么想。
  • 也罢,顺其自然。昨晚跟老妈长聊一个小时,向她详细介绍了我圈子里几个重要的朋友,以及我自己对当下和未来的看法,能感觉到老妈很欣慰。但我却对一些问题愈发困惑,周五约了许久不见的老友吃饭,我想听些不同的答案。

我最近发现了一个非常奇怪的BUG,我先把案例放出来,因为我也不知道怎么解释这个问题:

比如你在外部写一个文件temp.txt,里面只写一行内容:

{1: np.nan}

然后你用下面这段代码去读它:

import pandas as pd

df = pd.read_csv("temp.txt", sep='\t', header=None)

df.columns = ["col_1"]

print(type(df["col_1"][0]))

df["col_1"] = df["col_1"].map(eval)   # 不报错
df["col_1"] = df["col_1"].map(lambda x: eval(x)) # 会报错

print(df["col_1"][0][1] == df["col_1"][0][1])

即直接使用df["col_1"] = df["col_1"].map(eval)是不报错的(注意,我没有import numpy as np,所以第二个df["col_1"] = df["col_1"].map(lambda x: eval(x))就报错了,但第一个就不报错)

我现在无法解释这两种写法的区别是什么,但是这个情况实在是太奇怪了。如果我把temp.txt里的内容改为

{1: numpy.nan}

则两种写法都报错(前提是不import numpy),如果有人知道原理是什么,请务必告诉我。


20240117

  • 最后还是把3.31芜湖马拉松(10km组)报上了,一来万一扬马跳票,给自己多留个选择,虽然很想那天回家把主场半马刷个好成绩,尤其是去年扭伤硬扛了2个多小时才走完全程,很感人但更丢人;二来或许到3月底这段时间还会发生些什么呢,尽管大老远出省跑个10km性价比有些低,但到时候要是想去却去不了可多难受。
  • 这两天不知道为什么很累,作息几乎没有变化,可能是破事多了些,下班身体电量都只剩35(过往都能有50上下),今晚也是陪安迪热身时就觉得身体很沉重,但是预定是要跑间歇(力量训练后,适合间歇将力量释放出来,这是东哥说的,我觉得很有道理),临时改为变速12×(400米@1’30"+400米@2’30")。
  • 第一组跑慢,后面拉了点起来,基本上快圈都在1’24"以内,这个区间很舒适,反正顶完400米就能很舒服地慢慢颠,痛苦不会持续很久(想想周末1600米间歇是真的痛苦,明明1圈就不行了,还要再硬顶3圈),但成功干爆了宋某和安迪,安迪跟了10组,宋某跟了不到4组就吐了,回首不堪往事,真有被爽到。
  • 跟宋某聊了些,总是需要摸索生活交集的均衡点,每个人都有自己生活,没有必要非得硬融进去,但又很难忍住完全不过问。反正明早LXY回家玩儿了,解脱,万事年后再说。翻日历发现竟然还有三周才过年,特么现在就不想上班了,好难好难坚持这种生活和训练强度,尤其时年关将近,太容易松懈,一定要把冬训坚持下来。

关于df.stackdf.unstack重提,每次都分不清,想用都要回头查:

这个问题只要记住下面这一个例子就完事了:

df = pd.DataFrame({
    "index_1": ["a", "a", "a", "b", "b", "b"],
    "index_2": ["score_1", "score_2", "score_3", "score_1", "score_2", "score_3"],
    "count": [1, 2, 3, 4, 5, 6],
    "percent": [.1, .2, .3, .4, .5, .6]
})

df = df.set_index(["index_1", "index_2"])

"""
                 count  percent
index_1 index_2                
a       score_1      1      0.1
        score_2      2      0.2
        score_3      3      0.3
b       score_1      4      0.4
        score_2      5      0.5
        score_3      6      0.6
"""

stack的操作会让索引多一级,一般来说我们不会搞这种操作,因为多重索引不是我们想要的,上面构造的是一个二级索引表,所以一般的操作是通过unstack把它变成一级索引的形式,这样更好看一些:

df.unstack()

"""
          count                 percent                
index_2 score_1 score_2 score_3 score_1 score_2 score_3
index_1                                                
a             1       2       3     0.1     0.2     0.3
b             4       5       6     0.4     0.5     0.6
"""

这里会有个衍生的小问题,就是上面这个结果其实是带多级表头的,多级索引很多好办,直接reset_index(level=None, drop=False)这样就能一级一级的拆出来,而多级表头比较麻烦,不能很好地拆出来,但我们可以:

import pandas as pd
 
# 创建包含多级表头的DataFrame
data = {'A': [1, 2], 'B': [3, 4]}
index = ['Group A', 'Group B']
columns = pd.MultiIndex.from_tuples([('Header 1', 'Subheader 1'), ('Header 1', 'Subheader 2')])
df = pd.DataFrame(data=data, index=index, columns=columns)
print("原始DataFrame:\n", df)
 
# 获取第一级表头的值
first_level_headers = df.columns.get_level_values(0).tolist()
print("\n第一级表头的值:\n", first_level_headers)
 
# 获取第二级表头的值
second_level_headers = df.columns.get_level_values(1).tolist()
print("\n第二级表头的值:\n", second_level_headers)

来获取每个层级地值,但的确不太好把它们拆出来,除非是用df.T把索引和表头交换,然后reset_index,感觉很笨。


20240118

《癸卯年腊八 · 人去冬雨至》
广厦寰宇水濛濛,扁舟一叶探萍踪。
腊香不掩凭阑意,青衫湿处别恨浓。
一梦一醒一夜终,一叹一咏一枯荣。
待至三月花开日,归燕南飞喜相逢。

  • 冬雨初至,人未至,两周寒潮,不是很能提起兴致,各种意义上日子都挺难过。差不多有一年没有写过诗,现在性情变太多,说实话很讨厌现在的自己,但不想也再不能改得回去了。
  • 晚上回来先跟DGL打了40分钟羽毛球,很舒服,突出一个菜鸡互啄,但她还要比我强一点点,但只要别阴我,打个十几个来回还是可行的(现在反手高远球也能比较好的打上了),但是被一个不到一米六的小姑娘打得四方乱跑,实在是丢人…
  • 打完很高兴,羽球就是要手感,多打就能上手,回去要跟AK爬楼,结果乐极生悲,手机一摔,屏幕失灵,只得冒雨赶去五角场万达华为店(没有地图还绕了些路,好在凭靠第六感找到店),结果这儿也没维修部,重买了部新的(本来旧机也用了三四年,不心疼)。老妈说你爹年会刚中个奖,就给你败家败掉了,特么用的又不是你的钱,真的是。

一个ECHART画计图的demo,宝玺姐是真麻烦,既要又要,跟甲方提要求画一个正方形的圆一样。本子就那么大,还想画得又复杂又好看,受不了了。

<!DOCTYPE html>
<html>
<head>
    <title>ECharts 关系图</title>
    <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
    <!-- use from online-->
    <script src="https://cdn.bootcss.com/echarts/4.1.0.rc2/echarts.js"></script>
    <!-- use from local-->
    <script src="/static/js/echarts.min.js"></script>
</head>
 
<body>
<div id="main" style="width:1000px;height:800px"></div>
<script type="text/javascript">
    var myChart = echarts.init(document.getElementById('main'));
    var categories = [];
    for (var i = 0; i < 2; i++) {
        categories[i] = {name: '类目' + i};
    }
    option = {
        title: {text: 'ECharts 关系图'}, // 图的标题
        tooltip: {formatter: function (x) { return x.data.des;}
        },// 提示框的配置
        
        toolbox: {
            show: true,
            feature: {
                mark: {show: true},
                restore: {show: true},
                saveAsImage: {show: true} // 保存为图片
            }
        }, // 工具箱
        legend: [{
            // selectedMode: 'single',
            data: categories.map(function (a) {return a.name;})
        }],
        series: [{
            type: 'graph', // 类型:关系图
            layout: 'force', //图的布局,类型为力导图
            symbolSize: 40, // 调整节点的大小
            roam: true, // 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启
            edgeSymbol: ['circle', 'arrow'],
            edgeSymbolSize: [2, 10],
            edgeLabel: {
                normal: {
                    textStyle: {fontSize: 20}
                }
            },
            force: {
                repulsion: 2500,
                edgeLength: [10, 50]
            },
            draggable: true,
            lineStyle: {
                normal: {width: 2, color: '#4b565b'}
            },
            edgeLabel: {
                normal: {
                    show: true,
                    formatter: function (x) {return x.data.name;}
                }
            },
            label: {
                normal: {
                    show: true,
                    textStyle: {}
                }
            },
            data: [{name: 'node01', des: 'nodedes01', symbolSize: 70, category: 0,},
                {name: 'node02', des: 'nodedes02', symbolSize: 50, category: 1,},
                {name: 'node03', des: 'nodedes3', symbolSize: 50, category: 1,
            }, { name: 'node04', des: 'nodedes04', symbolSize: 50, category: 1,
            }, { name: 'node05', des: 'nodedes05', symbolSize: 50, category: 1,
            },{name: 'node06', des: 'nodedes06', symbolSize: 50, category: 2,}],
            links: [{source: 'node01', target: 'node02', name: 'link01', des: 'link01des'},
                {source: 'node01', target: 'node03', name: '数字经济', des: 'link02des'
            }, {source: 'node01', target: 'node04', name: 'link03', des: 'link03des'
            }, {source: 'node01', target: 'node05', name: 'link04', des: 'link05des'
            }, {source: 'node06', target: 'node04', name: 'linkcat2', des: 'linkcat2'}
            ],
            categories: categories,
        }]
    };
    myChart.setOption(option);
</script>
</body>
</html>

20240119

  • 不算颜烨和王凯这两位老搭档,SXY已经是我认识最久的朋友(没有之一),而且是唯一能算得上是朋友的异性,而困扰我的问题正在于此。
  • 晚上按约和SXY在芳甸路搞了顿火锅,如果我没有记错的话,这应该是我俩认识四年多来第二次吃饭,上一次在去年三月,近一年的时间,SXY似乎没有变化很多,还是那老样子,但我或许变了太多。这次很舒服,至少比上次要舒服得多,上次很不自然(因为觉得自己乳臭未干,而她已经快要毕业工作,所以大部分时间都是听众),但这次几乎没有什么可顾忌的事,也把想问的事给说出口了,答案在意料之中,凡事实际问题实际考虑,总是很难绝对地去评判,我困扰是因为上一段昙花一现的感情就败在这里,但总觉得有个异性朋友也无不合理,我真是不想就这么断弃,本来就没有几个能算得上是朋友的人,有个互相比较了解的老朋友,又是半个老乡,真的很不容易。
  • LXY离校后,我也不想去叨扰,她的生活肯定要比我丰富得多,我做好自己的事就完了,万事等年后再说,年前主线任务就是水论文+训练,如果上半年要跑全马,无非是南京和苏州里选一场,那都是后话了。
  • 今日跑休,明天计划进行长距离拉练,我最近状态很好,但是天气很差,如果明天上午世纪公园的训练取消,就下午找时间自行拉练,需要来一场30K探探底,雨不停就去打球(会打球真是件好事,可以对冲下雨的风险)。

排序函数:

df_name.sort_values(by, column_name, axis=0, ascending=True, inplace=False, kind=’quicksort’, na_position=’last’, ignore_index=False, key=None)

一列升一列降:

df_name.sort_values(by column_name, axis=0, ascending=True, inplace=False, kind=’quicksort’, na_position=’last’, ignore_index=False, key=None)
# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@163.sufe.edu.cn

import os
import pandas as pd


# 将所有的结果输出到同一文件(方便复制到EXCEL)
def out_to_the_same_file(root = "分类汇总"):
	strings = []
	filenames = []
	for filename in os.listdir(root):
		filepath = os.path.join(root, filename)
		with open(filepath, 'r', encoding="utf8") as f:
			strings.append(f.read())
	with open("comb.txt", 'w', encoding="utf8") as f:
		f.write("\n\n".join(strings))

# 将所有的结果输出为可以直接复制到EXCEL中标准格式的代码()
def formatter_content(root = "分类汇总"):
	_orders = ["gender", "age", "city_level", "income", "huko",
			   "new_citizen", "education", "occupation",
			   ]
	_key_value = {_key: _value for _value, _key in enumerate(_orders)}
	def _key(_filename):
		_filename = _filename[:-4] # 扔掉最后的.csv

		for _order in _orders:
			if _filename.endswith(f"_{_order}"):
				return _key_value[_order]
		assert False, _filename	# 没有匹配到结果,抛出异常

	cur_suf = None
	cur_filenames = []
	for filename in os.listdir(root):
		suf = '-'.join(filename.split('-', 2)[:2])	# 这个就是题号,必然唯一
		if cur_suf is None:
			cur_suf = suf
			cur_filenames.append(filename)
		elif suf == cur_suf:
			cur_filenames.append(filename)
		else:
			cur_suf = suf
			cur_filenames = sorted(cur_filenames, key=_key, reverse=False)
			print(len(cur_filenames))
			print('\n'.join(cur_filenames))
			print('-*' * 16)

			views = [] # 同一道题不同的视图列表
			for i, fname in enumerate(cur_filenames):
				fpath = os.path.join(root, fname)
				with open(fpath, 'r', encoding="utf8") as f:
					df = pd.read_csv(f, sep='\t', header=[0, 1], index_col=0)
				view = df["percent"] # 我只要百分比
				views.append(view)
			views_row = pd.concat(views, axis=1)
			views_row.to_csv(f"{cur_suf}.csv", sep='\t', header=True, index=True)
			cur_filenames = []
formatter_content()

20240120

  • 早上耐克训练不出意外地被取消,嘴上说不早起但还是定了闹钟,血亏。AK因为下午要年会,提前11点出去路跑30km,配速4’08",底蕴太厚,就这么加班,周六一觉起来还是这么猛。不过,我最近状态确实也很好,周一跟LXY跑完最后一练,周二周三立即换上大强度(体能+力量+变速),周四周五半练半休(下雨,羽球+爬楼),身体已经恢复得极好,感觉上30km应该是能下得来的。
  • 午睡起来,精神饱满,虽天气不佳,但无碍,环校10圈,25km(最难跑的是20号楼后面那段,风太大),基本上保持了4’20"的配速,中间只在20km处停了一次(到实验楼小解并补了点水),本来是觉得一定可以撑下来最后10km(4圈),但到第10圈后半程时明显感觉大腿不支,加上时至傍晚,气温降了很多,北风起,雨势渐长,不想强迫自己,就到此为止。整体上跑完比较舒适,腿没有不适,回实验室拿了张床垫吹着空调拉伸较长时间就完全恢复了。感觉上如果天气好,这个状态是可以顶完全马的,但无论如何,至少现在的水平是比之前任何一个时点都要显著高了许多。
  • 晚上直接放开吃!!!
    在这里插入图片描述

多记一个自动求导的例子,我发现其实之前写MRR的时候,对于ARGSORT的操作,其实近似的结果误差是可能会很大的,结果就是LOSS完全掉不下来,不知道该怎么处理:

y = 10 × ( x 1 + x 2 − 5 ) 2 + ( x 1 − x 2 ) 2 y=10\times(x_1+x_2-5)^2+(x_1-x_2)^2 y=10×(x1+x25)2+(x1x2)2

import torch
from torch import nn

# y = 10*(x1+x2-5)^2 + (x1-x2)^2
class Func(nn.Module):
    def __init__(self, size=2):
        super(Func, self).__init__()
        params = torch.rand((size,1),requires_grad=True)
        self.params = nn.Parameter(params)
    
    def forward(self, inputs):
        y = inputs[0] * torch.pow(self.params[0]+self.params[1]-inputs[1],2)\
        + torch.pow(self.params[0]-self.params[1],2)
        return y

class cusLoss(nn.Module):
    def __init__(self):
        super(cusLoss, self).__init__()
    
    def forward(self,y_pred, y_true):
        return torch.abs(y_true-y_pred)

model = Func(size=2)

optimizer = torch.optim.AdamW(model.parameters(),lr=1,weight_decay=1e-5)
loss_func = cusLoss()
x = torch.tensor([10,5])

for i in range(400):
    y_pred = model(x)
    loss = loss_func(y_pred,0)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    print("loss: ", loss.item())

for item in model.parameters():
    print(item)

20240121

  • 更阴间的天气,还好昨天没偷懒。午饭后找嘉伟练了1小时球,包场,一点半来了个不会打球的胖子,给嘉伟好好上了一课,嘉伟反手被压得惨不忍睹,每次救完后场想回中就被压,不回中就被放短,杀又杀不死,屁股都给打抽筋了。羽球说到底就是要能打得远,低质量近场球没有生路,业余场真的是一力降十会,自己平时手腕到大臂完全练不到,一点儿不会发力,过来的高远球怎么都打不回后场,好菜。
  • 下午在图书馆看了会儿书,想想真是羡慕王凯,就连二战的时候他都会每天坚持看哲学书,我真的从大学之后就再也没有看过书。但是,现在又能理解,哲学反而确是最有用的,知识的说教,奇幻的故事,都已无用,实体书确实能给到更坚实的信仰与观念,是更好的指导。
  • 招行满4减2的优惠还不结束,看来这学期吃食堂的人是真的少,库存用到现在还有结余,以前一般不满2个月就提前结束。从11月1日开始,我几乎一天不落地薅过来(一天两次,因为中午吃不到,所以只能早晚,现在连晚上都吃不到了,所以直接早上买两份),不过真也是多亏这活动,肯定不会每天都这么勤快地去学校吃早饭…

关于networkx画图的layout

import os
import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei']

from collections import Counter

df = pd.read_csv("../graph.txt", sep='\t', header=None) # 这个文件每行就是\t分割的两个词

G = nx.DiGraph()          # 无多重边有向图
for i in range(df.shape[0]):
    G.add_edge(df.loc[i, 0], df.loc[i, 1])  # 添加一条边
nx.draw(G, with_labels=True)

这个所有的layout可以用:

for i in dir(nx):
    if "layout" in i:
        print(i)

记几个比较特色的布局展示:

默认随机布局:
在这里插入图片描述

nx.draw(G, pos=nx.circular_layout(G), with_labels=True)

在这里插入图片描述

nx.draw(G, pos=nx.kamada_kawai_layout(G), with_labels=True)

在这里插入图片描述

nx.draw(G, pos=nx.planar_layout(G), with_labels=True)

在这里插入图片描述

nx.draw(G, pos=nx.shell_layout(G), with_labels=True)

在这里插入图片描述
刚好跟circular是反过来的

nx.draw(G, pos=nx.spectral_layout(G), with_labels=True)

在这里插入图片描述

nx.draw(G, pos=nx.spiral_layout(G), with_labels=True)

在这里插入图片描述


20240122

  • 我决定要首马破三,很疯狂,强如AK和嘉伟,首马不过257和259,但说句不要脸的,今冬厚积薄发,感觉破三已不遥远。
  • 昨晚饭后,冷,但还是去操场看看,有段时间不一个人摇,不习惯,踱了半圈,没有动力,偶遇倒三角大哥(在跑129的30km课表),起兴,4’45"的配速边跑边聊了会儿,原来是本家,同济博士,目前也是冲击破三,5000米后大腿稍许发酸,不再勉强。去年七月尚不如他,然今非昔比。
  • 近两三月,饮食、睡眠、训练趋于规律,每周1次力量和1-2次变速间歇,加上一月初两周养生10K,现在体能很好。手表目前预测是全马3小时9分。而前天的25K拉练,寒风细雨,也能连续2小时在接近破三的配速下,保持上身稳定和步伐轻盈。单论大腿与核心力量应该在嘉伟之上(只是体重远在嘉伟之上…),嘉伟上马前始终觉得短板在体能,所以疯狂堆跑量(连续几日20K以上,真很伤,按理当时他的水平稳开255,可冲250),而我现在觉得全马的一切都可以归结于心肺和力量,破三配速(4’15"/km)下心率不算高(约165bpm),而力量提升可以显著提高对乳酸的耐受能力,最直接的感受是大腿灌铅的时间大大减缓(我每次耐力训练都是大腿先扛不住,可能是体重的原因,但不想减,70kg刚刚好,男的太瘦实在不好,不精神)。
  • 翻了些陈年旧账,地铁上仔细分析了一下过去两个月的人和事,以及说过的话,觉得自己想得太简单,而且想太多,缺乏自知之明。但将来的事很难讲,我也不是一个喜欢做长远计划的人,总之走一步看一步呗,时间会见证一切,年纪越大,越难强求。
  • 跑休,下班去小姨家吃点儿好的,放在往年,现在该圆滚滚咯。

开三小时会(浪费三小时人生),感觉经济学研究,有些画靶射箭,用到的机器学习方法滞后,说作模型解释,但这么多年,也没人深入。如今风头偏转,还有人拿激光剑打原始人,拿GPT4跟RNN作对比(https://arxiv.org/abs/2312.08317),总之记一下AT那边的团队都想做啥吧:

  1. 小微借贷(平台)对金融包容性的影响研究
  • 群体:女性、农村、教育程度低、未注册个体户
  • 数据来源:调研数据、体系内数据
  • 阿里关心的是监管的问题,大数据风控问题是黑箱子,不清楚
    • 助贷、联合贷,不安全(与银行)
    • 乡村振兴
  • 阿里风控:
    • 机器学习模型判断
    • 策略,规则判断
    • 几乎没有真人来判别
    • 预授信额度,根据还款情况,经营情况进行改变
    • 监管关心的风控只看结果
    • 风控模型没有透露出来(防止被反控)
    • 北大IMF:小微贷款可控性,自己定义(假设)很多变量来进行判别对比
      • 模型一样,数据不一样,对比传统银行和蚂蚁业务风控模型
      • 数据一样,模型不一样,对比传统银行和蚂蚁业务风控模型
      • 但这样做很难发好刊
  1. 人机融合的借呗贷款批准研究
  • 外部冲击对机构投资者和个人投资者的冲击不同
    • 散户可能不会走,虽然金额小,但是规模大,所以会有个缓冲
    • 散户行为一致,从众心理,不动则都不动,否则一拥而散
  1. 无感积分对支付宝用户黏性作用的研究(公司很关心,且很少人做的题)
  • 无感积分:是一种便捷的积分获取方式,它允许消费者在购物中心或其他商圈内通过移动支付快速获得积分,整个过程不需要额外的操作。
    • 是直接积分到对应的商场或其他消费场所,然后可以抵扣一些消费(比如停车费)
    • 其实可能是无所谓微信或者积分,都是可以在对应的商场攒到积分的
    • 先发优势,微信先搞的无感积分,支付宝后面也开始做了
  • 这是个有差异化的研究,需要和业务对一下,看看是否能够提供类似的数据(这个数据的本质来源应该是商场,而非支付宝)
    • 只要知道支付宝和哪些商场在何时进行合作的
    • 比如支付宝上,用户点开“一点万象”小程序的数据是否有日志记录
    • 这个研究是董事长关心的,因为用户黏性是战略性问题
    • 注意:必须在业务在推进时进行研究,否则业务不鸟你
  1. 游戏化机制对用户消费的影响研究
  • 常态化的游戏(蚂蚁财富小游戏、蚂蚁森林小游戏、好友互动的游戏)、阶段性促销的游戏活动(余额宝之类)、季节性游戏(集福)
  • 老师主要指:蚂蚁森林、芭芭农场(这个是蚂蚁和淘宝互通的)、淘宝的数据(但蚂蚁和阿里完全切流,支付宝拿不到淘宝的数据)
  • 研究动机:
    • 淘宝上的游戏可能更促进消费
    • 蚂蚁上的游戏可能更偏于公益
  1. 移动支付对小微企业/个人行为的影响研究
  • 二维码支付的信用溢出作用:
    • 比如银行不给无记录的人贷款,但是支付宝可以提供一些信贷记录来使得银行给这些人从0到1,再从1到N
  1. 蚂蚁森林对用户绿色环保行为的影响
  • 目前平台上已经有20多个和蚂蚁森林相关的课题
  1. 理财行为对个人消费行为的影响
  • 理财行为
  • 房地产价格的变动,对消费行为的影响
    • 比如房价上升10%,所以觉得赚到了,可能会去消费,但是房子不会立即出卖,因此需要消费信贷来解决
  • 用户的理财行为、支付宝细类数据
  • 结论:财富效应,理财行为加剧了非理性消费,是不好的,但在学术上很喜欢
    • 监管很关注花呗对大学生、甚至更小的学生非理性消费的问题
    • 蚂蚁对此出台了很多相应的产品,改善这种现象
  • 波动上涨与平稳上涨对财富效应的效应(行为经济学)
  • 消费类型:
    • 生存型消费:衣食住行
    • 发展型消费:学习、运动
    • 享受型消费:娱乐
  • 这个应该说的是西财数据
    • 预测资产?
    • 在预测中,引入因果视角
    • 在信息不全(如缺乏资产数据)的情况下,这个其实是半监督、弱监督学习
      • 反事实推理、因果学习
    • 疑问;调研数据拿到的数据
      • 房产证、资产信息证明,很难较准
      • 问卷无偏?万分之五的回收率(已经是在)
      • 模型内部纠偏(防止问卷调研本身带来的偏差)
  1. 联合订阅对用户接受度的影响分析
  • 爱奇艺订阅,爱奇艺和其他平台(淘宝、腾讯之类的)一起订阅(典型的比如在移动流量套餐)
  • 免费用几个月,再联合订阅,再变成单一订阅,看看是否能够促进用户进行
  • 关键点:支付宝能够查阅到的这个问题
  • 但问题是有可能是忘记关自动订阅,结果就是
  • 需要挑一些联合订阅的事件,然后从历史记录上扒扒看是否有一些记录看得到

20240123

  • rebuttling… 这次coling小分给的最高的reviewer,summary分给的最低,别人都是刀子嘴豆腐心,就他豆腐嘴刀子心,下手真特么狠。
  • 西湖,故事旧缘处,记忆的起点。但不想去瞎凑热闹,纯找不自在,不过这条标毅线确实不错,26k爬升1300米,路线很美,以后越野赛前的热身候选。安迪是杭州人,他告诉我西湖边上还有更长的43k超毅线,跨年时浙大甚至有人开发一条100k的超长越野线,强悍。
  • -4℃,晚上跟安迪慢摇了10k,恢复状态,其实并不冷,我只穿了一件卫衣和一条西裤,5’07"的配速,一路说话,平均心率才142bpm。但后面做箭步的时候手指头真冻掉了,戴手套都不管用,做了4组(×30)后实在痛苦,把铃片搬去大活,吹着暖气补到9组,差强人意。
  • 跟安迪聊下来,越来越觉得杭州是个好地方,我一直有种感觉,就是上海金融化太深,太务虚(其实北京也是同理,只是非金融),核心技术还是集中在杭州、深圳这些地方,关键那边房价好低,听说安迪阿里总部附近的房价都跌到2w多,而且基础设施建得很好,除了教育资源相对紧俏。确实没得非要往上海这围城里钻,但谁又知道杭州何尝不是一座围城?一切都变化得太快,难以预料。

ax v.s. plt

fig = plt.figure(figsize=(6,4))
ax = fig.add_subplot(2, 3, 1) # 2行,3列,左上角

# 具体而言:
# Three integers (nrows, ncols, index). 
# The subplot will take the index position on a grid with nrows rows and ncols columns. 
# index starts at 1 in the upper left corner and increases to the right. 
# index can also be a two-tuple specifying the (first, last) indices (1-based, and including last) of the subplot, 
# e.g., fig.add_subplot(3, 1, (1, 2)) makes a subplot that spans the upper 2/3 of the figure. 

ax和plt的区别在于很多函数都要加`set_`,plt直接`xlabel, ylabel, title`即可
```python
ax.set_xlabel('...')
ax.set_ylabel('...')
ax.set_title('...')
# 这样也是一种方法,但我觉得画的没上面好看
fig, ax = plt.subplots(2, 2)
plt.subplots_adjust(hspace=1, wspace=0.5)

20240124

  • 今天有点不太想写(以前也不是每天线上写,只是最近有兴致,但每天一定会写纸质,这个是一定不会断的),但是接连写许久,不想就这么断弃,以后我也想回头再看看这段时间的心态变化,如今已很平静了,有些想出去玩,真的好久不出去玩,这周不行,下周只放一天,再下周就过年了,唉。年后有空一定要去爬个山练练手。
  • 下班抓不到人,遂独自黑练,变速12组×(600米快+200米慢),12月19日也是这组训练(与AK一起,不过更冷,-2℃,跑完AK就感冒发烧),但今天完成质量更高,前7组600米全部跑进2’05",后5组也只1组掉出2’10",很满意。我深信继嘉伟破三后,下一个一定是我,一定。
  • 有点想入门AutoCAD,很喜欢这种机械绘图,真是不务正业。

今儿宝玺姐让我帮她写南洋理工作的一篇关于GAIC(生成式人工智能咨询,纯TM造词,有AGI,有AIGC,就没听说过GAIC,这里研究的对象是蚂蚁的投顾模型支小宝2.0)对个人投资者收益变化研究的摘要,他们方法其实很简单,就是做差分对比,一是对比同一用户使用支小宝前后的收益差异,另一个是对比同时期同一类群体下不同用户的收益变化差异,从而缓和外部变量对实验产生的偏差。后面也做了些因果分析(但我始终觉得因果分析都是锦上添花的东西,根本不能作为主要佐证)。

他们最终的结论是,支小宝有用,但对新手用处不大,反而是对老手以及高风险偏好的人能有效改善收益。当然论文一个字没提用的样本容量,我也不知道他们到底收集了多少组样本来对比,主要这个事情其实就搞得很理想化,如果是我来做这个研究,至少应该要做个A/B test(当然这个就回到上次开会说的事,得在业务在推进时提出需求,否则他们根本不鸟你),即在用户即将申购或赎回基金前,给他们提供是否进行咨询的对话框。

他们做出的主要结论是:

  1. 支小宝总体有用
  2. 对新手的收益提升用处不大
  3. 对老手和高风险偏好人群的收益提升用处更大

很容易发现,有个致命的BUG是市场本身行情,行情好的时候大家当然收益更高,且老手、高风险偏好的资金多,能实现更高的收益提升,新手反而容易犹豫把握不到时机,反之亦然。所谓的差分对比消除外部变量(如市场)的偏差太理想化,所以这个结论就显得很有偏差。无所谓,反正都是水。

算了,不搞这些没用的,记一些绘图细节:

plt也可以subplot

import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(-2 * np.pi, 2 * np.pi, 500)
y1 = np.sin(x1)
plt.subplot(1, 3, 1) # 占页面的左边1/3
plt.subplot(1, 3, (1,2)) # 占页面的左边2/3
plt.plot(x1, y1)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(-2 * np.pi, 2 * np.pi, 500)
y1 = np.sin(x1)
plt.plot(x1, y1)
plt.show()

投影与极坐标(心形图):

import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(-2 * np.pi, 2 * np.pi, 500)
y1 = np.sin(x1)
plt.subplot(1, 3, (1,2), projection='polar')
# plt.subplot(1, 3, (1, 2), polar=True) # 等价效果!
plt.plot(x1, y1)
plt.show()
  • subplot方法属于API绘图,而add_subplot方法为面向对象绘图
  • 使用subplot方法自动生产画布与轴域,而add_subplot方法需要先添加画布figure,再在画布上添加轴域,add_subplot返回的即为子图的轴域
  • 当绘制的子图之间出现遮挡,subplot方法会绘制代码位置靠后的图形,而add_subplot则会绘制所有图形,只是出现遮挡。

20240125

  • 最近咳嗽的人太多,比之前任何一个时点都要多,不仅是实验室,公司更多,我和宝玺姐已是四面楚歌,除对面的一个实习生,前后两排全是病患。昨晚下班宝玺姐就说感觉很累要感冒,但今天还能挺住,我选择去后面没人的站立工位站着码字,远离病毒。我最不能理解的是,左手边思棚哥特么咳得那么厉害,还就穿件短袖,我现在扛过两轮寒潮的冬训,自以为已是金刚不坏之躯,怎么造作都不感冒,都不敢这么穿,说川妹子有特点,川爷们儿真更是突出。
  • 本来前两天大强度,今天有点想找人打球放松一下,但AK提议进行长距离拉练,机会难得,遂与AK进行环校线(一圈2500米)拉练,计划20km@4’20"配速,但是两个人自然没有诚信可言,何况是与AK。
  • 从第三圈开始,配速就开始朝着不太正常的方向发展(是我嘴贱觉得4’20"有点轻松,示意AK可以适当加一些),10km用时43分整,心率依然没有超过160bpm,示意AK可以顶完后半程,AK很是兴奋(因为我一路手机外放音乐,AK事后表示听着音乐真舒服,完全没有疲劳感,状态爆棚),决定给我点color see see,第6圈心率突然就飙到175bpm以上,就那一瞬间突然感觉不支,顶到15km休止,用时1:04:22,均配4’17",毕竟是上一天班,状态已非完满,已是满意。
  • AK最终4’15"配速顶完20km,这对他来说确实轻松跑,我追,他逃,我被拉爆。我渴望破三,AK 3月几乎每个周末都报名了比赛,4月还有2场,或许也是想找回巅峰期的感觉,生命就是这样需要一个刺激点,才能有动力不断向前
    在这里插入图片描述在这里插入图片描述

最近看到一个移动沙发问题,上GitHub搜MovingSofa,有大概10个左右的python仓库是做仿真的,这个问题真的很有趣。

PCA示例:

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

audiometric = pd.read_csv('d:/audiometric.csv', sep='\t', header=0)
pd.options.display.max_columns = 10 # 设置pandas展示的最大列数
print(round(audiometric.corr(), 2)) # 协方差矩阵
# 热力图
sns.heatmap(round(audiometric.corr(), 2),annot=True)
scaler = StandardScaler()
scaler.fit(audiometric)
X = scaler.transform(audiometric)
# PCA
model = PCA()
model.fit(X)
model.explained_variance_ # 每个主成分能解释的方差
model.explained_variance_ratio_ # 每个主成分能解释的方差的百分比
# 可视化
plt.plot(model.explained_variance_ratio_, 'o-')
plt.xlabel('Principal Component')
plt.ylabel('Proportion of Variance Explained')
plt.title('PVE')
#主成分核载矩阵
columns = ['PC' + str(i) for i in range(1, 9)] 
pca_loadings = pd.DataFrame(model.components_, columns=audiometric.columns, index=columns)
print(round(pca_loadings, 2))
# Visualize pca loadings
fig, ax = plt.subplots(2, 2)
plt.subplots_adjust(hspace=1, wspace=0.5)   
for i in range(1, 5):
    ax = plt.subplot(2, 2, i)
    ax.plot(pca_loadings.T['PC' + str(i)], 'o-')
    ax.axhline(0, color='k', linestyle='--', linewidth=1)
    ax.set_xticks(range(8))
    ax.set_xticklabels(audiometric.columns, rotation=30)
    ax.set_title('PCA Loadings for PC' + str(i))

20240126

  • 早班地铁一个年轻妈妈在给儿子(六七岁)辅导英文读物,我闭着眼睛听都觉得好累,然后到S空间后居然18楼混进两个小屁孩,晚上回来到豫园站上来一堆娃娃,有一个哭闹了好久,不停地尖叫。我以前以为母性的存在,女性多少会对幼儿有亲近感,直到上周跟SXY吃饭,才发现身边也有这么激进的丁克。说不生是一种自私,但可能生也只是很自私地想在一张白纸上填补自己的缺憾,至少我这么想过,让他从小跟我学编程和跑步,但是他真的喜欢吗,在白纸上,其实画什么都是玷污,难以做出绝对负责、让人信服的决策。四五十年后养老业、疗养机构或许大热,但我希望到70岁依然可以精力旺盛。
  • 两点半开抢除夕票,偏偏撞上汇报,本以为只要讲十分钟,结果慧悦全让我讲,一个多小时,我边讲边抢,多线程并进,失败两次后,成功抢到学生票,时段特别好(8:25~10:18),不用早起赶车,也不用拖到晚上吃堵车,舒服!
  • 这周连续三天大强度(周二力量+周三速度+周四体能),尽管状态极好(决心破三后,不再熬夜,虽然不可能坚持六点早起,但我可以每天十二点早睡呀),腿也已经有很明显的疲劳感,跑休,正好老妈寄了羊肉到小姨家,下班去大补一顿,看看明天能否再次拿捏宋某(🍔警告)。睁开你的眼睛看看,现在到底是谁更懂间歇。

今早清华发布了GLM4的宣传片https://www.bilibili.com/video/BV1hZ4y1n74A,感觉上没有比GLM3更新多少东西,本来GLM3的主要卖点就是工具使用(Tool using),GLM4可能更多还是各维度的完善以及性能提升,至少没有GPT3到GPT4的那种惊艳程度。我现在觉得,可解释性,是阻碍AI在各领域准入的最大壁垒,我现在认可AI在各类问题解决方案上的可行性,但问题在于准入,想要100%的准确率不现实,虽然这在很多关键领域很必要的,但也许我们并不需要AI做到100%,只要他能像人一样溯源其行为的逻辑,并能够很好的纠错,这样就足够了。典型的场景,编写数据分析报告,人也可能会弄错一些数值,但可以很好的找到错误在哪儿并纠正,AI或许不会犯低级错误,但可能在一些公式使用上出错,被人类发现后,希望AI能够快速发现数值错误的原因,并加以纠正即可(这对人来说,出错也是情有可原的,包括驾驶,人也会出车祸,何必强求AI呢)。以前我们总是想去解释AI复杂网络的输出,如今或许让AI能为自己的行为做出合理的辩护更合适,这才是一个人,而不是机器。

python竟然支持中文定义变量了,查了一下发现2022年1月就有了,我居然现在才发现(我是注意到pandas的dataframe居然支持使用df.姓名这种调用,以为是pandas改进了,原来是编译器改进了)。

# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@163.sufe.edu.cn

class:

	def __init__(对象本身, 姓名, 身份证号):
		对象本身.姓名 = 姓名
		对象本身.性别 = "女男"[int(身份证号[-1]) % 2] 
		对象本身.出生日期 = 身份证号[6:14]
		对象本身.体重 = 70

	def 在蜀地源大吃一顿(对象本身, 荤菜, 素菜, 米饭):
		对象本身.体重 += 荤菜 * 0.5 + 素菜 * 0.4 + 米饭 * 0.2

囚生 =(姓名="CY", 身份证号="100000197001010001")
print(囚生.姓名)	# CY
print(囚生.性别)	# 男
print(囚生.出生日期) # 19700101
print(囚生.体重) # 70
囚生.在蜀地源大吃一顿(荤菜=0.3, 素菜=0.4, 米饭=0.2)
print(囚生.体重) # 70.35

20240127

  • 天气预报全天大晴天,结果连太阳的影子都没见着,直到下午四点半才见到些阳光。不知杭州如何,天气好景致多少好些,精神气也不一样。
  • AK历来擅长在周六一大早玩命(他跑完下午还去加班,而我早上没定闹钟美美地睡个自然醒),今早他去世纪公园完成25K变速(5K快慢交替),其中5K快的均配3’35"/km,5K慢的均配4’15"/km,3快2慢,中间不休息,令人咋舌。尤其是最后一个快5K均配3’30",你宽哥还是你宽哥,据说是过阵子要回寨子杀年猪了,先把肥减下来哈哈。
  • 所以下午我也决定试试这组训练,宋某又TM鸽我(这次的理由是空气质量不好,实话说,106的空气指数在上海已经算很好了,31号300多的重度污染不还有人一大早去跑20多公里),最后只有嘉伟来陪我,没想到嘉伟也被我拉爆了,第二个快5K跑了2圈我觉得他带的太慢,示意让我来带,结果他到一半就力不能支下场了,我独自顶完第二个快5K,心肺爆炸。最终是4’07"的均配跑完15K,其中2个快组5K的配速是3’55"/km,慢组的配速4’35"/km(主要是慢组5K完全没把心率降下来,后面第二个快5K心率直接顶上极限,再起不能,绝无可能顶到25km,跟AK差距太大,但至少目前拿捏住宋鸽问题不大,当前这个切面上只有AK能稳吃我)。
    在这里插入图片描述在这里插入图片描述

下午收到一份KBS审稿,关于Visual Emotion Analysis,突然想到确实很多很简单的NLP任务可以推广到CV,是很好的创新,因为一旦把NLP推广到CV,就会复杂(好水)很多,比如VEA就是最传统简单的情感分析的延申,但已经很复杂,因为图像的情感会受画风的影响,其实很多时候并不是那么明确的二分类,而是需要更细粒度的区分。这篇没有在细粒度上做文章,而是偏于aspect-level的情感分析,即会对图像中每一块的情感进行热力标注,最终得到一个关于整个图像的二分类的标签。但是一些太复杂的,比如VKBQA,就纯吃算力,属于是有钱能使磨推鬼,搞不起。

如果要排序dataframe的一行,请使用(下面是寻找核载矩阵前topk最大值的方法):

pca_loadings.loc["PC1", :].sort_values(ascending=False)

或者取最大值的方法(不推荐使用argmax,请使用idxmax)

pca_loadings.loc["PC1", :].idxmax()


20240128

  • 看得出来SXY走完标毅线是真的很高兴,成就感MAX。年后看看AK要不要去拉练一下,我觉得肯定能4小时以内跑完标毅,但脑回路是真对不上,唉,越野比长跑更虐,男女差距更大,没有可比性,能走完全程已经是很值得骄傲的事了。
  • 下午一点约嘉伟打球(这是年前最后一次,下周末真没几个人陪我),虽然只一周练一次,明显感觉这次已经可以和嘉伟打得有来有回了,至少DGL应该不至于还能遛得动我(真没追求…)。先上周那个不会打球的胖子友情陪我练了好久,他倒不介意我菜,先半场练,然后全场遛四方,给我整得明明白白;后来再跟嘉伟练,他就不是很容易通过调前后场和正反手吃住我,能跟他有来有回打个十拍以上,但是点杀完全反应不过来。感觉这次比上周能打得更远一些,发力的感觉找到了。
  • 连续练了一个多小时单打,累得不行,喘得上气不接下气(但心率显示都没过95bpm,而且活动消耗很低,严重怀疑是手表坏了),到两点半之后明显感觉跑也跑不动,挥拍也挥不动,但嘉伟依然体力充沛(还是我菜,没法让嘉伟动起来),于是不会打球得胖子撺掇嘉伟一起去跟边上两个校队水平的人过两招(这家伙太想进步了),结果就是俩人都被虐得很惨,人外有人,又是一周嘉伟受难记。
  • 新食堂今晚有5块钱一条的红烧草鱼,个头不小,料还足,难得良心,叫了宋鸽和嘉伟,可惜他们都不来,只好我独自炫4条。要这么卖,我能吃到食堂破产。
    在这里插入图片描述在这里插入图片描述

python函数转latex公式(有点鸡肋,但很有意思转载):

项目地址:https://github.com/google/latexify_py

!pip install latexify-py

import math  # 可选
import numpy as np # 可选
import latexify

latexify.__version__ # 0.4.2

@latexify.function
def solve(a, b, c):
  return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)

print(solve(1, 4, 3)) # -1.0
print(solve) # \mathrm{solve}(a, b, c) = \frac{-b + \sqrt{ b^{2} - 4 a c }}{2 a}

可以查看公式图片,直接输出solve即可

在这里插入图片描述

或者带上@latexify.expression修饰器也可以。

也可以绘制分段函数,即代码里是多条件分支:

在这里插入图片描述
或者矩阵运算:@latexify.function(reduce_assignments=True, use_math_symbols=True)

在这里插入图片描述
以及算法伪代码生成,使用@latexify.algorithmic修饰器,然后输出函数即可得到伪代码,这个很好用。


20240129

  • 结果芜湖3.31竟然中签了,好事还是坏事?我不知道。快两周不联系,尴尬得不行,真不好意思去问… 等扬马报名再说吧,唉,到底还是知之甚少。
  • 下班发现接下来连日阴雨,决定提前完成力量训练。但得先跑会儿热热身,虽然感觉状态不错,但是真心一点儿没想着要奔着PB去跑(要跑成绩,绝不会挑工作日下班)。计划跑4’10"/km配速,结果抬腿第一个1000米用时3’46",我就知道今晚不可能是简单热身。久病成医,场地万米成绩,从41’15"到39’45",我用了722天;从39’45"到38’08",我用了37天。
  • 5000米用时18’59",已经PB,余力尚足。其实有想过冲刺到力竭把5000米成绩刷好看些,也省时间,但想想还是留点力气冲击万米PB。后半程稍有掉速,但整体配速非常稳定,心率也顶到极限,最终以38’08"跑完场地万米,平均配速3’49",大幅PB。要好好感谢被我套了六七圈的兄弟,我每套他一圈,他就会努力跟上,虽然不到半圈就掉下去,紧接着满嘴C语言,但确实给了我很大动力,想当年我也是这么认识的王兴耀
  • 节奏好的万米跑完真的一点儿不累,跑完补了力量训练,8组×30个箭步(负重20kg)。其实现在已经基本具备破三的身体素质了,但首马破三可遇不可求,天时地利人和,缺一不可。
    在这里插入图片描述在这里插入图片描述

濛麓问我p-tuning的问题,这就是搭上快班车的好处,我现在不过也是在搞这些花样,而回想大二寒假我还在玩泥巴,噢不,在带颜老板搞美赛(也没比玩泥巴强多少是吧)。

pipreqs库不兼容python3,pipreqs ./pipreqs ./ --encoding=utf8都行不通,conda list -e > requirements.txt很好但太冗长,不符合传统格式,只能通过conda install --yes --file requirements.txt使用,但是相对稳定性好些,pip freeze > requirements.txt是传统格式,pip install -r requirements.txt

另外conda支持导出yml文件:

  • 导出:conda env export > freeze.yml
  • 安装:conda env create -f freeze.yml

没用的小知识,python区分1和True:

def judge_true(a):
	return a is True
judge(True) # True
judge(1) # False

jieba.add_word(word, freq=None, tag=None)

jieba的用户字典,词语,词频(可省略),词性(可省略),不可颠倒

add_word(word, freq=None, tag=None) method of jieba.Tokenizer instance
    Add a word to dictionary.

    freq and tag can be omitted, freq defaults to be a calculated value
    that ensures the word can be cut out.

关于pkuseg的user_dict参数:

>>> import pkuseg
>>> t = pkuseg.pkuseg(postag=True, user_dict=[("安泰管理学院", "n")])
>>> t.cut("上海交通大学的安泰管理学院")
[('上海', 'ns'), ('交通', 'n'), ('大学', 'n'), ('的', 'u'), ('安泰管理学院', 'n')]
>>> from pkuseg import pkuseg as ps
>>> t = ps(postag=True)
>>> t.cut("上海交通大学的安泰管理学院")
[('上海', 'ns'), ('交通', 'n'), ('大学', 'n'), ('的', 'u'), ('安泰', 'nz'), ('管理', 'vn'), ('学院', 'n')]

一般是传入一个文件,后来发现用二元组列表传入也可以。


20240130

  • 烟雨清冷,浓雾郁结了整整一日,有些低落,还被DGL教育说快过年得听些积极的音乐,学校里还有认识的人真好,但情绪确实很容易受天气影响。
  • 晚上回来场地很湿,有点想找DGL去打会儿球,但操场开放,碰到安迪刚摇完10K离场,还是独自慢跑8K(明后下雨再室内活动了,有场地跑还是跑会儿,目前一月跑量232km,关键是保持了无伤状态,以前也有过一两个月到200k以上的月跑量,但是膝盖完全扛不住),4’35"的均配下最大心率都179bpm(平均159bpm,也是太高了),跑得特别疲惫。
  • 昨晚买票出了些问题,搞到快十二点才回三门路,睡得稍微晚了些,就明显感觉状态差了许多,右侧锁骨靠喉咙的地方每次吞咽会有点疼,我有些分不清是受凉还是刺痛,但是管不了那么多,喝十杯水缓一缓,应该不至于会感冒。
  • 跑完去吉买盛采购周六物资,要是不带点儿吃的,我指定得饿死在半路上。实话说,以前这种旅程总是会很痛苦,尤其是四年前,第一周在杭州玩儿的真的很快乐,但第二周心态就变了,结局就是在苏州极其煎熬,如坐针毡。然而四年过去了,我必须得长进些,反正只要我不尴尬,电灯泡就是别人,不过大概率就是当个移动行囊[摊手]。
  • 累,离校回寝时,浓雾也未曾散去,但至少没有下雨,折衷的结局或许也算不得太坏。罢工,早睡,明日太阳照常升起。

备份0130:

# -*- coding: utf-8 -*- 
# @author : caoyang
# @email: caoyang@stu.sufe.edu.cn

import re
import pandas as pd

from settings import RAW_DATA_SUMMARY
from src.pipelines.base import NLPPipelines


class JobPreprocessPipeline(NLPPipelines):
	# 1. DEFINE POSTAG
	# Comment@caoyang: Here I only use pkuseg, if you use jieba, you need to update the following 4 dicts 
	uncritical_pos_tags = {"pkuseg": ['r', 'z', 'y', 'e', 'o', 'i', 'x']}	# Pos tags which can be ignored
	noun_pos_tags = {"pkuseg": ['n', "nr", "ns", "nt", "nx", "nz", "an"]}	# Pos tags which refer to nouns
	verb_pos_tags = {"pkuseg": ['v', "vx", "vn"]}							# Pos tags which refer to verbs
	other_pos_tags = {"pkuseg": ['c', 'u', 'w', 'd']}						# Pos tags which are not nouns or verbs (but cannot be ignored, e.g. "的", "和", etc)
	# ----------------------------------------------------------------
	# 1. DEFINE EDUCATION AND MAJOR
	educations_lv0 = ["小学", "初中", "中学", "高中"]	# Education Lv.0 (Note that there are descriptions like "辅导小学/初中小孩", "初中级技术人员", "初高中教学辅导", "从中学习")
	educations_lv1 = ["职校", "职高", "技校", "中专"]	# Education Lv.1
	educations_lv2 = ["大专", "高职", "本科", "学士"]	# Education Lv.2
	educations_lv3 = ["硕士", "研究生", "博士"]		# Education Lv.3
	educations_main = educations_lv1 + educations_lv2 + educations_lv3
	majors_need_suffix = ["计算机", "英语",
						  ]	# These majors must have a suffix "专业"
	majors_all = ["法律", "金融", "机电", "机械", "人力资源", "财务", "师范",
				  "机电", "人力资源", "师范"
				  ]			# You can add new major strings here
	# ----------------------------------------------------------------
	threshold_for_skip = .5
	# Phrases containing forbidden string can be ignored when extracting tasks and skills
	forbidden_strings = ["00", "周岁", "岗位职责", "任职", "岗位要求", "岗位目的",
						 "职责", "职位", "招聘岗位", "工作内容", "工作描述",
						 "男女", "不限", "身高", "体重", "优先", "招聘", "入职",
						 "科技园", "有无经验", "诚聘",
						 ]
	forbidden_strings = list(filter(None, forbidden_strings))
	# All the tokens appearing behind uncritical tokens can be ignored when extracting tasks and skills
	# @date 20231114: I found that treatment (e.g. salary, accommodation, etc) may appear at the start of many job ads, so that I set a `threshold_for_skip` for ignoring the tokens behind uncritical tokens
	uncritical_tokens = ["福利", "晋升", "薪资", "工资", "工作地址",
						 "联系人", "联系电话", "待遇", "五险", "底薪",
						 "五险", "一金", "奖金", "上班", "工作时间",
						 "职位发展", "培训与发展", "绩效", "技能培训", "免费",
						 "职前培训", "级别", "年龄", "截止", "有无经验",
						 "包吃包住", "加班", "社保", "包住宿", "持有",
						 "学历", "专业不限", "毕业", "相关专业", "等专业",
						 "管理专业", "设计专业", "工科专业", "工程专业",
						 "营销专业", "计算机专业", "语专业", "会计专业",
						 "以上专业", "金融专业", "法律专业", "机械专业",
						 "自动化专业", "财务专业", "电器专业", "类专业",
						 "教育专业", "护理专业", "美术专业", "机电专业",
						 "法学专业", "建筑专业", "师范", "画专业",
						 ]
	uncritical_tokens = list(filter(None, uncritical_tokens))
	forbidden_strings = set(forbidden_strings + uncritical_tokens)	# 2023-11-14更新: 因为现在`uncritical_tokens`不一定被删除了,所以要把`uncritical_tokens`加到`forbidden_strings`里去

	def __init__(self, **kwargs):
		super(JobPreprocessPipeline, self).__init__()
		# Check 
		for pos_tags in ["uncritical_pos_tags", "noun_pos_tags", "verb_pos_tags", "other_pos_tags"]:
			if self.library not in eval(f"self.{pos_tags}"):
				raise NotImplementedError(f"You want to use library {self.library} for parsing, please update `{pos_tags}` above!")
		self._load_major_zyml(filepath=)

	def _define_regex(self):
		# Regex matching salary numbers
		# regex_salary_string = "[^a-zA-Z\d][1-9]\d{1,2}00[^\d号年届]"	# This regex is better, but when processing "工资4000-6000元/月", it can match "4000" only but ignore "6000"
		regex_salary_string = "([1-9]\d{1,2}00)[^\d号年届]"				# This regex avoid the problem above, but may extract something wrong	
		self.regex_salary = re.compile(regex_salary_string)
		# --------------------------------
		# Regex matching education strings
		or_string_education_main = f"({'|'.join(self.educations_main)})"
		or_string_education_lv0 = f"({'|'.join(self.educations_lv0)})"
		# You can copy from `regexs_for_substitude`, but you'd better add brackets to each substring(if you wish `re.findall` to capture it)
		regex_education_strings = [f"(学历)?([::])?{or_string_education_main}(以?及)?{or_string_education_main}?(以[上内下])?(学历|毕业)?",
								   f"(学历)([::])?{or_string_education_lv0}(以?及)?{or_string_education_lv0}?(以[上内下])?",
								   f"({or_string_education_lv0})(以?及)?({or_string_education_lv0})?(以[上内下])?(学历|毕业)",
								   ]
		self.regexs_education = list(map(re.compile, regex_education_strings))
		# --------------------------------
		# Regex matching major strings
		regex_major_strings = [
			f"({self.majors_need_suffix})"
		]
		regex_maj_raw = '('
		for major in self.:
			regex_maj_raw += f"{major}|"
			if major.endswith("大类") and len(major) > 4:
				regex_maj_raw += f"{major[:-2]}|"
			elif major.endswith("类") and len(major) > 3:
				regex_maj_raw += f"{major[:-1]}|"
			else:
				continue
		regex_maj_raw = regex_maj_raw[:-1] + ')'
		regex_maj_raw += "(相关)?(专业)?(优先)?"
		regex_maj = re.compile(regex_maj_raw)
		# --------------------------------
		# Regex matching experience strings
		
		# @variable regexs_for_substitude: List[Tuple(<regex>, <substitute>)]
		regexs_for_substitude = [("[<《「【(\(][^))】」》>]+[\))】」》>]", str()),	# e.g. 【岗位职责】, <span id="sda"></span>
								 ("\\[a-zA-Z]", str()),								# e.g. "\N", "\R"
								 ("[【】✅☞'️⃣]", str()),								# Delete special tokens (You can add more special tokens here)
								 ("原?标题", str()),									# Note that "原标题" and "标题" appears many times in corpus
								 (regex_education_strings[0], str()),	# e.g. "本科及以上", "硕士以下学历", "学历大专"				 
								 (regex_education_strings[1], str()),	# e.g. "学历高中及高中以上", "学历初中", "学历小学"		
								 (regex_education_strings[2], str()),	# e.g. "小学毕业", "初中以上学历", "高中及以上学历"		
								 ("\d{2}周?岁以[内下上]", str()),	# e.g. "35岁以下", "18周岁以上"
								 ("\d{1,2}周?岁", str()),		# e.g. "35周岁", "24岁"
								 ("\d{1,2}年及?以[上下内](相关)?(工作)?(经验)?", str()),				# e.g. "10年以上工作经验", "2年以内相关工作"
								 ("[一二两三四五六七八九十]年及?以[上下内](相关)?(工作)?(经验)?", str()),	# e.g. "两年及以上工作经验", 
								 ("\d+[、.\)))]", '。'),								# Replace index term with sentence split symbol (i.e. "。")
								 ("[一二三四五六七八九十①②③④⑤⑥⑦⑧⑨⑩][、.]", "。"),	# Replace index term with sentence split symbol (i.e. "。")
								 ("\d{1,2}[::]\d{2}", str()),								# e.g. "8:30", "19:00"
								 ("(\d{1,5})?元?[-~到或]?\d{1,5}元?[/每][周天月年]", str()),	# e.g. "40到50每天", "5000元-6000元/每天"
								 ("([^\d])\d([^\d])", r"\1。\2"),							# Match single digitals (It must be set at the last position in `regexs_for_substitude` list)
								 ]
		regexs_for_substitude = list(map(lambda _regex_string, _substitude: (re.compile(_regex_string), _substitude), regexs_for_substitude))
		regex_for_split = re.compile("[。;!?::\\(\\\\N)]+|\-\-\-+")	# 用于分句的特殊符号

	# Load majors from 《普通高等学校本科专业目录(2022)》 and 《普通高等学校高等职业教育(专科)专业目录(2021)》
	def _load_major_zyml(self, filepath = RAW_DATA_SUMMARY["major_zyml"]):
		df_major_zyml = pd.read_csv(filepath, sep='\t', header=0)
		self.majors_lv1 = df_major_zyml["major1"].unique().tolist()	# Lv1: 31
		self.majors_lv2 = df_major_zyml["major2"].unique().tolist()	# Lv2: 79
		self.majors_lv3 = df_major_zyml["major3"].unique().tolist()	# Lv3: 1451
		logging.info(f"Lv1 majors: {len(self.majors_lv1)}")
		logging.info(f"Lv2 majors: {len(self.majors_lv2)}")
		logging.info(f"Lv3 majors: {len(self.majors_lv3)}")
		logging.info(f"Default majors({len(self.majors_all)}): {}")
		self.majors_all = list(set(self.majors_lv1 + self.majors_lv2 + self.majors_lv3))
		print(f"Total Majors: {len(self.majors_all)}")

20240131

  • 这两天宋某指定是被我刺激了,昨天他独训8组×400米间歇(休息2分钟)+5000米节奏跑@4’15",平均一组400米1"15",今天又跑了39分半的万米。虽然宋某距离他的巅峰期有差距,但也是恢复八九成力了。
  • 看状态我明晚得上点强度,周五跑休,周六徒步,最后一周五个工作日力量+间歇+体能,很想回家前跟宋某比一场,年前圆满。现在我俩水平应该真的是五五开了,但万米成绩仍不及宋某巅峰期的水准,不过我的有氧能力要比除AK以外的所有人都要好些,包括嘉伟,所以我自信38分台的万米即可冲击全马破三,而当时嘉伟破三时万米已经是36分台了。
  • 晚上操场没开,给了我充分的借口去打球。下班兴致冲冲地叫DGL出来打,我自信觉得经历周日的洗礼,已经能打得过她了,想找回点场子,结果自取其辱。不过感觉这次差距也没那么大,我也不太好意思去放她短球,而且没有换裤子和鞋子,跑不起来抢不到球,反手失误又有点多,但球感好不少了,正手高远球发的也比较顺手了,毕竟周日被嘉伟遛那么久,没有点长进说不过去。
  • 今晚跟DGL打了有100分钟,没有感觉很累,但心率最高到148bpm,而且活动消耗超过了600卡,周日打了90分钟,被嘉伟遛得就差跪地上,心率都没过95bpm,消耗不过200卡,表指定是犯病了。

regex.findall的返回值:

  • regex中没有捕获元或有恰好1个捕获元,则返回格式为List[Str]
  • regex中有超过1个捕获元,则返回格式为List[Tuple(n)]n为捕获元数量,捕获元次序按照从左到右,自外向内。例如:
import re
regex = re.compile("((a)(b))((c)((d)(e))")
regex.findall("abcde")
# [('ab', 'a', 'b', 'cde', 'c', 'de', 'd', 'e')]

注意:.findall方法Return a list of all non-overlapping matches of pattern in string. 即不重叠的匹配结果,如\d{5}1234567890中只能.findall到两个结果["12345", "67890"],如需匹配重叠的结果(即["12345", "23456", "34567", "45678", "56789", "67890"]),可使用.finditer方法,参考链接

import re 
s = "1234567890"
matches = re.finditer(r'(?=(\d{5}))', s)
results = [match.group(1) for match in matches]

这里正则一定要写成带零宽断言的格式,(\d{5})(还是只能匹配两个结果)和\d{5}(报错,没有group,即必须有捕获元)都不行,暂时不是很能搞得明白原理。


20240201

  • 晚归状态很好,身体电量有53(下午摸鱼睡了会儿,都跑去杭州开年会,没人管我),冬雨未歇,冷得要死,本来带了装备跑环校线拉体能,临时改室内训练:①10组爬楼×实验大楼B1-15F ②3000次×单摇 ③200次×双摇。因为只穿短袖和腿套,鞋子也很轻便,整体感觉舒适,但也算是基本到位。
  • 爬楼45分钟(下楼电梯),中间不停,平均上楼用时2’45",下楼1’45",要比之前快不少;第二组单摇就更轻松了,居然连跳了2200下都没断,不到25分钟就跳完了;最后补200次双摇收尾,顶到心肺强度。练跳绳是因为周六跟嘉伟跑5K变速的时候发现,右小腿根部靠近跟腱的位置跑久了会疼(有种要断开的感觉),是小腿和脚踝力量不够(前掌跑法不伤膝盖,但吃脚踝和小腿),因为跑圈时左侧承重,时间久了右侧力量会比左侧弱,今天跳绳也发现,单摇时交替单脚落地,明显是左脚踩着重心,右脚落得很轻,反过来的话就失去平衡了。
  • 给东昌路的菜饭骨头汤打个广告,我之前一直在对面黄山菜饭吃,后者的夫妻肺片是猪头肉+口条,很香,我本来已经吃得很满足了。结果今天后者关门,被迫到前者吃了个肺片(因为一直觉得前者菜饭不如后者香),居然是牛肉(3大片,厚实)+耳朵边(这个给的不少,单价很贵)+胗(这个给的也不少,也不便宜),这也太划算了(都是22块),我直接干三碗饭,太香了,根本吃不够(小菜都差不多,我不贪,只盛满一碗黄瓜,饭看情况3~4碗,但就这样吃,这几天毛重已经快不到70kg了)。
    在这里插入图片描述在这里插入图片描述
早上审稿,一篇甲状腺细胞多分类问题,代码不开源,数据不公开,最主要的贡献还是数据去偏,完全不能repeat,关键这种小众领域主题,相关研究只写了不到不到半页,这行情下大家都特么在水,无非是谁水的更有技巧一点

如今LLM研究热点脱离底层,脱离实际,人人都想把LLM用到尖端或是娱乐领域,反而是社科研究,比如北大国发院每季度的小微调查,依靠问卷收集信息,虽然看起来没啥大用,但这至少对缩小阶层差距是有助益的。

即使把思维(脑力劳动)视为一种生产力,LLM的兴起是否是科技革命仍然值得商榷,历史上所有的工业革命、科技革命,其科技原理和科技成果都得到了公开和广泛应用,生产力得到极大解放,然而LLM或许并不能做到这些。

首先LLM不是人,而有人的地方才有江湖,人总是希望身边有各种隐形的壁垒保护自己,而LLM的出现开始削除壁垒,而既得利益受损,准入就会被严格约束(这可能只是时间的问题,随着法律规定的完善,可以预见到最终LLM可以得到广泛适用);另一方面,也是关键地,从耗能上来看,这更像是能源饱和下的产能重配,事实上从2017年Transformers提出开始,学界和业界就达成了共识,甭管什么过拟合、欠拟合,模型就是越大越好,18年GPT才150M,到19年1.5B,21年175B,再到GPT4现在万亿级别的参数,这就是个无底洞,就像人类的贪欲一样,它是永远不会满的,没有人会嫌模型太大,只会嫌算力不够,数据太少,好的模型能够收集到更多的数据,更多的利益,正反馈循环下,最终必然寡头垄断。而模型越大,试错、优化、部署、运行的成本也就越大,研究机构总会达到能够承担的上限,而资源会自发地向高收益汇拢。悲观地说,如果国家不出手,国内与GPT的差距永远也弥补不上。

零宽断言:
(?=pattern):正向先行断言,表示匹配位置后面必须紧跟着满足pattern的字符串,但不包括这个字符串在匹配结果中。
(?!pattern):负向先行断言,表示匹配位置后面不能紧跟着满足pattern的字符串,也不包括这个字符串在匹配结果中。
(?<=pattern):正向后行断言,表示匹配位置前面必须是满足pattern的字符串,但不包括这个字符串在匹配结果中。
(?<!pattern):负向后行断言,表示匹配位置前面不能是满足pattern的字符串,也不包括这个字符串在匹配结果中。
(?:pattern):非捕获型分组,表示将pattern包含在一个分组中,但不把这个分组的匹配结果保存到分组编号中。这个分组通常用于表示可选的或重复的子表达式,或者是限制量词的作用范围,而不需要把它们的匹配结果单独提取出来。


20240202

  • 真会找罪受,明日吴中区中雨,穹窿山雷暴,又逢春运,五点半就得起床赶地铁,第二天还得上班。说到底,别人瞎折腾跟我有半毛钱关系,我指定是又吃错药。
  • 今天原计划跑休(周一到周四都挺到位,明天还要作死),但状态尚可,我怕拖到下周被鸽,趁让宋某给我送雨衣的节点,回家前找他最后比一次,约定如果他赢,年前我请他吃顿好的。我主要想摸个底,看看彼此全力下差距还有多大(他12月万米38分整,就巅峰期水平而言,我还差他一丁点)。
  • 但是晚上回来细雨绵绵,场地很湿,气温骤降,并不是跑成绩的天气,但宋某兴致很高,我决定以5000米分胜负。我自以为至少是能跑进19分,前9圈都是我在前面带,倒数三圈被宋某反超,最终我19’34",宋某19’30",技不如人,无能吃🍔。高估状态了,五个工作日之后多少有些疲累。不过本来我想也是无论胜负,年前都要请他吃个饭。
  • 最近LXY偶尔在群里冒泡,而且十多天不发pyq,我真怀疑是不是被屏蔽了。而且今天看到芜湖10K中签率只有46%(全马中签率特别高,有96%,早知道还是报全马,才2000人,肯定能刷很好的成绩,但是总想在大一些的比赛完成首马,这样有仪式感些),都中的概率很低,报名费大概率打水漂…

regex1(?=regex2):匹配后面是regex2regex1
regex1(?!regex2):匹配后面不是regex2regex1
(?<=regex2)regex1:匹配前面是regex2regex1
(?<!regex2)regex1:匹配前面不是regex2regex1
(?:regex): 这个表示非捕获元

下面是java中正则替换示例,python的效果可能有出入:

  • ?=

    '我喜欢苹果'.replace(/我喜欢(?=苹果)/,'我讨厌') // 匹配 我喜欢苹果 中的 我喜欢 并替换为 我讨厌,因为是零宽度断言所以不包含苹果,故结果为 我讨厌苹果
    '我喜欢橘子'.replace(/我喜欢(?=苹果)/,'我讨厌') // 我喜欢后面不是苹果,所以这里正则未通过,匹配不到任何内容,故结果仍为 我喜欢橘子
    
  • ?!

    '我喜欢苹果'.replace(/我喜欢(?!苹果)/,'我讨厌') // 匹配后面不是苹果的我喜欢,正则未通过,故结果仍为 我喜欢苹果
    '我喜欢橘子'.replace(/我喜欢(?!苹果)/,'我讨厌') // 正则通过,匹配到 我喜欢 进行替换,因为是零宽度断言所以橘子不在匹配结果中,故结果为 我讨厌橘子
    
  • ?<=
    这里我换一个例子,比如下面我想匹配字符串中的工资数值(两个正则里面都是一个捕获元),如果用regex_1,就匹配不到后一个6000,因为overlap,但是用第二个就不会出现这个问题。

    regex_1 = re.compile("[^a-zA-Z\d]([1-9]\d{1,2}00)[^\d号年届]")
    regex_2 = re.compile("(?<![a-zA-Z\d])([1-9]\d{1,2}00)[^\d号年届]")
    print(regex_1.findall("工资4000-6000元")) # ['4000']
    print(regex_2.findall("工资4000-6000元")) # ['4000', '6000']
    
  • ?<

    '我讨厌苹果'.replace(/(?<!我喜欢)苹果/,'西红柿') // 匹配到 苹果 ,故结果为 我讨厌西红柿
    '我喜欢苹果'.replace(/(?<!我喜欢)苹果/,'西红柿') // 匹配不通过,故结果仍为 我喜欢苹果
    
  • ?:

    'hello world'.replace(/(?:hello) (world)/,'$1') // 匹配内容为hello world,但是hello并没有被保存,因此$1取的是world,故结果为world
    

20240203

  • 下午L在群里回复了我脚崴的消息,宋某又来阴阳我。但今天真的猪脑过载,我实在不想再去动脑子想这件事了。因为今天我想了很多事。
  • 如果只是为了初试越野,我不至于在滂沱大雨的冬日周六凌晨,5点就起床出远门(除非我真吃错药),虽然最终达成这一目的,并交了点学费(左脚踝扭伤),现在我知道,越野很难也很危险(今天五上五下,第三座山下破时崴伤,但后面两座山上坡我依然可以一路冲刺,但下坡就再也不敢莽了),远胜马拉松。然而,我更想搞明白的是,之于四年前,我真变了吗?或者更准确地说,真长进了吗?
  • 四年前,我只会和一个人交流,不会和一群人交流,老天让我在这个时候认识SXY,我那时还不知道有E/I人之分,只觉得我在人群里只会静默,而SXY就很会巴拉。以至于那时跟SHY和SXY三人同行时,如坐针毡,不夸张地说,当时很嫉妒SHY,正因如此,苏州是让我很痛苦的地方。
  • 但我今天在苏州真的很高兴,如果不是崴伤(导致我年前的训练计划全部报销),今天会是完美的一日。一方面,训练目标达成,足量的体能拉练和上坡跑训练对有氧和乳酸耐受大有助益;另一方面,我得到想要的答案,也认识新的朋友,更重要地,我似乎又看到四年前她那种令人舒适的模样,也加深对她的性格和行为的理解,SXY虽然嘴上说不成家,但有些事情终究水到渠成,我也会祝福她,但我们应该仍是朋友。
  • 用几个词形容SXY,爱凑热闹(我觉得就是喜欢玩,喜欢在人多的地方玩,E值MAX)、即兴而动、无计划主义、脑回路还有点对不上(P值MAX),我今天摔了有五六回,她居然问我要不要吃盐丸?直到最后一次她终于想起来包里有皮筋可以绑鞋上防滑,但军师已经给我绑鞋子的布条。另外,她出门坐高铁居然不带身份证,下雨捞起一件雨衣就穿,发现是上周穿完扔下根本没洗,又嫌太臭想扔,以及在登山前反复横跳地穿脱抓绒,真给我整不会了,我今天穿得很少,上身短袖+队服+风衣,下身只穿了一条紧身腿套(全身透风),大雨滂沱下3℃ + 湿冷,路上为了等她,差点没给我冻死在外面。
  • 徒步并不是一件容易的事,而SXY这个运动白痴现在徒步走得这么好,居然不是三分钟热度,是真的热爱。或许时势所致,大城市压力太大,许多年轻人在山野中寻求解脱,这样的群体已日渐庞大。徒步和跑步最大的不同就在于,跑步是一个人事,徒步是一群人的事(因为一个人太不安全)。诚然一个人难以走得很远,但同伴也未必上升为伴侣,有共同的爱好足矣。以前我觉得异性间不可能有纯洁的友谊,所以我觉得今天又是来当电灯泡的,但是没想到我现在也可以和同行的军师和黎佳聊得很舒适,这让我很高兴,有种心平天地宽的感觉,总算是比四年前长进了些。
  • 最后我因伤翘了聚餐,但高铁晚点,他们仨吃完饭来苏州站时又遇到我,检票临别前我向同行的三人分别表达谢意,因为我真的,很久没有这么舒坦过。我既再次认识了别人,又再次认识了自己。
  • 特殊情况

    比如:/(?=.*[A-Z])[A-Za-z]{5,10}/

    (?=<pattern>)一般用于匹配符合<pattern>条件的前面的字符串,如果(?=)前面没有内容,即(?=)被放在正则开头使用时,(?=)的作用就相当于检索全部内容是否符合它的要求,如果不符合也就没必要继续向后匹配了。于是,上述正则为先检查内容中是否至少包含一个大写字母,如果有,则继续检查并匹配5-10个大小写字母,将这5-10个大小写字母作为结果返回。

  • 常用案例

    1. 姓名模糊:re.subregex.sub('*', "李小龙"))
    2. 手机号模糊:'13912345678'.replace(/(?<=\d{3})\d(?=\d{3})/g, '*') // 139*****678
    3. 强密码校验:re.match("^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[\W_])(?!.*[\u4e00-\u9fa5])(?!\s)[a-zA-Z0-9\W_]{8,30}$", "Ab_9427??")(密码不能为空,8-30位,至少包含一个大写字母、小写字母、数字、特殊字符)

这里\u4e00-\u9fa5是GB18030的编码范围,其实这个区间上有0x9fa5-0x4e00=20901个字符,而且输出下来发现每一个位置都确实是中文字符,再往后会有韩文、朝鲜文、日文的字符,基本按照笔画、部首顺序排列。

使用python输出所有unicode字符,想了个很笨的方法:

for n in range(0x4e00, 0x9fa5):
	print(eval(f"\\u{hex(n)[2:]}"))

但是这样不行,没有办法将十六进制数的字符串直接拼到\u后面,加eval也不管用:

后来发现用chr即可:

for n in range(0x4e00, 0x9fa5):
    try:
        print(f"\\u{n} = {chr(n)}")
    except UnicodeEncodeError:
        pass

20240204

  • 昨晚疲累到极点,睡前身体电量只剩5,眼睛都快睁不开,却没有躺下就着,然后今早六点半醒来后怎么也睡不着,决定先起来(虽然昨天请了假,但还是得去商城路打卡),身体电量只恢复到58,思忖中午回来再补觉。抹了些黄道益和云南白药就去学校吃早饭了。
  • 说实话,昨天饮食作息全部打乱,我只喝下不到5杯水,吃了100g葡萄干+100g瓜子仁,其实能量已经过剩,晚上回来不太饿(因为瓜子仁太顶饱),但十点多还是泡了面加红肠,加上这周无法训练,我害怕练这么久又功亏一篑,必须从今天调整饮食,就算年前练不了,也不能就这样摆烂下去。
  • 昨天事太多,组织得不是很清晰。首先我肯定没有吃错药(今天没感冒,身体还是耐造的),我去苏州目的主要有三(递进):①准备越野赛;②8个多月没出上海,我很想出去走走;③故地重游,在和四年前几乎相同的人物、事件、地点配置下,验证自己到底有无长进。结局:①崴脚,这个不算大也不算小,这么多年崴了不是一两次,但打断了我的冬训计划,但凡事欲速不达,来之安之,把能做的做到最好,好好养伤,急也没啥用;②我认识两个新朋友并加入军师的徒步群体;③重新认识、理解SXY以及我自己。
  • 时间改变许多,但原野中,人的面貌终究回归本初的模样。我不奢求别人也能理解我的思维和行动,但我就是很偏执地想要知道一些问题的答案。我不太可能去重蹈覆辙,对于感情,只能随缘而动,与其思考自己要什么,不如审视自己有什么,未来的事无法揣测,我们只能把握当下。
  • 昨天一点崴脚后,有些失落,兴致全给败了,影响自己更影响别人,第三座山还有很长一段下坡要走,行程刚过半,后面还有两段差不多的上下坡。其实我看到群里LXY的话和宋某来阴阳我,但无法揣度也不知如何回复,当时有想过顺水单聊问问芜湖中签的事,但感觉突兀。后半程雨势渐长又不停赶路,连拍照的空隙都没有,虽然下坡慢了许多,但军师好心地在前面护我,上坡我依然能冲得起来(刚崴完还不是那么疼,但是休息下来后明显肿了许多)。结束后更换衣物,一路公交地铁、一瘸一拐地赶往高铁站,几乎没有空档,晚上回来后忙着洗衣刷鞋洗澡吃饭,搁置太久,不知该再回复些啥,而且感觉LXY最近应该很忙,隐身了般,连DGL的pyq都不给点赞。
  • 军师的徒步群看起来更像是个大龄单身群,群公告写了禁止申请异性好友,除非线下当面添加,禁止涉黄及调侃女性,不知他真的是女👊还是被女👊打怕了(虽然我觉得应该是后者哈哈),反正热爱徒步的人绝大多数单身,这事儿舟车劳顿、费时费力,出发就是至少一整天,两个人是很难有这么多时间去挥霍。
  • 今早起来更完,养伤,准备宅一日干活。

常用正则(一)(转载

  1. 汉字:^[\u4e00-\u9fa5]{0,}$

  2. 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$

  3. 长度为3-20的所有字符:^.{3,20}$

  4. 由26个英文字母组成的字符串:^[A-Za-z]+$

  5. 由26个大写英文字母组成的字符串:^[A-Z]+$

  6. 由26个小写英文字母组成的字符串:^[a-z]+$

  7. 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$

  8. 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$

  9. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$

  10. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$

  11. 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+ 12 禁止输入含有~的字符:[^~\x22]+


20240205

  • 昨天躺半天,练些腰腹动作,顺便把行李和房间收拾了一下,之后白天没时间,9号一大早就要赶车。现在看等9号再走很明智,最近高铁大规模延误停运,8号雨停,9号放晴,宝玺姐明天回武汉的高铁就已停运,AK回昆明估计更难。
  • 今早左脚踝基本恢复(第一时间冰敷以及翘高脚很重要,淤血凝不起来就不会肿得太狠,还是多亏军师准备齐全),黄道益确实见效,云南白药属实一般。出门前用肌贴打个封闭,走路已无大碍,但某人是真没良心,气死我了,军师昨天都知道问下我伤的情况,始作俑者就扯半天淡。
  • 中午去乳山路找了家菜饭,菜品不如东昌路,但那儿店都关门了,只能退而求其次。饭前毛重70.5kg,放心大胆地猛干三碗饭,回来照例爬楼到18F,准备复健。计划是今晚先做力量,明天下雨,正好脚再好些可以找DGL打球,结果发现她也在pyq找人打球(LXY又是难得冒泡,这还没过年就已经各种东西吃上了,坐等年后养膘…),这不巧了,年前一起过把瘾。
  • 晚归12组×30个箭步(+20kg),一开始脚踝还有点感觉,走得不是很稳,后面越走越稳,照往常的量加了4组到12组,做完脚踝居然一点感觉没有,索性再慢跑10圈(没有开表,大约5’30"~5’00"加速跑),补了两组单杠卷腹,回实验室做拉伸。这次恢复得实在太快了,年前说不定还来得及再搞一次强度。

常用正则(二)(转载

  1. Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

  2. 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?

  3. URL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

  4. 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

  5. 电话号码(XXX-XXXXXXXXXXX-XXXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$

  6. 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}

  7. 身份证号(15位、18位数字):^\d{15}|\d{18}$

  8. 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$

  9. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

  10. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$

  11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$

  12. 日期格式:^\d{4}-\d{1,2}-\d{1,2}

  13. 一年的12个月(01-09和1-12):^(0?[1-9]|1[0-2])$

  14. 一个月的31天(01-09和01-31):^((0?[1-9])|((1|2)[0-9])|30|31)$

  15. 钱的输入格式:

  • 有四种钱的表示形式我们可以接受:“10000.00” 和"10,000.00", 和没有 “分” 的 “10000” 和 “10,000”:^[1-9][0-9]*$

  • 这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$

  • 一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$

  • 这表示一个0或者一个可能为负的开头不为0的数字,让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧。下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$

  • 必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 “10” 和 “10.2” 是通过的:^[0-9]+(.[0-9]{2})?$

  • 这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$

  • 这样就允许用户只写一位小数,下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$

  • 1到3个数字,后面跟着任意个逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$

  • 备注:这就是最终结果了,别忘了+可以用*替代如果你觉得空字符串也可以接受的话。


20240206

  • 第四双鞋,最终还是下单特步160x3.0pro(去年锡马何杰穿的冠军鞋),标准色款(宁静蓝/新白),目前全网同价1099,但淘宝有春节跨减,966拿下。年后是赛季,感觉市场需求更大,不太可能降价,不如早买早享受。160x3.0pro其他色款要便宜百八十,但就之前买过的两双NIKE Vaporfly,标准色款更耐穿(21年10月买的标准款紫色现在还能穿,虽然破了些,但上周还能跑出38’08"的万米PB,22年11月买的黄色款鞋底已磨烂,扔管理室吃灰,偶尔拿出来慢跑用)。主要是160x2.0系列根本买不到(2.0和3.0差不太多),之前买的飞飙361现在也找不到,这些鞋厂宁可下架也不降价,太坏。
  • 下班找DGL最后打一次球,我左脚不太敢用力,她也只能和我五五开了,毕竟身高差太多,胜之不武,但多亏有个陪练,让我一周能练一回,慢慢入门。结束后,DGL问我过年去不去金华,我忽然想起11月好像是有说过这事,但春节期间或许会有些其他安排,暂时不是那么确信。DGL有些恨我不争,怪我太怂,跟我说了些事,说我以后上哪儿找LXY这么好的人,一通话把我讲得无地自容。
  • 或许DGL想的太简单,也可能我还是太懦夫,但LXY回家后,我始终觉得很难找到持久的话题(以至于越拖越尴尬),而且大家都不是很闲,就纯尬聊,还是要物理距离上近一些才能有谈资,或是有长时间的交互积累才能即兴扯点淡,其实最好的告白就是在一起,但这确是奢求。就像最近学校里就只剩DGL一个熟人,我就只能跟DGL聊得多些。噢,还有个宋某,上周五约了他这周吃顿好的,前天我请假休息准备晚上请他吃,早上八点就叫他,一直不回,我说十二点前不回消息劳资就不伺候你了,然后他下午一点才起床,告诉他周六晚上刚回家,我当时就想顺着网线把他拉过来摁地上摩擦
  • 唉,本已松下的那根神经又给提前绷紧,有些许烦躁,但也怪不得别人。过年再说吧。

常用正则(三)

  1. xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$

  2. 中文字符的正则表达式:[\u4e00-\u9fa5]

  3. 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))

  4. 空白行的正则表达式:\n\s*\r (可以用来删除空白行)

  5. HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)

  6. 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)

  7. 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)

  8. 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)

  9. IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)

  10. IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))

  11. IP-v4地址:\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b (提取IP地址时有用)

  12. 校验IP-v6地址:(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))

  13. 子网掩码:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))

  14. 校验日期:^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$(“yyyy-mm-dd“ 格式的日期校验,已考虑平闰年。)

  15. 抽取HTML注释:<!--(.*?)-->

  16. 查找CSS属性:^\\s*[a-zA-Z\\-]+\\s*[:]{1}\\s[a-zA-Z0-9\\s.#]+[;]{1}

  17. 提取页面超链接:(<a\\s*(?!.*\\brel=)[^>]*)(href="https?:\\/\\/)((?!(?:(?:www\\.)?'.implode('|(?:www\\.)?', $follow_list).'))[^" rel="external nofollow" ]+)"((?!.*\\brel=)[^>]*)(?:[^>]*)>

  18. 提取网页图片:\\< *[img][^\\\\>]*[src] *= *[\\"\\']{0,1}([^\\"\\'\\ >]*)

  19. 提取网页颜色代码:^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$

  20. 文件扩展名效验: ^([a-zA-Z]\\:|\\\\)\\\\([^\\\\]+\\\\)*[^\\/:*?"<>|]+\\.txt(l)?$

  21. 判断IE版本:^.*MSIE [5-8](?:\\.[0-9]+)?(?!.*Trident\\/[5-9]\\.0).*$


20240207

  • 下班前看了眼投稿群,没想到上个月的会这么快就有人收review了,我的偏偏不出,这年还让不让人过,艹。头大,本以为年前应该可以清闲点,突然冒出破事就很烦。
  • 今天AK和DGL也回家了,学校彻底空无一人。晚上回校开始复健,左脚踝热身转动时还是有一点点疼,决定顺时针绕着田径场最外圈跑,这样右侧承重,左脚压力要小些。先摇了5K多,越摇越快,感觉能加的起来,便脱了外套冲了3K(4’00",现在不换装备跑4分配也没有很吃力,),最后补了5圈放松跑(4’20"),比较满意,跑完左脚不疼,但肯定还没完全复原,是得谨慎点。
  • 昨天被从羽毛球馆一路教育回实验大楼,让我间歇性踌躇满志了一下,然后还是萎靡不振。DGL一路说我要E一点,但我真比以前E多了,要不然我能敢这么莽,而且你让我隔这么远怎么E,不还得等年后开学,想春节期间整点活,人多人少都好尬(但我刚发现年初五是情人节,往年初五都是出游日,今年出去肯定是人从众𠈌,还要被一路喂狗粮,艹)。
  • 头大。

智谱 GLM-4 API 年前开源仓库适配更新, 系列模型已经支持以下框架:

  1. TaskWeaver:一个代码优先的代理框架,用于无缝规划和执行数据分析任务。这个创新的框架通过代码片段解释用户请求,并以函数的形式有效地协调各种插件,以有状态的方式执行数据分析任务。
    仓库地址:https://github.com/microsoft/TaskWeaver

  2. chatgpt-on-wechat:基于大模型搭建的微信聊天机器人,同时支持微信、企业微信、公众号、飞书、钉钉接入。
    仓库地址:https://github.com/zhayujie/chatgpt-on-wechat

  3. Langchain-Chatchat:基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现,开源、可离线部署的检索增强生成(RAG)大模型知识库项目。
    仓库地址:https://github.com/chatchat-space/Langchain-Chatchat

  4. LobeChat:开源的高性能聊天机器人框架,支持语音合成、多模态和可扩展(函数调用)的插件系统。
    仓库地址:https://github.com/lobehub/lobe-chat

  5. LangChain(PR中):构建上下文感知推理应用程序
    仓库地址:https://github.com/langchain-ai/langchain/pull/16695/

  6. GLM-CookBook :非官方的GLM系列API入门学习仓库
    仓库地址:https://github.com/zRzRzRzRzRzRzR/glm-cookbook

官方API使用文档:
https://zhipu-ai.feishu.cn/wiki/F04DwgsoXiIDi4knQlAczWNfnif?fromScene=spaceOverview

opencv.dnn做图像分类(https://edu.csdn.net/skill/practice/opencv-a181ede3b8c7487fbcc212796c27ce77/8288?language=opencv&materialId=20834

图像分类DEMO:

# 输入指定大小RGB图像,1/3通道,宽高一般相等
# 通过卷积神经网络进行多尺度特征提取,生成高维特征值
# 利用全连接网络、或其他结构对高维特征进行分类,输出各目标分类的概率值(概率和为1)
# 选择概率值最高的作为图像分类结果
# opencv.dnn模块可以直接加载深度学习模型,并进行推理输出运行结果。下面是opencv.dnn模块加载googlenet caffe模型进行图片分类的代码,请你完善其中TO-DO部分的代码。
# 代码中LABEL_MAP是图像分类名称字典,给定索引得到具体分类名称(string)。
import cv2
import numpy as np
from labels import LABEL_MAP # 1000 labels in imagenet dataset

if __name__=='__main__':
    # caffe model, googlenet aglo
    weights = "bvlc_googlenet.caffemodel"
    protxt = "bvlc_googlenet.prototxt"

    # read caffe model from disk
    net = cv2.dnn.readNetFromCaffe(protxt, weights)

    # create input
    image = cv2.imread("ocean-liner.jpg")
    blob = cv2.dnn.blobFromImage(image, 1.0, (224, 224), (104, 117, 123), False, crop=False)
    result = np.copy(image)

    # run!
    net.setInput(blob)
    out = net.forward()

    # TODO(You): 请在此实现代码
    out = out.flatten()
	classId = np.argmax(out[1:])
	confidence = out[classId]

    # time cost
    t, _ = net.getPerfProfile()
    label = 'cost time: %.2f ms' % (t * 1000.0 / cv2.getTickFrequency())
    cv2.putText(result, label, (0, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 0), 2)

    # render on image
    label = '%s: %.4f' % (LABEL_MAP[classId] if LABEL_MAP else 'Class #%d' % classId, confidence)
    cv2.putText(result, label, (0, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

    show_img = np.hstack((image, result))

    # normal codes in opencv
    cv2.imshow("Image", show_img)
    cv2.waitKey(0)

20240208

  • 廿九,附近店大多关门,被乳山路的上品小笼狠狠宰了一顿,大排面(真的只有一个大排,别的啥也没)卖17块,新食堂同款才5.5元。我只好又买了一笼蟹粉包跟宝玺姐一块吃,但还是没吃饱,亏死。
  • 本来准备带宝玺姐去隔壁那家菜饭吃,虽然主菜不如东昌路的做得好,但菜饭烧得确实香。这周一第一次去吃,我提前问好老板能不能加饭,老板说当然行,给你吃饱为止,于是我给老板好好上了一课;周二过去老板已经有心里阴影,对我说你昨天吃太慢,请往里边坐;周三再去时老板看我眼神已经不太对(杀心渐起),我有些不好意思,第三碗没盛满,加了些白萝卜片凑数;结果今天周四再去,老板说今天不做菜饭,我俩只好到隔壁上品小笼被宰(卖方市场,任人宰割,等了有二十多分钟才吃到嘴,还贼抠,抽纸都不给,反正我这辈子不可能再去上品小笼吃,真气坏了)。
  • 晚归计划慢跑,补一回力量训练,8组×30箭步(+20kg),春节期间做不了力量训练,这样不至于间隔太久。
  • 天晴了,回家。

目标检测demo

# 使用Opencv深度学习的功能实现目标检测的功能,模型选用`MobileNetSSD_deploy.caffemodel`,已经实现了模型加载和预测的代码,如何将结果取出来并绘制到图片上:
import numpy as np
import cv2

if __name__=="__main__":
    image_name = '11.jpg'
    prototxt = 'MobileNetSSD_deploy.prototxt.txt'
    model_path = 'MobileNetSSD_deploy.caffemodel'
    confidence_ta = 0.2

    # 初始化MobileNet SSD训练的类标签列表
    # 检测,然后为每个类生成一组边界框颜色
    CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
               "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
               "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
               "sofa", "train", "tvmonitor"]
    COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))

    # load our serialized model from disk
    print("[INFO] loading model...")
    net = cv2.dnn.readNetFromCaffe(prototxt, model_path)
    # 加载输入图像并为图像构造一个输入blob
    # 将大小调整为固定的300x300像素。
    # (注意:SSD模型的输入是300x300像素)
    image = cv2.imread(image_name)
    (h, w) = image.shape[:2]
    blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 0.007843, (300, 300), 127.5)
    # 通过网络传递blob并获得检测结果和
    # 预测
    print("[INFO] computing object detections...")
    net.setInput(blob)
    detections = net.forward()

    # TODO(You): 请在此编写循环检测结果
	for i in np.arange(0, detections.shape[2]):
	    # 提取与数据相关的置信度(即概率)
	    # 预测
	    confidence = detections[0, 0, i, 2]                                                      
	    # 通过确保“置信度”来过滤掉弱检测
	    # 大于最小置信度
	    if confidence > confidence_ta:
	        # 从`detections`中提取类标签的索引,
	        # 然后计算物体边界框的 (x, y) 坐标
	        idx = int(detections[0, 0, i, 1])
	                                                                              
	        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
	        (startX, startY, endX, endY) = box.astype("int")
	
	        # 显示预测
	        label = "{}: {:.2f}%".format(CLASSES[idx], confidence * 100)
	        print("[INFO] {}".format(label))
	        cv2.rectangle(image, (startX, startY), (endX, endY),
	                        COLORS[idx], 2)
	        y = startY - 15 if startY - 15 > 15 else startY + 15
	        cv2.putText(image, label, (startX, y),
	                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)    
    # show the output image
    cv2.imshow("Output", image)
    cv2.imwrite("output.jpg", image)
    cv2.waitKey(0)

完篇(大年廿九)

沪上第八年冬,最漫长的冬,最寒冷的冬,最难言的冬。

借着人多壮胆,中午我把芜湖10K中签的情况给问了(我觉得再不联系,就真被人觉得是放弃了…)。离比赛开始还有很久,变数难料,但都中签的话至少目前不是什么坏事。

很久以前就发现,自己做事比别人慢半拍,不是做事慢,而是总在模仿同龄人从前的行为。本科阶段,有室友颜老板拉我做三次大赛,以至最后能搭上推免末班车。其实我俩人格几乎相背(ESTJ/ISFJ,他是极致的E和理性,我是极致的I和感性),但就是很互补,无论性格或能力。硕士阶段,颜老板忙着实习,交集变少,但始终是我重要的精神支柱,尤其在21年失恋后,下班回来凌晨一点多,陪我在宁远楼梯间长谈。直到他毕业后去蚂蚁,我潜意识里总想模仿他走过的路,也来这儿干了半年。

然而这半年,或者更准确地说,是这个冬天,自己变了太多,变得很陌生。缺少以前认真做事的心态,言行滑头太多,能更容易地和陌生人搭上话,比如以前我就不喜欢跟别人客套,觉得形式主义、浪费口舌,但这学期我每次打饭都会对阿姨加一句谢谢(有一定想她能给我多盛点菜的目的…)、打客服电话也会先说这么晚不好意思打扰您,出行请人腾位置、接受他人帮助时都会很客气,毕竟进社会伸手不打笑脸人,说白了就是不老实,丧失本心,缺少正气。就前两年金言来沪,我很羡慕他身上依然保持高中时嫉恶如仇的少年意气,让我自惭形秽。随年岁增长,这些曾经觉得很重要的东西却在渐渐消逝。

这半年里,我深刻认识到朋友的重要性。以前我总是觉得朋友一两个足矣,没有什么是我学不会的,并不需要别人给我帮助。如今认识到只靠自己真太弱小了,不管是学业或生活,尤其是上周六的徒步,没有军师的帮扶,我指定要交待在穹窿山。

好在这半年我真的多了些朋友。对我来说朋友分两种,交心的和说话的。以前对我来说前者才算是朋友(数年积累,彼此非常了解,以达到交心程度),因为我并不喜欢平时和人说太多话(虽然现在废话是多了点),这样能算朋友的屈指可数,凯爹和颜老板,SXY算半个(毕竟不是什么话都能讲)。但这半年,前者又多了两人(嘉伟和宋某),后者则增添不少,AK、LXY(?),DGL,同门两师弟,以及“监工”宝玺姐。

更重要的是,如今,对待感情的态度也变了许多。

  • 19年12月谈崩后,特别遗憾,想着将来不可能再遇到更合适的(半个老乡,同届本硕,同校推免,当时又是难得的大四空闲时段)

    现在回想四年前确实幼稚,刚认识三四周就特么瞎莽,真是活该,但如今情况却没有那么坏。

  • 于是,21年3月第一次尝到双向奔赴的甜头,我觉得自己是最幸运的人,一定要认真珍惜,争取走到最后。每日用EXCEL更新对方的数据库,确保不能忘了关于她的重要事项,结果却不到两月,就给我摔得粉身碎骨,落得彻底断交的结局。如今看就是当时段位还是太低,不会说话,也不会处理各种关系。

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 此后,我认为从零走到成家很艰难,各种三观、沟通、现实问题的阻碍,不如等着被人安排得明明白白,反正爱的是一个,成家立业的是另一个(我已经看开了…)。直到23年12月,我又不长记性地蠢蠢欲动,这次心理预期已经降低很多,结局别跟上次一样坏就行(但这也是奢求不是吗?实际上和平分手的能有多少呢?)。然而,伴随预期降低的,是对待感情的态度也没再那样认真,总想多一事不如少一事,以前就总想太多,老给自己找不自在,现在是眼不见为净,爱咋咋地。

    不过,这次多了几个朋友的支持鼓励,酒壮怂人胆,真挺好,人生就这样,每一出戏都是新戏,不确定性让人无法完全套用过往经验,但又因此而多样纷呈。

许多事情都无法速成,尽管时间对于如今的岁数已是奢侈品,然,千里之行,始于足下,重要的是应当向前行走,因为再漫长的冬天终有冰雪消融的那日,再寒冷的冬天也将等到春暖花开。

凛冬终逝,新年仍有太阳升起。


—— END@2024-02-08 18:00, Alipay S-Space 18F
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值