第二天开会倒是挺顺利。
林楠前一天晚上睡得踏实,第二天精神头还行。陈屿准备的备忘录问题列得周全,小组讨论起来效率高。那个关于历史数据申请流程的问题也被采纳了,负责对接的老师说会去问清楚。
开完会出来,已经下午三点多。
林楠回到公寓,打开电脑继续搞他的模型。
特征提取做完了,数据清洗也搞定了,该训练模型了。
他搓搓手,有点小激动。
这可是他第一次独立搞这么复杂的预测模型。以前都是跟着教程做,或者小组作业里负责一小块。这次从数据收集到特征工程,基本都是他自己弄的。
点下训练按钮。
进度条开始爬。
林楠盯着屏幕,眼睛都不敢眨。
训练集上的准确率一路飙升,80%,85%,90%……最后停在了98.7%。
“卧槽。”林楠没忍住,小声骂了句脏话。
这也太高了吧?
他有点不敢相信,赶紧跑验证集。
进度条又开始爬。
林楠心里打鼓。
验证集准确率刚开始还行,75%,然后慢慢往上走,80%……85%……
爬到88%的时候,停了。
然后开始往下掉。
87%。
86%。
85%。
最后稳在了84.3%。
林楠盯着那个数字,看了足足一分钟。
训练集98.7%,验证集84.3%。
这差距……
过拟合了。
林楠往后一靠,整个人瘫在椅子上。
妈的。
白高兴了。
他抓了抓头发,有点烦躁。
怎么办?
调参吧。
林楠坐直身子,开始调整正则化参数。加大惩罚项,重新训练。
进度条又爬了一遍。
训练集准确率降到96.1%,验证集……83.9%。
还更差了。
林楠又试了几种方法,换损失函数,加dropout层,调整学习率。
每次训练都要等好久。
从下午折腾到晚上。
窗外天都黑了。
林楠看着屏幕上那一排结果,训练集准确率全在95%以上,验证集最高也就85.2%,最低的掉到82%。
过拟合的问题根本没解决。
他有点泄气。
肚子咕咕叫,这才想起来晚饭还没吃。
林楠起身去厨房,泡了碗泡面。端回来一边吃一边盯着屏幕看。
越看越烦。
群里这时候有人@他。
是小组里另一个负责算法的同学,问他模型跑得怎么样了。
林楠犹豫了一下,在群里说了情况。
“训练集98,验证集84,过拟合了。调了一晚上参数,没改善。”
消息发出去,群里安静了几秒。
然后有人回:“这么严重?特征工程是不是有问题?”
又有人说:“要不要试试集成学习?”
还有人建议:“是不是数据量不够?”
七嘴八舌的,建议给了一堆。
但林楠看着那些话,心里更乱了。
他知道大家是好意,但问题摆在这儿,建议再多,也得他自己一点点试。
试了一晚上,屁用没有。
林楠回了个“我再想想办法”,就关了群聊。
他盯着屏幕发呆。
泡面都凉了。
手机震了一下。
林楠拿起来看。
是陈屿发来的私聊。
“还在弄模型?”
林楠打字:“嗯。过拟合,搞不定。”
陈屿:“具体什么情况?”
林楠把训练集和验证集的准确率发过去,又把特征工程的大致思路说了说。
陈屿那边过了一会儿才回。
“特征维度多少?”
林楠:“二百三十七个。”
陈屿:“样本量呢?”
林楠:“训练集八千,验证集两千。”
陈屿:“特征有点多。可能有些特征相关性太强,或者有噪音。”
林楠看着这句话,心里更堵了。
他知道陈屿说得对。
但二百三十七个特征,一个个查,得查到什么时候?
陈屿又发来消息:“明天周六,你有空吗?”
林楠愣了愣。
“有空。怎么了?”
陈屿:“找个地方一起看看代码?环境换一换,也许能有新思路。”
林楠盯着这句话,手指停在屏幕上。
一起看代码?
线下?
他心里有点慌。
但看着屏幕上那刺眼的84.3%,又觉得……好像也没别的办法了。
“去哪儿?”林楠问。
陈屿:“大学城有家咖啡馆,叫‘码农驿站’。很多程序员去那儿,网速快,有白板。环境还行。”
林楠听说过那地方。
确实很多搞技术的去。
“行。”他回。
陈屿:“明天下午两点?我把地址发你。”
“好。”
地址发过来了。
林楠看着那个定位,心里还是有点打鼓。
但转念一想,不就是看个代码吗?
专业问题,专业解决。
怕什么。
他给自己打气。
第二天下午,林楠提前十分钟到了咖啡馆。
推门进去,里面人不少。
大部分都是年轻人,桌上摆着笔记本电脑,屏幕上全是代码。空气里有咖啡的味道,还有键盘敲击的声音。
林楠扫了一圈,看到陈屿坐在靠窗的长桌旁。
他走过去。
陈屿抬头看到他,笑了笑:“来了。”
“嗯。”林楠在他旁边坐下。
桌上已经摆了两台笔记本电脑,还有一块移动白板,几支白板笔。
陈屿把自己的电脑屏幕转向林楠:“你的代码我拉下来了,大致看了一下。”
林楠有点惊讶:“你什么时候看的?”
“早上。”陈屿说,“先说说你的思路?”
林楠定了定神,开始讲自己的特征工程。
怎么从原始数据里提取特征,怎么归一化,怎么处理缺失值。
陈屿听着,偶尔在白板上写几个关键词。
等林楠讲完,陈屿问:“这二百三十七个特征,你都检查过相关性吗?”
林楠摇头:“太多了,没全查。就看了几个主要的。”
“那可能问题就在这儿。”陈屿用笔点了点白板,“过拟合,要么是模型太复杂,要么是数据有问题。你用的模型不算复杂,那大概率是特征的问题。”
林楠点头。
这个道理他懂。
但具体怎么找问题,他有点没头绪。
陈屿把白板擦干净,重新画了个表格。
“我们来理一理。”他说,“你把特征分成几类,比如用户基础属性、消费行为、时间特征……然后每一类里,哪些特征你觉得可能有关联?”
林楠想了想,开始说。
陈屿一边听,一边在白板上记。
两人就这么一个说一个记,把二百三十七个特征分成了七八个大类。
然后陈屿开始提问。
“用户年龄和注册时长,这两个特征你同时用了?”
林楠点头。
“那有没有可能,年龄大的用户注册时间也长?这两个特征可能高度相关。”
林楠愣了愣。
他之前没往这方面想。
陈屿继续说:“还有消费总额和订单数量,这两个也是吧?消费总额高的,订单数量一般也多。”
林楠赶紧翻自己的代码。
一看,还真是。
他把这些特征都放进去了,没做处理。
“还有这个,”陈屿指着白板上的另一项,“周末消费频次和工作日消费频次,这两个特征你做了标准化,但没考虑它们的比值关系。如果一个人周末消费频次高,工作日消费频次低,那这个比值可能比单独两个特征更有意义。”
林楠听着,脑子里有点开窍了。
陈屿没直接告诉他答案,而是在引导他思考。
一个问题接一个问题。
林楠一开始还有点紧张,后来慢慢放松了,跟着陈屿的思路走。
两人对着白板,一个特征一个特征地分析。
咖啡馆里人来人往,但林楠完全没注意。
他全部心思都在那些特征上。
“等等。”林楠突然打断陈屿,“你刚才说,用户活跃天数和登录次数可能共线性?”
“对。”陈屿点头,“活跃天数多的,登录次数一般也多。这两个特征提供的信息可能重复了。”
林楠盯着白板,脑子里飞快地转。
他想起自己之前做特征的时候,为了尽量多提取信息,把所有能想到的特征都塞进去了。
现在回头看,有些特征根本就是重复的。
还有些特征组合起来会产生新的信息,但他没想到。
“我明白了。”林楠说,“有些特征我得删掉,有些得组合。”
陈屿笑了:“对。特征工程不是越多越好,是要找到真正有用的信息。”
林楠拿起白板笔,开始在白板上标记。
这个特征删掉。
这两个特征合并。
这个特征和那个特征做交互项。
他越写越快,思路越来越清晰。
陈屿在旁边看着,偶尔补充一句。
等林楠标记完,白板上已经画得密密麻麻。
“我改一下代码。”林楠说,转身对着自己的电脑。
手指在键盘上敲得飞快。
删除冗余特征。
创建新的特征组合。
调整特征维度。
陈屿没打扰他,自己起身去柜台点了两杯喝的。
回来的时候,林楠还在敲代码。
陈屿把一杯水果茶放在林楠手边。
林楠看了一眼,愣了。
是他上次在甜品店喝过的那款。
“你记得?”林楠转头看陈屿。
陈屿坐下,打开自己的电脑:“嗯。你说过好喝。”
林楠心里动了一下。
他没说什么,低头喝了口茶。
甜的。
凉凉的。
正好解渴。
他继续敲代码。
改完特征工程的部分,重新开始训练。
进度条又爬起来了。
林楠这次没盯着看,他靠在椅子上,长出了一口气。
“不管结果怎么样,”他说,“至少思路理清了。”
陈屿笑了:“这就对了。解决问题不是一蹴而就的,得一步步来。”
林楠点头。
他看着陈屿的侧脸。
窗外的阳光照进来,落在陈屿的肩膀上。
陈屿低着头在看自己的电脑,表情专注。
林楠突然觉得,这样的陈屿……挺靠谱的。
不是那种高高在上的学霸,也不是那种只会说漂亮话的校草。
是真的在认真帮他解决问题。
“谢谢。”林楠说。
陈屿转头看他:“谢什么?”
“帮我理思路。”林楠说,“还有……没直接给我答案。”
陈屿笑了:“给你答案有什么用?下次遇到问题还是不会。自己弄明白了,才是自己的。”
这话说得实在。
林楠心里舒服。
他喜欢这种相处方式。
不装,不假,有什么说什么。
进度条爬完了。
林楠坐直身子,点开结果。
训练集准确率:94.2%。
验证集准确率:91.7%。
差距缩小到3%以内。
虽然还没到完美,但比之前的84%强太多了。
“成了!”林楠没忍住,声音大了点。
旁边桌的人看过来。
林楠赶紧捂嘴,但眼睛里的高兴藏不住。
陈屿凑过来看屏幕:“91.7%,可以。再优化一下特征,应该还能提。”
林楠点头:“嗯。我知道问题在哪儿了,后面好办了。”
他靠回椅子上,整个人轻松了。
折腾了两天的问题,终于有眉目了。
这种感觉,爽。
林楠端起水果茶,又喝了一大口。
甜。
真甜。
陈屿看他那样,笑了:“至于吗?高兴成这样。”
“至于。”林楠实话实说,“我都快被这破模型搞疯了。”
“现在不疯了?”
“不疯了。”林楠说,“活过来了。”
两人都笑了。
气氛一下子轻松了。
窗外的阳光暖暖的,咖啡馆里键盘声噼里啪啦的。
林楠看着屏幕上那91.7%的数字,越看越顺眼。
陈屿合上电脑,靠在椅子上。
“平时除了编程,”他随口问,“还喜欢做什么?”
林楠愣了愣。
这问题……有点突然。
他想了想:“也没什么特别的。看看书,听听歌。”
“不打游戏?”陈屿问。
林楠犹豫了一下。
“偶尔……玩一点单机游戏。”
“什么类型的?”
“就……那种剧情向的。”林楠说,“不用联网,自己慢慢玩。”
陈屿点头:“挺好。放松放松。”
他没再追问。
林楠松了口气。
他其实有点怕陈屿继续问。
因为他玩的那些单机游戏……多少有点少女向。
要是被陈屿知道,他玩那种画风可爱、剧情浪漫的游戏,指不定怎么想。
还好陈屿没多问。
两人又坐了会儿。
林楠把改好的代码保存,上传到小组共享文件夹。
然后在群里发了条消息:“模型过拟合问题找到原因了,特征工程有问题。改了一版,验证集准确率91.7%,还在优化。”
群里立刻有人回复。
“牛逼啊林楠!”
“91.7%可以了!”
“怎么解决的?”
林楠看了看陈屿。
陈屿冲他摇头,意思是你自己说。
林楠打字:“重新分析了特征,删了冗余的,做了新的特征组合。”
他没提陈屿帮忙的事。
但心里清楚,要不是陈屿,他可能还在那儿瞎调参数。
发完消息,林楠关了电脑。
“走吧?”陈屿问。
“嗯。”
两人收拾好东西,离开咖啡馆。
外面天还亮着。
下午四点多,阳光正好。
林楠深吸了口气。
空气里有树叶的味道。
“接下来干嘛?”陈屿问。
“回公寓。”林楠说,“继续优化模型。”
“不休息休息?”
“趁热打铁。”林楠说,“思路有了,赶紧弄完。”
陈屿笑了:“行。那有事群里说。”
“嗯。”
两人在路口分开。
林楠往公寓走,脚步轻快。
他掏出手机,看了眼时间。
然后给陈屿发了条消息。
“今天谢谢了。”
陈屿回得很快。
“客气。下次请我喝奶茶就行。”
林楠笑了。
“行。奶茶管够。”
发完这条,他把手机塞回兜里。
风吹过来,凉凉的。
林楠抬起头,看着天上的云。
突然觉得,今天天气真好。