七月在线公开课笔记-十七-

七月在线公开课笔记(十七)

七月在线—算法coding公开课 - P4:树实战(直播coding) - 七月在线-julyedu - BV1YW411K7va

欢迎收看7月算法公开课。我们专答课的主要内容是数实战。我将从如下几个方面讲述本课。首先讲一下数的定义,然后讲一下数的性质。然后讲几个例题,因为我们这实战型的这种讲座。当然例题是最重要的,前面会一道而过。

最终总结结束本课。那么关于数的定义,我们要承认如下几点,首先树是一种特殊的图,那么什么叫图,大家请自己复习。一般谈到图,我们就考虑它的节点是什么边是什么。那么树是怎样的图呢?它是一种特殊的图。

满足这三个条件的图,什么条件呢?它是无项图,它是无环图,它是连通图,这三个条件缺一不可,少了任何一个这个东西都不叫做数。那么对于分类来讲,一个叫有根数,就是有一个特殊节点叫做根。然后呢,如果规定了根。

那么我们当然就有父子关系了。因为相当于给数定了一个项。虽然。说这个图还是无相图,但是它有了父子关系,相当于一个有像图。但是从结构上来说,它是个无相的。那么无根数就是没有这样的节点。

那么我为什么把二叉数单独提出来呢?因为在这个算法领域或者在计算机领域,二叉数比较重要。比方说排序二叉数啊等等等等,都是和二叉数相关的。这个普通的数当然并不是完全没用,就是研究的可能相对少一些。

都在这个图论里面做一些研究。那么数的性质,我这里面不加证明的列出来。首先N个节点的数恰好有N减一条边。那么第二个呢,这个N大于等于2。个节点的数,也就是如果一个数的节点至少有两个的话。

那么它至少有两个节点是叶子节点。什么叫叶子节点呢?我们定义为度为一的节点。那么这个证明其实大家可以想一下,把这个呃度整个加起来,N减一条边的度整个加起来。根据哥拢原理发现至少有两个节点,这个度应该为一。

那么。树的任意两个节点之间有且仅有唯一的路径。所以这个有些问题他可能不告诉你我这个问题的研究的这个输入是一棵树。他会告诉你啊,我研究的可能是若干个城市之间,这些城市之间呢。这个互相之间都可达。

并且可达的这个路径是唯一的。那么其实这些城市形成的就是一棵树,那么它可能比较隐晦的通过这种条件告诉你,它是一棵树。那另外呢是说树是让所有N个节点都连通的边数最少的图。

因为你要把N个节点让它互相之间连通起来,至少要添加N减一条边。换句话说,就是我把数中的任何一条边去掉,这个图肯定不连通。这就是说树的每条边都是割边。什么叫割边呢?就是把这条边砍掉之后,删掉之后。

这个图变成了一个不连通的图。那么还有一个性质,就是说数中添加了一条边,就会形成一个圈儿。因为加了这条边是多余的,它一定会形成一个圈,这是都是感性上的认识,请大家注意理解。😊,那么我们直接看题。

首先就是li code的331题,这个题相对比较新了。他是说给定一个二叉树的前序遍历序列,问它是否合法。当然这个描描述还是相对模糊的,单独给一个二叉树的前序遍历序列是不能完全还原这棵二叉树的。

但是呢它给的是如果碰到这个空的节点,它就给一个井号。那么这个时候其实我们就能还原这棵树,为什么呢?首先什么叫前序遍历,我们先遍历根节点再遍历左子树再遍历右子树,这种便历顺序叫做前序遍历。

或者叫先根变历等等等等。那么它实际上就是假设来了一个节点,我就放在这里。然后呢,😊,下一个节点一定是它左子数的根节点。当然前提是不是井号,那么我就建立了这种父子关系。再下一个节点。

一定是这个节点的左左孩子就这样不断的往左走。那么什么时候往右走呢?我碰到一个井号的时候。😊,我就回退回退到它的副节点,然后再往走再走的时候就往右走。往右走之后画了一个节点之后。

再下一个节点是它的左左孩子还往左走。就是只要我不回退,我就一直往左走,遇到井号,我就回退,然后下一个节点往右走。那么大家想一下,我需要记录什么信息呢,实际上我们就变相的把这个数画了出来。

记录了每个节点的左孩子以及右孩子。然后每个节点的父亲都记录下来了。因为我要回退,回退之后,回退到副节点之后,我们发现这个节点是有左孩子的,所以再给他添加一个孩子,我就只能往右走。

当然这种方法不是不能做比较麻烦。😊,其实呢。这个题目它只是让我们返回一个布尔值,也就是说它没有要求我们返回整棵树,没有要求我们还原这棵树,而是返回一个这个现在给定的序列合不合法。

就是一个true first。那么我们没有必要把整棵树维护出来。我们可以想象一个节点,一个普通的节点,它相当于有两个空位,因为我可以挂两个孩子,左孩子右孩子嘛。那么再来一个节点的时候。

它一定挂在之前的一个空位上。😊,就是说任何一个节点,它只要不是根。他一定是某个节点的孩子。那么他具体是哪个节点的孩子,我们可以不关心,我们只关心有多少个空位就可以了。只要有一个节点。

相当于添加了两个空位。当然,如果我们碰到空节点,说明这个这个空节点是叶子节点,那么它一个空位都没有添加。那么这里面有一个特殊情况就是根的这个处理。😊,根节点不是任何节点的孩子,没有关系。

我们设置一个虚拟的节点。😊,我让根节点是他的孩子,这个虚拟节点呢只有一个空位,这是最开始的情况。然后。😊,我们就沿着这个序列走,还是沿着这个序列走。如果。这个不是叶子的话,我们相当于它占了一个空位。

但是别忘了它还多出来两个空位。因为这个节点本身可以挂左子数和右子树,所以它占了它父亲的一个空位,但是它多出来两个空位,所以是一个减一加2的关系。那么如果是叶子呢,那么它白占了一个空位。

它没有增加任何空位,因为我们不能在它下面挂节点。那么最后这个合法和不合法是怎么区分的呢?首先我挂一个节点无论是。😊,这个无论是叶子节点还是非叶子节点,它都需要占掉它父亲的一个空位。

所以无论如何空位是要减一的这也是我刚才说的,减一加2,这个为什么不是直接说加一的这个呃关键所在,必须要先减一再加2,那么减一的时候,我们发现如果没有空位了?那么显然这个节点没有地方挂了。

也就是说这个节点没有父亲了。那么这棵树就是非法的。那么。😊,如果有空位,我们就把它挂在一个空位上,我们不关心它具体挂在哪儿。因为我们不需要还原这棵树嘛,我们就把它挂在了一个空位上。

并且决定一下它是否增加了空位。如果这个序列便利完空位足够多,那么我们这棵树就能画出来,或者说就能还原出来,或者说这个序列就是合法的。😊。

但是呢别忘了我们这个遍利的序练是把所有的节点和所有的叶子都画出来了。所以最后空位的数要是0,也就是说我们最后。😊,这棵树没有地方能挂节点了,因为这个叶子节点肯定不能挂这棵树没有边缘的地方能挂节点了。

所以这就限制了我们这个空位不能多,也不能少。😊。

所以我们来看一下这个代码怎么写,这个代码写起来非常简单,尤其如果用java的话,就更加简单了。😊,当然我这里面还是采取用C加加,因为C加加写起来这个它没有这种split的东西,所以写起来相对。难选一点。

但是也还好,我这position等于一是什么意思呢?就是我现在空位的数,我认为有一个,刚才我说了,我们假设这个有一个虚拟节点的存在,这个虚拟节点只有一个空位。😊,他呢把这个。就是这个空位可以放根节点用。

所以这个空位是这个虚拟节点留出来的那个空位。那么我为什么要这么做呢?因为我想用C加加的那个就是类似于split那个功能。虽然它没有,那么这里面我把这个逗号全都变成空格。

这样我就可以用C加加的这个输入输出流来处理,相对会简单一点。啊,这里面题目给大家先看一下,就是这么一个题目,井号表示叶子。然后呢,它还有一个是说这个输入是合法的,所以我们不用去关心这些数是多少。

当然这个如果题目变得更难一点,可能会给你一些不合法的输入。然后你可能就需要看一下这些数有没有重复,因为这些数有重复肯定就不对嘛,一一棵树怎么可能这个这些数节点来回来去的走呢?那样就有圈了嘛。

但是对于本题还是最简单的情况,不用考虑这些问题。😊,我这样做,之所以要这样做,就是想把这个re order这个字符串放到我这个输入流里面来。那这样有什么好处呢?啊。

这样的好处在于这个我就可以把它读出来了。就相当于我做了一下类似于java的,按照逗号做split这么一个功能啊,这个要写一个str。然后就是我进入问题的关键。首先,无论它是不是叶子。我都要把空位数减1。

那么当然如果这样的话就非法了,空位不够嘛,否则我就相当于把它挂在了一个空位上。那么如果是叶子的话,它白占了一个空位儿。如果不是叶子呢?就是不是井号呢,它不是叶子,相当于我这个节点本身还可以带两个孩子。

所以加上两个空位。😊,就是大概这么样一个。然后最后别忘了return的条件是。最后空位数一定要是零,因为如果不是零,就说明我们有些叶子没有画出来。因为最后这个数再也不能挂节点了嘛。看看大概检查一下。

应该没什么问题,我们可以 run一下。这个lea code的速度变得有点慢,然后我们可以提交一下。哦,run了之后提交,可能要稍等。啊,它是一个正确的代码,然后呢。

这第一个题我们就讲完了。然后我们可以看一下第二个题。第二个题虽然是就说是一道题,但实际上它是三个小题目。他想讲的就是这个递归的框架,哪三个题目呢?分别是li code上的100题、111题和104题。

这三个题目是说这个呃考虑。两棵树是否一样相同嘛?然后最小深度和最大深度,这两个都是二叉树,这个也是二叉树,都是二叉树的问题。那我想说明的问题就是这三个代码写起来就是几乎是一样的,非常非常非常简单。

就可以写出来。然后我们现在来看一下这个它的代码。当然有些细节可能不相同。本质就是递归。😊,那么这个递归呢就考虑左子数、右子数以及根节点。比方说相同这个问题,我们一定是左子数相同,右子数也相同。

并且根节点也相同。

所以呢我们来看一下怎么写。当然有些特殊情况需要处理。😊,啊,这个窗口可以关了,我们先看一下这个相同的问题。现在我们要返回这个以P和Q为根的这两棵二叉树是不是长得一样,对吧?那么我们先来看一下特殊情况。

P是空的时候,当然零和空是一样的,在C加加里面,那么只有Q是空的时候才可以。😊,那如果这个时候Q是空呢,注意这时候如果留能留到这里面的话,就是如果能执行到这里面的话,这时候P一定不是空。

因为P是空在这已经返回了。所以这我们直接return first就好了。下面是问题的关键。我们需要。P和Q是一样的,并且这就开始递归了。P的左子数。嗯,left和Q的左子数也是一样的,并且。P的。

柚子树。和Q的右子数也是一样的,只有这三个条件同时满足就可以了。相当于我们先判断了根,然后这是一些特殊情况的处理,然后看一下这个他们的value是不是一样。然后如果他们这个也一样的话。

再看一下他们左子数是不是一样,右子数是不是也一样。来看一下。😊,当然这是预先这个判断一下,看看有没有编译错误。然后我们可以提交一下。啊,这也是一个正确的代码。那我们直接讲下一个,为什么把它们都放到一起。

当然我这个换一下顺序吧,先讲这个最大深度,因为最大深度相对这个简单一点。什么叫最大深度呢?首先它对深度有一个定义,就是从根,当然这是一个有根数了,到叶子的这个最长的距离一定要到叶子。

当然这有个加一减一问题。实际上这个一句话就能写出来,怎么写呢?😊,如果根不是空,那么大家想一下最大深度是什么?它一定是左边的。把递柜调用这个。就是说从镯子树到某一片叶子的。最大深度。然后呢,从柚子数。

到一片叶子的最大深度。取最大加一,为什么加一加一就是它自身嘛,从根走嘛,我们这是从左子数走的,这是从右节点走的。那么这两个取最大加一就是从根走的最长的那个路径。那么如果根是空怎么样呢?

根是空显然就是零嘛。😊,数都不存在嘛。那么我们。我为什么要先讲这个呢?因为这个求最大的时候相对简单一点,提交一下。😊,然后它也是一个正确的代码。然后我们来看一下这个求最小的问题。

那么这个从根节点到叶子节点是最小的那个,为什么最小和最大不一样呢?因为大家可以考虑一下,假设我就两个节点,一个根,一个左孩子,那么我们应该返回什么?我们应该返回这个一。😊,但是按照我们的说法。

从左孩子走啊,这个路径是零,从右孩子走,路径也是0。那么这个。😊,因为右孩子没有嘛,右孩子没有,我们一定要有一颗叶子作为落脚点。按照刚才那个左右孩子,那么这个。左边返回的路径是零。

右边返回的路径其实应该是-一,这样应该是对的。有一些细节需要处理。因为我们一定要落到一个孩子上面。那么这个时候大家可能细节处理一下,也许能处理。对,但是实际上我们需要这个落脚点在一个叶子节点上。

刚才那个最长路没有落到叶子上,我们可以返回一个长度为零的这个路。那么现在。😊,如果只有左孩子没有右孩子的话,你左右的这个返回值不是很好定义。当然如果细细的定义的话,也是能定义的。

但是我这里面采取一些这个迂回的策略,但是思路还是一样的,先处理特殊情况,如果根是空,那么返回零,那么。😊,这时候我就看一下,如果有左孩子,那么并且有右孩子的话,可以用我们刚才说的那个定义。

左右较小的那个加一。嗯,先写作吧。那否则呢。如果只有左孩子,没有右孩子的话,那么显然只考虑左边,因为我不能考虑右边,又一定要到一个叶子嘛,这就是和刚才不一样的地方,那么就直接return这个东西就好了。

所以你把不存在那边定义为正无穷,其实也是可以的。但是我一般习惯上还是就是自己判断一下比较好。那么再否则呢。这时候已经没没有左孩子了。那么那么显然他就是右孩子加一嘛。那么再否则呢。

这时候我们就发现在这个时候就是一个空的节点存在,就一个这个root存在,它既没有左孩子,也没有右孩子。那么大家看一下这个逻辑,如果左右孩子都有,跟刚才最大的最长的那个路径是一样的,两边取短加一。

如果只有左孩子没有右孩子,我们不能往右边走,因为右边根本就没有数,没有数,何来最短路径,当然你定义为正无穷也是可以的。刚才那个是如果没有数,我们可以定义为最长路径为0。那么这里面如果没有数。

我们可以定义为最短路径为负穷呃,正无穷,但是我现在没有这么定义,那么我就只考虑一边就可以了。这一样。😊,这个如果能执行到这里,一定没有左孩子。那么光有右孩子就是这样,两个孩子都没有,就是一个一。

那么大概提交一下,是这个样子。它也是一个正确的代码。所以这个第二个问题实际上我讲了三个小问题。

是哪三个问题呢?就是两棵二叉树是否相同,以及二叉树最小深度和最大深度。这三个问题,请大家自己仔细体会,它就是一个递归的基本框架。那么最后一个问题呢?我想讲的就是这个tra,什么叫trare呢?

又叫字典树,这个题目也不算特别新了,但也不是特别旧。那么这个概念倒不是就是很新的一个概念,其实早就有字典数是什么东西呢?啊,如果只是英文单词的话,我们就这个把它理解为26叉树就可以了。什么意思呢?

当然有些差就没画出来。这个标红点的地方就表示这些单词是存在的,否则就表示它只是一个前缀,那么这棵树有什么单词呢?还有一个B,它还有一个BCD,当然没有BC,因为这没有标。

那么它还有一个EFG它还有一个H这是I这个不知道是什么?它还有一个ABD,还有1个ACD等。😊,等等等等。那么这个。这棵树有什么好处呢?我们插入一个单词的时候,就是从根节点顺着叉往下走。

走到最后把这个它最后走到的位置标记上就可以了。那么。😊,这个查找的时候有什么好处?我想说这个有一个单词,它在不在这里面,我怎么查找呢?其实。😊,我也是跟插入是一样的,顺着这个走。

因为我那个单词它是A也好,是B也好,已经告诉我们走的方向了。如果能走到一个标记为ttroe的节点,那么显然这个单词就存在,否则这个单词就不存在。比方说我们查找AX显然不存在,从A根本走不到X。

那如果我们查找AB,那么显然AB也是不存在。从A虽然能走到B,结果这个位置没有标记为trorue,所以这两种情况都是这个不存在的。那么还有一种要实现这个star with,什么叫star with呢?

就是有没有一个单词。😊,是以这个某一个前缀开头的,实际上就是说这个东西有没有路。因为大家可以看到,只要我们能走到这里,就一定至少有一个单词以它为前缀。因为这个单词是这么插入进去的嘛。

比方说我想说有没有单词以EA。😊,开头呢显然是没有的,因为E走不到A,有没有单词以EF开头呢?显然有EF因为我们知道有EFG,所以我们沿着这个数直接这么走。😊,走到的位置,显然有单词以它为前缀。

当然不一定是一个真正的单词。走到标记为troe的单词位置表示有这么一个单词,所以这个数本身以及单词本身就指导了我们怎么走。那么它的优势在于它的这个插入啊。😊。

这个查找啊以及starsmith这些复杂度都是正比于或者说大O这个单词长度的。因为这个书的高度其实也是单词最长的那个单词。那么它的优势在于有些单词共享前缀的话,它可以少存很多。

比方说我所有单词都是以AB开头的,那么它这个AB只存了一遍。你有一万个单词,我这个AB也只存了一遍。那么这棵树怎么建立呢?其实我刚才已经把这个建立过程都说了,当然可以这个递归的键也可以非递归的键。

我采取非递归,大家可以这个课后练习一下递归的这种键法。那么。😊。

我们来看一下。是这个问题,lea code上208题。那么。注意这个。我把这儿要建立一个,首先对于竖节点的定义,我把这儿要建立一个这个。呃,就是我刚才说的标记,然后二6叉数嘛,所以这个。

要建立26个指针。然后大家别忘了这个题目告诉我们可以假设单词只有小写字母组成,所以我们就建立26个就可以了。然后。😊,这构造函数里面当然要初始化。

我们把这个next I next I就是刚才我说的怎么走,然后所有的都复为force,所有节点都没有标记,这个初始化就初始化完了,然后。我们要实现的就是insert word,对吧?那么。😊。

我们可以看一下怎么实现。当然先把根节点建出来。因为这个根节点它替我们建好了,那我们就可以用这个。但是为了方便我把这个word改成S吧,这样写起来可能短一点嗯。沿着S走,对吧?那就走呗。

这个SI就表示啊I的。😊,就是S的第I个字符。那么。这个C呢就把A到Z变成了0到25。然后我就从当前节点看一下。如果这个位置不存在,注意我这个零实际上是一个指针为空的这个意思。

那么当然我就要自己新建一个啦。自己新建了一个节点。那么如果能执行到这里,无论我是新建的节点也好,或者这个不新建的节点也好,我这个n next C肯定是存在的。因为如果不存在,我就新建了一个节点。

然后沿着走就可以了。最后别忘了,最后这个n这个have。把它变成处。呃,插入就已经写好了。那么这个search呢,其实search和插入基本上是一样的。那么。当然我把它变成key吧。

为了和那个S做一下区分。其实代码基本上是可以copy的,还等于root。然后呢。还是沿着它走。因为刚才我讲了这个对于tri尔来讲,它的插入。和这个。search就是查找基本上是一样的。好减去A。

然后还是判断。如果这个东西根本不存在的话,注意这里面不是新建了,你是查找不能改变这棵树,那么显然就把它。弄成forrs就可以了。否则我还是沿着走,这个跟上面都是一样的那最后显然也不是直接把这个。

Not have。return回去。那这两个的差别在于,因为在这里面,如果这个节点不存在,我就建立一下不存在,我就建立一下。所以最后闹一定不是空。那么这里面。我这样走完这个这个闹有可能就已经变成空了。

所以这个。这个大家要注意,当然这个其实也不太可能是空,因为空在这儿就已经回去了。但是如果这个这个其实是没必要判断的。但是从这个逻辑上来讲,no是有可能是空的,这里面闹不可能是空。

这里面其实闹也不可能是空,但是可能判断一下会好一点。然后对于search来讲。我也把它叫key吧。search其实这三代代码都是差不多的。😊,嗯,其实是可以copy的。然后我就再写一遍吧。

还是不从这个跟刚才的逻辑都是完全一样的。还是减A。哦,我觉得。Of prefi。然后我们可以看一下这个哦这profi。然后我们可以看一下,还是这个东西。如果是空,就return force。

其实这三代代码都是非常非常接近的,就是顺着走就可以了。😊,然后我就可以。那么注意这个最后其实return now就可以了,就是return这个ow是不是空。如果不是空的话。

当然我这里面相当于把指针变成了一个布尔值。如果不是空的话就。那个。就是处是空的话就是for。然后我可以提交一下试试,这里面没有run code的,它也是一个正确的代码。所以这三段代码请大家这个仔细体会。

基本上就是沿着这个单词往下走。这个怎么走呢?就是减去A就是表示它在哪个叉上,如果这个节点不存在。那么insert的时候,显然要自己建一下。那么search的时候,当然不能自己建。

那么这个star with和这个search其实是差不多的,区别在于这个search一定要走到一个为 true的节点的这个位置。那么start swift要求比search要松一点。

因为这个它只要就是这个节点存在就可以,并不要考虑这个not这个have大概是这样的三个流程。然后。

这个题目基本上讲完了,我们总结一下,首先就是理解数的便利。我们今天讲的那个第一题其实是数的变利。那么数的变利有这些题目,这些题目非常非常的就是呃可以说比我讲的那些那些问题的这个相对可能要简单一点。

基本上就是前序遍历啊,中序变利啊,后序遍利啊,当然都是二叉数,这个大家仔细体会一下立的co上关于数的问题非常非常多。思路呢基本上一个是便利,一个是递归递归就是这三个问题。

当然有一些什么二叉数和双向链表的这个呃来回转换问题等等。大家可以考虑一下这个理解便利理解递归,尤其我今天讲的第二个问题,三个小问题都是通过递归来实现的。

然后学习使用ter是我这个最后讲的那个字典数的那个问题。😊,好,今天的课就到这里,谢谢大家。😊。

七月在线—算法coding公开课 - P5:数组实战(直播coding) - 七月在线-julyedu - BV1YW411K7va

欢迎观看7月算法公开课。我们这堂课的主要内容是数组问题实战。开门见山数组比较简单,我直接选了3个lead code上的问题。其实之前选了5个题,由于时间关系又从中选了三个比较典型比较代表性的。

虽然是三个题,但是前两个题我都给出了不止一种解法,请大家仔细体会这个一题多解。直接看第一个题,deta code上315题,给定一个数组要求返回一个数组。

返回的数组表示原来数组中每个元素右边有多少个数比它小,就像逆序数的这种概念。比方说输入是5261,那么输出就是2110。为什么呢?五的右边有二和一比五小二的右边有一比二小六的右边有一比六小。

所以呢五的右边有两个数比它小二的右边有一个数比它小6的右边有一个数比它小一的右边没有数,所以输出是2110题目意思非常清晰。那么它本质就是一个逆序数,我们可以通过经典的规并排序的算法来求出逆序数。

但是这个题呢我们求的逆序数不是一个数,而是一个数组是以每个数开头的逆序数的个数。所以我们还是需要对规并排序的算法做一些改进,这个代码量还是比。比较大的,下面我来写一下。

就是这个问题。

那么首先呢。我们先把这个N定义出来,也就是。里面的个数,然后呢,我们把所有问题交给一个递归的函数来做。我们在主函数里面基本上不实现什么东西。为什么我要定一个position呢?

因为这个position实际上反映了。就是下标排好顺序的之后的这个下标,因为我们不能修改这个圆的数组。如果我们修改了它,我们没法找到就是原来这个数在哪个位置,所以我们不对nuumbs进行真正的排序。

而是对它的下标进行排序。排好序之后,这个pos0里面是最小呃最大数的下标。因为这里面我们采取的是由大到小的排序。那么我们调这个m函数的这个。经典定义。那这里面呢我们给出一个。几个参数。

当然这个pos肯定要给外那个answer呢,是实际上是它要返回的这个。结果当然它的长度也是N。那么最后我们把answer返回就可以了。那现在相当于其实还是什么都没写,关键是看这个word函数怎么实现。

😊,那我们看一下这个word怎么实现呢?它有什么参数呢?首先是所有的数注意再次强调,我们对于这个并没有真正的使用这个names进行排序,而是对这个。pos进行了排序。

这个pos实际上是下标answer是我们要的结果。注意我这个from to实际上是左臂右臂的区间,而不是左闭右开的区间。所以这有一个加一减一的问题。不过没有关系,from大于等于to呢。

说明我们要么只有一个数,要么没有数,我们可以什么都不做,直接返回。所以这个是边界条件,否则呢。我们把终点球穿来,分别对。两边进行排序,这两边是啥呢?是这个。from到 mid。以子呢。

me加一到right呃到to。然后这两边由大到小盘好去之后,这个answer其实已经有了部分的结果。那么我们需要的就是这个跨越两边的。逆序数,我们要加到这个answer上,那么也就是经典的规并的过程。

规并的过程我们通常需要一个额外的数组。我把这个叫做tamp,然后就是真正意义上的规并。这是两个列表,分别从XY,也就是说从from和to。来开始做。啊,from和me开始做,然后呢,有几种情况比较特殊。

一种呢就是。X呢已经大于幂的了,说明第一个列表已经耗尽了。我们直接把第二个列表拿过来就好了。注意我排的都是这个pos,所以我改的也都是pos,把它放到这个time破数组里面。那另外一种情况呢。

说明第二个列表已经耗尽了。那么我直接把第一个列表里面的数拿出来就好了,这个都是比较简单的结果。那么还有一种呢,我就要看哪个大,注意我们这个排序是由大到小的排序。所以我要看一下namemspo这个X。

如果大于namespo y。如果这两个位置上左边的数比右边大的话,这说明左边的数比右边的数以及到它结尾的那些数都大。什么意思?从toY到to这些数左边都比右边大。那么我要把对应位置上的这个。

东西要加上t减Y加一,为什么?因为从Y到to这些数都比这个X这个数要小,所以它右边这些数都比它大,这个就属于跨越左右两边了。那么注意我把它也要附成。😊,X。那么另外一种情况呢。

就是小于等于我直接把右边的数复过来。然后这个墨纸其实我们就写好了,注意我们要把它复回去。要把这个pos更新掉。I加from等于tI。然后注意这个时候有一个相等的情况,相等的情况其实放在这里面了。

我们不能轻易的动这个,如果轻易的动左边,这个逆序数会受影响,所以相等实际上看似没有考虑,实际上它隐含在这个里面,并且不会影响逆序数。所以我们不要轻易把左边加加,而要尽可能的把右边加加。

所以相等的时候把右边的数拎过来。😊,这个是一个非常就是细致的问题。虽然在代码上可能看不大出来,然后我提交一下。这是一个正确的代码。那么第一个方法是这样做,也是比较经典的规并排序的算法。

那么我们看一下有没有别的算法呢?规并排序其实本质就是分制的算法,我们还是用分制算法,但是用一个稍微暴力一点的算法,离散化加分筒的方算法。那什么叫离散化呢?首先给定的这些数数的大小,绝对大小是没有意义的。

比方说我给你两个数,1个1001个1000,这两个数没有意义,和一个01个一没有差别。所以呢我们可以把数的这个大小缩小范围缩到0到N减1之间,怎么做呢?排好顺序,最小的给0次小的给一,最大的给N呃。

最大的给N减1就可以了。那无论怎么做,这个需要N log N的时间复杂度相当于排序。😊。

那为什么要把数的范围缩小呢?我们想把它放到一个比较小的区间里面,这个区间只有从0到N减1,这个范围比较小,对我们比较有利。我们怎么分桶呢?首先桶就是区间的意思,大小我分成根号N这么大。

每个桶都是根号N这么大,当然有可能有尾巴,有多少个桶呢,有这么多个桶,注意加上这个实际上是因为这个除法是整数的除法,加上这个实际上是上除上取整的意思,只要有余数我就需要多一个桶,举个例子。

比方说N等于11根号N取整是3,那么实际上要分成4个桶,因为11除以三是除不尽的那四个桶分别是第一个桶区间是0到2,第二个桶区间是3到5,第三个桶区间是6到8,这前三个桶都是完整的,每个桶都有三个数。

最后一个桶只有两个数,也就是那个尾巴那个余数。那么。😊,给定一个数X,它所在统的编号,其实直接除一下,这个是一个取整,都是整数的除法就可以了。注意下标要从零开始,这是第零个桶,第一个桶,第二个桶。

第三个桶,这样分完桶有什么意义呢?我们把数想成动态的,我从最后一个数一个一个的把数加到桶里面,为什么从最后一个加呢?因为我每个数考虑的是比它右边的数,这个有多少个数比它小。那么我倒着加的话。

就是考虑当前这个数在之前加入桶的那些数有多少数比它小。那为什么要分成桶呢?我们有这么一个技巧。😊,首先分成统之后,我们可以统计每个数出现的次数。因为我们把数的范围已经缩小了,每个数都在0到N减1之间。

每来一个数,我就把这个对应位置加一,这实际上就跟计数排序是一样的。那么我们统理还可以统计每个桶包含数的个数,有根号N个桶,每放一个数,我就统计这个桶里面的数加一,统计完这两个数之后,对于X来讲。😊。

和X在同一个桶里面的数有多少个数比它小呢?我们可以循环这个桶里面的数,桶里面最多有根号N个数要循环根号N次。那么X之前桶里面的数有多少个数比它小呢,注意我们循环的不是数,而是循环的统。

这个时候我们以统为单位,因为每个桶里有多少个数,我们都知道了,我们直接循环桶把数累加起来,这样呢,实际上这个复杂度也只有根号N,因为我没有一个一个循环数,而是按统循环的。

这个也是为什么我最初统的大小取了根号N,因为统的个数和桶里面数的个数都是根号N级别的。这样呢总体复杂度,N个数循环完之后是N乘以根号N,也就是N的1。5次方的时间复杂度。

虽然比N logN的时间复杂度要高,但是。😊,这个呃就是在li code上是可以接受的N的1。5次方比N log n要大那么一点,但是比N方要好多了。我们来看一下这个代码。

这个代码量相对于刚才其实是小了很多的。😊。

还是这个我现在这个墨其实对我来讲没有意义了,删掉。那我要什么呢?这个东西我还要。这个N我还要answer还要。其他都不要了。那么我先把特殊情况处理一下。如果这个N比较小,比方说小于2。

那其实我是把空啊以及只有一个数隐含处理掉了,这些都没有关系。那么下面就是我真正的刚才说的,怎么做离散化。我用一个map,所谓mapC加加的map是key value的对。我把N个数放到map里面来。

为什么要放到map里面来呢?因为我放进去再拿出来的时候。😊,C加加的map是有序的,按照key由小到大的顺序排序的。所以呢我这样相当于省的一个排序。注意我这个加加第十一行的那个加加其实没有太大意义。

我只是为了把key放进去,我最后还会把那个Y6冲掉。那注意这个时候我再引入一个变量M。那么。通过这两个循环,我就把names里面的N个数映射到0到M减一里面去了。那注意这个M可能是小于N的。

这个取决于有没有重复的数。那么继续我们刚才的那个代码,就是8K的 sizeize。我们知道8K size其实就是SQRRT根号N嘛。我当然这里面可以写M,然后。定义两个数组,也就是vector。

第一个数组呢就是同。我们有多少个桶呢?刚才说了N加上baucket。sence减1除以baet size,我们有这么多个桶,我们有多少个数呢?其实就是N个数了。也就是M个数了。

这个实际上是以桶为单位计数,这个实际上是以数为单位计数。那么剩下的我们就是报利的来做了。刚才说了,倒着。把数一个一个加进来,你怎么做呢?每来一个数,首先这个数要被我们映射成0到M减1。

那么我把它映射成X了。那么ID表示X在哪个桶里面,它就是除一下,刚才都说这都是整式除法,那么。😊,我需要看。这个。在他之前的桶。那ID肯定都比。就是这个ID肯定都比这个ID要小在它之前的同。

所以我用这来表示把从这个ID减一循环到0。那么我把它加到answer上,这些数显然都比。这个这些数显然都比这个第I个数要小嘛,而且在第I个数右边,因为我们是从右往左算的。那么这个呢。注意桶的边界。

bucket size这是桶的里面最小的数。那看看这个是和X在同一个桶里面的。我把它加到。这个上面来,那这这时候我要写have这,注意这两个G的理念不一样,这个是以统为单位的。刚才已经强调了。

这个是以数为单位的。那么这两部分把所有的比它小的,在它右边数都算好了。那别忘了更新这个,我们现在多了一个X。多了一个这个ID的这个桶里面的数。那这样这个代码就写完了,我们提交一下。

它也是一个正确的代码。那么。还有没有别的方法?其实还是有别的方法的。

我们仍然用离散化,就是把所有数化到零到N减1,把这个数的范围缩小。那我们考虑二进制。比方说X这是二进制数,比X小的数其实只有三类X里面有三个一嘛,第一个一变成零,后面数不care,第二个一变成0。

也就是这个一变成零,后面是不ca画叉的表示不关心,那么这个一变成0。那实际上这三类数代表了三个集合,注意这三个集合是不相交的。因为它们的前缀都不一样。这个很像这个字典序的概念,所以呢任给一个X。

我们还是从右往左把数都加起来。我们考虑X里面的每一位,我把每一个一变成零,然后统计一下这种前缀出现的次数。那对于不关心的位,我就直接右移就好了。比方说这个例子。

我先把X右移一位遇到了发现是一个一是一个一,我就把这个一变成零。😊,就考虑1010这种数出现了多少次,加到上面去,就表示这些是以1010差比X小的这个一样,遇到这个一,我把它变成零就变成了100。

看这个东西出现了多少次。那最开始我看一下零出现多少次。那么这个其实就是这个算法的本质,用到了一个微运算,我不断的把X右移,每遇到一个一,我就看一下零出现了多少个就好了。😊。

那算法复杂度还是Nlog n的,为什么呢?因为X是最大到N,它的二进制形式有log n这么多位,它的二进制表示有log n这么多位。那所以我们循环次数是logN的对于N个数来讲。

循环次数还是N log N。那这个写起来代码量其实相对就更小了。我们来看一下。😊。

那我偷点懒把这个能复用的代码都复用掉。离离散化至少我们都是需要的。那么到这儿我们都可以用。那怎么怎么写呢?我现在。为了方便,我把names都重新复一下值。这时候我就把ns都变到0到M减1上去了。

注意这是sve。那这样。那么斯我已经都付好了,那关键是这个循环。我们要考虑要循环多少次,为了不计算这个。为了不计算这个log N,我用一个数组,我用一个布尔值来表示要不要进行下一次循环。

什么情况下不要进行下一次循环呢?就是当所有数都右移成零的时候,就不用再做下一次循环了。实际上移动的就是log M那么多位。😊,只是我没有做数学上的计算。还是刚才那个思路,把所有数倒着加进来。

那我们看一下,如果这个数不是零的话。那么。我们发现一个非零的数,那下一次肯定要继续循环了。那么刚才我说了。😊,如果这个数的最低位是一的话,注意这是和一作语。那么我需要把它加上去。这个cule里面存的是。

就是刚才说的每个前缀出现了多少次,异或一是什么意思呢?因为它最低位是一,我和一坐下异或就相当于减了一,把最低位变成了0,实际上就是求比它这一位比它小的那些数。那我不断的这样循环,就可以求出来。

每一位是一都把它变成零,比它小的数了。那么注意一个核心的这个别忘了把这个东西更新。😊,因为表示这个数出现了一次,然后把它右移移位。然后我们看一下。呃,有一个编译错误。第28行。哦,这应该是中括号。

它也是一个正确的代码。所以对于这一个题,我实际上讲了三种算法。第一种是就是比较标准的规并排序的算法。第二种和第三种都是用到了一些微运算啊,二进制啊等等这些方法。那其实还有别的方法,最经典的。

可能就是比较熟悉的同学想到了线段数,这个是比较经典的算法,但是写起来比第二个和第三个要麻烦很多。第二个比较暴力嘛,复杂度是N的1。5次方,这个是N log n达到了和第一个算法同样的复杂度。

但是这个代码量要小了很多,比线段数来讲,代码量也小了很多。那么微运算怎么考虑,以及我们这个问题实际上讲述了怎么利用序,因为求的就是逆序数嘛,我们怎么考虑序,我们用到了把这个数离散化。

把数的范围缩小等等这些技巧。😊。

那么们直接看第二个题。N加一个整数,每个整数的范围是1到N,那么显然至少有一个重复,它现在已经告诉你了,恰好有一个重复,也就是一到N每个数都只出现了一次,有一个数例外,有一个数出现两次。

那么求出这个重复的数,它是立 code上287题,有几个要求比较这个麻烦,不能修改元数组,然后额外空间是常数的时间复杂度要低于N方。那么关键是什么呢?关键是每个整数范围是一到N之间。

其实它已经相当于帮我们做好离散化了。我们上个题离散化的目的就是想把这个数据范围缩小。那现在数据范围足够小了。但是我们还有这三个限制,我们来看看第一种解法。😊,还是微运算,我们考虑二进制数。

假设这个N等于9,那么意思是就是出现了10个数嘛,假设我五重复了,当然这个并不代表数的顺序,嗯,这个顺序可以是任何的顺序,有两个5,剩下1到9都只出现一次,然后这个是1到9的二进制,那怎么做呢?

我们考虑最低一位。😊,我们先考虑所有数都是4位的,最低位1到9之间有5个数,最低位是一。那显然四个数最低位为0。那么实际呢就是它给这10个数里面,我们发现有6个数个位就是最低位为一,4个数为0。

那么标红了这两个不一致。那说明我们重复那个数,最低位就是一了。那么四位都可以这么做,对于次第位来讲,我们发现这个为零的个数不一致。那么我就知道次第位应该是零重复的这个数。那么对于次高位也就是正数第二位。

那么我们发现它应该是一,那么对于最高位,我们发现它应该是0。所以对于每一位来讲,我们都考虑一下实际就是一到N之间有多少个数为一,而这个给定的这些数有多少个数为一。这两个如果不一致的话。

我们就知道这一位它应该为一,否则这一位它应该为0,我们把每一位都确定下来之后,重复的这个数就找出来了。😊,那么有多少位呢?还是刚才那个因为每个数都不超过N嘛,有log个N位。

那么时间复杂度还是N logN。因为对于每一位我们都要循环N次。😊。

那我们来看一下这个代码,这个代码其实并不是很难写。把这个关掉。

这个就是我刚才说的那个问题怎么做呢?先把N。😊,弄出来,注意这个是减一的。那么这个时候我的数组下标实际上是0到N了,因为我已经把它减一了。同样我用N又移I大于等于0呃,大于0来表示这个log n。

我并没有数学上真正的计算log N。那么这个ined呢表示这个实际。给定的这个N加一个数里面有多少个数在DI位为一。那我们看一下怎么判断它在第I位为一呢?直接。用右移就好了。右一I位和E座鱼。

这个就是DI位把它吸出来。那这个竖的呢。竖的表示1到N之间。注意是JE到N之间。有多少个数,DI位为一,怎么判断第I位为一呢?还是刚才那个技巧,又以I位和一作语,那么加加数的。啊,这个循环稍微有点问题。

这个还应该在外面。所以对每个I,我们实际上循环了2N次,或者说2N加一次,反正是N的级别的。这个。那么我们怎么判断呢?如果实际唯一的个数比应该唯一的这个多,那么说明我们要的这个数,或者说这个结果。

这一位为一怎么把这一位复成一呢?和这个东西做或,因为这个东西是第I位为一的这么一个整数,做或就相当于把这一位复成一了。否则这一位是0,我们不用做任何事情,因为初值就是0,最后呢忘它就是结果。😊。

提交一下。啊,这是一个正确的代码。那么我们还没有有没有别的方法呢?😊。

二分怎么二分呢?我们这个区间当然是零到N也好,什么也好,只要是A到B。那么我们二分取终点,二分的通常就是取终点嘛。A到幂的幂的加一到B。我们看一下两个区间,这两个区间显然有一个区间是覆盖满的。

有一个区间有一个数重复,我们怎么知道重复在哪里面呢?我们循环N次,看一下给定的所有的数有多少个数落在这个区间,有多少个数落在另外一个区间,哪个区间里面多出一个数,我们就知道重复那个数在哪个区间里面。

那这样的话,显然我们数一下这个区间里有多少个数,如果它恰好有幂的减A加一个数,那么重复就在这里面。😊,否则的话呢,它这个它如果比幂的减A加一多,就是数实际上比这个区间长度要长的话,实际上只多了一个数。

那么它就应该在这个里面。所以每二分一次我们循环N次就可以找出。这个重复的数在哪个区间里面,区间长度缩小一半。那么时间复杂度还是N log n的。为什么?因为二分要log n的复杂度。

然后这个循环N次判断在哪个区间里面的数多,要循环N次嘛,所以是N log N。那么我先把后话说了。首先那三个限制条件,不能改变元素组,表示我我们不能修改数的顺序,也就是不能瞎折腾。那显然我们也不能复制。

不能使用哈希,因为需要有O一的额外空间。那么另外呢,时间复杂度小于ON方,我们不能暴力查找用两重循环这么找。那么这些限制条件限制了,我们不能随便使用这种方法,但是我们可以使用二分。

我们可以使用刚才那种微运算的方法,我们都没有用额外的空间,都没有修改元素组。那么我来写一下这个。😊。

那么这个其实写起来也不难。二分嘛。左区间。右区间。注意我是用left小于right,如果相等的话,区间里只有一个数。那么显然这个数就是重复的,所以退出来的时候,left和right应该是相等的。

我先算出me来,然后。我这个。为了倾斜,我区间实际上是left和me,以及me加一和right。我看一下哪哪些数落到了左区间,左区间我命名为smaller。循环N次嘛,循环所有的数判断一下。

nameumb么I是不是大于等于left?nameI是不是小于等于幂的?如果是的话,它显然是落在了左区间嘛。那么现在我看一下这个左区间里面的数是不是。me减left加一这么多个。如果它比这个多。

那么显然结果在左区间里面,否则的话,那这个数这个区间是覆盖满的。那么结果在右区间里面。那么最后退出来实际上是left等于right,所以return谁都可以。那携载也不太难。看一下,这是一个正确的代码。

那么。

这个是。第二种方法解决这个例2。那么最后一个题其实相对比较难,它是一个这个打气球的方法。打气球的问题,用动态规划。这里面实际上是讲数组可以做动态规划,给定一串气球要全部打坏。

每个气球上有一个整数打坏它的得分等于这个整数乘以它左邻距和右邻距的乘积,那么把最大得分累加起来,求最大得分啊,立子扣上312题,比方说这个例子,那么我先把。😊,这个一打掉了,所以得分是3乘以1乘以5。

然后呢变成这个样子了。然后我再把5打掉,得分是3乘以5乘以8变成这个样子了。然后我再把三打掉,再把八打掉,得分是167。难点在哪?难点在于我每打掉一个气球,它左右邻距会变。比方说我这个把一打掉了。😊。

把一打掉之后,三的又邻居变成5了,一已经没了嘛。那么我们考虑一下什么不变。😊,那其实无论怎么打气球,总有一个最后一个气球被打掉。那么我们可以枚举,假设0到N减1之间,我们最后把X号打掉。

为什么你要枚举这个呢?😊,如果有X在这隔离的话,那么这两个子区间,一个是零到X减1,一个是X加1的N减1,这两个子区间显然都要最大的得分,这是动态规划的自由子问题。那么有X在这摆着。

这个X减一的右邻距始终不会变,因为X是最后打的嘛,X减一的右邻距不会变,同理X加一的左邻距也不会变,所以X是一个隔离点,它非常有意义,我们不用考虑这个打掉气球之后,邻居会变的问题了。

所以边界的气球是不会变的。那么。😊,这个又代表了我们有最由子问题。那么我们想说明什么呢?用动态规划,我们用DPIJ表示,注意这个DPIJ是从I到J这一段的气球,但是注意I减一和J加一始终没打过。

或者说I减一和J加一都不变的时候,把I和J打干净,这一段气球都打干净。😊,的气球的最最大的得分。那么最终结果呢显然是零到N减1,因为没有负一,也没有N,所以这个天然的满足边界不变的这个红的这个条件。

那么我们最后要求这个,那么怎么递推呢?其实这个已经介绍了递推的方式,我们没举这个X,也就是没举这个K,那么显然I到K减一把这一段打掉的得分是最优的,K加一到J打掉也是最优的,最后把K打掉。

因为无论如何总有一个最后打掉的题求,我们可以没举这个编号,那么打掉K的得分呢,就是这三个东西相乘,注意我们已经说了这个DP的这个条件就是两边邻居不变,所以我们不用担心这个I减一是什么东西。

也不用担心这加一是什么东西,反正这两个东西不变,所以最后打掉K的得分是这个,那么转移方程立刻就出来了,就是这么一个东西。IJ就是把I到K减一打了把K加一到J打干净,这两个最优,再加上最后把K打了。

这个我是max没举KK。😊,那显然是I到J之间的没举这个I到这这么多次。那么时间复杂度呢,是N3次方的。为什么呢?我们要枚举K,然后这个I和J也要两重循环,注意这个I和J不是直接枚举的。

我们是枚举J减I由小到大,也就是I到J这一段长度由小到大。因为我们这个DP的这个关系注意这个I到K减一和和这个K加一到J,这个这个区间长度和这个区间长度都比I到J要短。

所以我们实际上是按这个区间长度来DP了,所以是按区间长度由小到大,也就是J减I的由小到大来算的。我们不是直接没直接枚举I和J,而是没举了一个长度。那然后再每举一个起点。

然后再每举一个K也是三重循环N3次方的复杂度。那么代码现象非常简单,直接用这个式子就可以写。但是要考虑一些变界条件。我们注意比方说这个KK减一,如果比I还小的话,这显然要理解为0。然后。😊。

这个I减一如果比较小,就是I是零的话,这个理解为一等等,把这些考虑到就可以了。然后这个边界条件初始条件我们也不用写,可以直接含在这个里面。下面我来写一下这个代码。

把这个关掉。那么。我们还是先把它的size得出来。然后。把边界条件都写出来,这样比较方便。后面我就是进入正题。就是DP了。我们用这个DP表示二维数阻嘛,就是用vector。刚才我说了。

按照区间长度由小到大。那么我从一来开始做。那么对于I呢?I还是我们之前讲的那个I。这个东西要小于等于N了。那么对于J呢,J实际上就是直接算出来I加Ls减一了。那么对于K呢。可以显然是爱到这只江了。

那么对于这个循环,实际上我们按照刚才那个式子求最大值就可以了。关键是这个最大值求起来也不是那么简单。因为有些边界,我们来看一下。有哪些?刚才说了,有DP。这个东西。I比K减一小的时候才是DPIK减1。

否则我们把它理解为0。😊,然后另外那边也一样,如果K减1呃,K加1K加1到J嘛,K加一比J要小的时候,我们才有这个东西。否则我们理解为0。那再加上就是刚才那个那三个数的乘积了,那三个数乘积也有这个问题。

如果I减一大于等于0。我们才有这个东西。M是I减1,否则我们理解为一乘以。这个那斯K是没有问题的。这边一样,如果这加一小于N,我们才有。那么是J加一,否则理解为一。这个其实就是考虑了一些边界条件。

该理解为零的理解为0,该理解为一的理解为一。然后。最后把那个刚才说的0到N减1这个DP值return回去就好了。看一下代码。

它也是一个正确代码。那今天我要讲的其实基本上已经讲完了。

那时间复杂度也是N3次方的。刚才大家看到了三个循环嘛。那么总结一下,今天讲了其实讲了三个问题。那么数组与序以及二分查找是前两个问题,我觉得也是比较重点的,要考虑一些二进制啊,要考虑一些怎么排序啊。

怎么离散化啊,怎么缩小范围啊等等一些技巧,然后数组与动态规划,这个其实是第三个问题,有很多动态规划的问题,我们都是用数组来表示状态的。比方说最长公共子序列啊,这个最长单调子序列啊等等等等。

那么另外呢还是要多思考多练习,其实数组只是一个载体。😊,也就是说,数组相关的问题其实范围太广了。数组只是一个存储的这个一种结构,它并不是一种这个就是非常非常非常这个专一的这么一种结构。

比方说这个队列啊对栈啊,那数组这个范围太广了。那么有很多问题没有涉及。比方说快速排序,这个partition过程就是今天讲的那个就是找到重复数,也就是第二个问题,其实呃可以用类似的方法解决。

但是它的限制条件太多了,我们没法用快速排序partition把把那些数都交换掉。因为它不允许我们修改那些数组的里面的值。然后to sum啊 sum今天都没讲全排列啊等等都没有讲。

因为这些其实还是和数组有一定关系的。😊,好,今天的课就到这里,希望大家给我提出批评指正,谢谢大家。😊。

七月在线—算法coding公开课 - P6:图搜索实战(直播coding) - 七月在线-julyedu - BV1YW411K7va

欢迎收看7月算法公开课。我们这堂课的主要内容是图搜索实战。这个图搜索是我之前讲的BF和DFS的统称。我将从如下几个方面讲述本课,先讲简介,再讲四个例题。最后总结结束本课简介关于图之前也提到过。

我们要抓住节点和边,节点就是元素,边就是元素之间的相互关系。当然,通常情况下,这个图是隐示的,也就是题目不会告诉我们有一个图去做搜索,我们需要自己发现关系,把它建立起来。关于题型有如下这么几大类。

首先就是求连同分量,这比较简单,也比较单一,后面三个都是跟求解相关的。一个是求任意一组解,这个和判断是否有解是等价的。能求出来就有求不出来就没有。另外一种呢就是枚举求全部的解,中间这个是介于两者之间的。

求满足要求的这些解。当然这个我们可以求出全部的解。然后再用要求过滤一下,把不满足的扔掉,只留满足的。那我推荐的方法其实是说在搜索的过程中,把满足要求的留下来。只要生成的解都是满足要求的是。

终维护这个解是合法的,这样就不用最后的过滤了,应该比求全部解要快一些。最差情况是一样的。因为有可能全部的解就是要都是满足要求的那这个其实也是搜索中的一个减值吧。这里我打了星号,那直接看题。

第一题就是li code上第22题,它是输入N求N个左括号以及N个右括号的合法序列。那这是求所有的解的问题。那关键问题是什么叫合法,左括号的个数不能少于右括号个数,否则右括号没法匹配了。那图是什么呢?

它没有告诉我们图,我们考虑一下节点就是XY当前位置的左括号个数以及右括号个数,为了合法X要大于等于Y边呢,我们从XY出发加一个左括号,就是X加1Y加一个右括号就是XY加一,所以它们之间是有边的。

但不是每个节点都有两条边,对于X和Y相等的时候,我们是不能加右括号的。所以这个时候从XY到XY加一是没有边的,大部分节点都有两条边,除了相等的时候,除外,它只有一条边。那么解是什么呢?我们从00。

也就是没有左括,也没有右括号到NN全部的路径,所以它是一个求全部的路径的问题,有一条路径就有一个解。那我们可以用DFS和BFS记录什么呢?

刚才说的XY以及当前的部分解DFS的思路是每次从这个解上修改一点,得到下一组解,而BFS就比较麻烦了。它要记录全部的部分解,所以相对来讲浪费一些空间。😊。

那对于方法二就是之前也强调过每个节点记录它所谓的前驱,也就是刚好能到达它之前的那个节点。但因为这个不唯一,它是一个集合,所以这个相当麻烦,而且最后还要还原路径。

还原路径的时候可能还需要DFS我会实现DFS以及这个的BFS的方法。一,下面我们来看一下。😊。

首先。我们把要返回什么东西定义好。然后我们写一个help函数。我先写DFS。DFS说了要记XY和一个字符串,就是当前的部分解,然后最后把它return回去。那我们看一下这个怎么写。这个是DFS。

我们传的东西先把参数写好了。answer是记录最后解的这个vector。那么我们需要看一下,首先。这个。Y等于等于N,因为我们始终保证X是大于等于Y,并且小于等于N的。所以如果Y是N。X一定也是N。

我们就找到解了。就可以return回去。那否则的情况我们就按刚才说的。X加1Y和XY加1,那X加1Y是什么呢?就是X小于N的时候,我们才能加X加1Y。😊,那么这时候相当于加了一个左括号进去。

注意我这里面那个n这个str不是引用,因为这时候不能写引用,直接传的是一个这个空串进来。那如果X大于Y或者说Y小于X,就是右括号不够多的话,也就是它们不相等的话,我们就可以到XY加1。

所以这个时候是把右括号加进来。然后阿 sir。所以DFS写起来还是非常简单的。我们来看一下。😊,这是一个正确的代码。我们来看一下BF反怎么写。关于BFS写起来就有点麻烦了。

因为这个队列总总是要自己定义的。那么我们看一下怎么写,这些都没有必要传了。就传两个参数就可以了。我们还叫help。为了写BFS的方法,一,我们需要定义队列里面的元素。刚才说了XY。以及这个字符串。

那么我们看一下特殊情况。关键是N等于等于0,显然空串是符合条件的。可以直接raturn回去。那下面我们就开始定义。我们把起点放进来,我暂时叫t。刚才说了,从00开始。我们把这个定一个对列。

BFS是说我把起点放到队列里面,然后如果队列。飞空,我就从里面拿东西。写一个循环拿什么,我暂时还叫tamp,因为这个可以复用。那么关键是我们怎么更新它,也就是说怎么扩展它扩展的节点叫做other。

我们看一下刚才说的,如果X小于N。我们可以加一个X,或者说加一个左括号,怎么加?X不变呃,X加一Y不变。加一个左括号。然后入队。另外一种情况是X大于Y。那么一样的X不变。Y加1。加一个右括号。

注意这里面我们保证队列里面存的全都是部分解。所以我可以判断一下它是不是解之前那个之所以没判断,是因为。它最后加的是左括号,这不可能是一个解,那加右括号就有可能形成解Y等于N的时候,就是我们要的解。

那么我们把它放进来。😊,这个know就是我们要的解。那否则的话我们把阿入对。看来这个BFS的代码长度比DFS长了很多,所以还是要很多注意的地方,而且可能有编译错误,我们来看一下。

这也是一个正确的那我们解决了第一个问题,我们再来看第二个问题。😊。

第二个问题比较简单,它是200题。给一个零一阵求连续的一的块数。什么叫连续的一的块数呢?就是每个一和它的上下左右叫做连续的,每个邻居再往后上下左右又连续,就是看一被零分隔成了多少块。😊。

它是一个经典的求连通分量的问题。那么图是什么东西啊,他也没有告诉我们图。节点就是所有一的位置边呢,如果两个一是上下左右的关系,我们就加一条边。那目标就是求这个图的连通分量。那么BFSDFS可以统一起来。

我们都用一种结构,一个是对战,一个是队列。当然,BFS可以直接写递归,选一个没有标记的点。当然标红了,因为我们需要标记刚才那个括号之所以不标记,是因为我们搜索的节点不会重复。

因为那个括号总是不断的增长的,所以不可能又绕回到之前那个节点,但这个。😊,两个点之间会它是一个无向图嘛,两个点的点之间会来回来去的走。所以我们要标记,不能再绕圈。

那么扩展邻居每扩展一次就是扩展到不能扩展为止,我们就得到了一个连通分量。最后。😊,能扩展多少次,或者说嗯能从这个一个扩展的点到不能扩展,然后再找一个没标记点,能找到多少个没有标记的点。

就有多少个联动分量。难点在于标记节点,也就是所谓的判重。我们来看一下怎么写这个问题。

那么。我还是先写。DF因为它比较简单。我还是推崇这个这种问题和刚才那个问题。用DFS比较好,因为代码比较短,出错的可能性就会少一点。我们先找一下。一个一的位置。那这里面。如果。这个东西。是一的话。

那么我们就做一下。把I和J传进来。同时,answer加E这里面answer还没有定义,最后把answer返回去。那么这个东西呢。oner显然是0。那我们看一下这个。关键看这个help怎么写。关于这个呢。

我可以先。把这个东西复制过来,为了节省时间,我把这个弄短一点。XY。那第二排是怎么写呢?先考虑废法。越界。或者呢Y对应。越界。或者呢这里注意AXY我们只考虑一的位置。不是一。

那么显然这个就可以直接退回去了。那么现在刚才我说了要标记。标记其实我们可以使用一个布尔数组来标记。当然这个。因为这个题比较特殊,我们只有我们只有两种字符零和一嘛,我就把一都标记为零了。

这样省了一个数组常规做法还是用一个布尔数组来标记。那么。注意这里面如果他不让我们把这个A变掉的话,我们可以先变一下,最后再还回去。比方说我把这个零写成问号之类的,最后在返回之前,我再循环一遍。

把所有问号变成一,这样其实就不变了。那在递归上下左右四个方向就可以了。😊,然后这个是DFS看看有没有编译错误。它是正确的。我们再来看这个BFS怎么写,刚才那是DFS。那么我们同样。

DF呃BF就是说我们需要定一个队列。首先。这个队列呢要存一个行,要存一个列。那么。根据刚才的那个框架,就是先把行和列放进来,把起点放进来。然后是说如果它不是空。我们就从里面拿东西,拿什么呢?拿行和列。

我同样复用了XY。这个是行。这个是列。那关键问题在于我们怎么扩展节点。刚才我说了四个方向。那为了方便,其实我可以定义一个偏移的数组,把四个方向算出来,这样会减少很多运算,上下左右代码会简单一些。

上下左右四个方向XY的偏移。那么我们怎么做呢?四个方向编历一下。把它加上去。那同样要判断。啊,注意这里面我们需要把刚才说的XY标记一下。嗯,同样看一下这个。刚才是判断非法,现在是判断合法大于0。

小于函数就是没有超出矩阵。大于等于两。小于列数。那同样要看判断它是不是一,这个就是NXNY。它是一的话,我们就可以了,可以了,先标记一下。把它标记成0。然后呢,再把它放到队列里面。

看一下这个明显BFS要比BFS要麻烦一遍。我们看一下有没有编译错误。有一个编译错误,我们看一下。第十五行。啊,这个是一个笔误,没写分号。这是一个正确的代码,我们再继续。

看李森。139题给定一个字符串,还有一个字典问我们能不能用字典拼出这个字符串,什么意思呢?把这个字符串切成一段一段的,能不能保证每一段都在字典里面出现。😊,那这个图是什么呢?它同样没有给出图。

我们节点其实就是整数,从零到NN是字符串的长度,表示什么呢?表示这个前缀什么叫前缀,就是从开头开始若干个连续字符,零就是没有字符,一就是第一个二就是前两个N,就是前N个,也就是整个字符串。

那边呢如果我们从一个前缀X。加一个字符呃,加一个单词字典里的单词,能够形成新的前缀X撇。我们有一条从X到X撇的边,什么意思呢?😊,从空串儿。加上字典里面一个单词I,比方说这个字符串是这样的。

后面不知道是什么东西,有两个单词,I和AM空串加一个I。就能形成一个这个长度为一的。所以0一有一条边,13有一条边,什么意思?一在挨着。3就是AM这个对应于AM这个单词。那我们从零能到1又从1到3。

所以从0到3有路。那么也就是从开头能有IAM三个单词,这就对应上了。那目标就是从零到N看看有没有路,这是一个寻找路径,或者说求一组解的问题,判断是否有解的问题。

因为这个返回的时候布尔值思考就是如何我们求出真的求出这一组解,或者说如何求出全部解。同样刚才已经提示过了,可以记录部分解也可以记录前驱,记录前驱稍微麻烦一点。

当然我们也可以用BFS也可以用BFS它们是统一的,我们就从当前的前缀开始加一个单词不断的mark就行了。那同样我们需要标记哪些节点已经走过了,这个是BFS和BFS特点,要判重,这个是难点。

那我们能不能用动态规划呢?BP是动态规划,这个我不赞成它是动态规划。因为它不是一个优化的问题。但是呢我们可以打出一张表来跟DP的思路一。😊,这个表示能不能连接长为X的这么一个单词。

那么我们就看能不能连接长为Y的这么一个单词。这个Y既是下标,又是长度,这个是下标从零开始的下标。那么Y到X恰好是一个字典里的单词,先接到Y再加上一个单词就能接到X。所以总的来说可以说是三种方法。

我都会大概的实现一下,还是先实现DFS。😊。

因为DFS比较简单。刚才说了,我们要标记。一个东西是不是实现呃,是不是经过过,那么。先有这么一个数组,然后。我直接raturn回去了。那我们看一下这个函数怎么写。S是当前的单词。ow是当前的位置。

word dec我就写成一个D了,为了简单一点。表示当前的字典。那最后还是vector布尔,就是记录是否经过的这么一个东西。啊,首先。如果。超出了单词。

其实大于等于和完全等于是一样的那显然我们已经匹配完了。那另外一点很关键,如果这节点经历过了,说明我们之前在这儿就没有搜到过解,那么没必要再搜下去,没有前途,所以就。把mark这个事情做完。

然后表示这个节点经历过,下面是递归的关键部分。我们从n这个位置开始。截一个子串,因为现在n是我们已经到达过的位置了。那么我们看一下再往后能不能接一个。那接一个呢,我们其实是要判断这么一个东西。

从n这个位置开始截取I减n加一截取这么长,然后find一下它。它不等于地点and的话就表示找到了,找到了,我们就可以继续继续的话。就顺便写到这里了。那么下面应该是I加一D have。

那如果这两个同时满足的话,就说明我们从这个位置接了一个单词,并且就能找到注意C加加的substr是起点和长度的。它和这个java不一样,不是起点和终点,这个比较诡异。

那么这时候我们就可以return true了,否则的话。要通过for。那这个是DFS的代码。我们看一下是不是对的。它是一个对的那我们看一下BFS怎么做。注意这个有些东西是没必要传过来的。

比方说这个n就没有用。那。同样这个因为这个have其实可以在本地定义,因为它不是递归的,但是为了方便在外面定义好了,我就直接用它了,那这个就不要了。那,注意也是如果S是空串。那么显然它是处。

那关键的问题是。然后把它标记上,把零的位置标记上。同样定义队列。然后呢。把起点放进去,用刚才说的所谓的框架,就是如果队列不是空,我们就从里面拿东西,我们拿什么?难酪。我就复用这个变量。

然后可以用这后面这个代码。那么我们看一下能不能找到他。这个就是判断能不能找到。他恰好能找到的话,理论上我们就从I加一继续找了。那可以看一下I加一是不是已经可以退出了。这个就表示所有串都找到了。

那么显然可以退出了,否则我就要入队。入队之前我要看一下这个节点是不是新的。刚才说了,同一个节点经过两次没有意义。😊,把它标记上。这就是BFS的写法,然后看一下,好像有个括号没有匹配这个。

然后我们看一下这个是不是对的。这也是一个正确的代码。那顺便再写一下刚才的那个那个DP的所谓DP的代码。那这个可以复用。我们把它改成DP好了,这样的话就省得在里面再弄一个东西了。那么显然。

我们是什么意思呢?从等于零开始。看看能接到哪儿。那么后面其实是差不多的。那这里面呢因为没有对列。我就可以直接把。把它复成一个处。什么意思呢?就是说我们先接到这个n这个位置啊。

注意这里面要判断一下DP now要是tDP now force不能往后接。刚才那个BFS它肯定是。他肯定是处,因为这个。它是便历过来的,但这个时候因为状态全是分复整数,我这样便历,如果当前接到n。

我再从那继续接下去。接下去之后,如果能找到。接到最后就返回处,找不到的话,就把这个能借到的标记上。因为这是从短到长连的,相当于从 now接到I,从 now接到I,把所有状态都mark上。

这个得力于这个状态全都是整数。所以我们直接放到数组下标里就可以了。那么我们大概看一下。😊,这代码不知道有没有错误,看一下。它也是一个正确的代码。我们再看下面一个问题。

为什么有两个问题呢?39和40题它是给一组正整数找出和等于target所有组合。那么一种情况是同一个数可以使用任意多次,想用几次用几次。另外一个呢是相同的数只能用一次啊,其实这两个解法是类似的。

我们考虑一下图是什么。😊,当前的和以及当前要考虑的数AI。也是一个peair,或者说这种对儿,我们作为节点X那边呢。考虑取这个数,就是加上AI下一个数,不取这个数,所以它减法是类似的。

那么我们想一下这个。呃,正整数是什么意思?因为我们不断的加正整数,有可能大于target,我们就不搜了,这可以作为一个减值。所以总的来说,我们要记录这么些东西。当然。这是一个求全部解的问题。

那么跟刚才那个括号那个问题类似,用BFS就会浪费空间,当然也可以存欠驱,但是最后还要还原很麻烦。我建议还是使用DFS其实这几个题都是DFS相对简单。我就在这里面时间关系我就写DFS的方法看一下。😊。

第39就是第一个问题。首先它要返回的是由小到大的数,我们先对它排个序。先对它排个序,排个序之后,因为这个candidates里面不知道有没有相同的数,无论如何我先写个help吧。

DFS显然这个东西要传过去。这个东西要传过去,然后00。然后还有一个是pass。还有一个是answer,当然还有一个是target。那这pass是什么呢?

pass是我们当前已经选了哪些数那answer是什么呢?answer是。这个最终的结果就是vector vector in。然后这个零一个是当前的位置,一个是当前的和,所以这些东西啊都作为参参数传过去。

最后返回的是answer,因为。vector vector,那么我们关键看这个东西怎么实现。把参数写好了。为了方便,我把这个也缩短一点,我把它就叫做A了。n就是当前的下标呃,sum就是当前的和。

他给他不变。pass表示我当前取了哪些数,这个是记录结果用的。这个是我最终的结果存在哪儿?那么同样刚才说的,如果这个东西已经比target大了,显然没有必要搜了,因为全是正数。

那现在就是s小于等于target。我们看一下,如果not大于等于A点size,就是所有的数我都考虑过了。显然我们就看一下它是不是解就可以了。相等就是解嘛。这个拼错了target。相等就是解。

那么我们就把这个answer。把这个呃pass加进来。没吞回去。下面就是一般的问题了。我们考虑一下什么时候我们会取这个数,我们可以这样考虑。那等于0第一个数肯定要取。或者它是一个新的数。

因为我们并不知道A里面有没有相同的数。尽管这个我们排好序之后,有可能还有相同的数,我们相同的数都放到一起去,我们就这样做。😊,这个A不变,我们下一次还总到表示一个数我可以取多多次。

但是下一个数如果相同的话,我就不会再取了。那么。😊,我们就这样。这个表示我要取这个数,把它加上去。然后。target不变,pas answer怎么表示我们要取这个数呢?pass里面要把它加上。

当然注意退回来的时候,我们要保证pass是没变的,还要把它退掉。那么另外一种情况显然是我不取这个数。不取这个s就不变了。所以这个是DFS的写法,大概检查一下。注意这个不取的时候,n要加一。

因为直接考虑下一个数,这个时候我再闹上循环,因为我要考虑no取多少次,然后取取够了之后再下一个相同的话就不取了,看一下不知道有没有错误。它是一个正确的代码。那么为了再讲下一个问题,就是和这个类似的。

只能取一次的。我就把这个代码复制过来,因为可以稍微改一下。哦,我把那个函数给删了,这个好像叫。叫兔吧。不小心刚才把那个函数给删掉。嗯,这个我先下吐吧。那这个呃搜的东西不变,这也不变。

注意这里面我们加一个布尔值表示上一个我取没取,其实初值没关系,出口 first都没关系,因为相同的数我们只能取一次嘛,我们就考虑上一个数取了还是没取,这里面我们叫last。那同样。

这个如果它是一个新的数。或者这个上一个数我取了。因为每个数只能取一次,即使相同。就是说他有两个一,就最多也就取两个。就是上一个数我们取了的话。我们才可能去我的理念是说,对于一连串相同的数。😊。

我一个一个取,直到第一个没取的时候,我就不能再取了。😡,所以这个无论如何就要加一。就是我一个一个考虑,如果它是一个相同的数,上一个取了,我才能取。如果它是个相同的数,没取上一个,我这个也不能取了。

因为我保证我取的三个一的话,我要取两个一,我保证我只取第一个一和第二个一,而没有取第一个一和第三个一,就是这个意思。所以就是相同的数要一取,就是取连续的一段。那么这个呢显然是个force。😊,啊。

这个初值其实是没有用的,因为因为这个tro first没有关系。这个第一个无论如何,我都会考虑取它。那这个其实加一个参数就可以实现了。那我们看一下,当然我们可以这个一个一个做。

最后把这个answer用一个set来存,最后在这里面去重也是可以的。但是这么做其实可以避免去重提交一下。啊,它也是一个正确代码。可见用刚才那个代码稍微改一下,就可以得到这个每个数最多只取一次。

因为这里面有两个一,是因为它原来就两个一。所以这个但是这两个一又是不一样的一。因为这个比方说是二的话,呃,比方说最后取一的话,结果这个target是一的话,结果只能有一个一。

因为我不能出现这个两个相同的集合。所以我必须在这用一个布尔值处理一下,就是相同的数,我怎么考虑,其实一个理念就是大家一定要记住相同的数,我连续的取。就是5个一在一块,我要取一个一,就是第一个取两个一。

就是前两个取三个一,就是前三个,这样的话不会跳着取。所以这个就是这个的目的,这样不会重复,也不会遗漏。啊,这个题目就讲完了,然后给大家几个思考题。😊。

这个7778、90是这个枚举全部的子集,其实做法可以用我这个刚才讲的最后这个问题来套。那5152之前也提到过,就是八皇后问题就是搜这个其实就是DFS的框架。

所以对于这种问题通常来讲都是DFS的写法比BFS要容易一些。那对于这这道题还有一些要说的,其实它就是一个背包问题。如果target本身不太大,我们可以打表,就是用NX表示这个。前个数能否到达X。

那么我们其实可以省一为这个从。呃,sam就是前面的sam往这个就是所有数的总和的sam从大往小的推。那如果这样的话,我们就把它呃附成处。这个其实是考虑呃。如果DP啊X减AI是t,DPX也是t。

因为X减AI加上X就得到了X,其实它也是一个DP的打打表的这种思路。那么这个。如果target比较小,是可以直接放进来的。如果target比较大呢,我们需要把这个布尔数组换成一个map,布尔。

或者干脆换成一个set in,就表示把所有的数。😊,到过的数全放到这里,递推公式还是一样,有一个小数存在,我加上AI也存进去。😊,那么难点还是说如何找到真正的这样一组解,还是需要记录路径。

所以又回到刚才那个尴尬这种方法,难点就是如何记录路径。还有刚才也提到过,它不算严格意义的动态规划,因为它不是一个优化问题,这只是一个波尔达表问题。动态规划一般有max min这种东西。那做一下总结。

首先隐视图的定义它到底是什么东西,我们需要自己发现规律来把它找出来。那判断是否有解,以及找到一个任意解,我们都可以用DFS和BFS来做啊,尤其是联通分量那种问题,它们俩是一样的,判断是否有解也差不多。

但是要找到一组解,可能BFS稍微麻烦一点。DFS会简单一点。那要找全部解的话,我推荐DFS因为它可以从一组解上1。1点改BFS没有这个功能。😊,那要找到满足要求的所有解。

其实就是DFS减值最差情况相当于每举全部。那刚才说了,它就是在一个解上修改一点,放弃最后一步回溯。这个是递归回缩这个内容。那BFS呢,如果要找到某种要求所有解。比方说我们要找到最短的。那么BFS最有效。

因为它可以找到步数最小的那它的难点就在于如何记录路径。关于BFS和DFS可以看我之前的视频讲过BFS和DFS。😊,今天的课就到这里,谢谢大家。😊。

七月在线—算法coding公开课 - P7:字符串实战(直播coding) - 七月在线-julyedu - BV1YW411K7va

欢迎观看7月算法公开课。我们这堂课的主要内容是字符串问题实战。字符串大家都比较熟悉,我就直接选取了4个比较典型的问题,基本上都是li code上的。有一个问题,例外,例三难度呢,基本上是递增的。

但总体难度是中等或者中等偏上的难度。先看第一个题比较简单。li code上第三题给定一个字符串返回它最长的不包含重复字符的子串的长度,返回的是个int,所以是唯一的要返回子串就不一定唯一了。什么意思呢?

比方说输入是这么一个字符串。什么叫子串呢?就是连续的一段字符。那么它不包含重复字符的话,最长的长度是3,比方说ABC啊BCA啊、CAB啊,以及这个ABC啊都是长度为3,不包含重复字符的子串。

再长我们截取4啊,5啊,以及更长的子串,无论怎么截都会有重复的字符了,就是这么一个意思。怎么做呢?😊,最简单的方法当然是暴力枚举,枚举一个起点,每举一个终点再判断重复。我们暂时抛开判断重复。

不说枚举起点终点复杂度已经N方了。那么有没有更好的做法呢?这个涉及到了比较典型比较经典的一个方法,叫做双指针,或者叫做滑动窗口。什么意思呢?我们动态维护窗口I到这之间,这是一个左闭右开的这么一个区间。

维护这个区间里面的字符情况,关键是怎么维护,怎么维护呢?我们保证这个窗口里面没有重复的字符。那么最开始A等于0J等于0,这是一个空的窗口,空窗口没有重复字符,天然满足。那么一旦条件满足。

我们就不断的往右滑动J。增大这个窗口,直到J被卡住。什么叫被卡住呢?也就是说,目前J指向的这个字符在这个窗口里面已经出现过了。那么我们再划过去的话,这个窗口里就有重复字符了。这个不是我们要的结果。

所以这个时候J就被卡住了。那么这时候我们就只能缩小窗口通过滑动I给J解围,怎么解围呢?直到I划过了和J相同的那个字符之后,这个新的窗口还是没有重复字符的。那么注意这个滑动过程中,因为窗口在减小。

所以这个自由解肯定不在这个时候,自由解肯定在J被卡住的时候,那么这是一个追赶的过程,J先往右走,卡住I往右走,给J解围。😊,这再卡住哎再给这解尾,就不断的这么走的这么一个过程。因为是两个指针。

不断的往右走,没有往左走的过程,所以时间复杂度是ON的。注意这个时间复杂度没有包含这个如何判断有没有重复字符这个操作。那具体怎么判断。我们当然可以用哈西呀,可以用这个各种方法来判断,当然最简单的办法。

可能是用一个布尔数组,因为C的字符的这个范围是0到255java呢,因为是unicode编码是0到6535,无论如何都是一个有限的。我们开这么一个数组,每加进窗口,一个字符,把它设置为真,每划过窗口。

一个字符,哎,每划出去一个把它设为假,这样就可以动态维护这个窗口里面有哪些字符,我们来看一下这个写起来非常非常简单。😊。

啊,首先刚才说了,返回的是个int,我把它命名为answer。😊,然后呢,这个东西就是我想记录的窗口里面有哪些字符,因为我是这个C嘛,所以256就可以了。java呢请开到65536。

目前这个窗口就是I到J的这么一个B区间。那注意这个时候我是一个死循环,在循环内部决定一下什么时候把它退出去。我要向右滑动J。前提条件是J不能被卡住,当然,J也不能划出字符串,所以这两个情况要同时满足。

划过加进窗口,那么退出的时候,显然刚才说了,就是一个最大值的可能。那么把它比一下最大。那注意,如果这已经划出去了,这个时候它是大于等于这个的,注意大于等于和等于是同样的。我们退出循环。

那否则呢这是一个解围的过程,怎么解围呢?😊,希望I划过和这相同的那个字符,否则有J在这卡着,这个I只能在不断的缩小。那注意这个因为我是Y循环,我要把它也。复为 force最后这个别忘了。

因为这个SI等于SJ的时候并没有执行,最后return一个answer。聊一下。

这是一个正确的代码。也是比较简单的一个问题。嗯继续看第二个问题。

这个问题在li code上比较新,其实这是一个就是比较老的题目,并不是很新的题目,只是在li code上出现比较晚。他说啊我给定一个字符串,它只包含小写字母,这是为了简单,只包含小写字母。然后呢。

我要求删除一些字符相当于这个去重的这么一个过程。最后呢结果中每个字符只出现一次,要求字典去最小,相当于你要把这些字母去重。最后当然长度不可能超过26了,然后要求字典去最小,不能改变字母的顺序。😊,那么。

最直接的想法是贪心,这个写的有点啰嗦。我大概描述一下这个算法。如果一个字符在字符串中。😊,出现的最后一次位置的时候,我们还没有把它加到结果中,就没有机会加了。因为再往后这个字符再也没出现过。

我们要求这个字符一定出现在结果中。所以。😊,当某个字符最后一次出现的时候,我就不得不把它加到结果中了。但是由于我们希望字典序尽可能小,在加进这个字符之前。😊,如果前面有更小的字符。

当然我们优先考虑更小了。因为我一加上它对于这个字符串的前缀来讲,这个字典序相对就大了。比方说我有一个X当它最后出现的时候,如果我发现前面有A呀,有B呀,我肯定要先考虑它们。

因为这个时候我加入X字典序肯定更大。那么这个就是一个贪心的思路,那。😊,当我某个字符最后一次出现的时候,我就看它左边。😊,出现的那些字符,并且还没加到结果里面的那些字符里面的最小值。

如果这个最小值比我当前不得不加的这个字符还小的话,我就先把最小值加进去,再继续考虑。那有些细节多个最小值,当然取最左边的,这样给右边足够的空间,时间复杂度其实是大于ON的。😊。

这个大家仔细思考。解一下,因为说的比较抽象。

关掉这个。这个写起来稍微有一点麻烦,因为思路并不是那么直观。我们看一下。这个表示就是每个字符出现了多少次。我们用in。来表示这个字符在不在结果中,注意这个name是动态变化了。

它表示在I这个位置以及这个位置更靠右的位置的时候,每个字符出现了多少次。那么我们把它。因为是C嘛,它减去A,就相当于把它画到了0到25之间。answer就是我最后的结果。

注意last表示我上一次已经确定了那个位置,我不能从拉丝,因为它已经确定了,不能从last丝的左边开始做。那么我们来看怎么做。首先为了简单,我先保存一个CC就是0到25之间。

那什么情况下就是我不得不加这个字符了呢?😊,这个东西等于一表示这个I的位置右边再也没有这个C这个字符了。那么当然前提是它不在这个。结果中。这两个条件同时满足的话,我们就不得不加入一个C。但是呢。😊。

刚才我说了,如果前面有更小的字符的时候,我们当然优先考虑更小的了。😊,那么更小的我们怎么做呢?找到前面的最小值,从last到I的最小值,当然前提还是不在。这个。结果中。

所以我们始终要考虑这个东西是force。如果他不在结果中,并且呢。当,这个是取最小值的一个过程。这两个条件同时满足,我们就发现J比X的位置要小了。我们就把X等于J。那最后当然我们要优先加这个X了。

嗯么别忘了把这个东西付成t。那么最关键的,如果X就是I这个字符的话,那么我们把I加一了。如果不是这种情况呢,我们直接扫过它就可以了,别忘了剪剪MC。什么意思呢?

注意这里面其实我们还可以减减这个n么SX减A。但是呢这个其实可以不写,为什么可以不写呢?因为。我把它已经加到结果中了,我们考虑的所有的字符都是in等于for的时候,包括这个。😊。

都是in等于firs的时候,我们才考虑in等于 true的时候,这些字符直接被跳过了。所以这个当我把印付上的时候,这个做不做是无所谓的。😊,提交一下。哦,有com complex error。哦。

这个return的位置。应该更靠上一点。这是一个正确的代码。那么。

我们主要想讲的其实是第二个思路。我们之所以这个不敢加一个字符,是怕后面有比它更小的。但是如果我们不加这个字符,它后面没有字符了,我们就后悔就来不及了。如果我们有一个办法可以后悔的话。😊。

我们是不是可以自由的来家自服了呢?😊,我们用一个堆栈临时保存这个结果的字符串。这个堆栈呢?从站底到站顶,对应着字符串,从左到右。因为我们希望字典续尽可能小,所以我们希望。这个对战底端尽可能的小。

换句话说,我们加入对战的字符,我们希望越来越小。😊,就是越小越好,不能叫越来越小越小家到对战里面的这个我们希望越小越好。那么。😊,如果这个字符X目前我想入对栈的话,那么对栈里面有比它更大的字符。

因为我这个最后取字符串的时候,是从站底到站顶这么取的。对栈里有比它大的,我希望把它弹出去,换成我们这个X。但是我不能随便弹,因为我把X弹出去之后,我把这个对栈顶里面的字符弹出去之后。

后面有可能这个对栈顶的字符再也不出现了。这样我就少了一种字符,这是不合法的。所以只有这个一个字符在右面还有的时候,我才可以弹出去它。所以这定义了如何。😊,就是哪些情况是可以弹出的。

哪些情况是不可以弹出的。简单的说就是如果右边还有的话,这个字符可以自由弹出对战。如果右边没有的话,这个字符弹出去再加不回来了,所以不能弹出去。那注意它是卡住对战的,不光它不能弹出去。

在它更靠下更靠站底的那些都不能弹,因为这个是一个对战,只要有这个字符在下面那些东西都不能弹了。因为这个字符本身不可以弹出去。这就是这么简单的一个方法,时间复杂都是ON的。因为这个每个字符进一次对战。

出一次对战。😊,啊,这个听起来比较复杂,其实写起来比刚才那个方法要简单,我也大概写一下。

那我还用这个就是。这些东西还可以复用,那么别忘了,我加一个对战。对战呢临时的保存结果。从左到右扫描这个字符串,注意这个name的含义是没有变的,都是从I以及I的右边有多少个字符。

有多这个字符出现了多少次。先把它减一。现在我们要考虑,如果这个字符不在。这个对战里面或者说不在结果里面,我们就要考虑把它加进来。加进来的时候,我们把能弹的都弹出去。一个条件,这个首先对战不是空,并且呢。

对站站顶的东西比它大,并且呢。这个东西在后面还有。其实这个要写大于0,但是为了方便,我就写这个就可以了。因为这个C这个和它不等于零是一样的,那么我就可以把它弹出去,弹出去,别忘了这个in要动态的更新。

但是这没关系,虽然我暂时把它弹出去了,我知道它在后面还会被加进来。😊,然后呢。我把SI加进来。这个in动态更新,虽然我这儿临时的把in付成for了,但是没有关系,后面还会变成tr,因为它后面还有嘛。

那么最后answer怎么取呢?注意我是从站底取到了站顶,所以要倒着取。当然我不断的把它弹出来就可以了。如果对战不为空。把它弹出来就可以了。那answer呢?注意这个加的顺序。大概提交一下。

这也是一个正确的代码。

那么。这个问题其实。

这个方法是最优的,因为它是1个ON的时间复杂度。我们再来看下一个问题。下一个问题描述有点复杂。其实仔细分析一下,它和例二是非常非常接近的。😊,我们来看一下它是什么意思。Yes。

翻转与交错给定义字符串S定义函数这个reward reverse。表示把它翻转之后的字符串,这个比较简单。比方说XS等于ABCre就是CBA就是倒着来。注意这个reverse是唯一的。

那么shale呢表示对其中字母全排列,任意排列之后的字符串,这是一个集合。注意这个reverse S表示它是翻转之后,字符串。shaffle S呢其实是个集合。比方说S等于ABCshaleS是6种情况。

因为是全排列嘛,都有可能。😊,那么还有一个定义,这mer给定两个字符串,mer把它们编织在一起,注意不改变原先字母先后顺序。比方说S一等于ABS2等于CD的话,mer表示这个把它们交错在一起。

比方说ABCD是一种情况,取A,然后这边取C取B取D是一种情况,只要不改变字母先后顺序,怎么交错都行。比方说我先把CD都取了,再取AB也可以。比方说我先取C,然后再取ABD也可以,这个情况非常非常多。

就没写。所以merge也是一个集合,沙le是一个集合,mer也是一个集合reverse是一个单独字符串题目是什么呢?😊,给定一个小写的仅由小写字母组成的字符串S撇R。然后我们知道它是这个morege。

😊,reverse S和shaphone s的结果。那刚才这两个都已经定义了,那我们求字典序最小的S。这是hackerrank上。的一个问题。那这个。呃,题目的样例是什么呢?比方说给定这么一个字符串。

那么结果有可能S是这个,为什么呢?如果S是这个reverse S当然是GGE了。那么shaffle Sshaphone S其实有很多,所以我没有写等号,我写的使用它是一个集合嘛。

我可以使用EGG那怎么把它交错起来呢?这个先取这个E,然后再取这个reverse的三个字母GGE再把这两个G取上,所以它给定的是最终默制好的结果,然后。😊,让你求原先的S。那么其实大家可以考虑一下。

如果我们把S撇翻转翻转,其实就是S和shuffleS的结果。为什么?原来它是 mergegere S和shuffle S因为shuffle无论翻转翻转之后还是沙uffle,因为它本身就是乱序嘛。

reverse翻转就是S本身了。所以如果我把S片翻转的话,它实际上是一个真正的S和一个shauffleS。😊,这个末日的结果。就是这里面说的,如果S撇翻转后。

其实就是一个真正的S和一个乱序的S沙uffle的结果。那注意shauffle刚才说了沙uffle的顺序是任意的,所以它永远是一个沙uffle,它反映了S中这个哪些字母出现过。

那么实际上就变成了我给你这个结果让你还原一个字典去最小的S。这个东西和例二非常非常像。例二是说我给你那个结果,然后让你把每个字母选出一个来。那现在是说我给你这些结果,让你把每个字母选出一半来。

比方说这个。😊,给定它,我把它翻转之后变成GGEGGE实际上我给你了4个G2个E。我希望让你按照这个顺序构成一个两个G1个亿的这么一个东西,每个字母个数恰好取一半嘛。😊,然后让字典去最小。

那既然题目这么相似,我们能不能这个沿用例二的那个思路呢?这个也是我选取这个题的这么一个目的。沿用例二的思路的意思是例二,关键是说我这个什么时候压入对栈,什么时候可以自由的弹出对战,弹出对战的条件是说。

如果我弹出这个字符之后,后面还可以再加进来,我就弹出去。因为我要保证它出现一次。这个时候如果我们沿用例二的思路弹出对战的条件就要变。它不是说后面还有就可以弹出,它是后面还有并且后面的个数足够。

我取到一半这么多个。也就是说后面的个数满足我们的需要的话,我们就可以自由的把这个字母弹出去,思路是一样的,只是把这个加入或者说把弹出对战的这个条件改变一下就可以了。我们来看一下这个题怎么写。😊。

就基本上可以复制上一个问题的代码。

比方说我就简单的复制代码。注意hacker rank上的这个题目和li code不一样,它不是写一个类就完了。它要我们写完整的输入输出。那当然我们不能简单的复制这个题的代码,有些东西我们要自己写了。😊。

比方说这个。tack要有吧。strrange要有吧。vector的本身就有。那么呃当然也不能简单的完全这么写。我们看一下怎么写。注意这个有些东西就要变掉了。比方说这个印这现在只是一个布尔值。

那么在这里显然就不行了。我们用一个比方说want来表示。want表示,就是说我需要多少个这样的字符。那么这个namem的含义还不变。那么需要是多少呢?需要肯定是原来的一半。帮他I等于。

那么I除以2除以2,我就用U移来代替了。然后我们再用一个have。have表示我已经选了多少个了,当是一上来我是都没选的。所以我原来的一个in在这里变成两个东西了,一个是我需要多少个字符。

还有一个是我已经选了多少个字符。当然这个namem表示我还剩多少个字符。如果那么剩的足够多。换句话说,那么剩的这个比我想要的还要多,那么加上这个我已经选了这个字符比这个w还要大的话,我就可以把它弹出去。

所以就是弹出对栈的条件需要变一下。😊,那我们看一下,注意这里面就不是这个inC的问题了。什么情况下我需要考虑这个呢?就是说我已经选的字符个数。Have。比这个want要小。我就要考虑这个,那怎么考虑呢?

前面这个还是不变,这个也还是不变。那这儿需要变一下这个name。加上have。就是说我已经有的加上后面的,注意这里面减一个一。因为我这儿已经减掉了。大于等于。Want。什么意思呢?就是说。

我如果这个字符后面的那些字符,加上我已有的这些字符。系。就是足够我的需要大于等于want嘛。那么我就可以就是临时把它扔出去,注意把它扔去,不是把它复为for了,而是剪减那个东西简减have。

因为我现在已经have少了一个嘛。这也是这个减一的条件,我及时把它减掉。😊,我后面那些个数也足够多。不就把他扔出去。那么很多东西要改,我我把这个C加进来的时候。就不是把have那个inC的问题了。

就把它变成一个加加了。然后最后结果是一样的,那么注意我们要自己写输入输出了。那这个S显然是一个strtrain了。我们自己reverse。你定一个solution。S。把这个方法名复制过来。先软一下。

看看有没有编译错误。哦,这个。那个S solutionution的S应该是大写的吧。对,solutionS是大写的。这里面有一些括号的问题。好,那么过了样例,我们提交一下。好,这是一个正确的结果。

所以这个是我想讲的第三个问题,基本上沿用第二个问题的这个答案。

那么最后一个问题也是我想讲的第四个问题。最长合法括号序列,这个也是lea code上一个问题。其实这个问题稍微有点复杂,它是第301题。他给定一个括号的序练。当然是可能包含非法的括号。

删除尽可能少的括号。简单的说就是保留的括号尽可能的多,或者说结果尽可能的长,然后让剩余的这个括号合法。它不是求一个长度,它求所有这个最长的合法序列这301题。比方说输出是这个的话,那输出我可以把它删掉。

就是这样的。当然我也可以把这个这个括号删掉。😊,这个括号删掉,第二个括号删掉,这样呢就变成了这样这样这样这样这样。所以它有两种结果。当然最简单的想法显然是枚举。当然它也是一种BFS,也就是广度优先。

我们对于每一位我们把它加上去或者去下来,其实还可以把它当做一个动态规划,其实BF或者说广度优先和动态规划之间这个差别并不是十分明显。而BFS不记录状态,或者说基本不记录状态。

广东的这个呃动态规划要记录一些状态。因为。我们用这个DPIJ表示圆串的前I个字符。左括号和右括号的差个数是J的最长的合法序列长度。因为这样的话,我们就少记了很多东西。因为这个对于同一个J来讲。

我们只记最优的那个长度就可以。注意这是个int。那么递推式是什么样子呢?😊,因为我这儿只取的长度,注意我标红了,它这个这是一个int,不是一个字符串。那么。前X字符左括号比右括号多这个。

因为左括号一定要比右括号多,因为要合法嘛,左括号不能小于右括号一定要大于等于。那么它有这么几种情况,如果SI是左括号的话,那么它是这样的。这个相当于左括号乘乘数可以少一嘛哦,这这里少写了加一。

这是这个要加一。这个如果它是这个呢。右括号的话,它是DPI减1J加1,这也少写了加一,这个要加一。那么如否则SI有可能等于其他SI可能是字母,它就是只能是DPI减1J。因为SI是字母的话。

这个字符无条件加上去,这个也要加一。所以这三种情况最后都少写了加一,什么意思呢?前I个字符左比右多这个的话,那一种情况是我把这个左括号选上,那么就变成了前I减一个字符。这个左比右这个。多这减一个。

因为他这儿算了一个嘛。那么否则就是这个前I减一个字符,左比右恰好多这个,那么这个也一样,一种是我不取这个DX个字符。那么前I减一个字符,左比右多了这个另外一种呢,我取第二个字符。

那么对于前I减一个字符来讲,左比右多了,这加一个,因为这加了一个右括号,所以这两种情况这要加一。那么这个呢对于这个SI不等于左括号不等于右括号,也就是说一个普通字母来讲。

显然这个无条件的取它注意这要加一,刚才强调好多遍了,这三个位置都要加一。那么初值。00显然是0,就是没有括号的时候,左和右是相等的。那么最好的长度是0。那么对于这种情况显然是负无穷。

因为这种情况不可能出现。那么通过这个式子就可以递推了。那么递推完了,我们只能得到括号的长度。那么怎么得到具体的括号范围呢?就是具体的括号的方案呢?我们在这些。😊,这个长度后面保存一个集合推法是一致的。

我们把这个集合里面的所有东西拿出来,这个集合里所有东西拿出来,末尾加一个左括号,这个集合里面所有东西拿出来加个右括号。所以这个算长度的方法可以类似的把方案算出来。但是注意集合的时候,如果取max的话。

因为我们要所有解。如果这两个相等的时候,对于整数来讲无所谓。对于集合来讲,我们需要把这两个集合末制起来。但如果某一个大的话,我们就需要。😊,这个就说只取某一个,要么取这个加一,要么取这个。

但是相等的时候需要集合merage对int没有这个没有这个这个说法,但做法都是差不多的。所以用集合来讲稍微有一点麻烦。我们需要判断哪个集合是不是严格的比另外哪个集合好。那么我们来看一下这个具体怎么做。

刚才说了偷懒记录路径,一种是我从这儿记录一个方案,记录它是可能用哪些推出来,最后还原路径。一种就是我刚才说的,对于每一个这种状态,我都用一个集合来表示这个状态对应的这个括号的序列。那么。

同一个和同一个集合里面,所有的串长度显然相同,因为它的长度全都是这个变量的这个值。那空间上有一个优化,就是DPI只与I减一有关。所以我们可以滚动数组,用一个一位数组代替二位数组,这个写起来稍微有点麻烦。

也是这个今天最难的一道题,我来写一下。

我先为了方便,我先把N写出来,N就是它的长度。然后呢。A vector set string。这个就是我刚才说的。记录最终的解的。那么长度为零的时候,显然是一个空串。然后开始循环。对于。第I个东西来讲。

我考虑怎么把它加进去三种情况,我就暴力的写了。如果是左括号的话。注意这个倒着循环,因为我用了同一个数组,这个DPI是通过这个DPI减1来推的。所以我在用DPI的时候,保证DPI减一没有被更新过。

所以是倒着的。那这时候假设我有一个函数叫better,一会儿我再写它的具体怎么实现,这个还真是稍微有点复杂。就如果J减一。比这要好的话。就说明我把J减一加上一个左括号放到这个J里面来。

那注意它是一个set。所以我们需要。这样写就是set的那种循环。把J减一里面所有东西拿出来。加上一个左括号,再加回去。我,这个是暗的。加到这里面去。注意这个如果它不比它好的话。

这个haveIJ就等于这个haveIJ减1呃,就等于这个原来的那个haveIJ。所以我没有必要更改,只有它比较优的时候,我才把它加进来。但是这个加有一种情况是这个东西要清空加,就严格比它好。

有一种情况是相等相等要 merge置,所以我这里面并没有对这个have j做任何操作,有可能要清空它,也有可能要 merge置,所以这个全都放到这个better这个函数里面了。为了这个简化操作。

那么否则呢。如果他是右括号。做法类似。那注意这个循环的方向是正着循环。同样我还是要判断。这是J加一了。做法类似。从J加一的be,然后把每个都拿出来,加一个右括号。然后。把它放到have这里面来。啊。

注意这个是星体,星体才是一个奏串,体本身是一个指针。再否则呢就是不是那两种情况,无条件的把那些字符拿出来。那注意这个时候set里面东西我们不能边循环边变,所以我们只好这个。自己写了,就是自己把它拿出来。

用一个temple暂时存一下,这和前两种情况略微有点不同。他还是这。把它放到ter里来。SI吧。然后再把它复过来。别忘了付回去,那么最后。Returning answer。那这个answer是什么呢?

这样事是一个结果,结果是从集合里面导出来的,所以还得再多一点事。haub0,因为左右括号相等嘛。便利。把它加进来。所以三种情况,一种情况加左括号,一种情况加右括号,一种情况无条件的加。

那么这个这三种情况。别忘了这个那个better那个函数还没写呢。better接受的是两个集合。我们看一下A是不是比B好。那么先考虑特殊情况,如果A是空的的话,显然。他不比B好。那如果B是空的的话。

其实我希望A等于B嘛,我就。return一个戳,我希望B等于A。那么第三种情况是就是真正意义的。既然它不是空的,我就拿出来一个看看它多长。因为集合里面所有东西的长度是一样的。那别忘了加一。

因为我把A里面要加一个左框号或者右括号。如果杨哥比他大的话,这里面注意我把B清空。我一return true的话,B就变成了,就是在循环里面,B就变成了A,要么加左括号,要么加右括号,但是要清空。

因为这个解更优,那否则就是它不比它大。那么我们看一下他们就是说是不是相等。如果相等的话,这个A还是比BU,我需要把它摸置起来,所以B并没有清空。提交一下。呃,有一个com然后第五章。手且我死。

这也是一个正确的结果。

然后大概对今天讲的做一下总结。

题外话,这个关于字符串C和C加加都是有字符数组的,就是ch星或者ch这个ee这种东西。C加加呢还有STR的str,这些大家都比较熟悉。注意java的str是不可以变的。那么如果我们要频繁的变的话。

考虑使用 build和 buffer注意这两个有一个是线程安全的,一个是线程不安全的。所以对于这个做工程的话,考虑一下线程安全用哪个如果没有多线程的时候,没有多线程的时候,可以考虑用这个不线程安全的。

不线程安全的效率要高。因为要维护线程安全的话,有一些锁啊等等一些问题。那么字符串题目还是比较广泛的。我们今天讲的第一个问题就是滑动窗口,第二个问题呢,以及第三个问题呢,都是用对战,这个对战几乎是单调的。

从单调对战上做了一些手脚,但是达到了N的复杂度。最后一个问题呢是跟BFS相关的,或者说跟动态规划相关的。好,今天的课就到这里,希望大家给我提出批评指正。谢谢大家。😊。

人工智能—kaggle实战公开课(七月在线出品) - P1:机器学习到底应用在哪些酷炫领域? - 七月在线-julyedu - BV1jh411y7Fh

🎼。OK好,那个首先非常感谢大家啊,小伙伴们来到咱们这个Kgo。比赛的这个实战这个课程。然后从今天开始呢,我们会陆续看到很多呃机器学习去建模解决的各种各样的问题。就看到它的一个流程。

包括各种比赛数据的比赛和工业界里面相对应的一些应用。呃,今天这个课呢,我想咱们先起个头,把计算把机器学习解决实际问题的这个流程,包括建模的方式和优化的方式等等。

以及可能我们会用到的工具啊和一些模板拿来给大家看一看。因为工具有了之后呢呃后续的事情就是就是去应用它了,对吧?所以就会相对而言会顺畅一些。因为我不太清楚大家每个同学的一个背景啊。

以及对 machineine learning的一个呃熟悉程度。所以今天讲内容呢,可能对有些同学而言,已经就是我我讲到具体的这个。一些知识点或者是啊对应的一些概念。可能有很多同学已经会有一个印象了。

或者非常熟悉了。但是有些同学可能觉得内容会稍微有点深,但没关系啊,因为咱们这节课主要是带着大家熟悉一下这个流程和工具,所以啊可能有有很多是大家需要课下去消化的这么一个内容。呃。

大家先在课上的话有一个整体的一个了解,一个。认知就可以了。然后从下节课开始啊,这个嘉浩老师和我会带着大家去看一些具体场景下的 machine型 learningning的一些应用。

各种各样的kego的比赛。然后我我希望大家在之后的每一节课上完课之后,大家都能在案例里面找到和这节课的对应。一些对应的点。就这节课会提到完整的工作流程。实际上啊你如果有兴趣去包括后面的课程。

包括大家更多的去了解这个不管是比赛还是工业阶的新应用的时候,你都会发现,实际我们去用模型场你去解决这个问题的话,不一定会对应今天所有的环节。可能也也有可能我们会在某些环节啊。

比如说特征选择或者是一些模型的啊。模模型的一些处理上会有更深入的一些工作。嗯,O然后咱我今天讲到内容,如果大家有任何不明白的地方,可以随时提出来,好吧。啊,这是今天的一个大体的一个大纲一个大纲。

然后我们可以看这三部分吧,我会给大家。第一部分会带着大家先看一下整个模型 learningning的一个用模型 learningning去解决各种各样的问题啊。去不管你是参加比赛。

还是说你去解决工业业界实际的实际问题的一个一个大致的一个总体的流程。然后在这个流我会根据这个流程得大家过一遍啊,是严格意义上来说是一个比较全的库。大家可能很多同学都用过啊。

叫SK learn叫s learn。那会我会把这个流程 machine型 learning力去解决问题的这个流程当中,涉及到的每一个环节。我们在我们可以去调用的库给大家过一遍啊。

或者说里面的某一个类或者是函数啊,告诉大家在哪好吧,然后可能会涉及到这么一些东西啊,包括。那个数据的处理啊,叫data preprocessing。然后特征的一个特征工程啊。

feature engineering的一些。相关的工作,包括啊model selection呢。然后我们会有一个方式去帮我们选择最好的参数。因为啊如果大家真的熟悉这个领域,或者是之前听人家开玩笑啊。

很多这个领域内的人开开玩笑说,哪有什么特别好的模型,无非就是嗯去找到都大家用的都是这么一些model,对吧?然后你做的事情无非是在这个model的基础上去找到了最合适的一组参数。

这也就是我们我们说我们需要去嗯。做寻找超参数的这么一个工作。因为大比如说比如说大家都是用的啊大家大家可能听说过一些算法啊,非常觉得非常好用的一些算法。比如说叫叫GBGT对吧?grading进去。

然后大家都知道叉级对吧?都听说了说哎呀讨厌参加比赛的同学都会用它。对啊,大家都是用的这个级 boost都是用的GBGT为什么会有差别?原因就是大家选择的这么一些。

我们叫做 parameter超参超参数是不一样的。比如说有多少棵树,比如说树的深度是多少?比如说你做不sing,你你要你你这个这个busing的轮数到底是多少轮。

所谓的这样一些hyperpar parameter会直接影响你最后的一个结果啊,前提是大家都用一样的数据集都让都用一样的特征。这个情况下,你所选择的超参数,它是一个。大的架子。😡。

你选择了这样的一个架子之后,你选择了这样的一个算法,这个算法才会去进行相应的训练,去得到对应的我们说的这些参参数啊priameter。OK然后。呃,我们我们做训练。

我们一定要有个方法去了解我们现在这个模型,我们当前训练到的这个东西到底效果好与不好,对不对?所以会有模型分析和啊可能大家都知道参加比赛的话,很少会有同学直接一个模型就就就干到top three啊。

这个事情是非常困难的。大部分同学都知道我们会有一个。model onble叫做模型融合的这么一个操作,对吧?所以我们会顺着这个123455条5个环节去带大家看一下,我们用这样一个工具SK learn啊。

这么一个package里面到底哪些哪些这个函数或者是哪些部分,哪些part是可以用的啊。然后链接在这个PPT里头都有。如果有同学提前预习过,应该已经看到了。然后我会给带大家过一遍KKgo的Vki。啊。

其实这个是很有用的啊,因为我不太了解,有有些同学我之前看到有些同学去参加所有的比赛,你不会去了解一下历史的一些情情形。来了之后呢,直接就看当前这个问题就就就就强行。试图去构建一个模型,对吧?

那你其实更好的方式是你去了解一下历史上有没有一些和当前的这个你的这个应用场景啊,你的你当前要解决的这个问题比较类似的问题。这个比较类似的问题呢有有几重含义。其中有一重是一会儿我会带大家看到的它叫做。

就是大家去做任何的东西,你是需要一个评判的标准的,对不对?你是需要一个标准的,而这个标准不同会直接影响大家的最后的这个效果怎么样。因为如果你做的优化是针对准确率做的,而最后我们的这个任务。

它所关注的东西是一个比如说啊准确率和和召回率都都关注的。比如举个例子啊,叫叫这个F score啊。或者是这个AUCok那那你只针对准确率去做优化的话,你即使准确率已经做到非常非常的优了。

可能最后去评估下来,你会发现。你的这个排名或者你这个分数都是低的。所以你需要去了解说我这个问题它的评判标准是什么,那你就要了解我们有哪些评判标准。所以整个Kgo体系里头,你会看到有这么多的评判标准。

比如说for regression的问题,回归类的问题,我们就有这么多有但最熟悉的叫me absolute error,对吧?叫做叫做这个啊军方误差或者是MME或者是MAE对吧?O然后。啊。

会有些其他的。呃,OK然后我们在分类问题当中,我们针对classification啊,这是另外一类问题,它又会有其他的一些评判标准啊。你会发现有这么多个标准在我们之前的比赛里头都出现过。

而这些标准衡量的方式是不太一样的。所以如如果你不了解它衡量的标准。你直接以你认为的分类的准确率去做这个事情。你会发现你最后结果不一并不一定是有的。这个地方的话,如果有同学之前参加过一些比赛啊。

比如说之前。呃,我不知道有有没有同学了解,就是很多企业啊,包括像滴滴这样的滴滴打车啊,滴滴这样的公司,他都组织过一些比赛啊。然后像那样一些比赛的话。你会发现他最后去啊。哦我我不好意思啊。

我再跟大家确认一下,现在听课的同学都听得到我的声音吗?OK好好,那个O那咱们咱们接着说啊,我就说不清楚大家有没有了解那样一个比赛。如果你了解那个比赛,你就会看到他的评判的标准和大家的标准就不一样。

我可以告诉你那个比赛的最终的第一名是用的叉吉布做的,是用GBDT做的。但是很多人都是用GPTT做的,包括那个比赛我当时有。有带一些同学去去做这个事情,但是最后效果确实没有人家的好,原因是什么?

你会发现你抓到这个关键的点。啊,滴滴之前有个比赛啊,滴滴。大概是去评估一下一个每一块地区,它的一个对司机的一个需求量啊,又或者对这个快车,对于专车它的一个需求量,好吧。那ケ我的winki呢可以。

KKgo的Vki,我我希望大家去看的一个原因就是你需要去了解你是针对什么目的去优化的那当那个比赛的第一名,那支队伍,他最后去参加比赛也是用的叉几。但是他做了一些优化。

他把它的lost function或者是我们用于评估的这样一个标准做了修正,对吧?那这个修正的方式呢。一会我们带大家看啊,叉几bo里头是支持你自己去自己去设定自己的。啊,sorry。哦,在这。他那个。

叉级bo里头是支持你自己去设定你的objective,嗯你的客观度,或者说你的lo function,你的cos function的,你是可以自己去。设定这个东西的,但是呃会有一点小小的要求。

一会儿我们再告诉大家啊,就是你你他是支持这个东西的。所以你要知道你最后评判的你的这个目标是什么,你再去针对你的目标去优化,这才能拿到在他的评估体系当中比较好的结果。好吧。

然后我们最后会给大家简单的过一下案例啊,我知道有很多同学说我我上过这个10月的这个mine learningning的这个课。那我看过这几个案例了。对,这几个案例只是告诉大家一个完整的流程。

或者说我们这个FK learn,或者说我们叉G boost应该怎么样去调用,只仅仅是这样一个作用。我这节课并不并不是整堂课的核心的内容,集中在这个案例的讲解上,好吧。

然后模型能理在工业界会有很多很多的应用。我们在这节课里头会涵盖其中的一大部分的应用。比如说大家比较关心的,因为能这个东西永远都是和钱比较相关的。所以在经济上会有很多很多的应用啊,包括股市,包括房价。

那这个会。应该是下节课。啊,嘉浩老师会明天的课,嘉浩老师会带大家看案例啊,相关的一些案例。然后我们后面会有课会涉及到能源相关的一些问题啊。因为大家知道。这个政府或者是国家比较关心的这几个几个方向。

里头有很大的一个方向,就是我们能源相关的。所以你会看到现在陆续的我们很多传统行业行业,包括电能电力的这么一些公司。他也会去组织一些比赛。因为他们在试图去通过一些数据驱动。

一些一一些数据驱动的这样一些方法去找到合适的方式。比如说我不知道大家有没有关注啊,大概在呃几周以前还在比赛的是国家电网呃这个电网有一个比赛,是用来predt,需要你去预测这这一个用户。

他到底有没有偷电啊,有有类似的这样的一些比赛,它是能源相关的对吧那现在这些传统的这些企业也开始试图又去找到一些数据驱动的方法去解决这样的一些问题啊,达到这个产能的一个合理的分配和合理的一个利用啊。

还有另外一大部分呢是互联网公司会需要的。像NLP相关的一些。那像检索啊,像分类啊,排序啊,然后toplk to model主主题模型以及文本的一些simity相似度。

基本上是基于这些东西和围绕着这么些东西的一些相关的一些问题。那这个在课程里头也会涉及到啊,然后如果有同学了解的话,像像google像facebook,它的主要的营收来源于它的广告。

而和广告相关的有非常非常重要的一个问题叫click through predictionCTR预估的一个问题,这个东西会直接影响他们最后的收入的。状况。

所以这个我们会有一节课会提到click three prediction这个问题,它可能可以用哪什么样的一些model去解决。那现在的工业界,包括BAT,包括google,他们可能在用什么样的方法。

什么样的model去去在它的data在它的数据上。去去完成这样一个任务。那可能其他的一些就是电商啊、连锁店啊、超市啊等等这样一些啊。不管是这个线上的还是线下的这么一些形式的这么一些电商的形式。

一些商店的形式,他们希望能做到一个销量的一个预测啊,我不知道大家有没有关注像阿里这样的公司的话,他会专门会有一些现在现在有个阿里啊菜鸟是吧?是物流相关的,对不对?所以其实不管是物流物流这一大块。

还是说这个有很很很多时候我们电商会很关注我我需我的一个供需状况,就是有很多东西它并不并不是说我拿过来了之后,我卖不完,我就放着,等到什么时候大家有需求了,我再买。因为都是有期限的嘛。

所以如果我能够提前的预知这个东西,它的销量是是怎么样的,对吧?这一天它的销量是么样的。比如说今天是这个呃平安夜,可能今天的苹果就比较好卖,对吧?或者是今天的这个鲜花就比较好卖啊。

但你有一个大致的一个预期的时候,对你的对你的这个整个库存各种各样的。这样些东西都会有很大的帮助,对吧?然后dep learningning更是最近被炒的非常非常热啊。

所以这节课里头会提到dep learning相关的一些应用。那大体的应用呢都会集中在这个图像上,在image上面。因为。图像上图像是目前落地比较多的dep learninging的领域啊。

包括但是像NLP这样的领域呢,虽然现在dep learninging在逐步的发力,但是还没有到这样一个程度。所以你会看到现在你去tablego上看和图像相关的这么一些比赛。

基本上是dep learninging垄断。它唯一的区别在于说你这个网络是什么样形式的一个网络怎么样搭建的,仅仅是这个差别而已。呃,电商的话会有很很大一部分的收入,也会来源于他的。

Recommendation system。啊,大家开淘宝,你会看到你搜完任何的东西,你点击完任何的东西,你下次再进去,你去看他屏幕上推这个。推荐给你的这样一些商品的图片。

一定是根据你之前的历史行为去做的recommendation。那这个是真的是有效的,确实是有效的。能够。很大程度去提高他们的营收。所以这是很大的一块啊,然后其他的一些比较杂了,包括像大家都知道。

像像一些这个气候啊。我不知道大家有了解有一些app像有一个app叫彩虹天气。他可以准确的告诉你说,你所在的地区。几十分钟以后雨会停,几十分钟以后可能会开始下雨。

那它背后的东西也是数据驱动的这一套m型 learning planning的算法在做的。社交网络就不用说了,现在像微博,像朋呃这个微信的朋友圈这种东西的话,其实里面是蕴含着大量的价值的啊。

所以实际上从从这样大量的数据上去产出一些。可以辅助我们决策,或者辅助我们去去应用的这么一些算法的话,也是非常有意义的。OK所以这是我们可能会涉及到的一些方向啊,而这些方向我列这么一些方向的原因。

也是因为大家如果之后如果现在现在已经在这个领域工作的同学肯定是了解的。如果之后想去这个领域工作的话,你会发现你做的你你所涉及到的这个。这么一些工作其实是可以划分到现在我列给大家的这么一些。

应用领域里面,所以我们咱们的课程也是这么组织的啊。

人工智能—kaggle实战公开课(七月在线出品) - P10:征服Kaggle大数据竞赛 - 七月在线-julyedu - BV1jh411y7Fh

🎼。

OK大家好,我们正式开始。首先做一个自我介绍,呃,我叫庞燕,是7月在线。呃,本次征服开口大数据竞赛公开课的直播老师。今天我们主要跟大家聊的是呃关于开口大数据竞赛。

Yeah。我主要会回答以下几个问题。第一个是呃what is the kgo呃,为什么要参加大数据比赛和如何参加大数据竞赛?OK那么我会通过以下5个呃tops来跟大家具体聊一下。

首先是cago的竞赛模式以及cago的所给出的一些数据,呃,和平台的一些选择,如何选择合适的比赛类型,然后我会给大家讲一下,就是呃针对一个项目是如何从最一开始再到最后的提交的一个整个的过程。

聊完这些之后,呃再跟大家聊一下参加cago比赛的意义和影响。OK我们从第一个呃tops来开始聊起。

开口的竞赛模式。呃呃我想和大家说一下的是,本次公开课的课件,我是用全英文写的。因为我个人认为开口比赛,因为它是国外的一个比赛,它整个的官方页面全部都是英文。所以如果要参加开口比赛的话。

那么最好是对英文的阅读有呃一定基础的比较好。当然在这次呃公开课的演讲的时候,我会全程汉语跟大家聊okK。

什么是开口竞赛?呃,在cago的官方主页上,它有一句话呃,翻译过来的意思就是说呃cago它是一个做模型预测的平台。呃,哦,从哪里获取课件?最后我们就是公开课结束之后。

我们的后台的老师会把课件发送到群里面。同时我们也会把录播的视频呃抛在7月在线的官网上,大家可以呃反复观看。OK我们继续呃,开go是一个做模型预测的平台。

那么在这个开go的官方网站上会有很多的一些呃各式各样的问题。同时针对这些问题,他又会有相应的一些数据集,换句话说,我们不需要自呃自己去收集数据集,开口本身已经提供了大量的数据集。

那么针对这些问题和已有的数据集,会有很多的一些呃参赛选手,他们以个人或者是组队的形式,并且利用自己呃已有的知识和一些呃开发工具开发软件来参加这个比赛。参加这个比赛最终的呃结。

我是做一个预测模型来解决之前提出的问题。OK呃,我给大家呃列了一些就是比较常见的问题。当然我这个是从大概是在两三天前从开go官网上直接播了一张图片,呃,很多人会这么说。

就是说呃开go本身它也是一个tel tricks to win data competitions。就是说在开过这个平台上,只要需要用一些雕虫小技就可以赢得数据的比赛。

我们可以看到就是说在这些已有的一些问题,一些问题,或者是呃数据上面吧,数据分析上面,在最后会给一些金额,这个是呃实打实的真金白银,而且单位是美元。呃,赢得数据比赛之后。

一般来说你会获得一些相应的报酬或者是一些荣誉等等。当然这个也全部禁言。在之后我们会跟大家具体分析一下。呃,开go它是一个非常有影响力的一个大型的比赛。呃,在。它本身是最开始他是做数据数据科学研究的,呃。

它有在200多个国家会有超过60多万的数据科学研究者来一起呃一起就是对这些问题和一些数据做一些公开的研究。呃,有相当很多的大公司与开go一起合作。比如说呃谷歌、facebook、亚马逊嗯。

包括一些像zelow这种呃地产商,或者是liftft和ubber呃这些打车软件等等吧。嗯,在开go上面会涌现出非常优秀的算法。呃,而且这些算法,它最终会运用在工业界和学术界。参加开口比赛之后,呃。

除了拿到奖金之外,而且更多的参赛者他会利用已经取得的成绩。呃,在找工作的时候呢,为自己的一些履历来锦向天花,找到理想的工作。当然这个其实也分两种情况。呃,第一种情况就是在开口本身的平台上去求职。

另外一种情况是就是在参加完比赛之后,呃根据自己的比赛成绩。当然呃成绩是稍微嗯可以说是比较理想的情况下对外求职。当然在最后我们会跟大家就是在求职这块会有所提及的。Yeah。呃。

还有一个话题就是说what's so fun about it,就是关于开go呃有哪些有趣的地方。呃,首先它有一个东西叫re time3点,它是呃翻译过来叫做实时排名。实时排名这个东西呃有利有弊吧。

我个人认为呃,它会让大家在参赛过程中很强烈的竞争意识。呃,有利的地方是我个人认为它会提高参赛者的斗志。但同时也会让参赛者过度的关注这个排名,就是不停的刷这个名次。呃,在我们以往的经验当中。

其实每一个名每一就是每一个选手或者每一个参赛的队伍,他们的那个排名其实非常接近分数就是零点几分是零点零几分的差距。所以个人认为这个呃过度的关注刷排名的意义其实也不大。呃,通过组队合作参加竞赛。

可以和很多大神们相互讨论,并且呃在呃呃论坛上学习学习大神们的方案,呃,让自己受益飞浅的时候得到快速的提升。呃呃在这个一个很好就是很友好氛围的同性交友平台上相互帮助吧。当然除此之外。

对于一些一些就是呃取得很优异的成绩的。比如说前三名会有一个丰富的一个呃资金的奖励。而且呃赢得比赛之后,你。会有很大的机会来拿到一些非常大的公司的一些呃非常好的一个工作机会。就是等等。呃,说到这个的时候。

我想跟大家提一下,就是cago的日志kgo block呃,kgo block它有大概5类吧。还有大概五类。呃,第一类是呃关于d science的一些新闻,数据科学的一些新闻,包括呃cago的一些新闻。

而且他或者是他的那个coel或或者是如何呃教你怎么样参加比赛就等等的一些教程。最重要的一点也是最后一点是winners呃 interviewviews。呃,他主要是说就是获胜者的一些呃实施的采访。

一般来说cago会对每一场比赛的前三名进行采访。同时聊一下他们的心得体会。呃,和他们在参加比赛的时候,是如何解决这些问题的步骤等等。呃,当然了呃开go也会公开他们的个人简历。就是但公看他们个人简历。

而且大多数获胜者也非常愿意公开自己的源代码。呃,个人认为多看一些获胜者的经验,也呃,能提高一些自己的能力。当然了,天下没有免费的午餐,开口一个博客专门专门的标题,就是no free lunch。嗯。

确实如果想拿到一个很好的成绩的话,其实很不容易。呃,需要付出很辛勤的汗水,才能有所收获。呃,聊到这个地方的时候,呃,我想大家更多的应该关注会关注一点,就是说我如何去报名。当你进入开go的官方页面的时候。

呃,比如说我们随便点开一个就是关于竞赛,呃,像这个竞赛,呃,像这个竞赛,我它是一个twitter的一个关于情感信息的提取的一个比赛。twitter大家应该都熟悉,就是好比我们国内的微博,新浪微博。

像美国的总统最爱在那个呃推特治国,就是这个认题OK。拿Twitter这个情感信息提取的这个比赛来说,它总共的奖金大概是15000美元。如果折合成人民币的话,大概是呃10万10万105000。

这个我个人认为是一个呃比较大的一个金额了。呃,他主要会对前三名就是进行相应的呃,给予一个丰合的报酬。OK那么。首先我们第一步当然是要注册一个账号了,这个注册账号既可以用。如果大家可以FQ的话。

那直接用谷歌账号就可以,或者是用自己本身的邮箱注册即可。当你完成注册账号的时候,后下一步就是点击这个呃join competition呃,就是参加竞赛。呃,然后经过一系列的呃自己的,比如说建模刷代码。

然后再多次的调餐,最后当你写完的时候提交s呃s prediction即可。那么这就代表你已经完成了一个比赛。当然这个提交呃自己的模型或者是呃就是提高自己的model吧,提交自己的模型。

它并不是一次性呃就是一锤子买卖。你每天都可以不停的提交你自己的模型,每天回来你可以优化自己的模型调参再提交,然后实时刷排名。那么说到这里,他就有一个大概的一个呃排名。对于排名高的选手,主要是前三名。

你比方说对于前三名推witter这个比赛,他会对于第一名给予7000美元的奖励,这和人民币大概37500。呃,那个。呃,335000呃,第二名的话会给予5000美元的奖励。呃。

大概是呃呃sorry第一名大概是呃49000小5小5万块钱的奖励。第二名大概是呃35000人民币的奖励。第三名大概是呃21000人民币的奖励。当然这个其实我个人认为也是很多了。

但是呃这个总价值15000美元的奖励,他并不是在开国比赛中并不是最丰厚的。还有很多呃更加丰厚的奖励。呃,现在由于是肺炎期间嘛,所以开国又会提出了一些针对呃肺炎研究的一些竞赛这个的奖金那是非常丰厚的。O。

呃,聊到这里的时候,我们已经知道了如何注册。那么下一步就是说根据每一个呃相应的问题,那么如何选择它的数据,如何处理数据,同时如何选择自己的相应的平台呢?

在开过比赛当中。主要有呃三种数据。第一种数据是training data set,就是你的训练集。第二种是test data set是测试集。那么我们在这里也能看到呃,训练集是一部分,测试集有两种。

相应的来说,对于训练级来说,它是公开的测试集这两种分为公开测试集和呃私有测试级。华为测试级私有测试集。那么公开测试集是大家可以一直能看到的,但是私有的测试集是呃暂时在比赛结束之前是无法看到的。呃。

对于每一个比赛来说,我们第一步通常是。嗯,根据已有的数据集呃,首先建模在在训练数据上进行训练,这是第一步。那么第二步就是说在公开的测试区上,然后做一些预测,注意啊,这是在公开数据上做预测。

然后提交自己的呃模型,并且呃系统会根据你所提交的模型来会有一个快速的排名。但是这个排名是基于公开数据以上的排名。OK。当比赛结束之后,最后系统会根据呃你的模型。

然后在他们本身的私有测试数据集上重新进行测试,然后再生成一个最终的排名。那么这个最终的排名才是你最终的成绩。也就是说在比赛之前,虽然有一个实时排名榜。但因为它是基于公开测试数据集的。

它并不代表你最后的成绩,最后的成绩是要基于你的呃私有测试数据集上来的的做出的那个排名O那么说到这个排名的时候,我们给大家看这个在开口上它有个专有名字叫leaboard简写是LB。

那么这个它其实就是一个排名榜。呃,我们可以看到在排名榜上,它有一个是public leaderboard和private leaderboard。在提交呃在比赛结束之前。

主要我们关注的是public leaderboardO我们可以看到下面嗯大概是。我看一下我鼠标呃,大概是呃。这一块吧这一块首先它的背景是浅绿色的,浅绿色的背景,它就代表是呃获胜的前三名。

这前三名是能拿到能拿到奖金的。再往下呃会排是背景大概是金色的,它会标注是go这个go的意思就是说,虽然你没有拿到钱,但是你的分数也非常高,你你所做的模型的系统非常好。

我们可以看的看一下他们每一个模型的分数,第一名是0。722,第二名是0。721哦,这个分数就是基于这个比赛的分数,它是一个降序排列。大家可以看到每一名的差距几乎就是0。001,这个呃分值非常的小。

而第四名和第五名,他们的是几乎是并列。所以说呃。呃,虽然没有拿到钱,但并不代表这个呃参赛者的提交的模型性能很差。相反它的性能非常好。除此go之外,还会有呃s代表银牌不代表铜牌。

凡是在这个 leaderderboard board上面榜上有名的呃选手或者参赛队伍,他们的模型都非常好。有一个统计,大概说是如果能在呃开过比赛上榜上有名。

那么就代表他们所他们是呃这个行业或者是相关问题的钱top时oktop1这个是非常难得的。所以说并不是说你必须得拿到奖,你才你的成绩才非常好。当你的榜上有名的时候,你你已经非常棒了。这个时候你出去找工作。

还是说出去比如说呃如果要申请学校跟老师top词,那都是一个非常强有力的后盾O好,我们继续。呃,说到这个地方的时候,呃,我想跟大家聊一下,就是一个技术吧。呃,为什么要聊这个技术呢?

因为我在我们的一些呃网往年的经验当中,我们会发现嗯,当一个队伍虽然他在公开数据级的排行榜上非常靠前的时候,最终的结果它不一定非常理想。那么如何克服这种现象呢?

我们主要采取一个叫cross validation交叉验证的一种方式,嗯,我们还是拿呃公开的测试集呃,公开的训练级和测试级的为例。比如说首先第一步,我们会把我们的测试结先随机的分成几个,分成几等份。

我们把每一等份叫做CV这个CV的意思就是说cos交叉验证。比如说我这一步,我把我的公开的呃训练节,我分成三个部分O我分成三个部分。然后。第二步是在呃所有的数据集上,我们进行呃除其中一个数据集以外。

我们进行预测。比方说我们把我们有train和。大家注意啊,这个train和都隶属于train data都隶属于训练集,只不过是把它均匀的分成了几等分。如果说我们把CV1和CV2作呃训练的时候。

那么我们就把CV3作为一个交叉验证的项目,就一个呃自我呃自我测试的一个地方。如果我们把CV2和CV3作为训练的话,那么我们就把CV1来作为一个自我测试的数据集。同理CV1和CV3做训练的时候。

我们就把CV2作为一个自我的测试集。就是do predictions all but one。在CV上进行训练和测试。那么最后会把呃我们这些信息就来自于CV所得到的模型的信息,然后进行一个推断。

在这里我想说的是。请更多相信自己的模型的性能。同时,针对于公开训练集和自己的教叉验证的模型来说,我希望大家能更多的信信自己的教叉验证的模型OK。分享两个小技巧吧,就是如果你的呃所遇到的问题。

同时他所提供到提到的呃数据集非常小的话,那么通常来说,越简单的代码其实能达到越好的效果。有时候代码不必冗长。但是如果对于。非常大的一个数据来说,那么希望能更更多的关注于就是我们的快速迭代问题。

OK还是那句话。相信自己的模型,同时相信自己调叉验证的呃结果啊,而不要总是过多的去关注于公开的这个公开的这个排行榜。给大家举一个实际的例子吧。

大家可以看到现在这个图片是大概是两年前也呃是zeo这个房地产公司所提到的一个就是呃比赛吧,这个比赛是做呃zio自家的房屋评估的一个预测的模型。嗯,当时大概的金额大概是我数一下啊。120万美元。

我数了两遍,我怕数错,120万美元OK那这个金额非常丰厚,是两年前的一个比赛。而且现在来说,他这个比赛已经关闭了,我们看一下结果。呃,目前大家看到的这个是后面的private leaderboard。

是最后的最终结果。最终结果是在。私有的数据体上是呃进行验证之后的一个排名。OK我们可以看到。最终的第7名和第10名,他们的排名分别下降了6名和8名。我们如果反推一下。

我们就可以知道现在的第七名其实是在最终嗯比赛结束之前的第一名,而现在第10名是最终结束之前的第二名。OK那很可惜的是,在比赛结束之后,呃,很可惜的是在比赛结束之后,他们并没有拿到钱。

因为他们的名次向下滑了。作为一个反面例子的话,其实不应该叫反面例子。如果说正面例子的话,我们可以看一下前三名。OK我们可以看下前三名,尤其是关注一下第一名跟第三名,第一名,他们的排行榜是上升9位。

也就是说在比赛结束之前,他们是呃第一名的成绩是第10名。O我们可以看现在的第三名和第五名,第三名和第五名,他们的成绩分别上升了133位和418位。说句实话,这个非常就是这个上升的名字非常可怕了。已经嗯。

可以说他们在最后一秒之前,呃,他们的模型并不是非常的好。如果尤其是那个第五名,他前面有418个人,现在都比他们好,都比他的模型好。但是他还是相信自己的模型最终取得了第五名的成绩,第三名他上升了133名。

最终也拿到了前O所以说呃很多人他其实呃为了迎合这个公开测试级的呃,测试的就是测试的结果的性能,他们去呃做了一些可以说过拟盒的事情。像过拟盒。虽然你在公开测试集上,你感觉你的效果非常好。

但是当我们当系统最后用私呃私有测试集的时候,性能不一定非常好。所以说在我们的经验是就是呃一些参赛队伍。如果你忽略了那个在公开测试集上的呃一些结果,更多的关注于自己在交叉验证时的结果的时候。

你的成绩通常来说还是比较好的。当然前提是你的交叉验证的结果也比较好。啊,运气的话确实很重要。对运气的话,运气也是实力的一部分嘛。当然其实我们主要还是不能靠运气啊。OK我们聊一下。

就是参赛的话有哪些to子吧,哪些工具或者是哪些平台嗯,在。呃,在开口比赛当中,主要是呃大家主要选择两个工具,一个是python,一个是R语言。但是换句话说,我们也只能选择这两个工具。呃。

选择这两个工具的话,我个人建议呃,大家对哪个语言熟悉,就需用哪个语言。嗯,不要因为它本身语言没有说优劣之分。呃,对哪个熟悉,你就采用哪个。像对于我本人来说,我我不会R语言,我主要是用python的。

所以我就会考虑python。OK在python的这个当中,呃,首先在开go上,它会给你提供一个叫朱pyter notebook book的一个工具。在上面你可以直接进行编程,直接进行你的测试。

它已经预先安装了很多的库。像这些常见的库,它上面都有我给大家实地举个例子吧。

我我现在退出我的屏幕,我然后我打开我的浏览器。

OK我打开浏览器。

我说开。进入开狗的官方主页。目前来说我是并没有进行登录的。当然你可以进行,如果你已经有了账号,你可以进行登录。我现在想给大家演示的是这块这块是它的一个可能。呃,我们可以点击try now。

okK我们现在进了它的一个col,它本身是我个人是因为是呃基于ropy book的一个界面。如果大家对朱py notebook book比较熟悉的话,呃,那个人认为用它的col基本上是无缝衔接的。

O给他们O给已经打开了。我们可以看一下,比方说呃我想验证呃有没有一些就是常用的一些安装的库。我们现在可以测试一下,比方说呃我现在。Import。CV twoO two是呃open CVV这个库的简写。

呃,open CVV主要是来进行识别图像和图像处理的一个库。呃,我现在打印一下它的。他的版本。OK然后我运行,我们可以看到它C two的版本4。2。0,这个我不敢说它最新的版本,但是基本上已经非常新了。

我们可以再做一个测试。比如说如果你要是用呃神经网络的话,我们有可能会用到pyto。OK用到touch,我们同样打印一下toch的版本。啊,sorry,这写成基 two了。Yeah。OKto的版本是1。

4以建一个自己私有的呃私有的。呃,私有在自己私有的课人的情况下,呃,在自己私有的课人的情况下,呃,我们可以搭建一些。比如说可以加载1个GPU或者是加载TPU等等,来加快我们的呃训练的一个一个过程吧。

OK我现在关掉。然后我们重新回到我们的呃PPT当中。

ok那么如何选择合适的比赛类型呢?

我这块是我是从他的官网上直接扒到扒下来的。那么呃在官网介绍当中,呃,开过的比赛类型主要是有两大种,第一种是常见的竞赛类型,第二种是一些不常见的竞赛类型。当然我觉得这是句废话。

那么我们看一下常见的竞赛类型有哪些。常见的竞材类型主要有4种,第一种叫featured,第二种叫research,第三种叫started,第四种叫playground。我们分别看一下呃每一种。

第一种featured。对于第一种来说,呃,我已经用就是黑体或者是红笔给帮大家已经嗯标注出一些关键字。它所谓的feature的这种比赛类型,它主要是针对积器学习的。

同时它会更多的是一些呃大公司来提出的一些针对该公司的一些专有的一些预测问题。给大家举三个例子。第一个例子是all state呃这个公司来提出的一个预测。它主要预测的是他们的销售呃销售。

通过他们销售历史来预测自己的保险保险的情况。第二个例子。第二个例子是维基百科来进行预一个就是那个负面一些消息的一个分类一个挑战。第三个例子是leaow这家房地产公司。

他们所做的一些就是对自己的房屋进行的一些预测。我们可以看到这些呃问题基本上全部都是相应的大公司来针对他们本公司的一些问题所提出的。所以说这个是feature这一类的一个比较呃很有意思的特点。哦,对了。

如果最后同学们拿到课件的话,呃,我这里已经给大家就是呃像标出了一个相应的链接。如果你点击的话,你是可以进去的。OK所以在课后也希望大家能跟嗯能在群里都关注一下,然后取得我们的今天的课件,O我们继续。😊。

Yeah。呃。对于fishature来说,它还有一个比较吸引人的地方,就是说嗯针对每一个问题,这些公司都会给出一笔非常丰厚的奖金来吸引大家来解决这个问题。最高可以达到100万美元。

100万美元大概是700万人民币。当然如果说你这个比赛的奖金越高,那么就意味着这个比赛越难O这个比赛越难。嗯,对于这类的比赛,不管你是你们领域的专家,还是说你是一个完全的新手。

其实我觉得大家都会以参加这种比赛,因为参加这种比赛,更多的是来呃,它是一个很好的机会来提高自己的呃编程能力,然后搭建模型能力和整个一个逻辑思维的能力吧。这是第一个类型。第二个类型是research。

从它的字面意思上来讲。啊,从哪里获取课件哈?就是当我们节奏之后,那个我们的后台工作人员会把我的课件就是泼到群里头。呃,最后我们也会把今天的直播视频也会挂到我们的7月在线的网站。嗯。

大家也可以到时候进行关注。好,我们继续。😊,Research这一类从字面意思上来说,我们就可以知道它主要是针对学术的一些问题。他们更多的是呃像做一些实验实验类型的,我们还是举个例子。呃。

在这里我列出了三个呃,第一个例子叫是谷歌它提出来的一个一个挑战,就是说呃在一些数据集当中,它希望你能快速的找出一些地标型建筑,这是第一个例子。第二个例子是呃做一些呃白头金的一个识别。

第三个例子是说呃就是是也还是围基他们所提出的,是希望能在一些呃很大规模的分层的呃文本当中进行一个快速的分类。大家可以看到这个类型非常多。大概有30万类,而能如何进行精准的分类。

这一类的问题主要是针对学术来来说,它通常并没有一些奖金。呃,呃通常没有奖金,但个人认为呢他会有时候会提供一些就是呃就是你解决问题的一些能力的一个机会。呃。

所以说research来说也是一个比较好的机会吧。个人认为。第三种类型是我今天想重点强调的,它是started类型。started类型。从C篇意义上来讲,我们就可以明白started主要是针对新手来说。

如果你是新手的话,我个人建议呃先参加这种类型的竞赛,然后再去返回去再参加research或者是feature的竞赛来拿取奖金O这种类型它更多的来说是针对新手。

而且它是经常会有的一种就是生命力很强的一种还是举两个例子。呃,一般来说呃如果进入开go的话,首先大家都会呃就是解决一个问题叫泰坦尼克号的生存问题。O泰坦尼克号这部电影大家都应该看过吧。

反正我信象是我很小的时候看的呃,他这个问题主要是说我现在已有已经知道这些我所面临的危机,同时我也知道自己的乘客的一些特征分布,比如说年龄身体健康等等一些特征分布。

那么哎如何规避这个风险或者是风险来临之后。哦呃,如何最大限度的救人这等等这些问题。第二个问题是进行一些房屋的呃房产的预测。房产的预测呃,这个也是一个老生常谈的问题了。呃。

一般来说started这类的竞赛。呃,它会把问题一直挂上去,基本上是不会关闭的。但同时他还有一个问题,就是说当你自己当你已经提交你的呃模型和竞赛结果之后,你的你的这个结果会在排行榜上一直挂两个月。

两个月之后,你的结果就不再参加比赛了。当然这也是一个公平问题。呃,既然这种类型的题目已经是呃就是一直以来就在挂在网上的。所以说很多模型其实基本上已经达到了满分。呃。

大家也可以在网上上看到就是关于这类问题的解法。呃,所以说它是一个学很棒的学习的过程吧。这个是我强烈参就是推荐新手们呃,首先去呃参加一个比赛。Yeah。下一种类型是叫做playground。

playground的话它主要呃是就是为了呃解闷儿。当然了,我当然了就是我相信有很多就是呃科技展们或者是很多大神们呃闲着没事干的话,就找一些乐子嘛。

那么这种问题就是为呃就是这些科技展或者是大神们所提供的这种类型,它也是一般来说它非常呃像那个started,但是它不大一样,它也是主要毛就是针对于新手的针对于新手的呃,它当是他会提供一些奖金。

对于前面started这一类的比赛,它并没有任何奖金,只是为了让大家一个锻炼和提升的过程。但是playground他会提个他有的会有没有奖金,但是他会给你个荣誉。但是呢有的来说他也会给你一些奖金。

当然这个奖金呃,如果是呃和之前呃和之前feature那种类型的比赛相比,可以说是微捕足足道的吧,这也就证明了playground也主要是针对新手的OK。我这也写了一些就是列了一些它的例子。

比如说呃猫狗比较像猫狗这种比较是我个人来说认为一般如果是呃学计算机视觉这方面的朋友,当你学呃神经网络的时候,这个基本上是你第一个所要面临的问题OK。呃,还有比如说叶子的分类。

或者是纽约城市的呃初册的规划问题等等。OK到目前为止,我们已经聊了4种主要4种类型,这四种类型是主要最最主要的四种类型。那么除了这些常见的类型,嗯,开过官网上还抛出了我还它还有三种比较不常见的类型。

它分别是嗯。recruit呃recment, annualual和limit。我们我们分别来看一下吧。第一个。从字面意义上来讲,我们就可以知道它主要是为了招聘而存在的。呃,这些呃这类这类的比赛。

它主要是一些公司,它进行组织的一些挑战。然后我们可以把这类的比赛来作为一个它是一个找求职面试的一个过程。嗯,我不知道大家有没有求职,就是在那个呃。呃,计算机领域有没有求职的经历?一般来说。

如果是跟就是编程相关的。首先呃首先你的简历经过初赛以后,然后一般会到公司或者是呃进行一个远程电话或者视频面试。呃,这个过程基本上就是呃现场编程的一个一个过程。但是如果你参加了开go的这种竞赛。

就是这类型的竞赛的话,它相当于已经进行的一次片筛选。所以说这类的竞赛,主要是针对求职来说的,呃,像这两个例子也很明显。第一个例子是沃尔玛的求职,它主要是做一个就是。库存销售的一个预测。

第二个是airn的一个招聘的,他主要是做一个新用户来定就是订票的一个预测。airn这个是美国的一个呃网站,它主要是做那个就是如果我想旅游的话,我可以通过airab定民宿订酒店等等。

okK所以说通过这两个呃比赛,我们可以看到。呃,很显然就是招聘OK。下一个类型是就是anual的。当然这个类型基本上我个人认为基本上呃对于我们现代朋友来说应该是不会参加的。当然我也是给大家列出来哈。呃。

他本身来说我不能把它叫做一个很严肃的比赛类型。嗯,开go它每年会就是举行两次,一次是。在3月份呃,他主要是做一个机器学习的一些比赛。另外一次是在大概在圣诞节的时候做一个优化的比赛。

最后一个类型是叫做limitity的限制级。限制级的类型。呃,这块它我们基本上看不到。这么说,我们基本上看不到想参加限制级的类型,一般是两种。第一种就是它是完全私有的。第二种是它虽然是公开的。

但是你无法进入。你想进入的钱,你必须是得收到别人的邀请。一般当你收到别人的邀请的时候,在业内的话,大家都会把你认为是大师,认为是master。所以说这种情况呃只有大神们才能进去,是专门受邀的OK。

聊到这儿的时候,我们已经给大家介绍了呃7种的比赛类型。嗯,我给大家总结一下,呃,如果你是初学者的话,呃,我非常建议大家从started或者是playground的比赛开始。

从这些初级的比赛呃来了解一些打比赛的一些基本的套路和解决问题的思路。当然同时也能获到一个比较呃良好的成绩,给自己建立一些信心。呃,如果呃已经不是初级者,或者是经历过这些初级的比赛的时候。

我强烈建议大家参加feature的或者是research的比赛。如果你是初值者奖金去的,那么直接进入rese,直接去参加feature的比赛。OK呃,说完了比赛类型,顺便给大家聊一下比赛题目有哪些类吧。

就目前为止嗯开go比赛主要开go的比赛题目主要有我个人认为大概是呃大概是四类。在最初的时候,开go主要是做数据挖掘 mining。然后随着现在AI的发展。嗯,它会涌现出了更多的比如说计算机视觉。

或者是NLPCR语言处理的一些问题,还有一些就是优化的问题。呃,如果你对计算机视觉这方面有兴趣的话,并且以后想申请就是相关方向的研究生嗯,博士生或者是相关的一些工作。

那么我个人认为最好就是专注于计算机视觉的比赛题目。呃,同一种类型的比赛题目基本上是有套路可循的,说白了都是些套路。如果你打的比赛多了,摸清了其中的套路,那么你的成绩也会自然就是越来越好。OK呃。

所以我个人认为就是说不要过多的关注于其他呃其他类型的题目,或者其他领域的题目,关注于本领域的题目,这是最好的。另外还可以就是有针对性有针对性的就是选择一些比赛题目的一些细分领域。还是比如说再举个例子啊。

还是计算机视觉的。如果当你进入开口的官网的时候,你可以发现在计算机视觉的题目下,它还有细类。比方说有些是和生物医学相关的。呃,我记得有一个题目是蛋白质的图谱分类,有的是和那个动物保护相关的。

比如说座头基的分类等等。就是说可以针对一些细分领域来进行深入的挖掘。嗯,当然了,如果你急于利用开口的比赛的经力来提升自己的背景,我个人认为自学起来呃,自学是没问题的,但是自学起来有点困难。嗯。

你可能不知道就是如何规划打比赛的这个路径。我个人建议就是找一个呃有经验的老司机带一带呃,找一个大或者大神带一带。当然了,一般大神大牛其实不是特别好找,而且有时候人家可能也没有那么充裕的时间。

所以我在这也就是推荐一下我们去月在线的开口实战课程。嗯,在那个课程里面会有呃专门的老师会给大家解释,就会解析一下呃往年的开狗的一些例题和比赛的一些经历。OK嗯,在最后结尾的时候。

我也跟大家会再去聊一下那个关系,关于那个开口实战项目的课程。OK我们去看一下。

第四个大问题呃,就是如果你拿到一个项目的话,你一般来说你会如何解决这个项目。当然,鉴于今天是公开课,我并不会给大家就是具体的讲某一个项目。因为大家的领域都不一样嘛。

我会给大家就是介绍一下呃一般的一个套路过程。OK。

。现在我们假设我们已经开始呃进行一个开go的比赛了。我个人认为主要有四大步吧,第一步就是进行数据分析,进行数据分析,同时进行一些数据预处理的过程。那么在这一部分的基础上。

下一步就是针对你数据的一些特征进行深入的挖掘和选择。然后再下一步才是建模,注意前两步的工作其实是非常重要的。至于建模是反而我个人认为反而是嗯不是相比而言。没有那么重要。😡。

当你只有当只有把数据规划好之后,把特征提取好之后,那么建模才会事半功倍。OK当建模完之后,那最后的呃一步就是提交了O当然了,如果仅仅说很笼统的说这四步的话,我觉得没有什么意思。

我给大家呃每很详细的介绍一下其中每一步的小门道。比如说第一步第一步数据数据分析。我个人认为在数据分析这一步主要有两个方面。第一个是数据的预处理。第二步是数据的可视化。拿数据数据预处理来说。

我个人认为这一步是非常重要的。O呃,通过对于你一个数据的清洗去掉一些呃没有用或者种就是冗余的没有用的一些信息,说白就是一个去噪的过程。然后呃当你的数据呃有些偏差或有一些误差的时候,那你可以用一些小技巧。

比如说规划。来整理一下这这些数据,这一步是非常重要的,只有把数据先规整好之后,那么才有利于你之后的一些进行。那么如何证明自己的数据规整好了,那么就涉及到第二个问题了,就是数据的可视化。

在数据可视化这块呃基于不同的领域,不同的项目,大家可以用相应的工具来进行数据的可视化。比如说你如果是做呃图像识别或者分类等等,就跟图像有关的。

你可以用m play或者是openC等等这些库来把你图像所抛出来。呃,如果是做数据分析的话,呃,我也建议大家用一些其他库来把你的数据进行一个呃统计分析。比方说这个工具叫做box plot相形图。

在这个相形图上嗯一般来说有5个要素。第一个要素minim最小值。第二个要素Q one是4分之1值。第三个是中值,第四个是4分之3值。第最后一个是最大值。那么根据呃这些值的分布。

你就可以大概的对你的数据进行一个了解。如同时对于奥莱尔对于那些异常值,那么最好是把它去掉,以防止对你的模型进行干扰。当然了呃对就是数据分析来说,呃,不光是相形图可以帮助大家呃。

还有一些常见的比如说散点图直方图等等,都可以进行这个数据的可视化。这一步的目的就是说来呃进行在数据预处理的过程中结束之后,我们要确定我们的数据已经得到了一个很好的处理。

OK那么这是第一步就是数据的呃预处理。第二步个人认为是呃特征的一个关于数据特征的一个处理。它比方说。对你的数据了解之后,一定要对进行数据进行特征处理。针对不同的领域会有不同的方案。嗯。

当然我在公开课就不给大家一一赘述了。在课程的实战,在开口实战课程当中,我们的老师会为大家做一个详细的解释。在这一步,我个人认为它最终的目的就是feature selection,选择数据选择。

那么特征选择。一定要选择对自己有利的特征来降低你的运算时间,并且提升自己的模型的性能。第三步是一个建模的过程。嗯,在这一步呃,首先我个人认为要建立一个比较简单的模型,一个VC model。

建立一个简单的模型,先把你的想法,先大概实现一下,把你的模型转起来。转起来之后,然后再回到我们第一个topic所聊的那个cros validation叫查验证。呃,一般来说呃。

把你的测试集大概分5到10个小子集就可以了。呃,通过。搭建一个简单的模型,同时进行运运转起来之后,来理解呃你模型的评估标准,再然后初始化你的操参数。调参提高性能。嗯,而且我建议大家多试一些其他的方法。

千万不要仅仅基于自己最开始想的那个模型,然后就一直针对你的模型来进行优化调餐。其实有时候你如果呃就是多用一些方法的时候,你会发现不同的方法会带来不同效果。可能你之后想到的一些模型想到的一些方法。

会比你最开始想到的模型所带来的性能提升更大。在这个过程当中,也建议大家经常去开狗的论坛上,嗯,就是跟其他一些大神多多交流毕竟这也是一个非常大的同行交友网站嘛。呃,都是一种方法。呃,然后提交你的模型之后。

你可以对比public呃public呃测试机上的排行榜的一个排名,然后优化自己优化和调整自己的算法。我再强调一下那句话,还是更加的吸引自己的模型。同时。

更多的相信自己的模型性能在交叉验证这样的一个性能的表现,而不要过多的关注于排行榜的表现。排行榜只是给大家一个相对的一个参考的呃范围,但是它不是你的标准。第四步就是提交了。呃,提交这块的话呃。

建议提首先是提交完自己的呃模型之后,当然你提交并不是一锤子买卖,它也可以进行多次提交。OK它可以进行多次提交呃,多次提交每次提交之后。

我们可以根据你先你先就是优化好的模型的一个排名来看到自己的一个一个性能的提升。然后同时根据跟其他模型相比,然后返回来再进行更改自己的模型,再次提交。最后还有一个非常重要的就是好运气,好运气也非常重要。

Yeah。参加比赛的意义和影响。当聊到这儿的时候,其实我个人感觉呃聊这个更多的是一种鸡汤文学吧。因为大家其实知道,首先我们参加这个比赛,当然了,我们也是希望拿到一笔奖金吧。呃,毕竟它是以美元结算乘以7。

1的汇率。这样的话还是一个比较丰厚的一个奖赏的。OK比较丰富的奖赏的。所以说除了你拿到奖金之外,我们还可以提高自己的能力,呃,提高自己能力。

那么就可以对我们将来的一个人生规划就是求职这块的一个一个很重要的一个筹码。同时呃我个人认为还有一个非常大的优势,就是说呃可以教到很多志同道合的大神们。通过这些大神们,其实他就是一个小小的人脉。

当你呃跟很多大神们一起交流过之后,你就会走进他们的圈子,不光提高自己的一些技能。同时你也可以增加你在该领域当中的一个人脉关系。还有一点,我就我想说的是这个popularity知名度。这个知名度来说。

我个人认为就是不管是参加比赛也好,还是说。就是在生活当中也好,打造一个自己的一个品牌,这个是非常关键的。这个品牌其实什么是品牌?我觉得对于我们来说,品牌就是自己就是自己的这个名字,对吧?呃。

通过参加比赛拿到一个很好的成绩,增加自己的知名度。那么这个时候不管你是在求职,还是说想呃读取研究生、博士生来进行跟老师tos的话,当说出你的名字。

同时你的名字后面跟着你在开拓比赛当中所取到的一些排名的话,一切水到渠成。OK一切水到渠成啊,有同学说呃开口的课程都是3年前的对我们的老师会就是重新更新课程的话,而且他因为是直播。

所以也会跟大家就是一个面对面交流的一个过程。OK说到这儿的时候,呃,那么左面呃右面这个就是开狗的实案例实战班。当你点击的时候。我已经把就是相应的链接已经就是超链接上去了。呃,当你点击的时候。

你就会可以进入。呃,可以进入我重新看一下啊。可以进入就是相应的课程。比如说你可以搜索7月在线。OK7月在线这个班级开口案例实战班,我们往下滑的时候,呃,我们往下滑。呃。

他可以首先就是对一些呃课程的简介跟大家聊一下,就是开口的具体的一些呃事业。因为大家注意开口它本身是有很多领域组成的。所以在公开课上,我并不可能就是针对某一个特定的领域跟大家仔细聊。

但是在这个呃实实战班里面。实战班里面老师会针对每一个不同的项目会跟大家聊。这儿虽然列出来了10个项目,呃,大概14个项目,但这14个项目是基于各个领域,基于各个领域的。呃,当报考课程之后,呃。

同学们也可以根据自己感兴趣的领域,跟老师就是实际聊一下。呃,来从老师身上挖掘更多的一些技巧,一些呃参加比赛的一些小的套路。

OK除了这个开口实战案例班如果有是同学对自己的就是可能是新手或者是想进入这个领域的话,不知道自己如何选择哪一个领域的时候,我更多的想建议大家可以考虑。可以考虑就业班。就业班在就业班里面。

这个就业班主要是针对计算机视觉方向的okK针对计算机视觉方向的计算机视觉方向是一个非常有潜力的呃一个领域吧。而且它的薪资就是在呃薪资里面算一个非常高的一个水平。嗯,通过。

就业班当中嗯打一下打一些就是很扎实的一些基础。比方说我们会从一些最开始的计算机视觉技术的基础,比如说如何进行图像处理,它的基础进阶,然后一直慢慢的过渡到机器学习与深度学习这块。呃。

再然后再会过到过渡到深度学习的高级技巧,呃,包括一些我们深度学习常见的一些领域。比如说目标检测呃,实力分割呃,图片搜索从识别目标跟踪等等。呃。呃,有同学问有优惠吗?呃,这个是有优惠的。呃。

具体的优惠请大家就是呃可以咨询一下小七,或者是我们的相应的老师。当你点击这个报名咨询的时候,呃,也会有相应的老师跟你进行呃一对一的联系联络。呃,在7月在线上不光有这两个班本。好。是这样的。呃。

我看一个同学说呃大专生就没戏了,但是我并不这么认为在我因为我本身是博士,在我这个求学的经历当中,我会发现就是说有很多本身不是计算机这个领域的同学,他直接转行到计算机这个领域。所以计算机领域。

你可以说他的门槛低。但是他的你也可以说他的门槛高。只要自己想学的话,他是可以学的。毕竟最终我们的目的还是为了拿到高薪,然后走向人生巅峰嘛。OK呃,像这一门课程的话,是我们7月在线一个精品课程。嗯。

他会他会根据。他会根据就是计算机呃视觉这个这方面的一个非常前沿的理论,然后进行不断的更新。而且它因为本身是直播课程,所以呃老师会实时的跟学生进行就是交流。呃,这种这门课程会有三位博士跟大家就是具体讲解。

OK大家对于今天的公开课,还有一些其他什么问题吗?在之后我们会把我们的课件抛给大家。呃,同时呃视频最后的录播也会呃公开的抛在7月在线的网站上。如果大家对今天的公开课有任何问题,或者是想跟我聊的话啊。

那大家也可以现在就是在打字好,感谢这些用户送出来的鲜花。

对,参加比赛的话,既可以个人身份,也可以哎组队的身份。组队的话有一个最大优势,就是说呃大家各负责一块儿,通过自己的强势来专注的负责某一个模块。

他这个开口的实力课来,我们先回到还有实例课。开口实力课呃,它本身只要我我建议就是如果你是想参加开口的实战班,那么你一定要有pyython或者是R语言的基础,这个是非常重要的。呃。

当你有了这个编程基础之后,我觉得你就可以参加这个是案例的实战班了。因为它案例的实战班,它会涉及到不同的领域,针对不同的领域,老师会给你讲解其中的首先是原理,然后推导和插建模型和如何优化的过程。嗯。

每一次开播老师都会就是针对他的实战班来进行,就是针对呃相应的变化来来进行更新这些视频。所以说大家不用担心。

实验班将由韩老师为大家讲解。

在CV剧小班这块,如果感兴趣的话,也可以先做一下免费试听。就是这些比较最基础的一些关于呃目标检测的一些问题。OK如果没有问题的话。

那么感谢大家今天来我们直播间来呃听我和大家聊一下关于开口竞赛的一些呃一些小东西。呃,我们会把我们的课件,就是播在群里,同时也会把录播视频放在官网上。呃,欢迎大家来看。呃。

同时如果有对于开口案例实战班有更多兴趣,或者是想呃想进行CV就业班的一些更多的一些信息咨询,也欢迎大家跟我们的后台老师进行联系。

OK谢谢大家。😊。

人工智能—kaggle实战公开课(七月在线出品) - P2:零基础入门Kaggle竞赛 - 七月在线-julyedu - BV1jh411y7Fh

对,如果大家大家对呃我们的直播课程有什么疑问的话呢,可以在我们的呃直播间,就是说可以发文字跟我们沟通。对,这个都是可以的。然后我会在讲的过程中呢,如果大家对我们讲的内容有疑问呢,我也会停下来给大家解答。

对,然后我们最后这个PPT呢,应该是会发发到我们这个呃就是说直播群里面。对。那我们今天开始我们今天的一个直播课零基础入门开go竞赛。呃,那么呃我们今天这个直播课的一个内容主要分为以下几点。

第一个呢就是数据竞赛的介绍。第二第二部分呢是开go常见的赛题类型。第三部分呢是开go解题流程和技巧。第四部分呢是开go的比赛案例。第五部分是如何一周快速上手开go。

那么我们今天的一个呃讲解的内容呢是主要针对想入门学习,或者说之前没有接触过开go的一个学员。那么这节课是非常适合你的。那么我们这次直播课呢就是想就是说从头带大家认识一下认识一下数据竞赛。

认识一下开go是什么。对。

那么我们今天的一个直播内容呢,应该是在一个小时左右。

那么我们首先来看第一部分就是数据竞赛这一部分。那么这一部分呢,其实我们首先给大家介介绍一下,就是什么是数据竞赛。第二部分呢就是说数开go的平台的介绍。第三部分就是说数据竞赛的意义。

那么我们首先来看一看什么是数据竞赛。那么可能大家在。

就是说做这个就是说上这个课之前,其实已经很听到了。就是说比如说国内的比较出名的天池平台data方或者说国外的有kego或者说d data这些比赛平台。那么这些平台呢其实都是一些数据竞赛平台。

那么我们接下来首先给一个定义就是数据竞赛是什么数据竞赛,它是以工业或者学术问题为导向的聚合广泛跨学课人才参与的利用算法模型和探索解决方案的研发模式。那么这个地方有一个要点。

就是数据竞赛它是以以特定的问题为导向的。在每一个每一场竞赛里面,它其实是一个特定的问题。而且数据竞赛它是我这个下面写了两点,就是它其实是一种众包的竞赛模型竞赛方式。它是对参赛的人员没有门槛限制的。

基本上只要你想参加这个比赛,你都可以参加这场比赛。第二点呢就是数据竞赛它是有一个明确的业务背景。比如说呃这次。对,我们已经开始了啊,我们是7点钟开始了。对,我们才刚开始不久。呃,对。

那么呃注意竞赛它是有特定的问题背景的。呃,就是说他每一场竞赛都是有一个特定的问题。那么我们这个。参加这场竞赛的目标就是要解决这个问题,对吧?那么数据竞赛它和普通的竞赛有什么区别呢?

比如大家如果在本科参加过这个英语竞赛、作文竞赛或者数据建模。嗯,数据竞赛和这些竞赛不一样的,就是数据竞赛,它是以具体数据为比赛内容,而且有就是说很定量的呃一个评分机制。比如说我们提交一个文件来算一算。

我们这个我们预测的结果和真实的一个结果,它们之间的差异性,对吧?它是一个定定性的啊定量的一个呃就是说评分,它不是一个定性的一个评分,而且它是一个有交互式的,比如说我们今天提交一个结果。

它能得出一个的得分,我们明天提出一个结果,它也可以丢嗯给我们一个打分,所以说它和这种普通的竞赛,它是不一样的。比如我们参加一个数学建模比赛,对吧?那可能只有一次提交机会,就最后的提交机会,对吧?

这是数据竞赛。那么我们再来看一看呃数据竞赛,其实它和这个呃我们现阶段的一个呃大数据其实联系非常紧密的。我们比较呃就是说很直观的一点,就是呃很典型的一个数据竞赛。

就是imagineimagine其实是在这个2013年嗯或者说2012年左右李菲菲老师提出来的。imaginenet,其实它的一个呃载体任务是对图片的类别进行一个分类。

载体总共包括1300万张图片和1000类的物体照片,就是说总共的训练数据集是1300万张图片,所分需要对这个类别进行分类,是1000类。那么。imagine数据集它是非常难的一个数据集。

就是它原始就是说需要对这个类别进行划分1000内。那么从2013年到2017年,这个分类就是说参赛选手的一个精度,从71%,逐渐提升到97%,这个就是说基本上是非常非常高了。

到现在而且是2017年到97%的嗯,应该是现在应该是接近98%99的,那么而且imagine这个数据集是深度学习时代的引爆点。呃,如果大家对深度学习有一定量级的话呢。

那么这个nexnet其实就是在20就是说参加这个呃imagine数据集而火的对吧?那么imagine数据集它其实也是一种数据竞赛,它这种形式也就是给进了一个训练级,给进了一个呃验证级。

还给进了一个测试集。然后你在测试集上面提交结果,然后进行一个打分,对吧?那么这个也是一种数据竞赛,而且是就是非常非常出名的一种数据。那么imagine数据集呢,它其实推动了整个行业的发展。

那么我这个地方画了一个直线图,就是说从2011年开始,或者说2014年就是说深度学习开始普遍嗯发展开始。就是说这个imagine就是说这个深度学习,它推动了很多的发展。

比如这个地方说的是资源语言处理这个领域。那么imagine数据集以及这个人脸检测人脸检测的LFW或者coco这种物体检测典型数据集呢,成成为了呃这种领域算法验证的统一标准。比如说我们想要发表一篇论文。

我们就想必须在这个imagine数据集或者其他数据集进行一个刷分。当我们的模型当我们的论文的模型达到一个 of时候,那么就很能说明我们模型的一个准确率,它的一个精度,对吧?那么现阶段一个深度学习。

它其实很多的一些论文都是在一个数据集上进行一个刷分,然后才能嗯就是验证你模型的精度,对吧?那么其实imagine也是一种最最出名的一个一种数据竞赛吧。对。

那么其实现阶段呢我们比较出嗯著名的一个数据竞彩平台是cago。那么开go平台呢,其实它是嗯国外的啊嗯cago它是国外全球最大的一个数据竞测平台,它每年都会举办嗯数十呃几十场的数据竞赛。

主要以算法赛和可视化比赛居多。呃,我们的直播是有回放的对。呃,开口平台它也具有完备的平台机制,从比赛题的介绍,赛数据分析、评分排名到最终分享。就是说它这个是非常完非常完善的。

那么开go呢是在2018年2019年,现在已经被谷歌收购了。所以说开go现在呃已经汇聚了全球应该是几十万的一个数据竞赛的一个人才了。那么在开口比赛中呢,他其实已经把这个数据竞赛的一个流程讲的。

就是说梳理的非常清楚了。我你可以提交一个文件来到这个排行榜上面看一下你的得分。然后这个排行榜会进行实时更新。最终呢这个比赛根据这个排行榜来进行一个呃划分这个排名。对。

那么开go呢其实它就是说这是这是一个比赛开go比赛的一个截图啊。开比赛其实它有以下组部分组成,就是说它会给出这个比赛的一个背景。

就是在这个over页面下面嗯比如这个script它会描述这个赛题的一个背景信息u就是它的一个评测的一个信息时间轴time然后这个data data页面呢,它会给出这个呃数呃比赛的一个数据集它的一个情况。

然后nch book呢就是我们这个它会呃开平台它不仅提供了这个评分机制啊,排名机制,它提供的这种在线的ch book这种机制。

那么大家如果对这个呃ipad notebook或者说呃这个呃R语言里面R语言里面chbook比较熟悉呢。其实nchbook它是一种非常非常方便的这种就是信息交流方式吧。

那么开go呢它自从被谷歌收购收购之后呢,它在这个呃嗯开平台的chbook里面我们。可以使用CPU的环境,也可以使用GPU的环境,也是非常方便的。嗯。

这个讨论的嗯未成dicussion就是我们在这个呃页面可以对这个比赛进行一个讨论。leaable就是对我们这个比赛进行一个排名,对吧?这就是一个典型的一个呃开拓比赛的一个嗯截图的页面。

那么我们再接下来再看一看,就是说我们刚才讲解的数据竞赛,它的一个发展和它的呃开个平台。那么我们接下来讲一个就是说和我们自身相关的。就是我们为什么要参加一场数据竞赛,呃。

我是非常建议大家就是说如果没有参加数据竞赛呢,可以是呃了解一下或者参加一下呢,为什么呢?因为对于我们个人来说,参加数据竞赛是对我们个人而言意义非常大的。首先数据竞赛它是相对于公平公正的。

是比较公平公正的,而且优优异的排名可以体现你的能力。比如说你在这个比赛里面,它排名前10%前5%或者说前20名前10名,对吧?这个都是非常好的一个经历,而且可以体现出你的能力。第二个呢就是呃数据竞赛。

他可以丰富你的经历,而且可以增加简简历和面试的得分。假如说你做了一场比较呃就是排名比较不错的一场比赛呢?那么你可以把这个比赛写到你的简历里面,对吧?这都。

是以可以当成一个项目呃来给就是说面试官进行一个呃阐述的对,第三个优点呢就是说数据竞赛,它可以带你带您就是说掌握真实数据据以及业务场景下的一个解决方案。因为我们现在一些数据竞赛。

它都是呃一些呃工业界的公司啊,或者说学术嗯学术的一些比如说今年的一些KDD的这种比较著名的一些会议,它呃举办的一些比赛。那么这种竞赛呢,它其实呃都是有真实的。业务场景和真实的就是说嗯业务背景的。

那么参加这种这种比赛呢,其实可以带你掌握就是说真实数据下的一个业务。还有他的解决方案。那么我还嗯就说想要强调一点,就是和理论相比,动手能力也可以呃就是也是非常重要的。呃,你已经开始了,为什么看不到。

你可以重新把APP退退一下,或者网页刷新一下。呃,那么如。和我们现有的一些机忆学习或者深理学习理论相比呢,动动手能力也是非常嗯重要的。就是说动手能力它可以考验嗯。

动手能力它可以考验我们就是说对数据挖掘流程的一个了解,而且呃它可以带领我们就是说对模型的调餐一个了解,以及对工具库的一个呃了熟练程度。因为我们现有的一些。呃嗯不管是呃一些机器学习或深度学的教材啊。

它都是以这个理论就是说为主要的,而没并没有以这个实际的实操,就是说为主要的内容,那我们参加一场竞赛,那么其实可以把这个理论应用到具体的一个问题中间。而且在参加这个竞赛的过程中呢。

你可以对这个模型有过更深入了解。比如说这个模型在这种场景下,它到底是怎么调参的,它在这个种场景下,它的一个训练曲线是怎么样的。而且你可以熟练的掌握一些工具库,对吧?

比如说你之前自己学pandas或者是学一些库的时候,你根本没有哦这种个具体的一个业务,或者说。没有遇到一个具体的问题,你不会学学到这么深入,对吧?那么如果遇参加这种竞赛呢。

其实也能够很大的呃增嗯增强你的动手能力。对。

那么我们今天呢其实这个主题就是说小白如何入门数据金彩,就是说你想零基础,如何入门数据精态呢。那么如果你是零基础,你想入门。数据竞赛或者说你是零基础,想上手参加一场开关竞赛。那其实你会遇到很多很多问题。

第一个问题就是说你对pyython或者说操作系统不太熟悉。那么你可能就首先你要学习一下pyython基础,对吧?第二个呢问题你就是说你对机器学习理论和酷使用不太熟悉。那么你也没办法很好的参加一个比赛。

对吧?那么右右边这张一右边这张图呢其实一个嗯挺搞笑的一个图,就是说当你呃一个机器学习新人或者是说机器学习初学者,你想参加一个数据竞赛的过程中呢,你可以。跨过这前面这些部分,就是说这是数据可视化呃。

数据预处理,数据归一化,直接到这个数据呃,就是直接到这个模型的训练化预测。就是说你可以跳过这些步骤。那么我们这些我们这节课呢就是教大家如何先跨过这些步骤,就是说先。了解一下Kgo它到底是什么样的。呃。

与此同时呢,我们嗯在是呃。8月份和9月份也在我们的7月在线会开设了两门与开go相关的课程。第一个课程呢是从头到尾带嗯就是说带你参加一场kgo比赛。这个第一门课呢,这个是呃学习周期是66次课。

总共是呃3周到4周。呃,第二次第二个课呢是嗯开go实战项目班。那么这第二个课呢是就是说稍微的内容会多一点。第二个课呢,它是包总共包括了12次直播课。那么总共嗯包括应该是10个比赛,具体的比赛。

那么如果大家就是说在看完我们今天的直播课之后,还想继续深入学习开go竞赛,嗯,我们比较比较建议大家去嗯报名这两堂课。对。

那么我们再来看我们今天的第二部分就是呃开go比赛的常见赛题类型,对吧?那么我们就是说今天的课程呢主要是面向初学的对吧?那我们就讲的比较基础。那么我们呃常见的赛题类型呢,其实可以根据我们的赛题背景。

赛题任务以及赛题数呃赛题数据进行分类。我们具体的。

我们这个地方是根据这个赛题的一个数据进行分类,我们可以划分成结构化的赛题、图像赛题、文本赛题和语音赛题,对吧?那么我们这个地方呢右边呢是我们现有的开Q平台的,它这个呃不同类型的赛题的一个占比啊。

我们可以看到这个结构化的数据挖掘,其实是占据了58%的比例。那么我这个其实是在呃2呃18年之前,很多比赛都是结构化的。那么现在呢很多比赛都是非结构化的,就是说图像的文本的语音的。

那么在这种非结构化的赛题,非结构化呢就是指图像文本或者语音这种嗯数据。嗯,非结构化的赛题里面嗯图像的赛题就是占据28%,还有文本赛题占据比较多。呃,有文本分类相关的课吗?对啊,有啊,我们这个往前翻一下。

就是这个实战班里面的有几次课都是文本分类的一个课。对,文本分类的比赛。对。

呃,今天直播呃时长是一个小时,应该是从7点到8点。对。那么我们接下来看,就是说其实cago平台它已经帮我们把比赛进行了一个进行在难度上进行一个划分啊。那么开go比赛类型我这个地方给大家总结好了。

就是说根据我们赛比赛的一个目的和形式,它可以分为featured playground started和other other types。那么这种就是这这这些分类呢。

其实它是根据这个呃你可以根据难度进行分类。比如说这个get started的,就是最简单的一一系列的比赛。还有这个playground就是稍微简单一点的。然后research和feature的。

这是这个实际的一个就是说一般的赛题就是偏难。那么在其他类型的赛题里面么,我们可以划分成这个呃rement就是这个呃招聘的,就是相当于专门用来招人的一个竞赛。还有这个每年一度的比赛。

还有这个邀请赛和这个课堂的比赛。其实现在go的平台上面有很多这个呃课程的一个大。都放在开歌上面,特别是国外的一些嗯课程啊。对,那么开歌比赛呢还可以根据这个比赛的阶段来进行一个划分。

就是说可以把它划分成嗯单阶段的嗯比赛而,两阶段的比赛,还有一个科勒赛。那么科勒赛呢其实就是呃和我们嗯大家就是说其他的一些比赛不一样。科勒赛和非科南赛的主要的区别就是科勒赛。

你的提交必须要通过开呃开歌平台上呢nch book来进行提交,它不能通过其他的一个形式。那么如果把这个根据比赛内容进行划分呢,就可以把它划分成机器学习比赛和数据可视化比赛。在K歌平台上面。

现在主要的是这个机器学习赛比较多一点。

哦,那么我们刚才其实就是说把这个开开个平台上面的一些比赛的一个呃类型给它划分好了。那么我们接下来就是说看一看我们遇到的一个赛题,我们能怎么解决。

我们我们这个地方呢是以现在正在进行的一个getingstar的这个入门赛叫real lot这个呃NRPV这个就是对呃twitter上面的一些推文进行一个二分类。这个赛题呢。

其实就是预测呃ttter上面的一些推文到底是呃真消息还是假消息,或者说预测它到底是一个呃真正的一个灾难的一个新闻还是假的一个灾难新闻,对吧?那么这个呃比赛的链接呢放在左下角,对。

也是大家课后呢也可以看一看,那么这个比赛呢其实也参加的人数比较多啊,现在已经到接近1800人呢?对。那么呃当大家遇到一个就是说参加一个比赛的时候,当大家拿到一个赛题之后,确定一个赛题之后要怎么做呢?

首先你要阅读这个赛题的内容,对吧?我们先首先你要根据你这个赛题的一个介绍,了解以下几点,就是说我们这个赛题的背景是什么,以及我们的赛题,它的背景,基于这个背景下面,我们需要完成什么任务。

然后看一看我们这个赛题有什么评分方法,对吧?这些都是我们需要了解的,而且嗯比较重要的点,就是你需要分配好你的时间,对吧?这个就是在嗯比赛的页面也会给出我们赛题的时间。嗯,在了解了我们赛题内容之后呢。

我们接下来要根据我们的赛题数据进行一个分析。因为这个赛题的数据呢,是我们在做的微竞赛的过程中最核心的一部分。我们需要根据这个赛题的数据构建我们的模型,对吧?那么我们这个赛题的数据就非常重要。

我们需要做哪些事情呢?首先我们在拿到我们的数据,呃,之后是需要进行一个数据分析的。呃。为什么要做一个数据分析呢?我们做这个数据分析是要找到我们这个数据里面是。有哪些分布的规律,它数据有什么样的字段。

哪个字段是什么含义,对吧?在通过数据分析的时候呢,我们要根可以根据这个赛题的背景来对这个数据进行进一步的理解,对吧?我们因为我们这个赛题的背景,它其实会介绍,比如说我们这个赛题。

它其实会介绍到这个这个背景就是ttter下面的一些推文,对吧?这个就是呃一个业务背景,那么具体的一个数据呢,你要根据这个它大的推文到底是怎么写的,它有哪些分布的规律,对吧?这些都是可以分布的嗯,寻找的。

那么还可以做一些预处理嗯预处理呢就是比如说我们twitter里面有一些推文里面可能有一些表情,有一些呃呃转移字符,有一些垃圾信息,对吧?这些都会在数据预处理进行一个处理,对吧?

那么在做这个赛题的数据理解和预处理之后呢,接下来做一个特征工程。特征工程呢就是把我们的一个数据转换。成我们模型能够输入的一个格式。那么特征工程步骤呢,其实。包含几以下几个步骤。首先是特征的转换。

把我们特征转换成我们模型可以识别的。第二个呢是特征的构建。比如说我们特征,你转换之后,你是不是还可以从这个特征里面抽出新的特征?第三步呢就是特征选择。因为我们选构建出来的特征并不是。

都就是说每个特征都是有用的。我们可以通过一系列的方法进行一个特征选择,对吧?如果大家对这个西瓜书,就是看过周志华老师的西瓜书。如果大家看过这个西瓜树,其实特征选择在周助华老师里面。

他这个第二章就有讲到了,对吧?嗯,有很多种方法。那么在我们构建完特征工程之后呢,我们接下来可以就是说构建模型。那么我们模型呢这个我们当我们选择好一个模型,比如说我们选择逻辑回归,对吧?

那么我们选择好一个模型之后,我们就可以进行一个模型的训练验证和调参,对吧?这些都是呃在我们西瓜书在一些教材里面不会讲到的对吧?它不会讲到哪些参数是什么含义的,呃,怎么进行一个调参,怎么调参,怎怎最方便。

对吧?当我们构构建好了模型之后呢,我们就可以进行一个预测打分,我们就可以。对我们模型进行一个预测,然后进行一个结果的提交,或者说更进一步的我们可以训练多个模型来进行一个模型的继承,对吧?

这些步骤其实就是我们参加一个开口竞赛需要完成的步骤。呃,报这两个课是带着打比赛吗?不是呃我们这两个课其实是带着大家复盘。比赛就是说带着大家入门一些比赛。对。

就是说带着大家从头把这个比参加比赛这个过程完全完完全全走走一遍。我们回到这个课程内容中间,那么赛题的内容开括赛题内容和数据决定了具体的特征工程和模型。嗯,就是说不同的一个数据。

它决定了我们适合做什么特征,以及适合什么模型。比如说文本的一个数据,它就适合做什么TFIDFwhat react这种。那么结构化的数据呢,它就不太适合做TFIDF对吧?

就是说嗯开格赛题的一个数据决定了具体的特征工程,做什么以及模型,它具体使用什么。虽然我们在这个时候呢,其实写到的这5个步骤是现行的,但是是需要反复进行的,为什么为什么说是需要反复进行的呢?

首先我们这个呃步骤其实是分分块的对吧?分到5个步骤,12345,但是并不是通过这12345得到的一个模型就是最优的,当我们通过12345得到的模型,它可能不是最优的情况下,我们怎么进行调整的,对吧?

我们是不是需要根据我们的模型的一个。精度来对我们模型的一个参数,或者对我们的特征进行一个调整,对吧?所以说当我们解决一个参参参加开开过一个竞赛的过程中呢,这个。流程并不是一个线性的流程。

可能是反复进行的。比如说我们在这个地方看我们就是说提交了答案之后,发现我们的模型的精度不是很好,对吧?那么我们就回过头来再看看我们的数据是不是我们对数据理解不到位,是不是我们做的特征工程不到位,对吧?

这些都是一个需要反复进行的一个过程。那么其实开go比赛呢,其实上面每个开比赛它有很多的资源。呃,我们在前面也给大家介绍了,在所有的开go比赛的过程中呢,其实它的页面都有嗯几以下几部分过成。

比如说有 data notebook book以及到team这这些页面构成,对吧?那么这每个页面呢都是有一些呃就是说它这个平台的使用的规范啊。对大家可以稍微看一下,那么我们再回到这个比赛的过程中。

这个real large NRP嗯,这个比赛呢,其实它是一个对文本进行一个二分类的一个比赛,对吧?它的一个比赛的背景,就是嗯用户在推导上面发表的推文,或者说这个文本是不是呃就是说真实的。

那么这个比赛的数据就是根据嗯推文的内容,或者说根据这个推文的关键词或者单词以及推文的一发表推文的一个定位来进行一个呃分类。那么我们这个比赛呢,它因为它是一个文本类型的一个比赛,对吧?

那么所以这个特征工程,你需要做NRP相关的领域的特征工程,比如说用TFIDF或者说用词向量,对。那么你有可能会问到,为什么这个地方你会使用到TFIDF或者4下量呢?嗯,因为这个是呃NRP领域的一个问题。

对吧?在NRP领域里面常见的一些特殊能合成,就是TFIDF和磁向量。对,这也是一个先验知识。那么构构建模型阶段呢,我们可以用这个SVM嗯数模型或者神经网络。对。那么我们根据大家对这个赛题是不是熟悉,嗯。

再可以进行划分。假如你拿到这个赛季之后呢。呃,你可以根据你这个。对这个赛题的数据是不是熟悉呃,你可以进行以下以下划分。假如你对这个赛题进行熟悉,就是对这个NRP,比如说对这个NRP文本分类比较熟悉。

那么你就可以直接下载数据进行建模的对吧?假如你不对,就是说对RP不太熟悉,那么你可以怎么办呢?你可以看一些教材,你也可以看一些这个嗯开go上面的loch book的分享和它的一些讨论,对吧?

这个是基于你对这个赛题任务,以及赛题数据是不是熟悉。第二个呢,就是你是不是之前你对这种类似的任务有了解。比如说你之前对文本分类有没有了解过。对吧假如你对文本分类之前做过跑过一些代码,对吧?

那么你可以直接把之前的代码或者之前的思路再到这个比赛里面用一下,尝试一下,对吧?那么假如你对这个文本分类不太了解,那么怎么办呢?你可以在网上或者说找一些相关的课程。

找一些相关的论文来学习一下这research及一下相关的一些呃解决方案,对吧?那么这就是一个解决开关进向一个流程。那么其实每一场开歌比赛它并不是孤计存在的,或者说任何一场数据竞赛,它都不是孤立存在的。

因为每一场数据竞赛它都是有特定的背景特定的数据。所以说很多开个比赛,它都是相似的,或者说是相同任务的,那么其实每一场开歌比赛,它都是有一些特点,或者说有一些相似之处,但是它也有不同之处。

所以说如果大家参与一场开歌比赛呢,其实嗯比如说我们大家就是说看我这个直播课之后,想去参加这个呃reroro这个比赛。那么其实你参加这场比赛,其实就是以一个具体的NRP里面的文本分类的一个任务来进行学习。

对吧?所以说你当你学完这个比赛之后,那么对其他的一个比赛,或者其他的任务你就会就是说熟悉很多,对吧?那么即使你参加了呃这场比赛,那么之后你假如说遇到了其他的比赛,那么可能也有可能就是说需要继续学习。

因为不同的数据它可能有不同的一个分布的规律,也就是说它会有不同的模型更加适合。对,这也是需要反复尝试的。能推荐几本文本嗯挖掘的入门书籍吗?怕上课听不懂。呃,我们课今天的课程呢是入门级别的。

基本上不会讲到很多的代码,或者是说只会给大家讲一讲具体的解决方案。呃,如果你想就是说深入嗯文本完掘呢,可以参加我们在这个PPT写的两节课。这呃对,那两节课都会讲到就是说相关的文本分类的一个例子。

那么呃我们再回到这个比赛,就是说如果大家对这个LRP领域稍微有一定了解,就是说这个这个就是说嗯啪啪啪打脸,对吧?

刚才说不需要用LRP领域的这是这个其实呃是把这个NRP文本分类的一些常见的解决方案写了一下,就是说可能是我参加这场比赛,我构建了几个模型,比如说最开始我是知道的这是一个文本分类的比赛,对吧?

那么我们可以。首先构建一个比较基础的模型,比如说构建这个TFIDF模型,然后然后用SVM进行分类,这是一个比较基础的一个模型。它们并没有用到神经网络。然后第二个模型呢。

我们可以用这个fast test训练一个磁项量,然后进行分类。然后第三个模型呢,我比如说我们可以训练这个what vector训练磁项量,然后进行使用这个texN进行分类。然后第四个模型。

比如说我们可以用比较最近比较火的bur磁项量进行分类。那么我们最终的模型呢可以用这个burt分类,再加呃统计特征的数模型进行一个呃。集成对吧?呃,那么我们这个呃模型的一个迭代过程呢。

其实是一个不断的升级呃模型和优化进度的过程。那么也是需要大家充分挖掘我们这个赛题的一个数据信息的过程。呃,声音太小了嘛,我现在已经是呃声音很大的,讲了我我刚才应该是看了声音也是挺大的。

你可以把这个你自己客户端的一个声音可以调一下。对。那么呃大家可能会问嗯会想到,就是我们刚才在这个NNIRP里面,NIRP比赛里面并没有看到这个数据分析数据处理和缺失值处理的过程。

就是我们直接是教大家从这个赛题的理解到模型的训练,对吧?为什么没有讲到数据分析数据处理和缺失值的过程。因为在非结构化的一个赛题过程中,特别是在NIRP的赛题过程中,呃。

一般对这个数据处理只需要做这个嗯关键词的。替换或者说删除一些呃呃转移符,不并不需要做很多的数据分析。因为你最终嗯就是说最后的使用的一些技忆学习模型呢,往往是这个深度学习模型。那么深度学习模型呢。

它拥有强大的建模的能力,并不是就是说对这个。输入的一个呃文本呢是嗯就是说并不需要进行进一步的一个特征的转换的。对,这是第三部分,就是说开go的一个解题流程。

就是我们具体1个NIP的一个比赛给大家讲解的一个解决的流程,对吧?那么我们接下来呢就会给大家串一下,就是说嗯刚才呢是以1个NIP的比赛,对吧?那么大家有可能想就是说我其他类型比赛是怎么样解决的呢?

开go的上面的一些其他的比赛是什么类型的呢?对吧?那么我们在第四部分呢会以一些其他类型的比赛,给大家讲一讲其他类型的比赛啊,就是说它到底是一个什么业务背景的,它到底怎么解决的。

那么我们首先看第一个比赛,这个比赛呢是呃呃也是一个非结构化数据的比赛。这个比赛呢其实是呃亚马逊雨林的一个图像分类比赛。那么这个比赛的一个业务背景呢,就是说是一个遥感图像的一个比赛。

它是判断地表的天气和地表的覆盖物。那么这个比赛呢,其实它的一个赛题的数据呢是有。一个图像数据对吧?那么这个图像的数据呢,它不仅给定了这个一个天气。以及给定了一个地表的一个覆盖物。

比如说它到底是丛林河流还是呃城市,对吧?那么我们这个赛题的一个任务呢,就是需要对需要根据我们这个图像,对我们这个地表的图像进行一个多分类,既对这个天气进行分类,也对这个地表的类型进行一个分类,对吧?

那么大家如果对这个图像分类或者深度学习有一定了解的话呢,那么。这个赛题很明显的是一个图像分类的一个比赛,对吧?

那么我们就可以自然而然的使用这种预训练模型resonnet或者说dnet或inception这些模型来进行一个fight tune微调来得到一个比较好的一个解决方案。

那么这个时候赛题呢其实也是比较直观的对吧?它是一个很典型的一个图像分类的一个比赛。那么这个赛题的一个难点是什么呢?首先这个赛题它是需要分。既对这个地表进行一个天气的分类。

也对地表进行一个呃呃覆盖物的分类,对吧?那么这个呃就是说它是一个多分类,而且这个大家也可以看到,就是说有一些天气它是分布比较多的。比如说多云嗯或者说晴朗它的分布都是比较多的。

而有些天气它的分布的情况就是比较少,或者说它出现的次数比较少。所以所以说它的类别分布差异比较大的,而且这个赛题它既然是一个图像分类的比赛呢,那么就需要有较好的一个呃计算能力。

这个地方呢一般是需要几个显卡才能完成这个比赛的对。怎么进行微调?这个呢你可以在网上搜一搜呃这个深度学习相关的一个知识点嗯,fin tune微调,或者说在我们的7月7月在线课程的官网上面搜索一下深度学习。

呃,我们都有一些9。9块或者说免费的一个深度学习的课。对。

那么呃这种这个比赛呢其实是一个典型的多标签图像分类比赛,对吧?直接通过一个呃呃文嗯图像分类的一个模型的训练和微调就可以完成,对吧?但是它有一些难点,首先它的类别分布是非常不一致的,有一些类别分布是很多。

有一些类别很少不均衡。而且这个赛题,因为它这个地表的图像,它很容易受到这个天气的影响,比如说这个右边这几张图片它都是灰蒙蒙的,为什么呢?因为这几张图片都是它的天气都是一个。有雾的天气,对吧?很自然的。

你如果这个图片或者这个地表有雾的天气的情况下,我我是很难对这个地表的覆盖物进行一个分类的对吧?那么我们怎么做呢?其实我们可以首先对这个地表的一个图图片进行一个去雾,对吧?通过某些去污算法。

把这个地表的一个呃让它更清晰一些,让它的模糊程度更小一些,对吧?就是转变成下面这种这几种图片。或者说呢我们也可以用一些数据扩存方法,或者说用对抗生成网络生成一些我们样本比较类别比较少的一些样本。

对吧这些都是呃可以进行的,是对天气和地表分类是分别进行吗?对,是分别进行的。同一个网络可以同时一个网络可以同时对天气和地表进行分类啊。那么我们刚才讲的是一个图像分类的比赛,对吧?我在讲这个比赛的过程中。

我并没有讲哦它具体的一个任务啊,我只是讲这个比赛它可能涉及到的知识点和它的流程和难点啊。为什么这么讲呢?就是讲几个不同的比赛,让大家体会一下,就是说不同的比赛它可能解决的方案真的不一样。

那么第二个比赛呢是一个free song的嗯嗯tgging的这个比赛。这个比赛呢其实是对音频进行一个分类的比赛。那么这个比赛的一个数据呢,就是一个音频数据,就是给给定了一段MP3的一个音频。

需要你对这个音频进行一个分类,它到底是由呃哪些就是属于哪些类别。那么我们这个赛题的目标就是对这个音频进行一个多标签分类,对吧?那么怎么做呢?这个赛题可能就是说也是一个自然而然的是一个语音分类的一个比赛。

对吧?我们就可以提取音频的特征,然后使用一些模型来进行一个分类。比如这个地方我可以使用一些深度学习的模型进行分类。对,那么这个赛题的难点就是它是一个curner赛。

就是说它是需要通过楼州 book来进行提交的。对。那么这个比赛其实还有一些难点,就是说他这个比赛所以上这个比赛也是一个标签分布极度不均匀的一个比赛。就是说它有一些嗯类别的一个语音标签是分布非常非常少的。

那么就需要进行一个数据扩增。那么在这个比赛的过程中呢,一个。非非常有效的一个方法,就是做一个mix up。呃,mix up它其实很直观的。其实这样的,它就是把两个音频直接做一个。数值空间的进行一个平均。

来得到一个新的音频。比如说这个音频最开始是属于类别一,这个音频是最开始属于类别2。那么我们把它两个音频做了一个平均之后,那么得到了一个新的样本。这个新的样本是属既属于类别一,也属于类别2。对。

这就是mix up。mix up呢其实最开始是在呃呃深度学习里面的图像分类任务被使用到,现在已经被广泛用到语音识别以及呃文本分类的领域。对。那么这种mix up呢,其实呃很直观的。

它其实也是一种数据扩增的嗯方法,把少量的一些样本和多量的样多量的一些样本进行一个mix up。可以对我们相当于对我们那些少量的呃就是类别比较少的一些样本进行一个上载样,对吧?这是第二个比赛。

那么第二个比赛和第一个比赛不同的是第二个比赛,它其实是一个很典型的一个呃语音分类的一个比赛,对吧?那么第三个比赛呢就是to sig格ma这个房房屋热度预测比赛。那么这个比赛呢其实和前面两个比赛又不一样。

它是需要根据纽约租房的信息来进行一个热度的预测。比如说当一个中介。张贴了一个租房的信息,对吧?那么这个网站呢,它是需要我们对这个租房的一个信息进行一个热度的预测,来判断这个租房。

判断这个房嗯房源是不是嗯很火热。那么这个赛题的目标呢,就是对这个房价的一个热度进行一个分类,对吧?那么我们怎么有什么思路呢?就是根据这个C题的一个数据。对我们房房子的一些属性进行一个统计。

比如说我们这个赛题里面,他给给定了一个房屋的一个基本信息,房屋的一个经纪人,这个经纪人就是中介的一个信息,以及一个这个房屋的一个地理位置进行一个统计,来进行建模,对吧?

那么这个赛题的难点其实它是一个结构化的一个赛题,就是它是一个表格类型的赛题,它和前面两个赛题是不太一样的啊。那么这个赛题难点就是你需要从多个维度来进行一个聚合的统计,而且需要大量的统计。对。

那么这个赛题其实是一个很典型的一个结构化的赛题。这个赛题虽然它只包括14个字段,嗯,这个每个字段呢就是右边这张图就是总共只包括14个字段,包括房屋的一些卧室的个数啊,嗯,这个嗯张贴的时间啊。

它包括有没有电梯啊,有没有这个呃就是说能不能养宠物啊,它的价格啊,它的位置啊,它的街道信息啊,来判断这个房屋是不是呃火热或者说是不是走俏的。那么其实这个赛题它很直观的很典型的,它是一个结构化的赛题。

但是这个赛题并不简单,为什么呢?虽然它只有14个字段,但是这144个字段里面包括了多种多样的一个数据类型,它既包括了数值类型,也包括了类别类型,还包括了文本类型,还包括了日日期类型,还包括了图片类型。

所以说这个C格玛这个比赛。其实它虽然是一个典型的非机呃,它虽然是一个结构化的数据。但是它里面。包括包括了很多样的非结构化的数据类型,所以说是非常难度非常非常有难度的一个一场比赛。

那么如果大家参加这场toC嘛,这场比赛呢可以完整的掌握嗯各种数据挖掘的技能。不仅就是说不管是结构化的一个呃数据挖掘技能还是非结构化的。在这个比赛里面都可以掌握。对。

那么我们再来看一看我们最后一部分,就是说我们刚才讲了这么多,对吧?我们。假如大家想学习开关,我们怎么在我们嗯从第一部分到第四部分的基础上,我我们怎么一周快速上手开关呢?首先呢。

如果你想快速上手开关,我们是给出以下建议的。首先。你是想学习开go呢,你肯定有以下的动动机。首先你是想使用记忆学习或者深度学习解决一些具体的问题,或者说想把一个数据挖掘的一些算法或者一个模型。

应用到一个具体的问题里面,或者说想学习python环境下的一些数据科学库,对吧?那么我们比较建议大家是参与我们7月份8月份1及9月份开设的两个开go的一个课程。那么这两个开开go的课程呢,并不是呃很难。

而且是入门的课,基本上都是入门课,基本上是从入门的python的库一直讲到我们具体的一个比赛的一个求解的过程,是一站式学习的入入门式的。而且我们开设的接下来开设了两次开go的课程呢。

是使用具体的案例进行讲解的,每节课都有具体的实践的过程,而且会有呃作业。对,那么我们还嗯我们的平台呢会提供了nch book的。运行环境,所以你不用担心你没有本地没有这个运行环境。对。

那么我们嗯再来介绍一下我们这两个课啊。第一个课呢就是从7月18号开始,呃,是以QC干玛这个租房热度预测比赛进行一个内容进行6次直播的一个讲解。那么第一个第一场比赛呢。

这个比呃第一第一个课程呢是从7月18号开始。呃,每周六周天进行一个直播,总共三周左右。那么第二个课程呢是8月22号开始的一个kego案例实战班。那么这个班呢其实它是偏向嗯进阶的。我们第一个比赛呢。

第一个课程呢是入门的。第二个课程呢是进阶的,就是说你如果还想深入学习kgo的一些嗯技能,或者说增加一些自己的一些动手能力。那么第二个比赛不第二个课程是非常适合你的。

那么第二个课程它的一个内容呢是既有结构化的一些嗯比赛的一些案例,也有图像的比赛。案例也有N2RP的比赛案例总共应该是9个比赛或者10个比赛的案例。对我们第一个呃课程呢是只讲解一个比赛,会讲的很细致。

第二个课程呢会讲解10场比赛。嗯,9到10场比赛讲解的是一个解决方案。那么第二场比呃第二个课程呢会就是说更加深入的讲解一些优胜方案的一些思路和它的代码。对。

所以说看大家的一个呃自身的一个学习的情况和学习的一个意向来选择我们接下来的一个学习路线。

那么我也是建议大家直接是嗯学习开go的,就是说怎么学习呢?直接拿到就是说打开开go的网页,直接选择其中一个赛题来进行学习。你不用担心你之前没有学习这个python啊,或者说机器学习啊。

数据挖掘深度学习这些。技能啊都是在我们开go的一个班里面都会讲到,而且在开go的平台上面,其实都会有很多的资料方便大家学习。是就是说学习开课呢就是说有两个两种模式。

第一种模式呢是从头到尾就是说我先把pyython积极学习,数句话掘深度学习都学习一遍,再学习开歌比赛。第二种模式呢,就是我直接选择一场开歌比赛,是边做边学。那么这两种模式呢,我比较建议大家直接选第二种。

为什么呢?第二种模式是你。遇到了一个问题就解决一个问题,遇到了一个问题就解决一个问题。你学习的知识点是有限的,而且你知道你这个知识点是用在什么地方的。而且第二个模式它是直接直接能够增加你动手能力的对吧?

我们是以一个具体比赛来讲解的,而且你的学习的这个理论和知识都是相互结合的对吧?我们拿到一个比赛,我们会讲解啊怎么做他们工程,怎么做调仓的,怎么做一个。呃,数据挖掘的对吧?嗯。

我们就是说如果是以嗯第二种模式来进行学习呢,可能这个入门的一个难度会更低。而且这个速度我就是说你只要是呃认真学习啊,一周是基本上就是说可以入门的。因为你如果是按照这种模式一来进行学习,你学习了很多之后。

你就很容易忘,对吧?那嗯你如果这种模式来进行学习呢,你边做边学,你就。相当于你学习的就是说你嗯呃需要学习的知识肯定会比模式一少很多。对,这是模式二的一个呃它的优点吧。对。

呃,那么我们今天的课程就呃到此结束了。啊,那么我们接下来呢会给就是说给大家看一看我们接下来两个课,它的一个链接啊。

呃,直接打开我们这个7在线这个平台的官网,直接搜kego,就可以搜到我们接下来的两个课。第一个呢是从头到尾带打开go比赛。嗯,这个课程呢是也是现在还在就是说比较实惠啊,200块钱,6次课。

然后我们这个课程呢是7月18号开始直播。嗯,然后我们这个第一个课,这个从头到尾带到开go嗯这个课程呢是以 twoC个嘛这个房房价预测呃,房屋热度预测来进行一个呃做的。我们这个课程呢是零基础的。

基本上是从零开始教你怎么讲pandas讲就是说怎么使用down派怎么使用SK里的一些模型,怎么做数据可视化,一直到我们最最终的比赛的b nine以及最终的一个提交。对,基本上是你参加。

就是说基本上是从零基础到最终能够提交。

我们都会把这些知识点给大家讲到。对,这两门课都是我到时候会开始,嗯,都是我和我的同事会讲的对。呃,我们这是第一个课。第二个课呢是这个开go竞赛实战的呃案例班。这个班呢其实也是比较实惠。

我们现在只要300块钱,嗯,就可以得到我们这个班呢其实它的讲解的内容呢就会稍微嗯深入一点。呃我们这个第二个班呢,它其实是每节课都会讲一些基础知识,然后讲一个比赛。比如大家可以看到。

我们其实在第二个班里面其实每节课都会讲一个比赛。第一个比赛是hopri房价预测。第二个比赛是第一个课程的一个内容就是说呃to格玛的房价预测。第三个课程就是这个allstate这个保险风险预测。

第四个课呢就是一个金融风控的一个比赛。所以说我们第二第二个课程呢可能会更加实操一点,而且这个节奏会更加快一点。

一直到我们后面这个第二次课呢会讲解一些图像检索图像分类以及物体识别的一些入门的比赛,而且也有一些NRP相关的比赛。对,所以说如果大家想深入学习一些数据竞赛的一些基识点呢,就是说可以根据自己的基础啊。

嗯选择嗯第一个比赛呃,第一个课程或者第二个课程进行一个参加。对嗯对嗯我们今天的一个呃我们讲课的内容呢,就到此结束。不知道大家对我们今天的一个课程内容有什么问嗯疑问呢?

我们今天的一个呃可以可以扫码关注一下我们的公众号,然后呃就是说有加群的方式啊,嗯,我们这个PPT呢会嗯发到我们的这个直播群里面。对。

呃,如果大家对我们的今天的直播的内容呢有疑问呢,可以打字和我沟通。或者说嗯对我们接下来这两门课有疑问呢,也可以嗯打字和我沟通。对。

一门课第一门课是只有6次直播,应该是三周。第二门课我看一下是。

第二门课是12次直播4周左右。嗯。每周都上吗?对,这两个课都是每周都有直播,也有录播的。你放心,如果错过了直播,也有录播的,用拍tor行吗?用tensorflow行不行?呃。

我们这个呃因为我代码都准备好了,都是拍tor的,也有tensorflow的啊,我也会讲一些tensflow的对。

第一个课是三周。餐桌。第二个课呢是6周吧,6周左右。对。对。呃看你们情况吧。如果大家既有就是说到时候报的这个班的,既有嗯想学习tensflow,又有想学习pathal系的,我也可以嗯准备两份代码嘛。

就是两个库都写一遍。对。

因为我们现在这两个课呢也都是在参与打折的过程啊。嗯,所以说建议大家如果想嗯就是说想深入学习的呢,可以就是说及时的呃就是说呃购买一下。对。啊,不知道大家对于我们今天的直播还有什么疑问呢?对。

我们今天的直播主要讲解了这5个5个部分内容,就是想让大家就是说如果零基础怎么入门开广对。如果大家对我们的一个直播内容或者课程的继续的内容呢,嗯有疑问的话呢,可以跟我沟通。我没学过拍多写。

我只学过ten字 follow。可以啊,我们在之后的课程也会讲一些t flow的。其实这两者不是差别不是很大。好,我看大家应该是没有什么问题了。对,那么我们今天的直播的内容就到此结束。

我们的PPT呢会分享到我们的直播群。好,谢谢大家。呃,最后说一下,如果大家还没有关注我们的公众号呢,可以。

关注一下,因为我们的一些平时的一些直播分享,一些课程的优惠啊,都会在我们的公众号上面进行一个分发。

人工智能—kaggle实战公开课(七月在线出品) - P3:Kaggle Expedia酒店推荐比赛 - 七月在线-julyedu - BV1jh411y7Fh

好好,行,然后我们今天给大家讲一个案例啊。就接着之前的推荐推荐系统,那么给大家讲一个cago的啊一个酒店推荐的一个比赛。

然后这个今天这个。哦。这样一个比赛呢,可能文件稍微有点多啊,大家能看得到我的桌面吗。所以这个比赛呢里面。用到了很多的方式组合去完成最后这个预测。然后嗯这里头可能会有7个文件,我会给大家7个文件。

然后分别是我会先给大家介绍一下我们的这个整个问题啊,一个problem的一个seing背景。然后有一个简单的解法的一个图示OK然后。

第二个文件是。呃,当比对一会儿我会说比对测试集和去年级的时候,你发现。测试集里头有一部分数据在训练集里面是有完全匹配的,意味着说他们把这个这种情况叫做data leakage,就是数据泄露。

或者说呃有额外的信息啊,你你捕捉到了额外的信息,可以直接去啊以一种che方式找到标准答案啊。当然了,这部分数据只占最后去评估提交结果的数据里面的3分之1,所以有标准答案的数据呢。

我们会先用这种方式去啊找到最合适的结果。对,然后后面的文件是第第二个文件。第三个文件。第四个文件。第五个文件分别是我们用。飞1森0啊raom forest。

然后GBDDgrading boosting decision啊,然后有1个SGDclass SGD class大家可以理解成是一个呃它这个训练方式呢就是一个呃grading decent。啊。

梯度下降。然后所以。所以它是一批一批数据往里面送,然后就update这个参数的一个classsifier一个分类器啊,大家可以先对可以先简单的啊。有这么一个认识就好了。

然后第五个文件是一个普苏贝耶斯的一个模型。所以大家看到这个地方有从随机森林到啊GBDT到SGD的分类这个SGD的class file到普苏贝耶斯总共4个model。

然后我们对这四个model去做了一个bling啊,我们之前给大家讲模型融合的时候,也对我们之前给大家讲模型融合的时候也提到了,对吧?这个model blending。我们说总共会有这么一些方式啊。

叫bagging然后 boostosting和tacking对吧?acking的话,那种层叠的模型的话,有可能会overfi。所以。

我们用了一个嗯比 stacking这种方式要稍微那个弱化一点的版本叫blding,对吧?叫混合。所以我们一会儿会用一个混合的方式,把这四个模型的结果组合起来去生成最后的这个啊final results。

因为我们去做一个mererin,对吧?把它整理成我们最后需要提交的格式。好,这是今天的一个大体的一个呃文件的一个课程的一个安排和这个地方文件我给大家做一个小小的介绍啊。因为我们会有7个文件。

可能今天的内容还是比较多的。但它这是一个完整的一个案例,然后大家可以从里头看到我们去做。一个data的一个exploration啊,数据的探索数据的分析。

然后以及我们去做一些feciature engineering这个特征工程的一些相关的事情。同时呢我们会在特征工程后的数据上去完成一个modeling一个建模的一个工作。

然后包括对这些用各种不同的方式去做建模,同时对这个结果去做一个混合,对吧?模型的融合,叫model blending。然后我们去生成最后的这个结果去提交的这样一个完整的过程啊,所以嗯O。

这个是我们今天的第一个文件啊,就是我们给大家介绍一下这个背景啊,一proble setting呃,都能看得到我的桌面吧。我再问一下大家能看到桌面,听到声音,对吗?呃,对,如果能听到同学回个一啊。呃。

因为我我不太清楚是网我会不清楚是网络的原因还是其他原因,我不太清楚大家能不能听得到。所以这个cale的这个比赛呢实际上是一个推荐系统的一个比赛啊啊cale上会有有一些推荐的一些比赛。

这是其中的一个啊很有名的一个比赛。然后这个比赛呢呃我直接把cale上的一个。

这个背景的介绍直接拉下来了。所以这个问题的一个背景呢是说呃大家每次出去旅游嘛,你像你用携程或者去哪儿的时候,你当你有一个目的地的时候啊,然后你需要去做这件事情时,你可能会提前去定各种各样的东西。

比如说机票,比如说这个。啊,住宿等等。那这个网站呢有点像是国你可以理解成是类似于国内的携程这样的网站。

所以你可以选择在上面去提前预定我目的地那个地方的酒店O但是他这个地方说了有一个问题就是说酒店特别特别多。其实你对当地呢那个各种情况也不是太熟悉啊。

所以你需要去做一个这个筛选这样的一个事情O所以呃像有些同学可能会去查大众点评或者怎么样啊,查一些相关的一些信息。那这个地方呢他是说我他希望能够通过以往的一些各种各样的数据。

能够帮助用户去呃做一些推荐recommendation啊,帮助他减少这个决策的这个过程啊,所花的时间O。

所以他提供了一些相关的一些信息。然后他做了一个事情啊,就是这个地方我给大家用中文大大致的说一下,就是酒店有非常非常多的酒店,对吧?如果你要定位,到时候我给他推荐哪一个酒店,这是一个很很困难的一个事情。

因为因为比如说你去啊你像你来北京或者你去上海,对,或者去深圳的话,其实这个tail是非常非常多的OK那你是很难定位到具体的一个酒店。那因为因为你的目的地只到了说城市这个级别的信息嘛,你说我去上海,对吧?

那我去我去这个深圳,我去北京,那你的booking就是你你的这个预定信息啊,你去上面不管是这个。提前买买机票哎什么这个东西的话,只到了城市的维度的信息的话,有时候他就不能明确你具体具体呃在哪。

或者你的活动范围在哪。所以。推荐具体的酒店这个事情是很困难的。然后他做了一件事情,他把所有的这些所有的这些呃这些hotel这些把它分成了100个cster。

啊,这是他自己内部的内部的一些方法去实现的,就分成大概100个团或者100个类啊,这些还tel。那你可以理解成他可能会从我举个例子啊,从价格的维度,从从这个呃里面的一些装饰的维度,然后地理信息等等啊。

各种维度去把它拆成了100个cluster。

对,然后这个可能是比如说像像儒家和。7天可能就会分到一个classer。O所以你可以理解成就是他把这个问题简化了一些,他帮你把所有的酒店分成了100个classster,然后你要去做一件事情。

你说现在手头上有一批数据,就是这个cus这些顾客他的一些behavior,他的一些行为啊,包括说什么呢?他这地方说了this include customeromer searcharch for。

就是我搜索的时候我去做检索嘛。你比如我去查这个呃上海中山公园,ok上海竟安竟安4ok就是你去这个上海外滩,所以你search你查的这个query等等啊,这些信息它是会保存的嘛,会有嘛。

O然后你和本身我这个app的一个或者是网页端的一些交互,我也是有记录的。比如说我做了点击,对吧?我有click,那那我比如说我我我查看了这个酒店的相关的信息啊。

我查看了它这个某一个某一个展出的结果相关的信息以及我的 book就说我预定了嘛?那我历史上我可能去过上海。

我在外滩定过一家酒店O等等啊所还有一些wether not result was a package就是说你到底说只是单纯的在我这个app上完成了一个酒店的一个预定,还是说你像大家知道这个携程嘛。

它主打商务的话,你可以一站式的把所有的这个机票啊,然后住宿啊等等啊,就是都一一次性的全都打一大包啊,全都预定好,所以这个地方也一样啊,就是说这个你的搜索这个结果是一个还是说不是。

然后呃这个比赛里头的数据呢其实大家知道啊,比如说像携程,比如说像像去哪儿。然后比如说像呃如果你用呃大众点评这样的app去去预定一些酒店的话啊,那大家知道这个量是非常大的。

然后尤其是他这个地方它这个地方的数据,我做一个简单的解释,它是从13年到15年对的数据。然后13年和14年两年的数据呢是用来做千 data用来做训练。然后15年是你要去做一个prediction做预测。

那13年和14年两年的话,实际上数据量是很大的。所以它这个地方做了一个selection就是啊ex嘛,你可以理解成是O就是采样了一部分数据出来。所以他做他给大家解释了一句话。

说我的数据实际上是从全集数据以后去做了一个random的一个selection一个采集出来的一部分子集。所以它可能并不能代表所有的tatistic就是所有的统计分布,就数据的统计分布。

这告诉我们一件事情,就是说如果现在我给你一个训练集。这个训练集呢你千万。千万千万要注意,不要在上面overfitting过拟合了。因为我给你的这个训练集,我并不保证它和全集的数据。

我所有用户的这个数据分布是一致的,它并不保证这个东西它是随机。他告诉你我是随机采样出来的。OK然后啊底下这些就给了一些额外的一些解释了。然后说为什么我要去做这件事情。

做exedia是非常非常感兴趣去给帮助啊用户去这个辅助用户去做这个决策的嘛。所以我做了一个he care group,就是我的酒店呢,我就把它划分成了不同的group,对吧?

一些一些11呃不同的这个cster。不同的这个classer对吧?那ok。然后呃我会根据一些,你看他这个地方是解释了一下,他说我是怎么去做那些分组的,就大家知道有100个团或者100个不同类啊。

你可以理解成不同的啊类的这个酒店。他说我会根据这个hitorical就是历史上的价格,cus star rating就是评分O然后只有ographicical location,就是地理位置啊等等嘛。

然后以及相对于城市中心的地理位置嘛,或者是商圈等等。他根据这些东西去划分成了100个那你要做的事情就是你去预测你去预测用户最有可能会booking最有可能会预定的这个酒店到底是哪个class你要求的你要求做的事情是class注意啊。

不是具体的酒店。然后对数据数据做了一个解释,说我的数据呢?我这个里头总共会有13年到15年的数据,但其中呢13年到14年的数据呢是训练级是千 data。

然后15年呢是我需要你去做预测的这个啊test dataok当然这个test data呢本身它是已经有标准答案的了啊,他自己所以他会做一个比对。然后呃大家很喜欢一个东西啊,叫做排行榜,对吧?

你去刷天池的比赛,你去刷这个kego比赛的话,对你都会刷天池和te的比赛的话,你实际上都会。去看每天呢他可能每天都会更新这个排行榜。那cago的话是你每提交一次结果,他都会更新这个排行榜。

这个board会去做一次更新。O但是你看到的这个叫publicboard leaderboard。所以就是你看到这个东西是公开给大家看到的一个排行榜。但它实际最后用来评奖。

或者是最后用来这个呃评大家谁的方法好的时候,用的是一个pripri leaderboard。所以呃很有意思一个事情啊,你们如果有兴趣的话,你可以去看看历史上的cago的比赛。

就是这个public leaderboard和最后最后拿到讲的这个private leader这个排名会有很大的差别。呃,就是一个小小提醒。如果有同学要去参加数据科学比赛的话,不管是天池阿里天池比赛。

数据晨堡或者是科赛或者是呃像cago这样的比赛的话,一定要注意,就是他可能不要不要太迷恋 leaderboard这个事情,就是排行榜。

因为展示给大家的public leaderboard和最后的用于评测。真正的这个结果好与不好的那个leattleboard可能不一样。ok。所以你的训练级他给你了13年到14年的数据。

然后你的测试集是15年的数据。OK然后你需要去做一个事情,就是做一个预测一个prediction,对吧?然后它这里头会有些文件啊,有会有些文件大概长成这样。大家可以看得到对吧?

这个 description包括什么呢?包括chan点 cV这个是整个训练集都在里头然后test set是我的test点 c我有个s destinations是tel个酒店的 attribute就是大家在搜酒店的时候可能会有各种各样的相关的属性嘛。

那包括酒店本身的属性,包括你搜索时候的一些属性queryquery和这个酒店的title的一些匹配度啊类似我我随便说的就是这样的一些相关的一些业务特征或者叫业务的属性。

那但是大家要知道这是一个比赛这个比赛呃主办方呢愿意拿出这么多数据来但是国外的公司包括现在很多国内的公司其实对用户的这个隐私其实是需要保障的。

所以我不能直接把明文的数据丢出来给大家说你可以查得到说是多少多少号的同学现在查了一个什么什么在在toky在东京的一个。这个是不行的啊,查了一个比如说东京塔旁边的一个一个tel,那这个事情是是是不O的。

因为你暴露了用户的信息,所以他们会去做一个事情,他们会对这个tel的 attribute去一个哈西你啊你可以理解成是一个敏的处理所以你能拿到的是可能是一些哈希后的I号。

你是看不到明文数据的O所以都存在这样一个文件当中叫destination点 c然后这个sle sub点 cV呢就是大家很熟了啊,如果参加数学科比赛的话,他就是一个提交的格式。

就是说你最后的这个结果要按照我给的这个格式去提交,我才能去评分。对不然的话我就评不了那包括有很前面之前有很多同学参加过天使的比赛,说那个我提交的结果,为什么最后结果是000045这结果为什么没有得分。

是因为你不符合他最后的要求格式的要求没有办法评分。好,然后我们来看一下这个数据集。数据集呢呃这个地方有个去年级和测试集啊,叫che点SV点V里面会有各种各样的信息啊。

这个colum name就是说有多少列嘛,大家去构建一个数这个数据呃叫数据库里头一个表的时候,实际上你也是会有很多列对吧?每个表那有些列呢会 time就显是日期对吧?

name name就是说个是一个全球性的一个公司一个公司嘛,一个以它实际上呃不仅有官方的点com那还有Uun对吧?

那个对那个英国或者是啊JP结尾的那是japan对吧等等这是一些 name就是网站的那个然后底下是这个。啊,大陆啊O就是在在在哪你可以理解成哪个国家啊之类的相关的一些信息啊。

这个user location country嘛,国家信息嘛,user location region啊在哪个区域,国家哪个区域,比如说你在中国的话,其实有上海有北京有深圳啊等等然后或其他的一些城市。

那user location的这个c啊re region刚才可可能啊简单理解成可以理解成这个ok华东华中、华北对吧?那那这个是region区域啊,那location city呢就是具体到城市呢。

那比如说华东,我在上海对吧?和我在杭州,那肯定是啊不太一样的ok或者是苏州ok那那个or destination distance是指的这个呃我我检索的时候的一个距离嘛。比如说我我我之后要去上海出差。

我其实可以在北京可以搜上海的相关的一些啊hotel的对吧?那实际上它是有个d有个距离的那比如说我在上海搜上海的话,可能就是说我过来出差,出差,我临时去找一个酒店。

就是这个距离大家能想象到它dance的话,它能在一定程度上体现出来说这个比如说一个紧急度啊或者相关的一些信息啊,OK这地方下面会有一些其他的一些维度的啊feature。

比如说啊us IDO is mobile是吧?是不是用是用手机app定的,还是用这个网页端,对吧?it package就是说我的呃我是用携程去定了一个打包的,这个包括我的这个怎么说啊,打包好的。

包括我的这个飞机呀,机票啊,或者高铁呀,以及包括我的这个酒店呢,还是说我单独订一个酒店,对吧?那这个channel channel啊。然后会有一些这个check in check out就是入住和。

酒店要入住的那一天的日期和你要你要这个酒店去啊。就是你要走了那一天的啊che out那一天的这个date日期,对吧?然后底下会有一些相关额外的一些更补充的一细节的信息了。比如说成年人的个数啊。

小孩的个数啊,对吧?这个你定的这个酒店它的这个这个呃可能是一个你要求是一个比如说两张床的或者是几个屋的等等啊,相关的一些信息啊。

这dination IDdestination typetype ID hoteltel的这个。所在的这个大陆所在的country,对吧?然后的market对吧?嗯,可以理解成是呃。

mabe这个地方是一个商圈类似相关的一些信息。啊就这条记录里头到底是一个啊是不是预定了,对吧?还是说只是发有没有发生点击。你看只是一和零嘛。那一基本说ok这个酒店我预定了,对吧?那如果是零的话。

就表示说ok我其实只是查看了一下相关的信息那再往下就大家可以看到个?是我这个所属的这个ster相关的一个一个刚才我已经给大家说了有100个ster嘛,对吧?

O那destination点V呢是包括下面一些信息啊,叫 name会有会有一个这个IO然后底下会有第一到D149,这是我刚才给大家解释过了。我说就是用户的信息。

你绝对不能把用户的信息直接曝光给大家曝光给直接拿出来,就像之前大家都知道这个S或哪被黑,然后就扒出来一堆的用户名和密码对吧?这肯定是不行的明文肯定是不行的,你至少要去做一个加密对吧?

所以这个地方第一到第149实际上就是 attribute。一些lessens就是隐隐含的这样一些信息,一些invo你可以拿来用的。但是你可能看不到明文信息okK。

然后很重要的一个事情是你去做任何的machine learning的这个参加任何比赛,去去看任何的这个问题的话,解决的问题的话,你必须要知道我的最后的评估的标准是什么。也就是说。我什么样做做的好,对吧?

我的评估标准到底什么?那这个地方有一个很常见的,你会经常见到的一11个评估标准啊,就是大家都知道很多accur像这种准确率,你肯定知道的对吧?

那ok像lock啊啊这样的指标你肯定是知道的 score等等。那这个地方的话,这个也非常常用啊,叫M叫me就是平均的一个准确度at k at k就表示说前多少位的一个平均准确度。

那它大概是什么一个意思呢?这个地方at5就是说呃我允许你给我推荐5个结果,就是我我允许你在100个里头给我推荐5个只要这5个里头有命中的,我就认为ok你算对了。那大家可以想象为什么是5呢?

你可以点开你的携程,点开你手机上的呃携程或者其他的一些。比如说大众点评,你可能一页一个页面单个页面显示的可能就是5个结果。我猜的。

所以这个地方5的意思就是因为后面那个可以调的那它判标大概就是就是因为一页只展示5个结果,所以用户只要在首页看到了,我就觉得说ok这个结果O但如果你不在首页,你要我翻的话。

我可能觉得这个就是一个不太ok的结果,所以他评判的是你给5个结果,你给我5个推荐的结果。只要这5个结果里头有一个命中了。O我就认为你说你这个可能是中的O是O的。

所以最后提交的这个submission的这个fi呢,大概长什么样呢?大概就长这个样子。所以对每一个user和even呢。

你可以pred就是你可以以下面这个方式去做一个提交这个提交大概是长这个样子你要提交两部分信息个I另外所以这个I。针对一个user和event,就是就是它是一个事件,然后你会去。推荐5个hotel。

大家看到了吗?99317520,这是hotel的ID号啊,classluster的ID号。OK所以他这个地方推荐了5个结果,只要这5个结果里头有一个命中了,我就觉得你说okK这个是这个是okK的。

当然当然了,你排的越前的话,你排的越前的话,其实是呃结果肯定会越好。但是在只要在这5个里头的话,其实你就是可以得分的OK。然后这个地方的解法这是就是做的这个呃。

Okay。所以啊这是一个图示啊,这是一个图示。所以大概大家可以看到大概是长这个样子。然后我们选所有的训练机拿过来或训练四个模型,分别是这个地方的rdom forest,然后GBDT啊。

随机森林GBDTSDSGD的,然后一个伯努利的普贝斯啊,我们普贝斯是还没有还没有给大家讲,是吗?那之后会提到它经常是它是一个经常会在啊自言处理以后会用到的一个分类器。但是你也可以拿来做其他的这个。

分类用对它是一个基于它的核心,就是一个BS公公式,是一比较简单的一个分类器。那SGDclass file,你可以认为它是一个online learning在线学习的一个class file。

你是可以一直一批一批数据往里头喂,然后去更新它的参数的,去update它的位置。啊,这个地方的GBDT呢之前和reno forest大家应该知道了。在Dcing chain那一刻。

应该老师有给大家稍微提到一下,所以。当你有多棵树,你去做一个并行的并行的这个模型融合的话啊,它的方式一般情况下就叫做reno forest,对吧?B型的这个集成。如果你去做一个串行的集成的话。

你每次去减少你这个er去对你分错的这些样本啊,或者说去去每次去集中精力去对你的那个 error的那一部分去做学习的话,这个时候就是一个ing decision对吧?应该应该叫做这个sing的方法。

但如果你这个sing方法优化的方式是基于gra的话,它叫做GBT对吧?ing decisionO所以我们的数据呢就会分同样一份训练级的数据啊,我们会拿过来做这样的一个事情会丢给这样四个模型去学。

但是中间会有一些细微的差别。举个例子来说,大家会看到我给random forest和GBDT的这个数据呢,实际上是。是啊带这个隐含的destination的这个影变量的。

但是我给这个普苏贝耶斯和我的SGDclass power的话是没有的,是没有这个。就是有这个东西是有一些是会有影响的。因为因为这个哈希过的这个结果呢,也是不能直接参与一些。

比如说像呃不太适合就直接用在logistic regression这样的model当中的logistic regression这样的LR这样的模型当中的。因为。它是类别型的变量嘛。

要么你就对它做一个one hot的一个处理。要不然的话你就嗯。不要直接拿过来用那te base model就是基于数的模型的话,呃,相对而言会好一些。所。上下会有一些差别,我丢给模型最后的参数。

参数是不太一呃,这个应该说数据和特征是不太一样的,但都是在这一批数据上产述的,圈ingda上产述的。对,然后大家可以看一下,有一些差别啊。

比如说 forest随机森林和我的GBDT我用的训练集只用到了其中预定的这部分数据。大家刚才还记得这个问题的设定,我给大家提了一下。

我说数据呢会有这个地方啊嗯看一下标签这个标签会有一个叫做叫做is booking,对吧?is booking这这个列这一列呢是零或者是一如果是一就表示我预定了这个这个跳这个酒店如果是零的话。

就表示说我只是点击看一下信息,但我没有我并没有预定。好,所以我的GBDT和我的 random forest呢,我是用只用了预定的这部分预有预定的这部分数据去做训练的。而我的SGD和我的这个普素贝耶斯呢。

我是用了全部的数据,就是有点击和book的,我都拿来用了。

对。然后里面会有一些细小的一些一些这个差异啊。比如说这个地方的renom forest随机森林呢,我是。呃,我不知道大家的大家用来跑能的这个机器或者服务器的性能有有多好。

我可以告诉大家这个比赛的数据量呢不小。所以如果你啊习惯用pandadas这样的非正件这个data analysis数据分析的package的话,你一次性把所有数据读到内存里可能会是一个比较可怕的事情。

你的内存可能会hold不住。所以你你在read这个CSV或者说读取数据的时候呢,有一个选项,它叫做叫做ch。就是你可以去告诉他说,我不一次性把所有的数据读到内存里。我可以一批一批数据读。

比如说我每次这个地方呢,你看refor是。

每次只读20万的数据进来。因为它这个数据量很大啊,就是我大家大家如果想想去看的话,你用这个pens load到内存当中,你可以看它的shape,或者是看它的对data frame的一些in。

你可以你是可以看得到的。这个时候呢大概有我可以告诉大家有3有接近4000万的训练样本,就就是所有的点击和booking和这个预定的数据加在一起3003700多万。对。

然后有预测的一个testing data呢,大概有也也是百万级别的几百万的t data。所以这个数据量级几千万的数据量级,你要一次性load到内存当中的是一个对内存是很大的压力。所以你需要做一些处理。

比如说这个时候我们是分20万20万的数据往里头读的,这个是分10万10万的sor100100万的数据往里面读的。

然后底下是20万和20万。对,那即使是这样的,即使是现在我给大家说的这种方式去做处理,也要求你你本地的电脑或者你的服务器至少有8G的内存。8G的空闲内存。如果没有的话。

这个程序跑的时候有可能会报memory的错,就是内存的错误ok。所以大家可以理解成我对数据去做了不同的处理,包括从数据层面的选择上做了一些处理,包括从fe engineering特征工程上去做一些处理。

然后不同的处理方式后的结果丢给了不同的模型去做训练。然后我对所有的这些模型产出结果去做了一个什么叫bling叫混合这样一个方式,我去给他们做了一个加权的一个平均去作为最后的这个结果。

然后去对上我的lage,我的data leakage就是我会有一部分数据我给大家说了,我说在测试集当中呢。

实际上你是可以在训练机里头直接找到答案的所以你可以直接拿来用的那有3分之1的左右的数据是直接可以拿来用的所以这3分之1左右标准答案就是直接可以查到标准答案的结果。

和这3分之2有我的4个模型去做bling拿到结果一起配合作为最后的这个solution最后的s的这个结果去提交拿到了最后的分数O所以这大概是。

一个嗯。这是一个一套比较完整的解法。那不是说我小打小闹去随便把它丢到一个模型当中去阐述一个结果。那这还是一个相对而言比较呃复杂的一个。

有一定的层次结构的这样的一个解决方案吧。

所以这个probleproble setting就是问题的设定和背景呢,我已经给大家交代完了,我们就来一个一个文件来看一下啊。所以这是第0个0号文件,是problem setting做一个背景设定。

人工智能—kaggle实战公开课(七月在线出品) - P4:kaggle ieee-cis 欺诈检测二分类大赛思路分享 - 七月在线-julyedu - BV1jh411y7Fh

呃,今天主要是分享一下去年的1个IECIS的气下检测比赛。呃,那是一个比较典型的一个二分类的。嗯。因为感觉这比赛性息量包含的性质还是蛮大的。且和平常我工作的内容性工工作内容性质也比较相似。

然后这个比赛反映出来很多问题也是比较比较经典。所以这个后来就挑了一个这个比赛来讲。嗯。嗯,首先是大概做一下这个比赛的这个背景介绍。嗯。那个这个是呃这这这这个比赛数据集是1个C加银行,呃。

主要是这个信用卡交易的一个数据。然后这个好坏用户的比例大概是29比1。然后这个表整体的呃这个比赛整体表的这个数据结构比较简单,它只有一张主表,一张副表,主表是这个交易表。

他是这个呃主要是放的是用户的一些呃交易卡的信息。然后附表是一个这个身份表。主要是用户使用这个设备信息相关的一些特征。嗯,我我继续讲。呃呃刚刚讲的这个。这个这个比赛这个数据整体的情况。

然后这个比赛比较好一点,就是官方在那个discus里面有讨论了所有这个字段的含义。呃呃,就像我这里写的这个称section DT是这个。日期时间的time。

然后AMT是交易金额productduct定是交易产品产品类型的这个编码。card一到card6是这个用户的支付卡相支付卡信息相关的东相关的一些东西。

然后这个Pmail和R emailmail是这个购买人呃,是这个卡使用者他的这个邮件相关的信息。呃,ADDR1和ADDR2是这个这个支付卡对应的地址呃,这些我就不念了,大家线下去看这个。代码就可以呃。

看这些代码就可以了,含义还是比较比较直接的。嗯,行,OK。刚刚主要讲这字段大概一些含义。呃,这个。这大这个大家现在去看就好了,这个也没什么可介绍的,反正就是。

实际上的这些呃就就是就是字面上的这些这些内容。嗯,然后是我们介绍一下这个比赛整体的这个这么一个思路。呃,这也是一般来说打比赛的一些常见的一些流程化的一些东西吧,比较固定一些。呃。

首先就是看比赛的一些背景介绍,然后就具具体的就是还有比赛的一个评分方式。呃,这个比赛比较好处方方呢对所有字段都会做都有做一些很非常非常详细的解释。

然后呃但之前参加一些像那个三那个桑德湾银行的一些匿名赛就比较麻烦。那个字段都是非公开的那些比赛像这种匿名赛就会有另外一些其他的套路。你这里暂时就不介绍。在展开来说,这展开来讲太多了。呃。

这里就介绍一下这个呃这这个相对来说半匿名的比赛嘛。因为大部分的字段含义都是公开,只有一部分字段的这个含义是呃没有公开的。然后就是查看这个过去下次一些比赛。

一些选手的这个叫什么top一top2这他们的那些solution,还有他们开源的代码。很多时候这些他们发布过代码都是可以直接复用,包括像这个比赛也是那像那些内内存优化。

后面我们会讲一些内存优化和性能优化的代码,都是其实都是以前比比赛里面的那些呃选手用过好很多次那些代码啊或者使用。😊,然后第二步就是做这个基本的这个EDA数据探索,主要就是通过可视化。

然后计算一些统计值来寻找这个数据中的异常之处。然后并并且呃并且在这个过程中熟悉熟悉你处理的数据。Oh。这些的话其实也是相对来说比较固定的。那比如说像类别特征,一般来说会去看它的类别的分布啊。

去看它这个类别取值的数量,就去看它这个字副样本,还有这个训练级和测试集这个分布的差异等等。呃,这个后面。我们讲代码的都会介绍呃,然后在这个过程中,一般来说会参考一些开源的柯蚪。因为。呃,录播呃,不会耶。

我我我没有开始录过这个选项。没事没事,那个我后面把朱be发给你们,你直接看朱弊者其实也是一样的。😊,因为就这些注释我已经写的,基本上写的很很全了。然后这呃。呃,这在这个数据探索的过程中,呃。

可以参考一些看人的可能,但是尽量还是自己自己去思考吧。因为毕竟每个人每个人他。探查数据啊,这做这个EDA方方向,他习惯不一样。有的有的选手是喜欢画这样特别多的图。

而我的话我我我就我一般画图就稍微画一点简单的图,然后看一些它的统一特征这样的。然后呃然后这个做完这个大概的数据,呃,做完大概的EDA之后,就做这个性能优化这块的东西。啊。

然后第三步是做一些性能优化的一些步111些1一些方法。这个这个其实还是蛮重要的。呃,一方面比如说这个呃对你你对这个pandas它的那个内存呃,数据占用一数据数据使用类型做一些优化,还有是一些常用的一些。

代码上面速度上的优化,这这步还是蛮常重要。因为你在内存占用,还有这个程序执行效率上面做优化之后,你可以节约非常多的时间出来。这样你可以在相同的时间里面尝试更多的这个性能优化的方案。

然后第四点就是建立一个基本的baseline。呃,简单来说就是。嗯,你做了一些初期的可能做了一些简单的这个特征工能之后,你先去呃先去做一个最基本的一个模型。嗯嗯,稍等一下,我先把这个先把这个讲完吧呃。

😊,就是你初去做了一些这个基本的特征工程之后,你就可以呃先建立一个基本的这个base line模型。然后后续我们在这个base line上面进行一些深入调整,这个是最基本的一个步骤。

因为你后续要做特征工程呃,就是比如说你引入一些新的特征,或者是你删除一些无用的特征。你都要在这个base line的基础上面去比较去去看去去去比较来来看你你新做的这些步骤是否能你先引入的这些这些操作的方法是否能能实际提高分数。

如果说不能提高分数,反而降低,那这种特征工程可能就方向可能就是有问题的。这种就没有办法继往下做,那就要去寻求别的方向。啊,然后第五点是建立一个好的CV策略。

这个如果说是对于以往那些无序的分无序的这个分类或者回归问题,其实呃CV可能并不是呃特别特别重要。但是这个但是因为这个比赛它有这个时间相关的一个特性。呃,然后初期。初期的话。

我测了不同的这个呃不同的这个交叉验证的方式呃,差别还是蛮大的。像stratifyify k four这种会带来这个时间泄露的这种特征。呃,会带来时间泄露这种这种验证方式,在线上的分数是就比较低。

啊像K four和group K four的这种呃。加叉应的方式在线上的分数就相对高一些。所以这这个其实呃是这个比较相对来说比较特殊的一个地方,就是你在CV上面可能要谨慎的选择。然后哎呦我天。

怎么卡错了?Oh。然后就是呃确定好了这个CV策略之后,然后我们再根据这个模型的表现去解对症下药,去找到你目前目前你的这个模型的问题,然后实施特定的实施对应的一些特征工程的方案。比如说衍生性的特征啊。

转换原始的特征,或者是进行特征选择等等。然后呃。然后在大后期,如果特征工程觉得已经实在做不下去,找不到什么新的特征的话,呃,那就可以考虑用tack一些竞争方法来上分了。这个是大概的一个大概一个思路。

然后下面这个。啊,然后下面就嗯讲一下主要的代码。这个第一章。第一张这个朱pyter主要是呃EDA一些呃一些一些基本的这个EDA的过程。呃,我就大概过一下吧。首先就是读取你的这些两张基本表。

然后通过has的功能来看,呃,那大家概览一下你数据的一个情况。但嗯。对,没错。然后是查看一下你这个。查看一下你的这个数据,你的呃你数据基本数据类型。然后这个地方需要注要需要注意的是。

因为因为相当来是CVCSV格式的。然后像那个card1card2卡3卡4,他们是以呃flow形式存储的。所以你读进来的时候,这些类别特征会以in和f的形式保存。因因此这个这个地方要注意。

就是你要自己把那些类别特征都标注出来。否则的话,如果你不标注的话,呃,原始原始数据的类型是以这个in或者f的形式存储的。那这样训练时候就有个问题。因为模型可能会直接把类别特征当成连续特征。

这个地方要注意。然后是做一些,然后就是只因为它就只有两张表,一张主要一张副表,所以副表上面啊没有做我我没有再说,没有再去做太多的这个特征衍生的一些东西。嗯。😮,嗯,好吧好吧好,可能设备问题吧。

行行我继续讲吧。😊,然后这个呃然后因因为它只有两张表,所以就直接做了一个表合并的一个工作。如果说副表有很多的话,你可能还要对每个副表去单独的去做一些更深入的更深入细致的一些探索。

因为呃比如说有的副表它有很多缺失字段,有的缺失字段可能非常多。那这样你没有必要再把它con进来,或者是有些副表里面有特别多像呃特别多这个相关性特别高的。比如说100。99或者一的这种特征。

这些基本上也要呃要在初期初期的时候直接删除。但是这里的话没有这个问题。所以呃我就因为它只有一张副表,所以我就直接把它合并在一块,没有再在副表上做更多这个详细的工作,而直接把它合并到主表上面来。

然后一起来做这个数据探索的一个工作。然后这里是一个小tips吧,就是你在附表的时候,你可以加一个海的ID的字段。这样的话你 merge到主表之后。呃,merge的主表中就会自自自自动生成一个新的特征。

这个特征表示的是呃这个用户在副表里没有出现而,在主表没有呃这主表中没有出现这么一个信息。呃,如果你没有加这个字段的话,呃,这个mer进来的话。

你就没有没有就没有办法反映这个用户在副表上是否出现这么一个信息。那当然它只是一个特征衍生的小技巧,在这里在这个比赛里面这个特征字段没什么太大帮助。那在其他比赛里面可能会有一些一些帮助啊。

OK然后这个做然后然后是做一些这个基本的这个统计性描述。这个呃因为因为这个字段比较多,所以一般来说你像做这种大比较大,比较长统运行描述。如果你直接在朱弊上面显示的话,这列会非常多。这页页面就会比较卡。

所以呃我都直接保存到本地的那个excel文件,然后再去excel里面再去详细的看一下这样。这里就呃不进唉,算不进入那excel,再再这样的话太拖拖节奏了。这个就是他们这个呃他们大概一些统一特征。呃。

然后就是做一些基本的一这些可视化的工作了。你基本上做一DA基本可视化是免不了的。因为很多时候你通过单纯通过这个数字,你很难很全面的去看明白,看清楚这个特征是具体一个什么情况。然后做EDA的话。

我就因为我我我就比较我比较慢,我因为因为VR我是一个一个一个特征去做好这个。如果有一些特征就是数量特别多的话,呃,可能会呃简单的就是跳过一下这样。但是这里的话呃还是还做的蛮多的吧,做的蛮多这方面的。呃。

相对来说这个比较重要一点的特征都会仔细的去看一下这样。首先是这个transactionDT。他在这个官方文档介绍呃,官方的那个discuss介绍里面表示是一个呃时间类型的一个特征。

然后我们把这个特征pro出来就会发现呃,其实这个特征就是一个时间指示的特征。呃,比如说呃就算正常,比如说呃比如说某个特征是呃2010年1月1号到2012年1月1号,它就是一个标标标志时间的特征。

只不过它没有直接以日期的形式展日期的形式展现出来,而是以一个呃而是以这个连续特征的一个形式展展现出来。呃,这个。这个可以看成是一个类似于这个啊,实际上就是把时间转换成一个时间戳的一个表示方式。

类似于这样的,但是它又不是时间戳,因为它它的这个sstarday起始的这个时间还是不知道的。所以你你只能知道它它是一段时间的表示,但是你不知道它具体的具起有月份什么是多少。

这个是他test transaction低题的一个。也呃一个一个一个特征图。然后我们把这两个特征图合并在一块儿。😊,就可以发现,实际上这个transactionDD这个特征,它就是一个日期表示的特征。

然后中间断了一小块,或整体的话呃就是一段连续的特征。其实我们通过后面的分析就可以知道测试这个时间跨度大概是一年多,1年01个月。这个后啊这个后面后面后面后面后面再讲吧。那像这种特征。

其实我们EDA的时候就可以。很清楚的知道这种特征没有办法放到放到放到那个建模模型里面来用。因为首先我来看一下,在在训练级这个训练级这个transsectionDD它的数据范围是0到1。

6乘以1亿的7次方。而在测试集是1。8,从11。81亿的7次方到3。41亿的7次方。这个特征的。这个特征的分布形式在训练级和测试级完全是不同的,是完全不相同的。所以这个特征实际上没有办法使用。

因为你在transctionDT这个时间段呃这个这个数据时间呃这个这个区间。区间对这个特征进行训练。那那然后你再去测试集去预测的话,你所有的这个测试集预测关于这个点预测的节点都会都会在一个分值。

因为你在训练集训练的时候,你最大的这个 transactionDT的阈值也是就也就切切到1点大概1。6乘以1亿的7次方这个地方。而你这个测试集所有的数据都是在1。8乘以1亿的7次方这个地方。呃。

因此这就表表示你所有的这个你在测试预测的所有数据的所有数据都会都会把预测到这个最右边的一个分支。呃,因此这个特征我们在来做EA的时候就可以就可以知道这个特征其实没有办法建模了。呃,可以。

所以在后续建立baseline的时候,记注意要把这个DT给transctionDT给排除掉。然后是看这个transaction AMT。这个特征的话呃,一个是box报图。可以看出来。

在这个che和test的数据集上面,这这个特征的分布还是有一定有一定差异性,还是可以看出来。像这个呃在确的数据集上有存在一些比较大的。比较大的transseMT的词,但是t上面最大就到1万。

所以这二者分布上面是有一些差异的,可能后续需要做一些log变换之类的处理,或者是一些分散的处理。不不过这个只是一些EDA的时候,一些一些基本的思路而已,没有。后续的话可能还后续还要再做一些测试。

然后这个就是对呃标签为零和标签为一的用户,用户的这个特征来做一些对比。从这个图上面我就可以我们就可以看到这个。呃,像正常用户正常用户有有有有一部分正常用户,它属于大额交易的,而大部而所有的这个异常用户。

他都是倾向于小小额交易的。因为它最大的只有5000,就是就属于一个正常交易的范围。而这个正常用户里面是会有一部分人那个做这个大额交易的。

因此这个我们可以从这里看出这个trans transactionctionMT对于这个好坏客户还是有具有一定区分度的。并且可以知道,对于其他用户来说,呃。

可能大额交易的大额交易的大额交易是否大额交易是一个比较强的特征。其实其实如果我们不使用GBDT而使用LRR的话,做到这一步就可以去分离一些分离这种特征了。比如说呃比如说我们可以写成一个新的特征。

这个特征表示它的M交易金额是否大外这种特对L来说是有帮助的。但是对于GBT其这种特征功能是没有用。因为G因为GT系列系列算法它都可以自动识别到特征中的这种模式因不需要再去做这些这些工作。

然后我们比较一下这个呃训练集和测试集这个transctionMTMMT的这个分布的差异。可以看到它整体上分布差异并不是很大。呃。

这里的这个部分异常的这个呃呃部分这种偏大偏大点的样样本占比总数占总数的比例还是相对比较小的。这个是更细致的一些观察。因为呃。因为那个值的跨度如果很大,然后比如说有一些特别大的值,但是数量又很少。

那这样你pro出来的话,就会变成这种形式。如果要看的更清楚一点的话,你你就去指定这个去指定这个范围,把那些大的点排除掉,这样看的会更清楚,更更清晰一些。

这个是呃transaxMT在训练集和数据集上面呃训练集和测试集上面的差异。然后这个是它在正负样本上面的差异。你还是一样。如果不做一些具体设置的话,实际上很难看出来一些细节上面上面的一些一些差别。

所以这个最好还设置一下这个range,把它设置到一个相对合合理的范围。这样的话你才可以看得出来具体的这个具体的差异在哪里。然后是productduct CD这个特征。呃。

这个特征是属这个特征属于类别特征,而且属于这个低级数的特征。它本身这个类别其实很小,只有五个类。呃,所以这个这个这个类别成相对来的处理处理一下简单一点,甚至可能不需要去做额外的处理。呃。

比如说像比如说高技术编,高技术特征,一般来说要去做编码。啊,但像这种的话,其实王浩展开也可以。因为他本身类别就很少,无所谓。呃,然后步骤还是一样啊。

我们先看一下训练集和测试集上面这个特征分布情况的差异性。然后再看一下这个呃不同。类别用户下面这个特征的分布差异性。没看到这个特征。它本身的区分度还是还是比较高的。因为。对于好客户和坏客户来说。

这个特征分布分布差异分布差异还是比较大的。而实际上后面我们训练模型,然后看它特征号线的时候,也会知道这个productductCD呃也是相对一个比较重要的特点。

这个从EDI上面也是可以看到也是可以看到大概的。嗯,然后我们看一下这个一ca6这这6个类别特征。呃。🤢,对呃,可能是这个问题。对。首先我们看看卡的一吧。嗯。呃,这里我们先对这个card6和card6。

看一下它的那个water count的情况,也就是看它的类别情况和不同类别占比的情一个情况。呃,这个water count是做类别特征分析的时候一个很常见的函数。唉,后面详细看这些吧。呃。

我们首先看一下这个迪一它的类别数量有13553个,所以它属于一个典型的高技术类别特征啊,对于这个类别这种类别特征的话呃,因为垃编M它本身是可以对类别特征直接进行直接进行编码。

它底层是做了规定不定的编码啊,不做了那个梯度编码呃,这里我们可以。使用一些常规的编码方式来来处理这个类别特征。啊,这个后面再说吧。首先首先card一的类别是113559,并且这个有很多都是属于这种。呃。

只有E22这种少数这种呃这种re value的这种形式。呃,劳后看特色卡也是类似的一个情况。然后这里是呃通过这两个代码,是主要是检测这个t。因为为我我们我们是要看这个特征,在训练集和测试题上分布的区别。

但是呃像看一这种类别这么多,我们很难可照画出来。所以通过其他一些方式来看。那这里这里我是看那个在card一在t上面test test上面有出现呃test上面和和和那个确上面有哪些特征是不一样的。

然后通过这个代码可以发现。通过这代码可以发现这个。呃,在tt的券中有3538个类别是没有共同出现的。然后通过下面这个代码,我们可以知道有9360个类,9360个样本。它在呃训练题上出现。

但在测试题上没有出现过。然后看一下这个card,相对card一来说,card类别数量会小一点,但是它它这个类别基数也不小,有501个,也是属于一个高技术类别特征。呃,接下来这个步骤基本上都是一样。呃。

我们大概看一下这个类别,它它的这个类别数量有多少,然后每个类别占比是什么情况,然后看一下它在这个训练器测试计上面的分布大概是差异性大不大,这样的。然后是ca3ca6。🤧基本上都累死。都类似一样的这个。

呃,数据探索的一个过程。呃,代码那个我讲完的话,我会发找个地方发吧,我看他们到时候发哪了,然后我把数据集和代码都发过来。然后你们要需要跑的话,可以自己跑一下。嗯,大概这样。嗯。

这些就这大概流程性的东西了。嗯,下面基本上差不多,那看了四的话,那类别比较少,所以这个。呃,所以我直接做了一些可视化的一些工作。然后需要大家注意一下,就是抗似它是一个相对于其他特征来说。

它是一个有包含有文本信息的一个特征。就它的类别像discoverma的visaam Americanican express表示的是这个这个卡的类型,它是属于一个文本特征。

一般来说呃在这个table比赛里面呃,在t比赛里面,这种特征可能可能相对可能会携对更携带更多的信息。因为它它具有文本信息,你可以结合自己的一些先验知识,然后去呃比如说去做一些呃文本的一些处理啊。

或者是一些衍生性的工作。呃,但是这里有没有没我我没有在这方面继续下功夫。比如说像discover这种卡,如果说你能从外部数据里面得到呃这种卡,它整体的一个违约率之类的话。

可能会是会是一个比较好的一个特征。呃,但这些当时刚开始当当时参加的有有去搜索过这方面的数据,但是没找到。所以所以后续这方面没有再去做深入的研究。

如果如果说我们能从一些一些网站上面得到像这个discover visaammericica expresspress这些卡整体的一个违约率的话,可能会是一个比较好的特征。嗯,然后看了6月是。

也是包含有一些完的,但是我都没有展开去网。本身对于这些卡的这些新验知识,这些新验知识我也不是特别了解。什么discover这些卡就只是知道有这种卡的类型。人家对于这种卡的一些特性什么之类的。呃。

我不是很清楚,然后也没有去深入研究。如果对这个感兴趣的话,可以自己去深入研究一下,看看能不能挖掘出一些新的新的好的一些好好的特征这样。😊,嗯,然后基本上嗯。流程大概是这样,这些就整体上就这么做就够了。

就是把一些就是把这些特征通过一些方法来看它的分布啊,然后熟集一下这些特征的这个数据情况之类的就OK了。然后是ADDIAADDR这个这个是用户的这个呃呃地址地址特征。这个操作基本上上面类似的。

因为它本身也是属于一个相对来说基数比较高的类别型特征,所以去做可视化很麻烦。因因此是直接通过一些统计特征来来观察这个特征的一个大概的分布情况。这个他的这个距离特征。它是一个连续型特征。

表示的是呃表示的行业是距离。然后是这个用户对应的他的邮箱的特征。啊,像这个这种特征。可以看到它也是一个比较详细的文本特征。这个实际上有一些呃在开源的课程里面,有一些选手对这个特征做了一些处理。呃。

比如说像这个呃比如说我们看这里。嗯。嗯,我看一下啊。呃,比如这个anonymous点com,这是这表示的是这个匿名邮箱啊,那这里就可以演生出一个新特征,表示这个用户是否使用匿名邮箱。可能从直观上理解。

可能用户使用匿名邮箱,那种用户可能会有一定的问题。然后比如说像这个呃我看后面后面的例子比较好一点。那这个Gmail点com和这个Gmail实际上它是一个东西。

只不过它这里Gmail它记录的东西不完整而已。呃,所以在这在这个邮箱方面也可以做一些额外的工作。比如像奇mail点com奇mail,这明显是同样同样的一个邮箱地址。那大家都可以自己去。

把这两个邮件地址分别合并起来。这个的话也能提升差不多千亿到万亿之间的一些一个分数吧。不我我没有做。因为这个是另外一个开源课呢里面,我后面看看了开源课呢,我才才知道有这么一个东西。自己去做的时候。

没有去做这么细致的这个处理。还像像那个ho hot email这个这个其实也是可以合并的。总之就是t数据里面,如果有这种包含这种详细的文本信息这些特征的话,最好自己去仔细看一看。

每一个我仔细看一看这个其实文本特征具体什么情况。这样的话呃,因为相对于纯粹做做完那种label encodecoder编码之后,那些类别特征来说,它包含信息会更多,有更大的操作空间。

那像这如果把这个这些特征直接去做类别编码,那压根就你就没有办法再用。因为它只是一一大堆编码而已,不知道它实际行业没有办法去做具体的展开。然后像这些,比如说呃比如说对其诈还是比较熟悉的,呃。

可能会知道这些骗子一般会使用什么样的邮箱。比如哪些邮箱的监管可能会差会弱一点呃,骗这其他分子更喜欢用这些邮箱啊,这些都可以作为先的知识结合进来,然后来延伸一些新的特。嗯。呃,然后是看这个C系列特征。

C系列特征都是一些技术类的特征。哎,我们在前面那个。前面也介绍过。它都是一些技术类的特征。呃,官方的discus我们只介绍了,其中有一个特征是和知法和这个知法相关联地址数,其他的意思行业就不知道。

那反正只要知知道它这个技术特策就行了。嗯,然后就是针对于这个CE系列特征做了一些可视化的工作。呃,就是呃呃就这个这方面的话要注意最好你每个特征单独画一个图标都放都放在一张图里面。

一方面呃一方面你把太多特征挤到一张图里面,会会会比较卡,处理速度比较慢。然后另一方面,你自己的这个视觉效果上面也比较也不太好。可以看到这个西特征整体的这个分布情况。呃,也是比较集中的。

它大部分呢集中在某个区间之段啊,其实感觉参加了类似于这种就金融类比赛,这种分布的特征还蛮多的。就是。就是大部分特征都聚集在一个区间里面,然后少部分特征可能在其他区间里面,现特征特别多。

OK那大概的情况这样,然后也是一样,看了他在数练集合测试集上分布的差异,还有他在这个好坏客户上面分布的差异。嗯,大概这些。呃,然后是D系列特征,呃。

D系列特征官方上面官方给的结果是这个这个是这个特征是属于时间性质的特征。但具体是什么时间性质,它只是。他只提到了。官方是提到这个D特征里面有呃D特征主要是关于时间间隔的一个特征。比如说三次交易。

单次交易和上次交易之间间隔天数,但具体是什么间隔因,他也没有具体介绍。那目前我们就知道我们是只能知道这个低械特征,它属于一个时间相关的一个特征。嗯,然后也是做了一些可能化的工作啊。

这个基本上大码都是一样。这这基本上一套的东西。嗯,没什么可变,反正每个人根据自己的习惯来来写不同的可视化的代码。可以看到这个低特征相对来说区分都会。还是比较明显的。但是这里。在不同的这个任务类型上面。

这个特征的分布差异性还是比较明显,相对于之前那些特征明显的多。然后是M1到M9,M1到M9是典型的另外一种特征,他们全是呃大部分都属于部类型特征,也是也就是属于那个te或者fo这种特征。

它表示的是因为他官方给的这个M特M系列特征定义是属于一个匹配型特征,就是是否匹配上。如果是的话,就处,否的话就是否,它是属于一个典型的一个0异系列特征。

这个特征其实你用lightG BM或者叉G boost。这种222类特征你不需要去做额外的处理,因为它就你把它当成类别或者当成连续特征,实际上对于模型来说是没有区别的,因为它只有两个类别。

那只有其中一个M4有3个类别,其他都是两个类别的D级出类特征,也可以叫它不形特征。它全都是触和或s这。这个类型。🤧这种特征其实没必要去做什么可视化整明,它本身只有两类。所以它的特征分布情况赢不了了啊。

嗯,O。是。两类特啊,不是,当然不是了。为什么两类特征不适合单入模型?这个哪类特征什么特征不错,但是这个这个其实没有这种说法了。具体的特征好不好,你还带进去之后才知道这个特征的效果怎么样。

这个M特征没什么可多的,特征本能就比较简单。然后是微特征。呃,微特征因为。虽然呃代码会发,哎呦这么多人问。微定的因为微定的数的太多了,有几百个去做可视化的话非常麻烦的。当然呃。我之前之前是有做。

但是太多了,放到这边就他妈占版面卡的要死,所以就没没在做。因为很多很多微特征它是都是没有用的,要不就是相关性特别高,重复重复重复特征特别多,冗易特征特别多。要不就是确认比较多。

所以所以我这里没有没有再把它贴出来,应该不算是一个一个做特别多几百个呢。在这里微特征后面后面我再介绍这个特征呃处于一个高度冗余的一个特征级。然后是ID类特征,呃,需要注意就是IDID类特征。

它有ID01到ID38,其中01到11的话都是属于连续型的特征。这个地方要区分清楚。Yes。然后是这个啊这些都是一样,就是做一些可视化基本上一些工作。这个的话其实每个人根据每个人习惯嘛。

你不用按照我这个代码来,你自己觉得那种你用C报啊,或者是yellow break之类的,就说可视化都可以,就自己怎么说怎么来吧。呃,然后是这个IDI112I3ID38。

叉级布s的来自于这类别特别多的可能需要做特。而叉级布,它因为它叉级布它本身没有办法对类别直接进行建模。因为它是没有办法处理类别特征的,LGBM它底层是做了梯 two编码。

所以它才可以对类别特征直接进行进行训练。因直呃但是呃怎么说。你对类别特征进行编码的话,比如说你去做特征编码,你可你会引入一些新的特征特征信息进来。

所以呃其实也是比较推荐去对类别特别多的特征来做这个特殊处理。呃简言之就这样说吧,你叉你在处理类别特别多的特征的时候,你必须去做编码处理或者是一些embedding之类的处理。

否则的话你叉没有办法直接去训练类别特征M的话它因为它本身是做了T编码,它可以对类别进行处理。所以这方面的话呃你可以试试看有有时候你做去做这个像equ啊,之类会有效果。

有时候没有这个你都可以试试就你做完特征之后放进去跑个loV看看得分有没有上升,这样就可以了。啊,O。然后是在这个ID列特征。这个哎呀可算,这些基本能感觉没么好说的,就就是这些东西呗。😊。

反正各种各样的那种机器学习相关书上面都说的很清楚啊。没有说特别需要处理的地方呃,特别需要注意的基本东是没有哦,还有是这里有dise type。US也是一样。

它是一个呃包含比较丰富文本信息的一个的呃一个一个特一个类别特征。这个的话呃在开源课堂里面也有人做一些额外处理。比如说这个LGH221,他们都是属于LG旗下的,就是型号的这个手机。

那这里就可以做一个合并的编码。这里LG呃,比如说呃都属于都是属于LG,你你可以把它合并成合并成一个大类。然后这个汉达ID是我们先在副表上增加那个字段。🤧嗯,他只只有1。0呃,只有114万是1。0。

剩下的都是属于1。那就表示呃只有144233个人在可以在副表上面找到数据,剩下的用户都没有办法在副表上找副表上找到数据。然后呃这个就是其他的一些一些工作。这些嗯也没什么可说的了。那最基本就这些。

然后就是数据合并之后保存。然后然后接下来我们进入下一步。呃,样本不均衡怎么办?呃?这个呃这个后面我总结的时候,我会额外提出来,这这这个也是这个比赛一个比较有意思的一个地方。

相对来说它比较反比较真实的反映这个样本不均衡,它本它的本质问题是什么?然后然后是第二步我们进入进入这个相关性分析。一般来说这个其实table数据呃做开口的数据呃。

像这种表格型这种数据比赛可能不太会去care相关性的东西。但如果你是高相关的。比如说你相关性为0。999或甚至是一这种但这个比赛数据里面就有很多特征,它的是相关性特别高的,就达到0。

999这种特征当然是我们我们需要直接删除的。一方面删完之后,你可以节约这个内存提高这个运行时间一方面这个呃一方面你如果是相关性特相关性高的特征特别多的话,对于这个差距或来基本这类算法。

它的这个泛化性能是有影响的。呃,最主要主要原因就是你高相关特征特别多之后,你这个模型的这个采样会特别偏向于去去偏向于采样这种高相关的特征。举个例子,比如说你有1000个特征。

其中有980个都是完全一致相关的特征。那只有20个是不相关的特征。那在这种特征上,你去做你去去做去做训练的话,你每次呃去做列列采样和含产样得到这个数据集,可能都是一些高相关的特征。的这个数据集。

那这样的话,你会你就你的数就会反复在这一组就在这一组980个相关性特别高的特征上反复的去采样。那最终你整个模型会非常依赖于这类高相关的特征。

从而导致你这个模型它本身的这个多样机机学器的多样性受到很大的损害,让你模型的放行性能就会变得比较差啊,具绝试验的话呃呃后面后面关于这个问题,我我也会给到这个代码,那在后在后面再看就行。然后这里的话。呃。

这里的话这个初期有一个比较好的一个操作,就是呃微特征的删除。呃,这里有这里有这个这个比赛第一名这个第一名的这个大佬发的一些呃对于这个相关性相关性分析的一个一些一些一些建议吧。首先就是嗯一般来说。

我们尽量比较少删除这个特征点,然后。这里我我们后续会对微特征做相关性分析,并且删除高相关的特征。而且这个阈值卡的很低,卡到0。75。主要是因为呃张特discus里面也说了。

微特征主要是CDM这些已知原始特征的特征的衍生。所以它可能不包含新的性质。它就是在CDM这些特征上面反复去使用一些特征工能得到一些冗余的特征。呃,所以这里对V进行这个相关性分析。

并且去除掉很多高相关的特征之后,呃,可以发现locgoCV的得分不仅没有没有降低,反而提高了。这个我们可以看后面后面这边呃有一个比较。嗯,然后这里。呃,这里有一个需要注意的一个地方。呃。

不能不能算是技巧,就是一些最基本的需要你需要你知道的东西。就是一般来说我们计算特征相关性的时候,是直接用pandas点ca来计算的。但是pas点有个问题,就是如果你不同特征间存在缺失值。

它不会去计算你那个缺失值共有。你比如说像这个下面的123N312最终它计算相关性的时候,只会计算这个3。因为只有这个一部分,这个部分是这两个特征都没有缺失的那这样计算出来结果就就会等于一。

你显然这是这是错误的。所以我们在做相关性分析之前,需要把这个需要先去确定这个不同特征,它的缺失值,然后把这个确失值相同的特征放在一起。这样才能去做一个比较合理的相关性分析,否则就会出现上面这种情况。

你两个特征存在不同的缺失性缺缺失值,然后公共的部分只有一小部分。比如说你。两个特征有有有一个呃,比如说有两个1万个,有1万个曲值特征吧。然后其中只有100个特征。

是两个特征都共有的那这样你最终的相关性就直会间在100个呃直播间在100个样本上面去计算。那这样显然就是不符合呃不符合正常逻辑。你现在计算肯定错了,你本能是1万个值,但你只在100个值上计算相关性。

那计算值出来,那计算计算出来的值是没有没有意义的。🤧。然后还有一个这个技象,就是呃如果我们需要像这个这个比这个术于比较它有transctionDT这种日期特征。

然后如果我们需要呃快速的指道哪些特征是和时间强相关的,直接和直接把特征和这个日期特征进行相关性相关性分析就可以了。如果他们具有比较强的相关性,那这个这个特征就是就是具有比较强的时间特征。

那这种强时间特征,我们就要进行一些呃强时间特征的处理。比如说呃你把强时间特征和这个时间这个时间时间日期特征做一些减啊,或者除一些一些操作来消除它的这个时间相关性。

这个对于letGBM这种算法是比较重要的。呃。这里的话首先我们需要去查看这个确失值相确失值相同的一个特征。

啊,这些代码后后面后面我都会给你们这些代码我都放在放在这里了。

这都是一些比较常用的工具代码,后续的话有需要可以自己自己自己使用。ok可以看到这个这样我们可以分出来不同的这个确认值组啊,但这个是确认值只有零的啊,就没有确实值的特征,这个是确实值35万特征。

然后这样的话我们可以自动把垂实值相同的这些特征都放在一块儿。都都聚在一块。可以看到这个不同组的这个特征。你可以看不同组合特征之间,它缺失差异起来比较大。比如说这组他们都是只缺失314个。

呃这一组他们缺失40多万。呃,这样的话我们就可以后进行后续哎才才可以放心的去做相关的分析了。而且一般来说,如果这些特征的缺失值完全相同。像就是完全上那种概率是很低的。那如果他们确认是完全相同的话。

很大概率表示的就是这些特征它可能都是在同样的样本上面缺失的啊,这个现下大家可以自己去看一下。像比如vi,像比如这组特征,他们实际上都是同样的45万个用户。45090000呃45909个用户。

他们就是确实都是都都在这这些特上面缺失信息。那这样的话,你去做呃相关性分析的时候,你做相关性分析的时候,你会你就会在这个相同的值上面去计算,就不会碰到上面我们所说的这个这种NBNA的那种情况。

🤧这样的话计算出来的这个相关性才是准确合理的。呃,呃,如果其实你们也可以自己去比较一下,如果不做这种处理之后,你直接去做相关性分析,你会发现多了很多特征,他们之间是高相关。

但实际上他们之间是没有特别大的相关性。呃,有啊有啊,这个出币者到时候都会打包给你们。然后就是看一些,然后就是做一些基本的相关的分析。呃,这个是原来那个冠军solution呃。

那个冠军他的呃那那个第一名冠军,他给到了一个方案,而,他给到了一源代码。不过后面我我做了一些封装,可以快速的删除一些特征,它卡的它相关性卡的阈值很高,它卡了0。75,只要0。

75以上的特征就是它直接都删除掉。原因就是我们上面说的啊,因为这个微特征它是属于。它属于原始特征CDM呃,属于原始特征衍生出来一些特征。所以呃说明这些特征没有新的信息,它可能很多是冗余的。

呃在进行相关性分析的时候,也确实。有很多威特的他相关也很高的。那比如说像这么下面这些。先像这个相关举证,我们就可以看到它有很多高相关相高相关的特征。那这里需要注意的就是,因为这个微特征它本身。

它本身是属于冗余的特征,它有很多都是呃可能都是完全呃都是都是一样的数据源算出来的一个衍生特征。所以我们就可以把阈值卡到0。75。但是如果是像其他的那些,比如说呃比如说我们后面会看到的那些。

后面会看到有一个特征是。啊,这些都是这些都是属于微特征,他们的这可以看到微特征里面有很多相关性特别高的特征。然后它本身就是冗誉特征,所以呃这些相关的特征都可以毫不犹豫的删除掉。

🤧然后但是有一点需要注意的就是这个呃因微微den它本身属于容易特征情况比较特殊。一般来说我们不会卡到0。75,这么严特的。就正常比赛,如果你你去做相关性分析,阈值卡到0。75,阈值考到0。75的话嗯。

你稍等一下。啊,比如说这也是个C特征,它就有很它也有很多这个高相关的特征。如果你按照0。75的阈直卡的话,它基本上大部分全部都全部都要删除掉。但是因为C特征它本身并不是冗跃特征,它是属于一个新特征。

因为C到C,它都属于技术特征,它并不是属于其他特征的衍生。所以这个。呃,所以所以我们不能就拿0。75那么那么严格分数去卡去卡,卡,否则你会删掉太多有用的信息了。呃,没有,相关用的呃。

用的就是piearman。用的那个质相关系数不是用MIC。所以所以所以这个地方需要注意就是呃之所以我们做了我们在之所以之所以我们会去做相关性分析。删删除那么多特征。

主要是因为微特征有太多冗余的冗余存在了。所以我们才敢卡0。75那么连的阈值去删掉大部分特征。相对于C这种正常的特征,一般我们不会卡那么多,只会把一下这种E呀或者是这种0。0。

99啊之类的这种特征就去做一些删除。但甚在是0。960。95或者甚至是0。8的这务。我说这个这个其实不会去考虑删除的。你删完之后你去看logo识别,一般分数都会降一点。一般来说。

如果是呃比如说像这种C1到C15,就正常来说,因为这个微特征,它之前主办方在主办方之前有说过,这个微特征是由是由这个已知的特征衍生出来的,所以它的冗余程度是比较高的。所以才会去卡0。75。

正常的话像C1这种特征。在这个原始特征呃都不会去卡卡那么低的阈值,一般就会把只会去删这种相关性特别高。比如像这个一就C2和这个特征完CC2和C一特征完全就是相关的,完完全就是一致的特征。

这种特征会去做删除或者是0。99这种这么高的那像低一点0。960。97这种一般都不会怎么会去删。删的话分数一般会低一点,可能会低一个万一之类的。这种但是对于像这种开国他们比赛来说。

万一可能就差了有几十名。所以大部分时候呃选手做比赛都不会特别去删除那么呃去去去做那么严格的相关性分析,只会只会去删除一些这种非常相关的,极其相关,就完全一致的这种特征,才会做删除。

那这个C特征我也只删除了一和0。99这种到相关的特征。🤧嗯。那这里我是取超过0。97的特征去做删除。呃,其实我后面测试的时候,发现就是删多了,上0。97就删多了,应该删0。99级以上的这种特征可以。

我上因为我后面又做了测试,就是不30。97,只30。99到1之间的这种特征。呃,分数会提一个差不多万一这样。所以在做这方面的时候,呃,大家还是要注意点。

一般来来说只只去只去操做这种相关性特别只是相相关特别高的特征比较好。除非碰到V这种情况的。呃,本身就是属于种于特征,你才才可以去卡去卡这种比较比较急的比较比较严格的预子。那像这种的话呃,是不是冗誉特征?

是不是容易特征的判断呃,相对来说比较麻烦一点。这因为因为这这个比之前di同学讨论,我才知道原来V一他有这么多种特征。那如果他不讨论,我可他也不知道。所以如果碰下次再碰到这种问题的话,呃。

比如说像这种都是属于V或者都是属于C特征,可以建议可以去尝试一下。就比如像这种V1这么一组特征,你可以去卡几个相关性,比如卡0。80。90。99之类。然后然后根据这些相关性系数上完之后。

你再去跑logoCV看看得分怎么样的。😊,呃,那这里的话我们就把呃这一张这张朱P的nbook,主要就是把这个相关性的一些相关性主要做了相关性分析,然后删除了一些高相关的特长。

然后关于类别特征的相关性问题的话,呃呃这个这个我没有准备,类类别特征相关这个其实。嗯,类别特征相关性还是有一些需要讲。

因为它它在类别特征相关性没有办法用peearman或者是呃peterson或者candal系数来计算。那需要使要使用一些类别相关的一些特一一些指标来计算。呃,这个我没准备,后续有机会我再补充吧。呃。

然后呃通过这个这张I主片的会做过,我们来我们确定了这个要删除的这些微特征,还有要删除一些C特征。我前面V就通过前面这些分析,就是去掉了。很多高相关的V特征,还有这个一些部分高相关C特征。

然后其他特征的相关性整体来说就没那么高,就比较低了。不会不像这两个村这么夸张。哦,另外呃还有一点需要注意的就是是这个在这里就是呃举个例子吧。比如说比如说像这个。C4和C1C4和C它们的相关性达到0。

97。那这个时候应该删掉哪个特征,可以删掉C1或者删掉C4。呃,这里的话呃我用的规则比较简单,我就直接去看C1和C4,它本身的这个取值取值数量是多少。比如说。比如说这里。比如说C1和C4。

这里C一的取值,C1的这个完全呃C的这个完全不相同的取值有1495个。而C4有1223个,所以就这里选择上出C4。因为相对来说如果你取值数量更多,呃,相对来说对于数来说,你可能能分裂的地方更多。呃。

也就意味着这个特征可能包含的信息量更多。啊,当然这只是一个呃我自己用的一个比较简单的一个判断的规则。嗯,其实你也可以用用那个其他的一些评价指标啊。比如说呃嗯比如说那个看这个特征的这个IV值。

你也可以通过这种方式来做。不过那个麻烦IV值本身计算也耗时间。像这种直接看它的unique的这种函数操作速度很快,很方便,而且效果也还不错。你本身相关性很高的话,这两个特征本身就没有太大差异性。

所以在这些细节上面做一些处理就好了。呃,这是这是我自己的一个方法,其实也不一定一定要使用这种方法,你可以。呃,使用别的方法来看看效果会更好。只不过用这个方法比较方便快速已。啊。

OK这个基本讲的就差不多了。这在讲已经讲完了。自然主要就是把相关性的一些问题都处理掉。呃,然后就是呃。刚刚说的一些优化的工作,还有这个base line的经历。呃,首先就是这里这个。

这个控制随机性的这个这个是这是一个非常重要的来说。一般来说我们在做这个模型建立的时候,都要首先要把随机性固定住。嗯,比如因为你每次你比如说这个模型的这个交叉验证,还有模型本身呃GPT它本身的行列采样。

都带有一定的随机性,所以呃我们要把这些随机性都控制住,你要保证完全一样的呃交叉验证的这个。数据齐,你这样才能合理的去。呃,这样你才能合理的去评估你这个后期做一些特是隐身之类的工作。

它是否能带来真的正的争议。否则的话,你每次采样的数据集都不一样。你只能这个交单验证的这个。结果也也是不一样的,但你没有办法评估一些比较小的分数。比较小的分数的提升。然后这个呃这里的话。就简单的走。

简单的做一个基本这个baseline的模型。啊,这里做了一个大概的封装。啊,就是不用训练的分装,像每次的话只要掉这么一行就可以,不用找这么一大段,特别占特别占屏幕。啊。

然后就是这里就是我们前面说到这个降低内存占用的问题,一些技巧。呃,首先就是类别特征,因为像pandas里面类别特征一般它是用string类型的str string类型的数据来存储的那这种数据存储它内容占用量很高的。

然是这里的话,我们直接把只有label encodecoder,把这些类别特征全部都编码成那个连续连续特成用int用int型的数据来存储。这样的话这个内存占用会以小很多。呃,然后就是这个。嗯。

这个也是一个很常用的工具函数。呃,它实际上就是。呃,他的逻辑很简单,就是根据你这个你这个数据集上面,你的数据的取值范围,然后来确定你应该使用什么样的这个存储方式。

这个线下是大家可以看下这个这个函数基本上也是呃基本上没次比较都会用,确实可以呃在大基本上大部分时候可以解。比如说你直接用readCSV读进来这个date frame之后,因为这个函数处理完之后。

内存占用一般都能减少50%以上。这样的话你整体这个你数据集会比较清亮。你训练的时候速度也会更快。然后数据读取啊,处理的速度也会更快啊,这是一个非常方便的一个工具函数。

那这后面呃我做总结的时候都会放到总结里边,就这些常用的一些呃开go u这种工具,工具函数都会到这个,在这里不用额外去记一下。嗯,然后这里是。呃。我们这里就是已经处理完了,这个已经优优化完了这个内存占用。

所以这里可以看到这边减少了70。7%的这个内存占用。然后就确定交叉验证的方式了。呃,其实正常如果是无序的分类问题的话,呃,是不需要,其实不太需要去关注这个交叉验证的方式。但是这个问题挺特殊。

运动交叉验证方式分数差别还是还是有还是有比较大的差别的。因为它本身是有带有时间性质的一个问题。所以这里还是得确定啊,所以这里事先得确定一下交叉。因为我们后续要做logo CVV。

首先那个CV就是交叉验证嘛。那我首那我们明先要先确定一个合理的这个交叉验证的这个方式,然后才可以进行后续的这个logoCV这些测算之类,后续的工作。这里的话呃我出去就。

看了一下那个常用的一个strify keyboard。一个是普通的keyboard。还有一个是time service speed的时间叫时间税这还有没有?最后呃提交到线上的话。提交到线上的话。

分数最高的是K four。所以后续我一直都是使用K four的。那这里还有一个blue bike for的。不是k,这个是我。这个我我其实之前一直没有。

就是在就比赛结束之前一直用的都是keyboard的。所以他最后看这个冠军15的发现他用的是这种不如K的这种形式。它实际上是这种呃主角叉验证的方式。对所以那个在做这个课题的时候。

我也去测了一下这这种招商验的的方式,它线上的这个分数。呃,整体上说。这个是提交到线上之后的这个成绩。这个这个是A版,这个是B版。可以看到这个。呃,strrateify keyboard的分数。呃。

相对于这个K four的是要插了。千三的。呃,呃稍千接近千4500呃group kboard相对于Kboard来说比较接近。然后time service board在线上分数很差,差了将近两个点。呃。

所以这里就是时间问题,就时间相关的这些问题,就麻烦在地吧,你就交强验证,你得你还得事先去确定使用这个交强验证比较好,要不然分数确实差异非常大。正常如果是无序的话,其实差影P没有这么大。

可能就差了千一千一千一乘4这样的这个这里的话差异就特别大。OK然后这里我们大概建立一个基本的一个baseline的一个模型。可以看到这个模型嗯。现看这个模型,它这个它这个是它的这个线线下的成绩。

线下模型训练的成绩。一开始没有做什么处理,但分数很低啊,只有0。92多的AUC。然后在线上的话是0。93多。整体来说,线上和线下。数据及整体分布差异性不是很大,可能就差了千几。

这个相对来说就一就是是一个比较好的一个这个logo CVV的策略,说明我们这个logo CVV和这个呃是是具有一定就具有比较好的泛化性。因为它和这个A版的差异差异差异不是特别大。okK那我这里讲完这里。

我讲第三。我们前面已经建立完baseline之后,然后接下来就去做模模型分析了。呃,这个是我们之前。这个做IGBM训练的时候,他他过程中这些日志。

我们可以发现这个这个模型问题就是就在于它的这个过拟合特别严重。可以看到在第一折的时,在第一折的时候,这里训练级AUC到1了,但测试级还在0。9。那其他美则也都差不多。

画画性能差不多都差了将近7个差了将近7个点以上。就所以说他这这种情况发高招特别特别高高了将近7个点。那显然就是属于一个典型的一个过敏的问题。那我们就要针对过年的问题使用一些。呃。

看过拟合的方法来缓解这个过拟合的情况。那这最简单直接一个是上参数。一个是使用这个约输。约束性更强的一个成熟。🤧,但使用完这些参数之后,我们就会发现。他对于这个模型的这个方号误杀。是没有太大帮助的。

它放化误差还是很大。那,一般来说,如果你放化误差在5个点以上的话,你很难通过简单的调仓去弥补这么大的一个差异性。我也基本上没有见过见过谁在比赛中用单纯靠调仓就可以把放化误差从7个点以内缩到两三个点以内。

这个是基本上是很不太可能的。因为调仓的一般就于来基变上参数布的这种模型,它们这种模型本身鲁帮性比较强啊,你只要参数设置的合理的话,后期调仓的整体的争议并不会特别大。能提高个差不多千千级的话。

已经算是非常好的一个情况了。更不就是这里7个点的放好误差,就很难通过简单的调餐,就去弥补这种这么高的误差。呃,然后我我是尝试两组,并且每组它这个约束性都更严格。这里的mac step更小。

然后采压比例更小。但是最后结果也是一样。放放误差呃,可以看到这里放到误差,随随着这个。参数这个约束性的增强,这里放化误差虽然是降低,但是它整体logoCV也是降低。

🤧这个实际上是属于一个等于其实你没有去实际上真正去解决问题。因为你本身那个logoC为你的放化性能还是差。虽然你你在这里看它的放化误差减少,但你是以这个你是以降低模型拟合能力为代价啊。

你只是把这个模型的拟合能力。你你的能力降低,从而从而导致他在训练级和测试集上的分数相对来说都降低。然后然后通过这种方式来缩小你这个放框模程。但是你这样这样这样其实际上是没有意义的。因为我们。

我们我们希望的是它logo是不是高,总之它的泛化性能也低,呃,泛化性能泛泛化误差也也尽量小。所以这里呃。做调仓的,这里其实也是可以去做一些调仓的工作,然后也是可以提高一些。

比如说你直接去科隆上找一些比较好的参数来跑,那分数可能还能提高个一点。但其实这样在初期没有太大意义。因为你本身参数的能够给你带来的上限是很少的。

重要像t这种数据重要的基本上还是在特征上面做一些额外做很多额外的处理,有新的特征,这样这才是呃打table数据的一个比较比较正正经正经正常的思路,也是比较有效的思路。调仓的话是不可能。

就靠调仓完全解决这种问题的。但这么高的高我涨你很难看调仓。🤧The。呃,因此我们要换一个思路,我前面说了一个比较简单的数,就通过调战方,那这个方法可行。因为这里这个放货率很高,你很难通过调战。

直接就是直接就是呃处理处理处理完毕这样的问题。那下面就从另外两个角度来来处理。一个从样本的角度。哎。😊,一个是从样本的角度呃,相调一些对于这个模型影响比较大的异常样本。但这种方式一般来说是用不上。

很少看到有人用这种方法来用。首先就是呃你去删除异常样本的话,这异异常多异常异常检测算法。比如说像或者是LOF或者是简单的呃命这种算法,他们检测出来的这个异常值,其实对GPGPDT系列算法呃不太适用。

因为本身这个模型它的基本假设出发点和GPTT是不一样的。就算你检测到了这个异常你通过这个异常检测算法,检测到异常样本对于这个呃GPTT系列算法来说可能也是没有帮助的。🤧。呃。

简单来说就是GBTT它影响GBTT模型训练异常样本,你没有大概率不太可能通过其他简单的异常检测算法来检测出来。所以去这么做是没有太多编辑效益的。然后就是第二点就是呃大部分检查大部分异常检测算法。

实际上它的这个实施很麻烦,特别是像K means这种呃基于距离的,或者是LOF这种呃。呃,LOF这种基基于那个密度的这种算法,它计算计算复杂度都很高。你跑一你跑一些跑个几十万数以级就要跑半天的那种。

然后第三点就是对于异常样本的这个定义。一般来说嗯。你很难通过主观的定义去定义哪些样本,对于这个模型的影响是比较大的。🤧还有就是如果你在呃训练样本存在一部分的噪声样本。

实际上它是可以提高这个模型的鲁棒性的。当然这个像样本角度出发的话,是有一些这种处理处处理的方法。比如说呃面对不均人学习,我们常常经常会用到的一些采样啊,这副采样,或者是这样面啊学习之类的。

当然在这个比赛里面呃,这些方法都没有办法用。呃,用完之后效果会变得很差。具体原因的话,后面会后面呃总结的时候,我我我会我会介绍一下。呃,然后就是第三点,从这个特色工程的角度出发。

🤧这个就是基本上没场表格型这种结构化数据的比赛,基本都是从特征工程角度来出发的嗯。这个。啊,行,记住。首先我们需要知道的是呃,过敏和它的本质原因是数据分布的差异性。

当然如果呃其实很多书上都会有不同的解释,会解释说呃是由于这个模型复杂度太高啊,或者是数据集的这个维度太高啊等等等等。但其实它本质原因还是数据级分布的差异性。

主要是因为呃测试集和数据集之间分布存在一些差异。因为模型你本身学到的是呃输入和输出之间的映射关系。但是如果说呃你要预测的模型,它输入它的这个输入分布差异定很大。那这样的话,你去呃你在训练一下。

你和效果就会比较呃,你合出来的模型效果就比较差。哎呀,怎么说?呃这个怎么说会比较清楚一点,嗯呃呃举个例子吧,比如说像那个我最最简单,我们一开始学习机器学就会接受一个数据,load。

就是那个英尾花那个数据集,那那个数据集其实你用YGBM,你用1112100个树还是1万棵树来去拟合它的其实泛化性能都是。差异性是很小的,因为这种理想数据它本身特征又少。

然后它特征分布都是都是比较完整的呃都是比较完美的那种分布。它训练和测试集整体分布都是很所以相对来说很接近的那这种数据集,你不管怎么去增加模型的复杂度啊,其实对于最终模型的这个泛化性的影响都是不大的。

所以所以它所以过拟额的本质原因,实际上是分布数据分布的差异性导致的。因此我们。呃,要从这个特征的角度去解决这种差异性,去检测出这种差异性,然后去用一些手段来这个缓解这种差异性。

如果说两个数据如果说两个数据它的分布完全是一致的那在这种在这种数据集上,你使用LGBVM或者无论你使用多复杂,多深的多深的数多多呃多少数量的这个基基数的这个集械集成模型效果可能都差不多。🤧K。

那这里我就涉及到这个特征风迁移的问题了。呃,在ki上面。测温分布迁移的这个常用的方法,一个是对抗性验证。这个是呃这是一个非常好用的一个技巧。它思思路也很简单,就是把训练级的标签设置为一。

然后把训练测试级标设置为0,然后训练一个I级本或者是做交叉验证。呃,这样的话会更好一。这样的话会会更明显呃更稳定一些。

然后通过这个AUC的大小来观察来判来来作为这个训练级和测试级这两个数集分布性分布的差异性。并且通过这个训练完这个特征的特征重要性呃,来观察是哪些特征带来的比较大的特征偏移。呃。

然后后面我还会介绍另外一种呃,就是这次开lo第一名的ch,他说介他都使用了一个呃用来用于检验这个特征风变移的方法。这这个我在后面会介绍啊。啊,这里我给了他他的原始dicus里面,他给这个方法的一个链接。

这个后续大家现在可以看一下。嗯。首先那个对干的它的思路就是呃就是我上面说这个,然后它的原理其实也很简单,就是让你通过模型来判断这个呃分布的这个差异,这其实是一个非常好的一个方法。

因为呃我们说我们我们平常测试这个不同数据分布差异方法其实蛮多的。比如说像用简单的用PSI这种指标呃,或者是用KS这种指标呃,都可以都可以看到呃都可以是作为这个特征分布偏移大小的一个一个一个一个判定。

但是这些方法问题就是呃这些指标判定出来的偏移的特征,可能对于来GBM它的影响并不是特别大。🤧嗯,因为那letGBM或叉距不置它本身这种数模型,它本身对于分布不平呃。

它本身对于偏移特征分迁移那个偏移的特征的这个鲁班性就会比较强。但是呃所以那个它拟合的时候,可能一些微小的这个特征分布迁移,其实并不会影响模型最终的这个效果。呃。

所以你用PSI或者是PS之类的这种指标计算出来的,也计计算出来结果,可能计算出来有些特征迁移挺明显的。但是对于模型的影响其其实没什么帮助。你把这个这一特征删完之后,分数也不会提高,可能还会有一点下降。

所以你直接使用你你你使用的这个模型来检验。你通过这个模型,通过通过模型本身来识别这个模型或就通过这个模型本身去识别识别这个偏移特征。这样的话得到偏移特征相对来说就是比较呃相对来说对于你使用的模型来说。

就是比较比较真实的一个偏移特征。这个这也是这里要展开说一下,我怕我说不太清楚,就是我们在做特征选择的时候,不是都会有这个过滤式特征选择嘛。这是所有过滤式特征选择都会面临的一个问题。

就是你使用的指标和你和你进行训练的这个模型可能是脱节的。呃,举个最简单的例子,比如说相关性皮尔皮尔逊相关性。我们对做回归问题的时候。

对两个特征做这个皮尔逊呃皮尔逊相关皮尔逊相关的这个分析皮尔逊相关系数的计算。呃,可能有一些特征嗯举个例子。比如说有个特征是这样的。啊,比如说这么比如说这么一个简单的数据吧呃这个。X和Y之间。

你去计算它的皮尔逊相关系数,它的相关系数很低的。但是如但实际上搞错了,这个错了。但实际上这种特征对于这个呃GBTT这类系列算法来说是一个非常强的特征。

因为它们X和Y之间的这个他们之间的这个排序相关性是非常高的。Y是12356X是0。1010。10。11100。

他们之间的排序相关性是完全相同的那这种特征对于这个XG布或letGBM来说是一个很重要的一个特征。但是如果你只使用过滤式指标,比如说比尔性指标啊,比尔性相关性来算的话,你会发现它算出来相关性是很低的。

呃,这所以这这个是过滤式特征选择。选择方法一个比较重要的一个呃比较比较大的一个缺陷。因此这个我们在做。在做做比赛的时候呃,比较少也会用PSIKS这种去检验。呃,虽然也能检验出来。

但是效果没有对抗验证这种方法来的直观方便快速。🤧是。嗯。呃,这里后面我我叉级bo可以自动解决正负样本不均衡的问题。嗯,这个怎么说呢?X级 boosts它可以它相对于普通的模型来说,它本身是集成模型。

它对于正负样本不均衡的呃敏感性并不是那么高,但是它也是没有办法自动去解决正负样本不均衡的问题的。如果用超级p的嵌入式方法做特征选择就行啊,这个完全是不够的。

超级boush的这个嵌入式这种特征重要性的这个方法,它有非常多的问题。嗯,一般来说我我们可以作为一种特征选择的方式,但是不能把它当做全部特征选择的方式。呃,就打比赛来说的时来说的话,呃。

插级不它本身自带的这个特征选择的方式有特别多的问题,所以才会有像proation importanceport啊unno importanceport呃,或者是下巴这种东西的出现。

都是因为它原生的这种嵌入式特种选择的这个特征重要性的方法,有各种各样其各种各样的这些缺陷。然后我们才会才会才会后后续才会发面的解放。这个这个后续呃后续我会在后我在后面会会详细说的。Yeah。

就想呃主要详细说一下它的嵌入方法的这一些缺陷,然后怎么改进,使用什么方法去改进这样这个这个后面会提到。🤧是。呃呃,这这个这个后面我我会提,你稍等。呃呃。

下面这个就是特征呃关于这个对抗性检验的一些呃对抗检验它是基本的代码。这个是这个线下大家自己去看就好了,这个大码都觉得很简单。呃,可以看到呃我们初去检验之后,然后根据这个特征重要性。

你们可以发现这个一个很奇怪,一个很有意思的现象,就是只有transctionDT有特种重要性,其他所有的特征空献都是0。这个其实我们在做EDA的时候,就已经发现全世T它本身就是一个偏音很严重的特征。

他这么一个特征。它本身的偏异就就很严重,所以这里用对抗性验证就很容易可以检测出来这类的特征。啊这里就呃这里就。呃,这里但根根这个例子。

我们可以发现这个非常 importantport的第一个第一个问题就是其实我们在做EDA。做EDA的呃,我稍,我先结合下面这个来说呃。

比如说我们刚刚删除刚刚发现这个transaction transactionctionDT它是一个偏异很严重的特征嘛。因为它对于在它的对抗性验证中,它贡献特别高,就是就只有这么一个真正贡献。

所以我们把这个真删除之后,我们再跑一个再跑一个这个对抗性验证。呃,可以发现。😊,现在这个这会儿就是啊ID31card1D15这些偏异也比较严重的特征,它的特种重要性就展现出来了。嗯。

所以这里反映出了这个非ture important的第一个不足的问问题,就是当那个。你在你特征中存在一些特别强的特征的时候,他会把一些。呃,也效果也不错,但是不那么强的特征重要性cover掉。

这样的话你没有办法去合理的评估每一个特征的重要性。比如像这里,因为它一个全se机题就可以完全把训练题和测试集分开了,所以其他的特征就都没有办法通过这个特征重要性的这个图来展现出来。

这个时候你就没有办法合理的去评估所有特征的好坏。这是非 important的第一个第一个问题。然后这里的话我们就可以发现呃,首先第一个偏严重的特征transactionDT。

然后这个然后是ID31卡的1D15这些特征呃都是通过对抗间验的检测出来偏异比较严重的特征。然后我们再对照一下之前做的那个base line它的特殊重要性。我们可以发现像这里的card一。然后card2。

这些在这些baseline比较重要的特征在那个。在这个对抗性验证这些特征重要性里面都是排名比较前,比较靠前的啊。那这个时候其实我们就可以呃呃很清楚的知道,就是因为这些特征的偏移。

导致了模型整体的这个泛化性能的呃泛滑性能这个降低。呃,因此我们后续需要针对于这些特征。这些偏异比较厉害的特征去做一些处理,就把它偏移变得不是那么厉害。

这样的话我们就可以在一定程度上来降低他的这个方法误差。啊,然后这里又遇到一个新的问题,就是呃我们通过对抗性验证,确实可以找到这个。呃,确实可以找到这些那个偏移偏移比较厉害的特征。然后大家现在其实可以测。

比如说像我们前面检测出这个transsectionDT,它的偏异比较厉害。我们可以把这个特征上完之后,重新跑一遍logoC看看它的得分。呃,我在线下是测了做了两个测试,一个是把T删完之后。

跑了一个locgo CVV,还有一是还有一个是把这个card一删除之后,跑了一个logo CVV呃,结果是不一样的。呃,把删完之后呃,分数会提高一点点,但是把card一删除之后,分数降了不少。呃。

那这里就。就就会有一个比较麻烦的问题,就是卡的一个圈seDD,他们虽然都属于偏移特征,但是这些偏移特征呃,他们本身。嗯,对这些偏异特征删除本身对于这个模型带来影响是不一样的。

主要原因就是因为transDT它虽然是一个偏异很严重的特征,但是它对于未知数据预测能力很差。因为它也也是它对于这个未来数据,它是没有办法预测的。但card一它不一样。card一它虽然是发生了偏异。

但是它card一它本身对于呃好坏样本的这个区分度是比较高的。所以你在删删除card一之后,虽然虽然是降低了这个card一的这个啊虽然是呃虽然是移除了这个card一它偏异的影响。

但是你也把它的这个区分能力这个区分能力这这部分的贡献给删除掉,所以会导致最终这个logo cV会会下降一下。因此这里就介绍第二种方法,就是ch之前在他的solution里面介绍了一个呃验证的方法。

那这个方法是不是也很简单?哦,那解释一下偏移特征吗?因这里没有现成的图,唉,直接口述可能会比较。呃,我简单说一下呃,所谓的片异特征就是这个特征,它在训练级和测试集里面分布不一致。啊,对对,就是这个意思。

它是有两种情况,一种是类别特征,一种是这个连续特征。呃,举个例子,比如说连续特征,比如说像我们前面那个transactionDT,它在训练级数据集里面,数据范围是0到。

数据范围是差不多0到四五万这个位置,但它的测试级是6万到十几万这个位置。但像这种特征,它是属于完全偏异的特征。因为它训练级的数据分布和测试级的数据分布完全就是两个不同的分布。但一般来说。

因为因为全DDDT它是属于时间性时间类型的特征。所以它这种。它这种他就这种时间性质啊,这种时间时间特征,它天生就具有这种分布不一致的问题。你在因为它本身是一个时间,它肯定是不断递进的。

所以它的这个分布肯定是不一样的。啊,一般来说呃,大部分情况下不会这么极端,但是也会出现。呃,就是它一般来说偏移特征特征偏移不会像全三个DD这种偏移,就是属于完全偏移,它可能属于部分偏移。

比如说你在训练集上是属于零的,训练集上数据数据范围是0到8万。但是在测试集上面可能是4到440万呃4万到10万。那这样的话8万到10万之间的这个数据就属于训练集上没有出现的数据。因这也是属于一种呃。

因因此这个我们可以也可以称称之为这个数据数据偏移。呃,特征偏移,这就是偏移特征的一个一个概念。那相对于类别类别特征,对于特别类别特征来说呃就比较简单。就是比如说你在训练级里面有ABCD4个类别呃。

有ABCD一直到这226个类别。但是在测试集里面。😊,哦,不是啊,说错了。比如说在训练集里面有ABCD4个类别,然后在测试集里面有BCDE5个类别,多出来一个类别。

那这样的话也是呃也也这这这种是属于这个类别特征的那个偏移问题。OK呃大概介绍就是这样。呃,如果没听明白的话,嗯,我想想啊。嗯,没听明白的话,到时候你可以看到我的支付吧,上面发了一些相关的一些文章。

那个可以可以去参与一下。因为我我我不是很擅长这种语言上的表达,更多的时候可能还是通过文字啊、图表之类的方式,这类是一个比较好的好理解的一个方式。然后这种口头表达的话,就是只能大概介绍一下这些东西吧。嗯。

回头回头我发资料的时候我一起发给你们吧,稍等一下。呃,然后刚刚我们讲到这个ch验证的方法,呃,这个方法思路很简单,就是你把你对呃比如说你有你有这么多特征,你把每一个特征单独抽取出来。

训练一个做一个交叉验证。然后通过这个在这个交叉验证上面,训练集和数测试级的这个分数的差异来评估这个这个特征的偏移的这个问题。呃,我们可以看看这个这个是做出来的,这个代码按照这里跑就可以了。😊。

这是一个这就是那个呃我所说这个验证法的一个呃跑任务代码。思路就比较简单,跑出来这么一个东西。比如说对于V41,我们把V41单独抽出来做一个跑一个交叉验证。那这样的话它的券C是0。5073,它的C是0。

47918呃呃这里这里计算是它的平均的平均C平均平均C。那这样我们就可以看到这个V41这个特征对在对于这交叉交叉验证时候,它这个C的贡献是0。5073。对于0。

47918说明他他在这个位知数据上面预测预测效果是很差的。还不如随猜测。😊,So。呃,所以所以这这种方法就是呃可以比较好的这个判定出这个不同特征,它的一个偏移程度。它比这个对抗性验证像会会更更加详细。

而且更加更加直观一点。因为它是直接以我们所关心的这个评价指标作为这个衡量标准的。这样我们就可以很直观知道这些特征对于这个呃交叉验证的贡献大概怎么样。然后这个呃会制证的时候。呃。

我我暂着像chase验证方法,我不知道他的名字叫什么。😊,呃,亏则验证还还有一些需要注意的地方,就是因为我这里用到的是交叉验证。所以关于这个交叉验证的话,这里计算的是它交叉验证的命值。呃。

但是后来我发现应该是计算它的这个这这里是这个命值均值。后发现应该计算它的这个命值会更合理一点。因为你用这个平均值的话,你可能可能这这个特征在这这个特征在这个比如说5折交叉验证。

这个特征在其中的4则上面效果不好。但在其中一则上面效果效果不错。然后最后平均下来是0。49,那这样我们就会错误的把这些特征给删掉。但如果用命的话。

我们求我们求这个特征在每个在所有的这个交叉验证里面最低的分数。😊,呃,这样的话相对来说就会可靠的多。嗯,啊这这这下面就是对于这个非竞证法的一些一些阐述。呃,资料在那个冠军开源的那个代码里面都有。哎。

这个比赛比较好的一个地方就是他第一名他把他的那个代码非要完整的公布到那个开源的科隆上面。所以这个呃对于这个学习来说帮助还还还是还是比较大的。因为很多比赛的冠军的这个冠军的那个s路ution。

他都只是给了一个解决方案。但实际上呃很多时候解决方案可能帮助并不是特别大,重要的就是呃这些。重要就是这些这些这些选手他是怎么去一步一步得到这些强特的,怎么一步去分析问题。

这个才是呃我觉得参加课能最重要的一个地方,就是你要形成自己自己的一个解决问题的一个思路,一个框架。比如说每部该干什么,下一步该干什么啊,每部需要呃做哪些注需要有哪些注意的地方,应该怎么规避之类。

这个才是比较重要。而方案很多时候方案没有办法你一个比赛方案是没有办法复用的。Yes。呃,这个 kernelnal的话呃 kernelnal其实这个就有,这里就有。后续的话。嗯,需要我给保安子贴出来。

郭鞋去自己去找一件一样的,挺好找的。就在那个他的那个看那个比赛的notebook界面里边。呃,然后这里的话呃我看一下。然后我们这里的话有一个重要就是这个dtaOC。

可以看就是上表这里这个调了AOC用衡量的就是这个模型它可能会带来的放化误差大概是多大。这么一个级别。然后我们对这个调的AOC去进行排序。从最高到大从最小最大大小最大大小排下来。

D它的这个它的这个泛化泛化误差是最大的。这个和我们之前做对抗验的结论也是一样。然后是AMP然后再往下看product2和就基本上大部分的类别大部分类别特征,它都发它它它的偏异程度都是比较严重的。

那这里问题其实其实就已经找到一大半。就是我们我们刚刚我们这个我们通过这个。base就是aseline那个logo那个模型的特征重要性图可以看到可能有很多这个这些类别特征。

它在最终的这个特征贡献里面占比都是比较高的。而这些特征又恰好的恰好这个偏移比较厉害。所以就是这些这些特征是导致这个模型放物价差的一些的一些祸少。因此我们要先去处理这些偏移比较厉害的特征。个刚我们删除掉。

然后删完之,你logoV会提高一些。然后接下来我们就把重点放在这个类别特征处理掉。因为大部分都是属于这个大部分偏移偏移最严重的特征都大部分是属于类别特征啊,只有MT这个连续特征。

就就这么一个连续特征是于比厉害特征。所以我们下面先处理这个类征偏移。首先就是嗯类别特征特征的偏移特有有这么一些思路吧,一个就是直接删除,但是它会有一定的信息损失,特别像card一。

card一是一个很强的一个是一个比较强的一个特征。删完之后分数会降。然后是这个如果是那个偏异严重的类别特征,我们可以把类别转化为一个连续值啊,这也是这个比赛的一个一个小check吧。转换成连聚值之后。

呃,能够起到一些意想不到的效果。但是这个che个之所以check是因为这个这种方式,你放到可能放到别的比赛里面,效果就不好了。但在这个比赛里面效果还是不错的,可以很好的解决这个特征偏移的问题。😊。

然后像对于这个。偏于连续对偏于严重的连续特征呃,一般这种使用最数变换或者是分箱的这些方法。呃,来处理来来解决它的连续。嗯,对对,就是转成labelend。然后还有一个就就需要注意的是。

如果我们是去做特征的删除。那像对于特别是对于类别特征这种,可以做一些特征抽取的工作。比如说呃比如说frequent编码或者是呃group by这种。就是如果一定要删除特征的话,最好是提前做做好这些工作。

尽量把这些特征的价值都榨取完之后再把它删除。呃,然后接下来就是呃我们根据上面的结论,呃,就是根据这里的一些解决方案,然后来做一些尝试不同的方案来处理。嗯,比如说像这里。首先是这个。呃。

首先我们通过这个label encode的功能,把这些类别特征全部都编码成连续特征。然后呃这是第一个方案,就是我们把类别当成连续特征,然后删除无用特征。啊,这里说一下这里的无用特征指的是这儿。

就是UC我我们刚刚通过ch验子得到这么一张表。那这样这里veUC表示这个特征对于这个放对于这个未来呃对于这个预测数据预测结果的这个对对泛化性的一个贡献。可以看到这些特征它的贡献是0。50。5级以下。

那这些特征可以认为就是对于未置数据的预测完全就是没有帮助的那这些特征可以尝试删除之后,看看效果怎么样。这个是把类别当成邻系特征之后,并且356特征之后,它的那个logoCV的结果。呃,系。

可以看到这个相对于我们原来这个base,这个是base light的分数。相对于face line分钟,我们logo系V提高了这个千1。5左右。然后我们线上的分数是呃提高万2。然后然后接着是第二种方案。

呃,我们把类别转成连续特征,但是不删除这些无用特征。呃,实际上这里的话这个地方我原来用的是那个平均值去计算它的YAUC平均值,其实更合理的方式应该去计算它的最小值。因为有就像我之前说了,有一些特征。

它可能在5折里面有4折表现的是不怎么样,但是有一折表现很不错。但最终平均下来的分数也是比较低,呃也会很低。但这种特征不能说没有用,因为它在其中一则它是有贡献,还有是有它是有贡献放法性的。

如果删掉之后会会损害一部分的放法性的。因此因此这里这个地方要注意。呃,后续代码这边我会改一下。就是把之前这qui验证的这个。呃,我就就把这个计算均值改成计算最小值,或者是均值最小最大值都计算出来。

这样会更更合理一些。然后我们来讲下刚刚就讲的这个方案。哎呀,我的天哪,一个半小时吧,他讲的太慢了。嗯,可以看到这个。😊,我们把这个类别转成连续之后,分数是上升了一些。然后第一个方案是类别。

第一个方案类别删除呃,无无用特征删除。然后第二个方案是无用特征不删除。但是呃类别也找成邻去了,我们再看一下分数。那这个时候呃logo思维分数就提升了更多了。然后我们提交到线上之后,呃。

可以看到相对于呃删除删除删除那个无用特征,这个不删除无用特征方案它。不删除无用不删除无用特征,仅仅是类别转成连续的呃,这个方案它分数就提升了1100,现在是0。938。

那其实这个呃这个这个原因其实也其实也也也也也也也不难理解。呃,这个是我把那个类类别型特征转成inter之后重新做的quiase验证。呃,可以看到就是我们把类别转成连这次类别的类别转换成连系特征值之前。

它的这个chase验证的这个评估的结果,这个是之后的。可以看到呃有很多特征,比如说像M系列特征,它M系列是属于二次特征。所以进行这个把类别转成in型特征之后。

它这个这些表现其实基本上没什么变化的那像对于这种card一。card一这种特征大家可以明显看到,它原来的这个区分度是0。8013,但是在value上面是0。74,然后泛化误差是接近5个点,但是改。

但是转换成in型特征之后,这个card一的寸沿UC虽然降低了,但它整体泛化误差下降了很多。呃,降到原来的差不多一半一半以下,现在只有现在放化物差只有0。02392和AUC呃。

所以这就是呃你把类别特征转化成连续值之后,它的那个logo是V会提升的一个原因。因为它的放化物质价降低了。这虽然是以这个它的区分度,它区虽然是以缺减它的区分度为代价,但是呃缺点区分。

你把看页这个区分度削减完之后,其实还有其他的一些特征可以补充这部分的这个缺这部分的这个贡献的缺失。所以它最终分数是反而上升的。那,可以看到现在我们最优的线上整金是0。938557。

然后就是呃连续特征的偏移啊,呃,这里我就只尝试了一个对数变换。因为分箱的方法很麻烦,要是而且分项分项分箱是一个相对来说比较悬的一个东西。呃,你也是需要去调餐的,包括这个不同分摊方法等平等句呃。

角色式分加卡官分析这些都要去尝试。那这样的话,整个步骤写下来太多了。呃,很浪很浪费时间,而且感觉也没什么太多的帮助吧。这些自己线下试一下就可以了,没什么可说的。呃,这里我就只是简单做了一下对数变化。

就是对这个我们前面的这个偏移最厉害的transaction AMT。😊,🤧是。你在这个样子。就这个MAMP做的对数变化。然后做完对个变化之后,还是一样跑一个logoCV,看看它的效果怎么样。

可以看到呃做对制变化之后,基本上没什么帮助。logo词维本身分数还下降。所以后续我就没有再去做这个对数变化了。这个帮助并不是特别大。OK呃,然后就是这块讲完了。然后就讲讲这个呃最终特征隐生嘛啊。

对特征隐生那块。首先还是一样,呃,我们这个读取的数据。然后呃在之前做完相关性分析之后,剩下的一特征。然后是做这个label encodeder。呃,现在我们呃现在我们这现在分数最高是0。938左右。呃。

然后是然后接下来就进入这个特征隐身的工作。这女生呃,我是一步一一般来说就是一步一步来嘛,就是呃思路其实就是前面说的。你衍生出一个新衍生出一组的新特征,放进去之后,呃。

然后看看那个locgo系V的分数的高低,就大概是这样的一个一个一一个一个流程。首先就是呃对这个重要的类别进行编码。啊啊这部分做这个特征衍生的这个套路的话,就要结合这个之前我们所说的这个特征重要性来做。

不这。呃。因为实际上你去做特征衍生。比如说比如说比如说举个例子,比如说我们要做类别的编码,理论上来说,你是可以对所有类别做编码。但是一般来说,如果你对所有的类别做编码,你会导致衍生出来的类别特征特别多。

所以就是我们在做特征衍生的时候,要有有一放矢,要就尽量去做。价值比较高的特征衍生的一些方案。比如说我们从前面通过这个。我们前面通过这个。这个是这通过这个baseline特征重要性。

我们可以知道card1,然后card2ADDR1这种类别特征,它是属于贡献度比较高的那也就是说这种特征相对于其他的类别特征来说,它携带了更多的信息。

因此我们优先会从这些携带信息多的特征上面去做特征去做特征衍生的工作。这里就是呃排名比较靠前排排名最靠前的几个类别特征。我选了一部分。嗯,这一块的话其实要做细也是可以的。

比如说你选取top多少的类别特征去做,然后选完之后,你再去跑个logoCD看看效果怎么样。那这里我呃为方便我就只做了一组。呃,我们这里对它进行这个frequent编码,做的是呃频率编码。

不是做 targetgeencoing。 targetarencoing呃,我没有去做这里只举了一个fr free encoing的那个例子。啊,然后需要注意的就是我们做完这些编码啊。

做完引特征衍证之后,第一个需要做的工作就是相关性分析。因为因为实际上在做特征衍证的时候,包括像类别类别的交叉,还有呃类别和连续的group by或者是连续值之间的交点存除都会产生非常多非常多的特征。

而且产生大量特征里面很有可能有很多特征,实际上是完全重复的相关性特别高的特征。呃,那这些特征你要优先做相关性分析进行删除。那这里呃这里我们把显示的特征和原始的特征进行一个比较。

可以发现这个整体的话呃整体相关性的情况还是还是可以的,没有说特别特别高相关的特征。就只有这么一个是-0。92,那其实影响并不大。🤧吃。然后的话呃这里就还是一样。

用前面我们所说的那个chrisase的那个方法来啊,这里我把它分装成一个函数,换到这个。

放到这个这些工工具文件里边,啊,这个后续我可以发出来,到时候有兴趣可以看一下。

也是依样用这个灰子的方法来变证这些衍生的特征的效果。那可以看到这些呃根据这个规式验证方法,可以可以看到这些特征整体上上来说效果都是不错的。首先它的这个偏移。它的偏移就是比较低,不会那么高。

还有其次就是他在train和 valley上面的分数都是比较不错的。可以看到它的区分都还都是很很不错,都挺高的。所以现在所以所以我们在隐生的特征上面就不做额外的删除。

直接把这个隐身特征全部都放到原始的特征数据器里面,然后去去跑个某,然后再去跑个logoCP看分数是怎么样。嗯。啊,可以看到这里的这个命AUC相对于原来又上升了。我们刚原来是0。938多。

然后现在提高到线上之后,提升了大概1600左右。这实际上是一个呃600,实际上是已经是一个非常非常强的一个特征了。一般来说呃,我们说的所说的强特可能是百一或者是千七八这样的。

那么仅仅这里仅仅通过一个简单的。频率frequent的频率源码,我们就提到了这个600的分数。所以说这个已经是一个很很很大的一个提升了。然后我们再看一下这个特征重要性。

可以看到我们隐生的这个cardFEFEADDEFEcard2FE它都是属于很重要很好的特征,它区分都很高。在特征中贡献度也比较高。包括像这个阿E那个FE这些,这都是等于是贡献到了强特。

所以它的分数上升了不少。呃,然后这里我没有在尝试他可以encoding或者WA encoing。但其实思路也是一样的。你可以呃做完编码之后,然后做一下相关性分析,然后跑个验证,看看它结果怎么样。

然后放进去看看效果。这个。呃,感兴趣可以自己做一下吧,你不再去再写这么多太麻烦了。W他他给跟WE该差的特别多。🤧这做出来就是特征太多,很麻烦了,所以我就没得继续写了。😊,呃,然后是呃刚刚说的是第一个最。

最常见的这个套路就是类别重要的类别做编码。很多时候可以发现一些可可可以挖掘出一些新的好的特征。啊,这是属于就是套路型的。就是你什么比赛都可以用这种思路来做,只不过有的比赛有时候有的比赛没用而已。

但都可以去尝试一下。然后就是呃重要两个两个类别特征的合并,而,这也是一样。根据之前的那个特征重要性特征重要性举证来做重要的特征。重要的特征就是两个两个合并。这里我做到了这个做到三阶合并。

因为他去做四阶合并的话,维度太高了。而且效果感觉应该也不会太好。啊,他主要是维度太高了,内存撑不住。你为做到二阶和三G,差不多,已经是我这台电脑能能能够承受的一个范围了。所以我是只做了二阶和三阶的。

关于具体四阶五节什么之类的这种呃,我不好说它效果不好吧,那就是我。自己本身这个硬件设置没没有办法,硬件设施没有办法承担那么高的计算量,那么大的内存占用。所以我只最多只做到三节。

也就是两个两个特征合并和三个三个特征合并,最终形成了这么多的特征组合。🤧然后还是一样。因为我们前面说了,这个是把类别当成连续特征嘛,所以这里所有的类别我们都是可以当成连续特征,包括像相关性计算。

也可以直接使用spiman或者是平时相关系数来来计算它的相关性。嗯,再提升要做服务器啊,那太麻烦了。其实我我这台笔记本系能已经是不错了,32G内存,然后呃6核就对于这种小型数据来说,已经算okK了。😊。

再往上提升的话,那可能就要。就得配更多钱了。那其实没有必要做要有要那么好那么强的配置。我觉得这配置已经算是笔记本里面比较好的一个配置了。啊,后面再说后面再说。😊。

这个就是我们衍生出来的那个二阶和三阶的类别类别特征。然后现在思路也是一样的。呃,我们和原来的那个特征做一个相关性分析。啊,这里我就没有再去把它的举阵呃,相关特征相关的矩阵列列出来了。

这里我就直接分装成一个函数了。呃,这函能大家可以也可以自己使用。呃,其实实就是就是我之前说那些特做微特征的时候,那那些相关性处理的这个思路。就是首先是得到了相关应举证,然后是去切分它的阈值。

然后是根据这个呃老师相关特征,根据它的取值的情取值的数量来来决定删除哪一个特征。这里我做一个简单的挑战,这个是这个是相关系数。我测试了不同相关系数下呃。

对于新特征的切分的这个最终的loc CVV的表现的效果。啊,直接看这里吧,这个是最终的一个结果啊,如果我们按照0。8的相关性的这个阈值来切分切分这个衍生特征的话,它的logo CVV哎。

它的A榜的数据是9438。如果是0。89999是09434,如果是0。9899是0。9是9464。如果是这个不进行相关性分析,不删除相关特征的话,是。9463。可以看到呃,我们在把相关性的阈值切到0。

98999的时候,它的分数是最高的。0。9464。所以呃所以就采取这种方案,我们使用0。98。0。98999的相关系数作为一个作为一个相关切相关性特切分的阈值。来处理。现在我们分数已经提升到0。

9464了啊,这个时候差不多嗯。哦,还没到差不多10%到15%左右排名吧。啊,那这个不算暴力啊,那更暴力的有还有几千维度的那种啊,那个才是真的变态。那个因为我一般是打solo赛了。

所以所以就一个人就只能有一台就其其实际上就只有一台笔记本作为作为一个配置。呃,所以没有我没有办法做太太复杂。其实你要做更复杂,还有更多啊。😊,你做四节五阶的展开,还要去做疯狂的g派之类的。就理论上来。

像这个比如说这个比赛啊,包括冠军的思路。呃,如果那个包括冠冠军的思路,如果你如果说你的算力是无限的话,你可以去做无限展开。你可以对所有类别特征去做编码,对所有的连续特征去做加以乘除。

这样的话你可以衍生出几十万几百万维度的特征,然后去做特征选择,你这样一定能够这是一定能够达到第名的。但是问题是大部分情况下,不可能会有这么高的算力去做去做这么复杂的特征衍生特征选择之类的工作。

你跑都要跑死了。你光是内存占用,可能就是上几百个1个TB之类的。就当代笔记本不可能承担这么高的,所以我们只能去做一些呃相对来说呃更有价值,更有价值更高的一些事情。

尽量就尽量是利用我们有限的资源去做这个就把就把你的资源放在刀刃上面去使用。🤧嗯。那现在可以看到我们切到0。98999的时候,效果是最好的。因此,我们选择就选择这个098999作为阈值切分切切掉。

就是你也你这些这些隐子当中特征有一部分是高相关的嘛。你按照098999的阈值去切掉,相关性比较低的。提升维度后PC呃PC基本上不会用PC它只是一个降维的一个算法,它并不会提供信息量。

它不像bedding,不像那个inbedding那样,它会把比如说像你用 to对类别特征去去dding能够提取出这个类别之间的一个贡献关系。但是PC的话它就纯粹就是一个降维的算法。

只是把只是在只是在损失部分信息的情况下,把特征维度降下来而已。所以一般来说PC是不没没有办法打比赛时,一般是不会用到PC或者是任何的一个降维算法基本上是用不着用不到的。但这么多比里面唯一一个。

这么多年唯一一个夺冠的,也就只有一个用了一个呃深度制编码器,忘了是哪个比赛,好像也是三德拉银行的一个比赛吧,就是那么一个一个比赛,冠军用的是深度制编码器拿到第一。也就是唯一的一场。

大部分还是用GBM布的这些算法。然后PC的话,这种特征处理的方式,基本上没有见这样没用过。嗯,你当然你可以自己现来试一下,一般来说效果都是比较差的。因为PC一定是会带来星息损失的。嗯嗯,嗯,O。呃。

然后刚刚讲到哪儿了啊,就是啊对,这个切分相关性009899作为这个阈值。然后我们把这些课程删除删删除掉。之后呃那然后那现在这样的话,嗯,这前面两个这个特征隐身的步骤就做完了,一个是类重要类别的编码。

一个是不同类别之间的这个两两之间的合并。这样做完的话,我们现在现在的分数是。呃,0。9464多少0。9464啊。Yes。呃,然后讲一下第四点呃,这个就是最经典的goodby了,也是舞蹈的goby。

这个就基本上是大部分。呃,也是属于开口特征隐身的一个常见套路,就是类别和连续特征之间的呃呃类别特征和连续声之间的gby。呃,然后这个前面这个。呃,前面我们在呃思路也是一样。

通过特征重要性排名前几的这个连续特征和特征重要性排名前几的类别特征来做这个gue by。看看能不能产生一些新的特征啊,新的有价值的特征。🤧像blby这种相对来说比较符合逻辑。比如说嗯。😊。

比如说你的transactionAMT和你的这个card一进行group by。这样的话,它在人类人类逻辑上理解就是呃平均每种卡类型的消费金额。

你逻辑上面是讲的通的那这类特征往往来说也会带有一定的信息量呃,呃,也相相对于你直接去做无脑的特征展开来说,它会它更有更大概率会带来这个呃有内在逻辑,并且有一定价值的性有一定价值的性的特征。啊。

下面我就你们就对这个重要的连续特征和重要的类别特征去做grru by展开,grru by特征衍生。

呃,这里这个呃这这这里就隐成一大堆一大堆特特征了。这incodeAC这这些函数我都放到这里了,后面有需要自己可以看。

哎呀,12点了,我天。然后还是一样,这里的话就比较麻烦。因为我们前面衍生的特征其实数量都不是特都不是特别多,就只有十几二几十个这样。这里头已经衍已经衍伸到上百个新的特征了,那这个地方就比较麻烦了。😊。

而我们需要做这个呃我们需要更仔细去做这个特征隐身的工作。呃,比如说比如说像这个最基本的呃常变量这个特征里面呃,我们衍生出来新特征里面有很多都常变量啊,也就是说这个特征。

它的这个取值所有取值都是完全一致的。这些特征你就可以直接先删除了。这个特征是完全无用的特征。这些特征可以先删除不掉,然后还是一样。呃,我们要去做相关的分析呃,但是。😊。

衍生出来的特征里面有很多都是缺失的,有有很多特征是存在不同缺失率的。所以就像处处理微特征一样,我们这里也要处理这个不同缺失情况的这个特征。在这里。啊。

然后这里需要注意的一个地方就是嗯比如说像看这里呃这个特征。这个VV和car2的衍伸特征,还有这个下面这个特,他们虽然有有存在缺失的情况,但是他们缺失比例都很低。那这种特征其实无所谓。

我们可以把它和缺失值为0特征放在一块去计算。因为它缺失值本身是很少的。它不太可能会很明显的去影响到相关系数的计算。那对于这种呃缺失率很低的这种特征。

我们可以考虑把它直接和没有缺失的特征合并在一块来进行这个相关性的计算,这样可以大大提高你的这个效率。啊像这种呃0。缺失全部都缺失0。7445特,它就没有办法和上面这些缺失率很低的特征去计算。

因为你计算出来结果是不可靠的,像这种特征,你就单独自单独自己去计算它的相关相关性就可以了。然这里的groups就是根据我们上面这个不同组。这种确失率比较高的这种0。74的一组啊那种0。71的做一组。

然后分分分到不同的groups里面去。然后我们再把剩下的缺失率都很低的特征啊,全部都放在这个TV里面,就把所有的这个所有的组的所所有组都放到这个groups这个组里面去。然后还是一样。

我们一样就是卡不同的阈值来做相关性分析,看看分数是怎么样的。那从这里可以看出呃,我们当我们的阈值卡到这个。0。799的时候,线上的分数是最高的。呃,现在的温都达到0。9478了。😊。

那这个时候这个呃那那现在的话,那到目前为止的话,差不多呃常见的套路就已经打已经已经差不多差不多啊,但还还有一些还有一些没用,呃,首先是一个一个是类别特征编码,一个是类别之间的。重要类别特征的编码。

一个是类别和类别之间的一个合并。然后还有是类别和连续重要类别和人系之间的groupby啊,这里还有一个我没列出来,就是类别和类类别之间的技术。

这里后面这里有还是不这里我忘了用。类别的类别这件技术。呃,简单类那边这些技术,这个是不是也很简单,就是嗯你不同类别之间,比如说你有ABC3个有有有个类别的啊,算了,这个你直接看代码吧。

你直接把代码给他看就好了。

这个你们自己去看代码就行,思路和挺简代的。我应该放在这里。嗯,这里。

这直接去上这个代码就去了,你不解释解释挺麻烦的。然后最后就是这个呃前面我们已把这个常见的特征衍生的套路用的差不多了。然后这个时候去做超参数的调整。🤧因为我们之前都是之前一开始使用的超参数,都是属于默认。

自己都是自己随便设置的一些超参数,没有去做细致的调餐。呃,所以后续我们可以通过超参数的调整来提高分数。一般来说超参数的调整呃,能够提高个千千12这样这样的情况啊,大概是这样啊。

除非你一开始使用的使用的那个超参数已经是比较好的。如一开始数超参数随便设置的话,后期可能提升并不是特别大。那关于这个超开口上超参数调优的方法,主要是大部分都用贝斯。

一个是呃贝一个是基于高斯过程的一个是基于TP算法那个的那个贝优化,主要是这两种啊这两种贝优化那个调参的模板,后面我后面总结的时候给。然后这里的话,因为超作调整太耗时间了,然后也太占把面了。

所以我就直接用了。开源的baseline里面呃,开源的 kernell里面用到那个超参数的调调整,但是只是就随便用了一个,可能可能会相对起到好效果的。好像我的这个参数吧,具体的我没有再去做仔细的调参了。

呃,然后这里呃刚刚刚刚我们说到这边。呃,刚刚我们说到这个。这里我们已经。你稍等一下。呃,刚刚我们已经把这几个呃特征隐生的方法做完了,然后也通过呃相关性分析啊,特这些特征呃。

这些那个特色选择的方式删删除掉一些呃甚至很多冗余的或者是无用的这个隐身特征。然后接下来就是跑超参数了,就是就是调调参了。那调仓的话呃,我按照这种参数我重新跑了一下。原来的话这里是。行列材量都是0。75。

然后这里这些参数都没这么设置的。用了这个超参数之后,看看效果大概什么样。呃,效果大概提升了。千0左右。大概提升00左右。哎,这里分数我没有给出来。啊,对,没错,线上的话,我记得是提高1100吧。

然后接下来再再往下做的话。就就比较忐讨了,前面那些步骤只能。只能保证你差不多达到百分之前10%到15%之间左右的吧,就属于一个base line的一个水平。就因为这些这东西都都套路,大家都会用。

所以你只能基本上是只能打到b baselinease line这些套路上。然后就是接下来的思路就是去在一些细节上面看看能不能。再得到一些提升。这样。比如说呃最基本的我们把NNN值用这个负值由来来代替。

然后看看结果。🤧切。因为这个。对呃无论叉级布s还是垃机变啊,或者是开的布,他们本身都是呃开布置是没有办法处处理处理垂直值的啊,但叉级布置和垃机变M,它是可以直接处理垂直值的。

但是呃但是这个方法有一个问题就是。比如说我们有一个特征有1万个区值,有有有10万个趋值。你假如其中有9万个99000个。都是AN值。都是NA啊。那这样的话呃,叉级不会来GBM我们在分裂的时候。

它只会在剩下的1000个样本里面去做分裂。也就是说你10万个样本的分裂问题,你最终只使用这个特征中的1000个样本就做去进行分裂。那这样带来的效果就是很可能会导致混拟合。

因为你在这100个样本上学到了这个特征分裂的规则,可能对10万个样本来说,压根都不适用。呃,这就会导致一定的这个过年和问题。所以有时候我们会把OAN用一个特别大的负9999来。

比如说-9999这种来来填来填充。这样填充完的话呃。差级步子会来基本上分裂的时候,就会考虑10万个全部的特征了。这样它在分裂的时候,就会把这些缺失的,把这些存在缺失值的99000个特征考虑进来。

再可以在一定程度上呃缓解过你和效果。但是但是你用负值就是填充之后,你可能也会带来一些问题。就是你因为你是完全用同一个值来填充的那可能你导致这种学学出来规则也是有问题的。

因此这种方法就是呃也是属于一种开过去个,你没有办法去稳定提高你的分数,你只能只能测只能把用用这种方式处理的时候测一下,看看效果怎么样。这里的话呃我们对连续值进行填充。因为之前缺失值呃。

这些类别型特征在处理的时候都是直接用missing,都是用负一来代替作为这个缺失值的填充。那这里我们对这个类别特征做一个布局填重,然后跑一个logoCV看看效果怎么样。🤧嗯。

这里的话它分数它漏实明显是降了千一的,相当于之前降了千0的。所以这个方案我们就不采用了。呃。然后呃其实还是有蛮多需要蛮多可以提高的地方。但是呃说实话时间太太紧,我没办法准备那么多。嗯,比如说我们前面的。

呃,g by,比如说这个类别特征的编码,我们可以做更多的编码去尝试看看能不能发出去发掘更多的信息。呃后或者是这个类别的合并。呃,我们也可以尝试对更多的类别进行合并。啊。

还有这个类别和这个连续执行输入板也是我们可以尝试使用更多的组合。来对这个来进行来进行特征衍生来产生更多的特征呃,或者是使用 toolsGP论这种呃这种特征衍生的工具来做特征衍生。

这些其实都是一些都是一些思路了,都是可以去尝试的那因为我是一个人做,所以没有办法去做那么去覆盖那么全面,只能挑一些相对来说,我觉得比较重要的地方比较重要比较有意义的地方来说吧。因为这些都是属于常见套路。

这些学的话呃效果还是挺好的,以后打什么比较都会用,当然不能保证你拿什么牌之类的,打个line可能还差不多再往上打的话,那就那就涉及到很多很复杂的东西。可能要对问题有个深入的理解。

或者是你有一些比较好的特者隐身的一些技巧什么之类的。Yeah。呃,然后这里我们直接介绍这个magic吧。呃,这个像这个这个magic feature最后才。最后我才我才发现发发现还有这么一个东西。

就是我们这个问题,我们每一个我们的样本数据集里面,每一个样本,实际上它都不是代表独立一的用户。我我之前一直以为啊等一下啊。微色洗面奶。呃,规测是一般比较少会用这个,因为嗯呃当也不是说比较少。

这个怎么说呢?就是你用呃举个简单的例子吧,比如说你用rener searchTV和grase searchTV一起来做特征搜索。呃,在搜索相在相同时间相同搜索组合的情况下。

一般runner searchTV要比gase searchV更好。因为ranner searchV它搜索的范围更大。然后呃然后相对于这个runner设设置CV来说,贝斯优化。它用来调的话,效果会更好。

因为贝优化它是呃它会考虑到你之前使用的一些之前使用的这个超参数组合的效果。比如说呃你的NSNest是从5000到6000,然后你的分数提高了。

那么那个贝S优化接下来就就会往这个5000和6000就会往上去调整。因为它会这个模模型会认为这个Nestt数量是和分数成正相关,它就会往上再再去采样。

它可能会采6000多的这么一个值去做继续的这个超参数的一个调优。所以它的效率相对来规设系未来说是更高的。就呃比如说你不V搜索了1万个特征,11万个超呃是呃,不是不,有100个超声组合。

然后你用BS优化也搜索100个超声组合。一般来说,一般来说BS优化的效果是要呃BS优化能搜索到更好的特征组合。啊,然后就讲一下这个meic嗯,其实还有蛮多其他future。但是这里就介绍最重点的。

就是我们每一个样本呃呃就是每每行每一行的样本,它实际上不是一个独立用户。这实际上是一条交易记录,也就是说一个一个用户它它会有多条交易记录。那么这那么这个问题就相对来说比较简单了。

我们如果能够通过一些标识找到每个用户的话,嗯,那这样的话对于分类区分效果会更好。😊,呃,这里的话那个chris他用到的。他用到这个。他呃他们那个小伙他就是后期一直就是在找这个UID。

也就是用户的唯一性标识。啊,这个说实话,其实我是我是没有想到他可以用这种方式来靠E和ADDRE这个倒是。这个倒是挺好去理解,但是他这个。他的这个后面这个DEN。XZ减去XD1。

他通过这个交易时间来判定投资用户这个技巧哎,说老话,我也我也不知道他是怎么弄出来的那太厉害了,他对业务理解比较比较比较还是应该还是比较深入的。😊,他通过一些他可能通过他自己的一些分析。

他得到这个这个DEN它是信用卡开始交易的日期。那一般来说,可能每一个用户开始交易日期它会有会有差异。所以这个特征会作为一个强区分度的强作为一个强区分度的一个一一个特征来区分这个用户。

而这个卡卡一表示就是这个信用卡的基本信息ADRE表示这个信用卡,这个信用卡它所对应的这个呃支付卡信用卡它所对应的地址。然后XDEN代表的就是这个用户他开始交易的时间。

因此他通过这三个特征来来确定来确来确定就是这个是同一个用户。呃,但这个说实话嗯,这个没什么套路,这个没有什么报办法能够就是你通过你你很难通过套路来得到这么一个这么一个特征功能的一个方式。

这个只能说完全就是他们。比较强的业务理解啊,然后比较强的对问题的理解。呃,所以所以他才会想到这么一个衍生的一个方法。那这样的话。

我们找到一个非常神奇的这UID这UID特征用来标识的是每个用来标识是不同的用户。哎。啊,还有一个这个小ts,这个他应该是这个应该是在这个比较早的开人柯隆上面得到了一个111个特征衍生的方式。

就是把比如说呃。我们原来transectctionMT交易金额是这样一个形式,它后面它会有小数点,然后它这里的操作就是把这个。把它这个小数点给切分出来。切切换成这么一个新的特征。啊,之所以这么做呃。

之所以这么做原原作者,他原作者他的那个他给的这个原因是因为呃你小数点后面数字的大小表示了你这个表示这个你你的交易可能属于不同的国家。

也就是说你的这个小数点后面的这个呃呃就就是你这个小数点后面这个数字的大小代表了你这个不同交易地区。啊,大概是个这么意思。那可能有的地区有有的地区后面小数点会置么会偏高,有的地区后面小数点会什么会偏低。

那像这个特征也是就是说老实话,这个也没有办法通过套路来得到。这个只能说啊太强了,要不就是他对他对于这个问题,他可能就是可能可能这个行业从业人员之类的,对这些这些基本的这些。😊,这人还是比较。

还是还还理解还是比较深入的,确实比较厉害。这个我没有办法通过没有办法通过什么套路的方式来得到,这只能说靠自己对问题的理解或者对业务的熟悉程度吧,这个是没有办法去复现的一个通西。😊,然后接下来就是。

找到找到这个UID之后,呢然后接下来就是对对这个相对来说重要的一些特征来做这个。在做这个呃go by了。那这我们把这些特征加进来以后,然后再看一下分数。可以看到现在线上的分数提高的特别多啊。

这里这里算错了,这里应该是属于6。线上的分数是实际上这里提高了0。9588呃,loc cV是提高了0。9588,提升了差不多一个一个多点。然后在线上的话,哎。哎,线上打机忘了打进来吐血。等一下。

这个到线上的话是差不多1。9588左右。啊,那差差不多这样,0。95888大概得分是这样。这是他A版的数据,然后在B版差不多排到名牌的区域吧。嗯,行,大概是过程。哎呀,我的妈讲了两个小时了。😊,嗯。

大概过程就这些啊,然后其他的话嗯就没什么可说的了。嗯,讲的比较仓促,因为可能我没怎么准备演讲稿这些,所以讲的讲的话可能会比较乱一点。但不括代码上这边你们感兴趣可以去看一看。

然后这些代码可以付现什么跑一跑。😊,这些常用的一些工具都是都是比较重要的。嗯,代码部分差不多这么多吧,然后讲一下总结好了。好。嗯,首先是就比较从学校技巧总结,一个是比赛思路。这种前面已经说过,嗯。

大大部分大差不多都都是按照这个思路来做的。只不过在每个细节上,可能每个人做法都不一样。那像前面这些比赛,其实还有还是有很多。比如说像我们最终衍生完特征之后。

我们特征选特征选择的方式可以换使用呃递规特征消除啊,或者前线后项特征消除都是可以。呃,在这里会在这里会说,稍等啊呃在问题总结里面会说,稍等一下。呃,这是比它整体思路,还有一个性能优化的问题。呃。

这就是一些性能优化一些常见常用的工具函数。一个就是呃简单的就是把pandas的数据类型,尽量用呃内容占用小的数据类型来表示。呃,然后这个是用numb来提速这个AUC计算。

这个可以直接放到letGBM里面唉,不过这里我没用,因为它本身我本身电脑性能还不错呃,然后做UC机上的时候速度不慢,所以我就没有用到这个。不过这个后面大家可以试一下。😊,呃。

然后就是相关性特征处理的正确方法。和一些采用功能采用功能的那个啊,这个是这个是我后来分装的。这个还是比较,那这个这个这个函数来。用这个相关性处理函数来处理,相关性还是比较方便的。

我们可以把这个相关性阈值作为一个超数的调整,然后打开看看logo CVV的表示啊,logo CVV的分数。这样的话呃会很方便。你不用手动人工一个去看了,因为太耗时间了。然后就超餐数据化的模板。

这个是呃这样筑这个是BS优化啊,这个是GTBE的BS优化,也是haperro这。其实优化它有多种,一种是还他们它们不同的地方主要是在于这个他们使用的代理函数不一样。

用的是TPE然后还有那个另外个化用的是化用的是过程还那基和化实现。啊,这个就是呃BS优化的模板。啊,还有就是超参数调整的话呃,如果你电脑性能性能不错的话,你可以在作为做完一些大型的特征衍身的工作。

比如说一次性引入很多特征,你你你每次引入一两个特征,两三个特征,四五个特征,这么少少量特征,其实可能不太需要去做调仓。因为你你少增加少量特征,可能对于最终的影响。并不是特别大吧,感觉。

当然如果你电脑性能好,你可以尝试每次都去调战。但如果你电脑性能一般的话,呃,像我这样电脑性能已经不错了,我都很少去做调战的工作。因为这个这玩意儿实在太耗时了。😊,就我我差不多呃50多万的数据。

50多万的数据,200多个特征吧。跑一次交叉验动要花40多分钟。那你做调仓,你调个十0组,你就要花400分钟,要花好几个小时啊,太费时间了,而且边辑效率也不大。所以调调仓的话。

习惯习惯上来说我是放到最后去做的,这样会比较方便一点,比较省时一点。然,下面这个是B斯优化的一个调仓的模板,这个这些都都是可以开箱即用的。很方便。你通过这个调调完之后,然后直接把超参数记录下来。

然后作为呃呃作为作为那个超单数调整之后的那个呃作为最终那个超单数调优之后的那个超参数,然后记录下来就可以了。然后这个是移销算法的这个。呃,超常数调整的一个函数模板呃代码。

但是嗯一下上法效果之前用过用过用用过几次,感觉没有贝斯U好用,可能是因为它对于初始化太敏感了一点吧。反正这个一常上法我们很少很少在用。

主要还是用base优化和那个hrop类和呃主要是来还是用上面这两种base优化的方式来做操长的调整。还有这个呃这个也是一个很重要的一个固定随机数的函数。呃,这个建议你每次开一个新的科程,或者说分析这。

你都要先去设计随机性那设计完那个随机性之后,然后你再去你再做下一步的,比如说交叉验证啊或者是参数条之类的,这个是一定要固定住。因为你你因为随机性,比如说你抽样的随机性。比如说你模拟训练的随机性。

你都会带来很大的这个不同的抽样啊,都会带来很大的抽样误差。那这样你的抽样误差就会对你真真实的这个特征工程带来的这个分数的提升带来这个很大的困扰。比如说你抽样误差误差达到达到110的点啊,这这很正常。

你不同抽样数据集就能得到抽样误差,达到1%这是很正常的一个事。那你你这个超参数的这个然后你这个每次特征工程的可能提升的分数有些千级,那这样就直接被cover掉了。

所以所以这个是一定这个技术一定要一定要一定要提提前添加的。😊,呃,然后就是特隐是那些常用的代码,这个方案就是我刚刚介绍的那些。然后结合这个特殊重要性来做。这个就没有必要再再继续说了哦。

然后就是你预预测的时候,现在一般开头上预测不会再去用demo去预测,而是用交叉验证。的5个子模型去平均预测。就是你你做交叉验证,你就五则交叉验证,你5则交相验证会形成5个子模型。

你就把这5个子模型去做这个。你做平均就可以了。嗯,然后就是呃另外给了两套模板,这个这。这两个模板都是一个很很好用的工具。首先那个开go us,这里面封装了一些比较常用的这个开购工具。还有我在。

文件夹同一个文件夹像那个积累这些工具,这些都是很好用的。你可以直接使用的一些一些工具,你就不用反复的去造轮子了,到时候直接做特做做特征工能,或者是做什么衍身之类的,直接使用这些函数就可以。

这是一个很好的一个模板。然后就是呃。这个。呃,这这个模板也很好用,它给的是它实际上是给给了这么一个目录。然后你在这个目录下,这些是这是这个什么特征选择特征工能之类的工具。这这里面工具他已经帮你写好了。

不过你可以去自己去做一些定制化的开发。然后这个就是你每一个步骤,你应该做哪些事情什么之类,他都大概给你列出这个纲要。我的整个课件都是在。这么一个模板上进行的非常的方便。😊,非常简单,呃。

然后不过还建议自己去跑,自己拿个什么数据跑一遍,然后调试成自己这种习惯模式。对呃,对,都有都有没错,这都有。😊,这些的话嗯感觉就是。你不管打比赛还是工作,你最好一定要形成这么一个工作目录。

这样你就不用重复去找人。要不然每次分析问题,你都要重新去写一道一个代码,非常麻烦非浪时间没有必要。那有这么一个模板的话,就方便很多。还有这个工具模板也是还有这些工具代码也都是一样的,很方便。呃。

最后是这个。嗯,简单下就他的片移的检验和缓解方法。嗯,这这其实我之之前已经说过了。嗯,这个不用再说了,这之前我已经说的差不多了。你有问题的话,你到时候直接群里问我就可以了。啊,最后是问题总结吧。

一个是首先不均衡学习的问题。嗯,可以看到在这这次比赛里面,海外客户比例是2029比1。但是实际上你们排名排名前前的几个路选里面都没有使用不均衡学习的方法。比如说做采样啊或者做代价敏感学习之类的。

实际上在线下可以自己去测一下。我们使用呃采样上下采样或集成采样之类,效果会很差。那主要的原因是因为不均衡学习的本质,你要你要了解不均衡学习本质的问题,就是正负样本比例选殊并不是模型训练效果差的本质原因。

而是一个表象不均衡不均衡原不均衡不均衡问题,它导致模型本差的本质原因是一个是类别分布的重叠。简单来说就是不同类别特征。😊,它它特征非常接近,或者是更极端的,可能特征完全一样的情况下,标签就不一样。

第二个造成问题就是很多完全没有使用,没没没没有用的样本引入就是这些特征对于这些特征区分度不高,它可能是介于这个你的分界线呃,你的分界面分界面周围的这种样本。那这种样本它对于这终模型训练的效果,呃。

对于对终模型模型区分,好坏好坏客户的帮助很很低。然后第三个是类别工作子分布。呃,这个问题的在异常检测里面还是挺严重的。因为因为很多时候做异常检测都直接把直接把标签归为异常和正常两类。

但是实际上异常用户里面可能有欺诈用户或者是普通的呃老赖的用户或者是已经死亡的用户等等。这些用户的分布差异性是不一样的。但是因为业务啊或者是label标注这个问题,他可能最后定型为同一类。

所以从而最能导致这个。😊,最终导致是实际上是它是不同分布的这个类别,它都画在一块儿了,这样就导致模型你没有办法去很好的去学习其中的这个不同之处。那简单来说,这些问题其实在比例正常的数据集里面也会出现。

只不过在在正负样本比较悬殊的情悬殊的情况下,是这种情况是经常发生的。因此我们会误以为是不均衡导致的这种问题。啊另外我们需要注意的就是不均衡有两种有两种情况,一种是相对不均衡,一种是绝对不均衡。

相对不均衡,指的就是好坏客户它的比例虽然相差比较大,但是样本的基数很大。那这种情况下,其实我们不需要去做什么额外的不均衡学习问题的处理。因为呃就像我们前面所说的,当样本数量够多的时候。

这些现象其实出现的概出现的可能性会低很多。比如说你的。😊,你的客户你的坏客户有10万个,你的好客户有1亿个。那这种情况下,其实模拟对于模拟训练来说是没什么影响的。

因为你10万个坏坏客户足够去学习这个坏客户的特征分布了。呃,然后我们再说一下这个不定衡学习的各种方法吧。呃不定衡学习方法大连就分成两种,一种就是采样,上载下载上集成采样。还有一种就是损失函数。

也就也就我们平常所做代价敏感学习,就是对损失函数去做各种模改。比如说就最最简单的balance那个classbalance,就是实际上就是对这个呃客户进行加权,或者是这个focal loss。😊。

呃folo呃,这种方式都是一样,都是从损失函数修改角度出发的。那这种这两种方法无一例外,他们都会间接或者直接改变数据的分布,结果是难以预料的。嗯,比如说产接采样,比如说我们本来是1比29的客户。

然后特征是一种情况。然后然后我们切方法成1比10或者1比1的时候,它特征的这个它特征分布肯定会发生很大的变化。那这样就会引入我们之前所说的特征偏移的问题,从而导致这个从而导致这个模型呃不拟合。🤧嗯。嗯。

但是呃呃呃一般来说这个。呃,但这个比赛他因为他样本数量,他坏客样本数量比较多,所以他不需要去做这个资限采样。平常呃有时候在工作中会碰到这种问题。比如说坏客户数量特别少,能只有几十个甚至一两百个。

那这种情况下,我们没有办法只能去只能去做代价敏感学习,只只能去做这种采样或者是模改函数之类的这些方法操作。一般来说呃可能会一般来比较常用的方法去做集成采样。

然后再去结合这个代价敏感函数的方式来来这个应对这种不均衡学习的问题。😊,不过大家需要注意,就是嗯需要需要了解,就是不仅决得本质问题,不是因为类别不平衡,而是因为其他级别。然后关于不进合学习呃。

要展开来说,其实说很要说很多。我我这后面有发了一些呃相关的一些材料,但是其实还是有很多资料没做完的。😊,然后推荐的话,推荐大家去看这本书。这本书对于这个不进行学习,它给了一个非常详细,非常系统性的阐述。

呃,另外还有一个就是呃关于这个inbalance date的一个重标。欢迎般 day的一个论文综述,这个大家可以看一下,帮助还是非常大的,但可以让你了让你这个比较充分了解这个不均衡问题的一个本质。

这样这样的话,你就后期呃你再去进行一些处于处理什么时候呃,这些一些一些应对方方式处理这种之外呃,就你会比较呃有比较充分的去了。因为你充分了解这个问题,所以你才会比较好的去解决这个问题。

然后是关于这个特征偏移的问题。呃,我们就前面说特种变异它本质可以认为是过年的本质原因。嗯,那对于这个结构化数据的这个特征偏移,其实没有特别普实性的方法。就像我前面对于类别特征处理。

这里用直接把类别转成int,但是你换成换一个数据肯定没有办法用。那老外包括还有这个连续特征处理,做分箱或者是做对数变换之类的,其实并不是它并不是一个普普适性的一个一个一个方案。那可能你这个数据有效。

效个数据就没什么作用。然后关于特征偏移的话,呃,这里涉及到这个迁移学习的问题。对于图像和我文本,我们可以通过迁移学习的方式来缓解这种特征偏移,特征分布不同的问题。

但是t数据集它在应对特征偏移方面没有什么特别可靠的学科或者特别可靠的方法。那这里简单介绍一下这个这本教材嘛。

machine learning这本是比较详细的介绍我们前面我们我们所说的这个特征偏移的问题。还有一个就是呃迁移学解妹手册,这个大家可以看看,他讲讲的是迁移学习。

其中那个讲的是这个呃他讲的讲的很多都是关于特征偏移的问题。他其中讲述到了那个领域自适应,就和这个t数据集的关系特别重。呃,特关系特别大呃,比如像像一些这个特征迁移的一些解决方案。就之前。呃,有发过论文。

那些解决方案都会有。比如说像那个样本权重的呃样本权重的改变啊啊,或者是这个不同特征子空间的寻找之类的,这些都有。因为太多了,没有办法在展开介绍,所以呃教材就放这里,就大家感兴趣可以自己去研究一下。

还是帮帮助还是蛮大的。😊,还有就是性能优化的问题。这个性能优化其实可以从很多方面入手嘛。就像我们之前前面做过的。呃呃最基本当然这个这也最最基本也是比较复杂的。一个是从算法层面去改进。

那这个一般来说嗯不太可能会做这个东西,因个难度难度需求太高了。那当然还是有一些呃其他的方式来提高效率。比如说呃我们在做特征之前评估一下特征本身的呃实力啊信息量啊,然把一些常面量ID需要这无用特征删除。

来通过这些方法来提高你这个整个程序运营的效率。然后还有这个前面说到数据类型的优化。😊,还有python这些高性能优化,比如说南玛系等这样跳过其python它本身的那个类型检查来提高速度。

或者是使用多进程的方式,或者是把矩证运算搬到GPU上面等等,这些都是可以提高性能性能优化呃,提高这个python运行性能的一个问题。这个其实是一个。嗯,我觉得这个这个问题是一个非常现实。

也非常有意义的一个问题。因为平常不管你在比赛还是在工作中,其实都都是很重要的。就是关于pathon的性能优化。嗯,为什么性能优化的情况下,可能运行运营的速度效率会差个几百倍,都是都是这样出现的。呃。

关于paon性能优化,就推这两本吧,其实这两本看看差不多就可以了。这两本如果深入研究一下,其基本上没什么太大问题吧。这个对。系能优化这个展开来说里面也好多啊。

最近比如说最比如说呃就比如sea吧n或者ea它本身n是LVM编译的。然后season它本身是呃通过这个C语言编译器来来跑。所以它都跳过了那种类型检查。因为因为它是动态类型数据类型的。所以你的数据处理。

它在底底层实际上会做特别多类型检查,它会检查你这个数据是什么类型的,然后不同类型下它会配不同的运算,它会非常耗消耗时间。它n这种直接指定静态数据类型的这种方式,就不会。😊,啊。

这些的话具体介绍在这本书上,还有他们的numb么新人官网上都会有详细介绍,这里就。不反过去说了。最后就是特征选择的问题。嗯。怎么样我们我们那个这己大概列出来,过滤式,还有嵌入式还极极便简。

还有这个呃包裹式。这这些啊这个我之前没有没有说,主要是因为。就长开说太麻烦了。太多了。我听经讲了两个半小时,我天这在长的说候要吐血了,这里大概说一下吧,就是这是这是一些常用的。然后我们在做特征选的时候。

我们。😊,我们需要对这些特征选择方法都有特别充分的了解。比如说像特征重要性。哦,刚刚忘了说特征重要性缺陷了。一个就是我刚刚说过,他特别强的特征会。😊,被cover掉。不错的。但是不那么强的。

然后一个是这个非ture importantport它。没有办法反应。特征对于。画画性能的贡献。呃,首先我们就要需要知道的非joinport,它是根据模型在训练级上面分裂的争义或者分裂次数来计算出来的。

所以非joinport它实际上它没有反映这个特征。对于测试,对对于预测的贡献的。他反应的仅仅是。罗西拟和训练集。的过程中的争议或者分裂次数的。我不行。也就是说反映的是。对训练集。预测的贡献。

不反应对测试级呃对验证级。或者测试集。预测的贡献。呃,所以针对这种方法,就出现了像permation importance呃,n importance。

这种这些呃这些常用的这些呃这些这这些这这些特重要性的方式,最开始都是从开头上面流出来的。嗯,再比如pro important,就是你预测的时候,把特征做sble。

然后n important就是对标签做svele,然后重新训练就看特征重要性的这个效果。嗯,还有这个提到我我们刚刚提到这个对抗性验证。但对抗性验证它只能反映特征的偏移。

但它没也没有办法反映你这个特征对于这个预测的贡献。但proation importanceport如 importanceport呃到这呃是可以反映这个是可以反映这个特征对于呃泛华性能的贡献。

但是他们也有自身的一个问题。promentation importance它首先是它对于这个高相关的数据集。偏偏差比较大。呃,这是这要写好这讲好多,它对于高就是如果你特征中有很多相关性特别高的特征。

那这些特征可能相互之间都会有很多呃会有很多替代的效应。比如说你有一个特征,本来特征关功能性是是100呃,但是你有100个这种相关特别高的特征,就最最终就会导致这种特征的特征重要性很低。

然后这个它的这个可这些 importanceportance的效重要性很低。哎呀,这太多了,我我我把。我回头我把我把支付账号上发给你吧,我这我这上面都写过写过写过类似的东西。这这玩意儿展开讲太多了。

再讲不完了。😊,嗯,然后。嗯,大概就这些吧大概就这些吧。我妈讲的太久了。😊,行,okKOK就这样有什么问题你们在群里问我就好了。然后有空的话,我回答一下。😊,哎呦,马海是讲完了。好好,谢谢大家谢谢大家。

😊,呃,哎,对了。

群你你们加群了是吧?哦。推荐这个杯子呃,我我买的是战神战神系列。😊,啊,会呃,应该那个应该是我应该会放到那个群里边吧。其他啊,可以。哦,没有哎,我我这我这些作币的怎么没有放到ge号上面啊,就是在本地的。

😊。

嗯,行行行,百度云。嗯,行,我整理一下吧。哦,对对,你让他拉我一下吧,我我没有加那个群,唉,我不知道还有直播群那个东西。我把这个打包一下就可以了。呃,不过这个代不过代码有点乱就是了,因为。😊,呃。

有很多,比如说像这些模块我都没有写,这只是一些呃工具模块,我我都没有在这里面写代码,只是混着写的。呃,所以这个你到时候要跑的话,自己看看吧。或者有什么问题问我就好了。哦,行行,OK。嗯。

哎我我我我是第一次讲,所以哎我感觉讲的很多细节。😊,讲的不要含无清,所以这个。😊,各位到时候可能还是呃有问题就反正问我就好了。就是大概的。然后呃会的话,我尽量帮他回答。不会的话。

就是我可能会贴些地址给你们的,我们自己看就好了。嗯,就打比赛这个东西说实话确实很难把很多细节都讲清楚。嗯,而且很多时候。嗯,logo CV跑出来效果和那个理论上差距完全不一和理论上完全不一样。所以呃。

呃,行,后面再说吧,后面再说。数据分析的嗯。嗯,后续应该不会吧,就是。可能主要还是开口上比赛或者是国内一些比赛的。一些分析分享之类的,但是。那,其实这个比赛。那怎么说呢?这个比赛已经算很好了。

因为第一名他把代码都开源了,而且讲的很清楚很详细。但是你要真的去深入离去复线的话,还是有很多地方是。还是有很多地方是搞不清楚的。比如说他比如说他选择那个UID的那个过程,他到底怎么怎么选出来的。

但他选择UID他具体为什么要和为什么要和那些特征去做合并。呃,去做去做bue by也是需要去商讨的。所以很多细节上面你没有办法去复现,只能说个大概了。就是这些东西还是得自己亲自去打比赛的时候。

才会有比较深的体会。嗯。嗯,但不只是这些啊,其实很多细节我还没说。比如说那个per important我我没说,还有那个地位正常消除或者前线后段正消。因为这些正性消除它所消耗的时间太多了。

所以所所不会不会说一个一个去说。😊,当然感兴趣的话,呃,有时间我说一说吧,那个也没什么难度。反正这些开上的这些套路都没什么难度就。呃,就是这种table的数据集,这个方法都是很直观的方法。

没有什么特别难理解的地方。难的地方就是算法理解上面。但是这个其实很多地方都可以看了,原理什么之类的。啊,对对,是嗯,没有什么通用的方法,没有什么推用方法,所有的方法都会有他自己的缺漏。嗯。

所以就是然后就是而且。嗯,其实你仔细去分析不同不同选手,他那个他的那个代码逻辑,你会发现就是可能有的选手他从比如说像ch,他是一开始删了很多微特征,然后再去做后续的特征工程。

但如果你一开始不去删微特征的话,直接去用他那特征的,效果会打折挺多的。呃,所以说他应该是他有有自己一套解决问题的思路。我们比如说删除努力特征之后,然后加入一些高价值信息的特征。

然后可能然后另外一些一些选手思路就是你能暴受暴力特征隐身啊,然后通过呃比较强的算力去做特征选择,就说比如说像比较暴力前向后向特征消除或者是地位症效之类这种呃思路不太一样。就是只能说你讲这种东西。

你只能理解一些。常用的方法,然后具体怎么去组装,还是你自己去做。但我也不知道怎么跟你说怎么去组,可能每个人他自己的思维模式不一样嗯嗯。O, O。呃,行,那个那就先这样吧。呃,回头我加了那个群。

然后我把百度云或者是直接把这文件传给你们。然后具体的呃就你们自自己再看就行了啊。OKO谢谢谢谢。😊。

posted @ 2024-10-23 18:36  绝不原创的飞龙  阅读(12)  评论(0编辑  收藏  举报