本文讲的是机器学习的一种算法。由于数学难以理解,所以转换为白富美相亲来类比,同时大家也能明白这玩意能用到什么地方。
机器学习里有种算法叫决策树算法,这个算法好多资料讲的非常非常复杂。这算法是一种监督学习算法。
决策树概念:
比如我是个媒婆,我要给白富美挑合适的男人,比如一个男人30岁,有钱,长得一般,职业发展空间大,我推荐给白富美了。白富美看都没看就说不见。我就有点奇怪了,这么好条件都不见?于是推荐个20岁小鲜肉,是个富二代有钱,长得帅,暂时无职业。然后白富美答应见了。后来他们谈没谈成我不知道。但是白富美还让我继续推荐男人。我就一个劲推荐男人,从中也发现了一些规律:
白富美可能比较喜欢年轻男人。
白富美可能比较喜欢有钱男人。
白富美可能比较喜欢长得帅的男人。
白富美可能对男人职业并不感冒。
那么我手上有另外100个男人。我如何提前知道白富美是见还是不见?
首先明确一件事。这100个男人每个男人的特征已经是完全定死的了。白富美见或不见这个男人也是确定的一件事。因为白富美不会在我第一次推这个男人时说见,第二次说不见。
先说个决策树形状,就跟树木形状差不多,每个分叉都是一个条件。最后都会达到叶子,产生一个结果。
这里就可能需要有点算法上的东西。但是本文不讲算法,只讲理解。一般常用的有3种算法。
一种叫ID3
一种叫C4.5
一种叫CART
ID3算法大概是这个意思:先把特征拿出来,比如本文就是年龄,财产,外貌,职业。会去找这几个特征里信息增益最大的那个。 这个信息增益根据我的理解,就是互信息,也就是熵与条件熵的差。简单说就是我发现,我推荐给白富美的男人里,大于30岁的80%都没见,但是别的特征里她见或者没见都不是特别明显可能见40% 不见60%或都在50%左右。那么这个年龄就是信息增益最大的特征。作为决策树的顶端节点。也就是第一个分岔口。后面的特征就不包含这个根节点特征了。然后继续看财产,外貌、职业,找其中信息增益最大的那个。作为第二个分岔口。最终生成一棵决策树。这个决策树的最终结果就是我们打的标签见或者没见。我根据这个决策树把新的男人特征输入进去,最后生成个见或者不见的结果。
C4.5算法是ID3算法的升级版。是利用了个叫信息增益率的玩意。简单说是这样,ID3算法有个很大的缺点。比如我已经推荐给白富美50个男人,白富美也已经做完了选择。但是我在给这50个男人分类时把某个特征分的过细,比如这个男人资产1000块算一档,每增加1000算一档,50个男人基本只占了其中50个档位,每个档位一档(假设这50个男人每个人的资产差值都大于1000)。于是这个财产档位就具有非常强的信息增益。因为每个财产档位对应一个100%确定的结果。按照ID3的算法,这个财产必然会被用做根节点来分岔。这就很容易导致过拟合。就是一般人常说的回测牛b实战垃圾。于是,C4.5算法就是对于分类过细的标签除一下,让分类过细的标签进行惩罚。这样可以有很好的泛化能力。
CART算法是利用基尼系数来算的。基尼系数一般是衡量一个国家贫富差距或者两极分化的指标。根据我的理解,CART也是ID3的升级版,和C4.5区别就在于它不是除熵,是除基尼系数。基尼系数就可以理解成近似熵的玩意。实际问题中CART算法用的也比C4.5多。
代码应用:
学了没用有啥用?赶紧用起来。我就模拟上面给白富美推送了2个男人,年龄,财产,外貌,职业,就是上面的,由于男人太少,再推荐2个男人,白富美见了个年龄24的,4000资产(假设文章开始那2男人一个是1w一个是8000),外貌80分,有不错职业(为了方便,就简化成有职业和无职业)。而另一个有98分绝世美颜,26岁,3000资产,无职业的白富美没有见。生成一个决策树。我们手上还有2个男人,一个是22岁,5000资产,70分颜值,有工作,另一个是29岁,5000资产,40分颜值,有工作。可以猜猜看白富美到底见了哪位呢?
代码贴上:
from sklearn import tree
#年龄,财产,外貌,职业
X = [[30,10000,60,1],[20,8000,90,2],[24,4000,80,1],[26,3000,98,2]]
Y = [0,1,1,0]
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, Y)
print clf.predict([22,5000,70,1])
print clf.predict([[29,5000,40,1]])
说一下最终预测结果,白富美见了第一位,没见第二位。看来果然还是更看年龄一点哈。
随机森林
随机森林是对上面算法的一个优化。决策树顾名思义只有一个树,森林会有n个树。但是每个男人让白富美挑的结果都是确定的,怎么才能生成不同的决策树呢?答案就是在样本里随机取样或者上面那几种分类方法换着用。这样生成的决策树就不一样了(随机森林的随机性一般体现在这2个随机点,样本随机和属性点换方法随机)。就有点像有好几个白富美像我正在研究的这个白富美,那么新的男人推给这些相似属性但实际不同的白富美见还是不见结果也不一定。于是对于性格相同但实际不同的白富美(指不同决策树)就有不同的结果,他们会告诉我见或者没见,我就产生了几种方式来综合他们:
第一种就是采取投票结果,5个美女表示见,3个美女表示不会见,那么最终结果就是推给真正我要研究的白富美大概率会见。
第二种是一种adaboost方法,有点复杂,简单理解和上面那种方式相比就是我国和米国的比较。还是拿上面那个例子举例,前面我们通过加上随机性让一个白富美变成了很多很多相似性格的白富美。这些白富美有些跟我们研究的白富美几乎一模一样,有些不算特别像。那么我们拿这个几乎和原版一模一样的白富美推送和原版一样的男人,见与不见的效果肯定和原版仍有一点不同。那么,这些不同的男人也就是原版白富美明明见了,但是盗版白富美没见。于是这些男人的属性就被赋予了更高权重,而原来和原版一样选择的就被赋予更低权重,再重新生成新的白富美。这个白富美会对这些男人见与不见也产生结果,这个结果可能还不如上面那个白富美像原版白富美,但是这个白富美和上面那个白富美他们会有比较,谁和原版像,谁就有更大的话语权。最终产生一系列有不同话语权的盗版白富美,他们的最终意见则表示原版白富美最可能的意见。当然这个误差大不一定是坏事,比如有个白富美的99%的选择都和原版白富美不一样。那么投票时候这个白富美说见,那大概率原版白富美就是不见。所以具体到数学里很复杂,所以这玩意用数学公式讲出来一般人都理解不了咋回事。
代码应用:
这个参数就去官网查这个函数就行了,就不细说了。还是拿上面那个例子来预测。
from sklearn.ensemble import RandomForestClassifier
X = [[30,10000,60,1],[20, 8000,90,2],[24,4000,80,1],[26,3000,98,2]]
Y = [0, 1,1,0]
clf = RandomForestClassifier( random_state=1)
clf.fit(X, Y )
print(clf.feature_importances_)
print clf.predict([22,5000,70,1])
print clf.predict([[29,5000,40,1]])
最终结果和上面单独决策树结果一样。