什么是随机森林

众所周知,树模型是高方差、低偏差的模型。因此,它们容易过度拟合训练数据。如果我们不修剪树模型或引入早期停止标准(例如每个叶节点的最小实例数),我们可以概括一下树模型的作用,这很吸引人。好吧,它尝试沿着特征拆分数据,直到实例对于目标特征的值来说是纯的,没有剩下的数据,或者没有剩下的特征可以吐出数据集。如果上述之一成立,我们就会生长一个叶节点。结果是树模型增长到最大深度,并因此尝试尽可能精确地重塑训练数据,这很容易导致过度拟合。像(ID3 或 CART)这样的经典树模型的另一个缺点是它们相对不稳定。

例如,考虑使用分类缩放特征 *A* 作为“根节点特征”的情况。接下来,这个特征从数据集中被替换,不再存在于子树中。现在想象一下我们替换数据集中的单行的情况,这种变化导致现在特征 *B* 分别具有最大的信息增益或方差减少的情况。这意味着什么?好吧,现在特征 *B* 比特征 *A* 更受欢迎,因为它作为“根节点特征”会导致完全不同的树,因为我们改变了数据集中的一个实例。这种情况不仅可能发生在根节点上,也可能发生在树的所有内部节点上。

请注意,在上图中,建议将目标特征列中的“X”作为实际值的通配符。随机森林方法已被证明是解决过度拟合和不稳定问题的最有用的方法之一。

随机森林方法基于两个概念,称为装袋和子空间采样。Bagging 是*bootstrapaggregation* 的缩写形式。在这里,我们创建了大量与从原始数据集提取的原始数据集相同长度的数据集,并进行了替换(装袋中的 *bootstrap*)。然后,我们为每个自举数据集训练一个树模型,并将这些模型的大多数预测作为我们的预测(装袋中的 *聚合*)。这里我们取回归树模型的均值或中位数,以及分类树模型的众数。

你可能会问为什么我们抽取样本有替换?好吧,让我们假设我们的原始数据集有 100 个实例(行),并且我们想要创建一个由 10 棵树组成的随机森林模型,其中每棵树都在与原始数据集长度相同的数据集上进行训练。如果我们现在从原始数据集中抽取 100 个样本而不进行替换,会发生什么?确切地说,没有什么,因为我们形象地说只是将数据集从一个容器转移到另一个容器。如果我们这样做 10 次并在每个数据集上训练一个树模型,我们将获得 10 倍完全相同的数据集(假设模型参数相同)。如果我们现在预测一个看不见的查询实例并对 10 个树模型的结果进行平均,即运行随机森林程序,我们将一无所获。这让我们回到最初的问题,为什么我们使用装袋方法?我们使用bagging方法(记住重采样)是因为我们知道单树模型对数据的变化非常敏感并且有很大的差异。为了解决这个问题,我们在不同组成的数据集上创建多个模型,并取其预测的平均值。这里我们应用了平均多个模型的方差可以减少方差的原理。

我们可以通过一个代表不同树模型并从相对较远的距离向目标射击的枪手来用简化的术语来说明这一点。因此,步枪(我们的数据集)的小幅移动将导致完全不同的分数(我们模型的输出)。但平均得分击中了靶心。这意味着平均值的方差小于单个模型的方差

伏一个r(X¯)=σ2n 瓦H电子r电子 σ2=伏一个r(X))

随机森林方法所基于的第二个概念是子空间采样的概念。Bagging 使我们朝着拥有更强大模型创建更准确结果的目标前进。不幸的是,事实证明袋装模型是相关的,因此通常相对相等。也就是说,基于相关性,它们会产生相似的结果。这可以归结为 Bagging 使用每个模型的整个特征集(所有描述性特征)。现在假设有一个或两个非常强大的特征,它们在“预测性”方面超越了所有其他特征(例如,这两个特征的信息增益比其他特征大得多)。即使我们通过替换采样来改变数据的组成,这两个很可能仍然是主要特征,因此将分别作为根节点或第一个隐藏节点层。结果,这些树看起来都非常相似。

现在事实证明,如果我们使用纯装袋,数据中隐藏的结构可能会丢失。为了唤起这些隐藏的结构,除了这两个强大的特征之外,我们还必须加强它们,让它们有投票的声音。我们怎样才能做到这一点?好吧,最简单的方法是从我们的数据集中移动这两个。显然,这不是一个好主意,因为我们想要拥有它们,但也想要考虑并合并不那么占优势的特征的声音(投票)。长话短说,我们通过随机绘制一些米⊂p 树中每个分裂的不同特征,其中 p表示每个分割的特征空间。这里文献推荐米=p.bagging 和子空间采样的结合给了我们想要的随机森林模型,它的奥秘在于假设大量弱学习器在预测准确性方面比一个强学习器更好 - 或者你为什么认为“问“观众生命线”被设置为*谁想成为百万富翁*节目中的生命线??-. **完成 - 恭喜!您现在知道随机森林背后的概念。** 这是最强大的机器学习算法之一。

随机森林背后的数学

幸运的是,几乎没有我们以前从未见过的“随机森林”特定数学这样的东西。基本数学原理与分类 和回归树相同。

与随机森林的主要区别在于,我们多次执行我们在决策树和回归树上所做的所有步骤。也就是说,如果我们有一个分类缩放的目标特征和平均值或中位数,如果我们有一个连续缩放的目标特征,我们会种植大量的树,让它们做出决策并通过最频繁(模式)的决策来聚合这些决策。因此,对于分类缩放的目标特征:

最大参数吨 ∈ 吨 吨r电子电子米○d电子升秒 在哪里

最大参数 代表模式(多数票), 吨 表示单个树模型的结果(预测), 吨 是树模型创建的结果空间(所有结果)和 吨r电子电子米○d电子升秒 是单树模型,每个模型都产生一个结果 吨. 因此最常发生的结果吨 ∈ 吨 作为预测返回。

随机森林伪代码

如上所述,随机森林算法基于自举聚合和子空间采样原理的组合。因此:

Tree_Outcomes = [] 对于 i=1 到 n:从原始数据创建引导样本 使用通用停止标准在该引导数据上训练树模型,其中: 对于每个分割:子空间样本数 m=sqrt(p)特征空间p在这个节点选择最好的特征(最高IG,最低方差)来分割数据沿特征分割数据删除特征将每棵树的结果添加到Tree_Outcomes Random_Forest_Outcome = Majority vote(模式) Tree_Outcomes 中元素的数量 # 对于分类 Random_Forest_Outcome = Tree_Outcomes 中元素的多数(平均值/中位数)# 对于回归返回 Random_Forest_Outcome

使用 Python 从头开始​​随机森林

幸运的是,对于随机森林分类模型,我们可以使用分类树章节中创建的大部分分类树代码(对于随机森林回归模型也是如此)。我们必须在实际的树构建代码中实现的唯一真正改变是我们在每次拆分时使用一个大小为的随机特征样本米=p 在哪里 p表示该节点的特征空间。所有其他更改都是“围绕”树构建代码进行的。也就是说,从代码的角度来看,随机森林是通过为树代码提供一种很好的“超级英雄套件”来创建的。

我们必须实现的第三个变化是,随机森林模型实际上不能像普通树模型一样可视化,因此可视化部分是过时的事件,内部每棵树都是构建的,我们实际上可以绘制每棵树来推理决策随机森林模型。但是,当树模型的数量增长到数百或数千时,这没有用。

第四个变化是我们必须添加一个列表,其中存储单树模型的预测,最终返回该列表的众数值作为预测。

在这里,只评论了由于随机森林的创建而导致的造树代码的变化。有关树构建代码本身的进一步评论,请参阅分类树页面。为了可视化,我们将在 这里使用UCI 蘑菇数据集。

"""
导入需要的python包
""" 
import  pandas  as  pd 
import  numpy  as  np 
from  pprint  import  pprint
import  scipy.stats  as  sps数据集 =  pd 。read_csv ( 'data\mushroom.csv' , header = None )
dataset  =  dataset 。样本( frac = 1 )
数据集。列 =  [ '目标' , '帽形状' , '帽表面' , '帽颜色' , '瘀伤' , '气味' , '鳃附件' , '鳃间距' , '鳃大小' , '鳃色' ,'茎根' ,'茎表面-环' ,'茎-表面-环' ,'茎-色-环' ,'茎-色-环' ,'面纱型' , '面纱颜色' , '环号' , '环型' , '孢子印色' , '人口' , '栖息地' ]############################################### ############################################### ####### 
########################################### ############################################### ##############def  entropy ( target_col ): elements , counts  =  np 。unique ( target_col , return_counts  =  True ) entropy  =  np 。总和([(-计数[我] / NP 。总和(计数))* NP 。LOG2 (计数[我] / NP 。总和(计数)) for  i  范围内len (元素))])返回############################################### ############################################### ####### 
########################################### ############################################### ##############def  InfoGain ( data , split_attribute_name , target_name = "target" ):#计算总数据集的熵total_entropy  =  entropy ( data [ target_name ])##计算数据集的熵#计算分割属性vals的值和相应的计数,counts =  np 。唯一(数据[ split_attribute_name ], return_counts = True )#计算加权熵Weighted_Entropy  =  np . sum ([( counts [ i ] / np . sum ( counts )) * entropy ( data . where ( data [ split_attribute_name ] == vals [ i ]) . dropna ()[ target_name ])  for  i  in  range ( len ( vals ) ))])#计算信息增益Information_Gain  =  total_entropy  -  Weighted_Entropy return  Information_Gain############################################### ############################################### ####### 
########################################### ############################################### ##############def  ID3 ( data , originaldata , features , target_attribute_name = "target" , parent_node_class  =  None ): #定义停止条件 --> 如果满足其中之一,我们要返回一个叶子节点##如果所有 target_values 的值相同,则返回此值if  len ( np . unique ( data [ target_attribute_name ]))  <=  1 : return  np . 唯一(数据[目标属性名称])[ 0 ]#如果数据集为空,则返回原始数据集中的模式目标特征值elif  len ( data ) == 0 : return  np . 唯一( originaldata [ target_attribute_name ]) [ np . argmax (NP 。独特(originaldata [ target_attribute_name ],return_counts =真)[ 1 ])]#如果特征空间为空,则返回直接父节点的模式目标特征值 --> 注意#直接父节点是调用ID3算法当前运行的节点,因此#模式目标特征值存储在 parent_node_class 变量中。elif  len ( features )  == 0 :返回 parent_node_class#如果以上都不成立,那就种树吧!else : #设置此节点的默认值 --> 当前节点的模式目标特征值parent_node_class  =  np . 唯一(数据[目标属性名称])[ np . argmax (NP 。独特(数据[ target_attribute_name ],return_counts =真)[ 1 ])]############################################### ############################################### ############ ############!!!!!!!!!实现子空间采样。绘制多个 m = sqrt(p) 特征!!!!!!!!!############# ################## ############################################### #########################################功能 =  np 。随机的。选择(特征,大小= NP 。INT (NP 。SQRT (len个(特征))),取代=假)#选择最能分割数据集的特征item_values  =  [ InfoGain ( data , feature , target_attribute_name )  for  feature  in  features ]  #返回数据集中特征的信息增益值best_feature_index  =  np 。argmax ( item_values ) best_feature  =  features [ best_feature_index ]#创建树结构。根在第一次运行树中 获取具有最大信息#gain的特征名称 (best_feature) =  { best_feature :{}}#从特征空间中移除具有最佳信息增益的特征features  =  [ i  for  i  in  features  if  i  !=  best_feature ]#为根节点特征的每个可能值在根节点下生长一个分支对于 价值  NP 。unique ( data [ best_feature ]): value  =  value #按照信息增益最大的特征分割数据集,然后创建 sub_datasets sub_data  =  data 。其中(数据[ best_feature ]  == 值)。滴滴()#使用新参数为每个子数据集调用ID3算法-->递归来了!subtree  =  ID3 ( sub_data , dataset , features , target_attribute_name , parent_node_class )#添加子树,从sub_dataset生长到根节点树下的树[ best_feature ][ value ]  =  subtree返回(树)    ############################################### ############################################### ####### 
########################################### ############################################### ##############def 预测(查询,树,默认 =  'p' ):对于 关键  列表(查询。键()):如果 列表(树。键()):尝试:结果 = 树[关键] [查询[关键] 除了返回 默认的结果 = 树[关键] [查询[ key ]] if  isinstance ( result , dict ): return 预测(查询,结果)else :返回 结果############################################### ############################################### ####### 
########################################### ############################################### ##############def  train_test_split ( dataset ): training_data  =  dataset 。iloc [: round ( 0.75 * len ( dataset ))] 。reset_index ( drop = True ) #我们删除索引分别重新标记索引#starting form 0,因为我们不想遇到关于行标签/索引testing_data  =  dataset 的错误。iloc [ round ( 0.75 * len ( dataset )):] 。reset_index ( drop = True )返回 training_data , testing_datatraining_data  =  train_test_split (数据集)[ 0 ]
testing_data  =  train_test_split (数据集)[ 1 ] ############################################### ############################################### ####### 
########################################### ############################################### #####################训练随机森林模型###########def  RandomForest_Train ( dataset , number_of_Trees ): #创建一个存储单森林的列表random_forest_sub_tree  =  []#Create a number of n models for  i  in  range ( number_of_Trees ): #Create a number of bootstrap sampled datasets from the original dataset bootstrap_sample  =  dataset . 样本(frac = 1 ,replace = True )#通过调用train_test_split函数来创建训练和测试数据集bootstrap_training_data  =  train_test_split ( bootstrap_sample )[ 0 ] bootstrap_testing_data  =  train_test_split ( bootstrap_sample )[ 1 ] #为每个训练数据生成一个树模型#我们在 ID3 算法本身中实现了子空间采样。因此,看看上面的 ID3 算法!random_forest_sub_tree 。追加(ID3 (bootstrap_training_data ,bootstrap_training_data ,bootstrap_training_data 。压降(标签= [ '目标' ],轴= 1 )。列))返回 random_forest_sub_treerandom_forest  =  RandomForest_Train (数据集,50 )#######预测一个新的查询实例########### 
def  RandomForest_Predict ( query , random_forest , default = 'p' ): predictions  =  [] for  tree  in  random_forest : predictions 。append ( predict ( query , tree , default ))返回 sps 。模式(预测)[ 0 ][ 0 ]查询 =  testing_data 。iloc [ 0 ,:] 。下降('目标' )。to_dict ()
query_target  =  testing_data 。ILOC [ 0 ,0 ]
打印('目标:' ,query_target )
预测 =  RandomForest_Predict (查询,random_forest )
打印('预测:' ,预测)#######在测试数据上测试模型并返回准确度########### 
def  RandomForest_Test ( data , random_forest ): data [ 'predictions' ]  =  None for  i  in  range ( len (数据)):查询 = 数据。iloc [ i ,:] 。下降('目标' )。to_dict ()数据。loc [ i , '预测' ]  = RandomForest_Predict ( query , random_forest , default = 'p' ) accuracy  =  sum ( data [ 'predictions' ]  ==  data [ 'target' ]) / len ( data ) * 100 #print('预测准确度为:',sum (data['predictions'] == data['target'])/len(data)*100,'%')返回 精度RandomForest_Test (testing_data ,random_forest )

输出:

目标:e
预测:e
<span style="color:#000000"><span style="background-color:#ffdddd">c:\users\tobia\python\lib\site-packages\scipy\stats\stats.py:245: RuntimeWarning: 无法正确检查输入数组的 nan 值。nan 值将被忽略。“值。nan 值将被忽略。”,运行时警告)</span></span>
预测准确率为:88.72476612506155%
88.72476612506155

############################################### ############################################### ########## 
##########画出预测精度相对于树中的随机森林#############数
## ############################################### ############################################### ######## 
import  matplotlib.pyplot  as  plt 
from  matplotlib  import  style
style 。使用('五三十八' )无花果 =  plt 。图( figsize = ( 15 , 10 ))ax0  = 图。add_subplot ( 111 )准确率 =  []对于 i  范围( 1 , 11 , 1 ): random_forest  =  RandomForest_Train ( dataset , i ) accuracy 。追加(RandomForest_Test (testing_data ,random_forest ))对于 i  范围( 10 , 110 , 10 ): random_forest  =  RandomForest_Train ( dataset , i )准确度。追加(RandomForest_Test (testing_data ,random_forest ))对于 i  范围( 100 , 1100 , 100 ): random_forest  =  RandomForest_Train ( dataset , i )精度。追加(RandomForest_Test (testing_data ,random_forest ))打印(准确度)
ax0 。绘图( np . logspace ( 0 , 3 , 30 ),准确度)
ax0 . set_yticks ( np . linspace ( 50 , 100 , 50 ))
ax0 . set_title (“关于随机森林中树木数量的准确性” )
ax0 。set_xscale ( 'log' )
ax0 。set_xlabel (“树的数量” )
ax0 。set_ylabel ( '准确度(%)' )PLT 。显示()

输出:

<span style="color:#000000"><span style="background-color:#ffdddd">c:\users\tobia\python\lib\site-packages\scipy\stats\stats.py:245: RuntimeWarning: 无法正确检查输入数组的 nan 值。nan 值将被忽略。“值。nan 值将被忽略。”,运行时警告)</span></span>
预测准确率为:78.72968980797637%
预测准确率为:76.71097981290005 %
预测准确率为:82.7178729689808%
预测准确率为:92.66371245691778%
预测准确率为:88.13392417528311%
预测准确率为:90.00492368291482%
预测准确率为:89.51255539143278%
预测准确率为:89.51255539143278%
预测准确率为:85.37666174298376%
预测准确率为:88.33087149187593%
预测准确率为:80.20679468242245%
预测准确率为:89.85721319547021%
预测准确率为:89.75873953717381%
预测准确率为:89.561792220581%
预测准确率为:90.15263417035942%
预测准确率为:89.75873953717381%
预测准确率为:92.31905465288035%
预测准确率为:88.87247661250616 %
预测准确率为:90.98966026587888%
预测准确率为:89.36484490398819%
预测准确率为:89.6110290497292%
预测准确率为:89.75873953717381%
预测准确率为:89.6602658788774%
预测准确率为:90.15263417035942%
预测准确率为:89.90645002461841%
预测准确率为:90.15263417035942%
预测准确率为:89.7095027080256%
预测准确率为:90.00492368291482%
预测准确率为:89.51255539143278%
预测准确率为:90.15263417035942%
[78.72968980797637,76.71097981290005,82.7178729689808,92.66371245691778,88.13392417528311,90.00492368291482,89.51255539143278,89.51255539143278,85.37666174298376,88.33087149187593,80.20679468242245,89.85721319547021,89.75873953717381,89.561792220581,90.15263417035942,89.75873953717381,92.31905465288035,88.87247661250616,90.98966026587888,89.36484490398819,89.6110290497292,89.75873953717381,89.6602658788774,90.15263417035942,89.90645002461841 , 90.15263417035942, 89.7095027080256, 90.00492368291482, 89.51255539143278, 90.15263417035942]

鉴于数据集和这种模型,我们实现了大约 90% 的准确率,考虑到我们的模型是“从头开始硬编码”,既不是高度优化的,也不是稳健的随机森林模型,这是相当不错的。我们也没有改变每个分割随机选择的特征数 *m*,这也是一个可以影响预测准确性的参数。
正如我们所看到的,一旦树的数量增长到很大的 n(注意对数缩放的 x 轴),精度曲线就会变平。尽管据说随机森林模型“不能过度拟合数据”,但进一步增加树的数量不会进一步提高模型的准确性。然而,随机森林模型的一个缺点是它们需要相对较长的时间来训练,尤其是在树的数量设置为非常高的情况下。尽管有这个缺点,例如 Caruana 和 Niculescu-Mizil 2006 *(监督学习算法的实证比较)* 表明,与其他监督学习算法相比,随机森林模型通常具有非常好的预测准确性。

使用 sklearn 的随机森林

我们现在将使用预先打包的 sklearn 随机森林分类模型RandomForestClassifier。

 sklearn.ensemble 导入 RandomForestClassifier
 sklearn.preprocessing 导入 LabelEncoder
 sklearn.model_selection 导入 cross_validate#Encode这是字符串整数特征值
 标签 中的 数据集。列:数据集[标签]  =  LabelEncoder () 。适合(数据集[标签])。变换(数据集[标签])X  = 数据集。drop ([ 'target' ], axis = 1 )
Y  =  dataset [ 'target' ]#用 100 棵树和熵作为分割标准
实例化 模型Random_Forest_model =  RandomForestClassifier ( n_estimators = 100 , criteria = "entropy" )#交叉验证
精度 =  cross_validate ( Random_Forest_model , X , Y , cv = 10 )[ 'test_score' ]
print ( '准确度为:' , sum ( accuracy ) / len ( accuracy ) * 100 , '%' )

输出:

准确度为:100.0%

好吧,牛眼!

Python 中的随机森林相关推荐

  1. 预处理--python实现用随机森林评估特征的重要性

    python实现用随机森林评估特征的重要性 随机森林根据森林中所有决策树计算平均不纯度的减少来测量特征的重要性,而不作任何数据是线性可分或不可分的假设. import numpy as np impo ...

  2. 数据分享|Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户...

    原文链接:http://tecdat.cn/?p=23518 项目背景:银行的主要盈利业务靠的是贷款,这些客户中的大多数是存款大小不等的责任客户(存款人).银行拥有不断增长的客户(点击文末" ...

  3. python实现随机抽取答题_如何在python中实现随机选择

    这篇文章主要介绍了如何在python中实现随机选择,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 想从一个序列中随机抽取若干元素,或者想生成几个随机 ...

  4. 集成学习中的随机森林

    摘要:随机森林是集成算法最前沿的代表之一.随机森林是Bagging的升级,它和Bagging的主要区别在于引入了随机特征选择. 本文分享自华为云社区<集成学习中的随机森林>,原文作者:ch ...

  5. python随机生成英文字母_在Python中生成随机字母

    有没有一种方法可以在Python中生成随机字母(如random.randint,但用于字母)? random.randint的范围功能会很好,但是拥有仅输出随机字母的生成器总比没有好. 简单: > ...

  6. python中生成随机整数,随机小数,0-1之间的小数

    python中生成随机整数,随机小数,0-1之间的小数 1.生成随机整数 import randomprint(random.randint(1,100))#生成1到100之间的随机整数 2.生成0- ...

  7. python机器学习-建立随机森林预测模型并特征分析(完整代码+实现效果)

    实现功能: python机器学习-建立随机森林预测模型并特征分析. 实现效果: # 导入需要的库 from warnings import simplefilter simplefilter(acti ...

  8. 在jupytor中运行随机森林预测泰坦尼克旅客生存情况

    在jupytor中运行随机森林预测泰坦尼克旅客生存情况 数据集链接链接: link. 百度网盘:链接: https://pan.baidu.com/s/1_pQ-3iG4dr0hrvU_5hYUtg ...

  9. 欺诈场景中的随机森林实践(基于SAS场景的实现)

    本周,番茄风控发布了关于决策树进行相关的规则探索的内容,如: ①如何做好信贷风控规则的挖掘(实操干货上) ②手把手教你用python实现决策树的策略规则挖掘 以上关于树模型相关的内容,大部分都是用py ...

最新文章

  1. dataframe iloc_DataFrame
  2. QList模板类常用接口函数
  3. tomcat web.xml配置
  4. shell编程详解(一)
  5. html5 video 直播流无声音,【报Bug】html5plus 使用 VideoPlayer 播放部分rtmp没有声音
  6. Head First设计模式读书笔记二 观察者模式
  7. Android 系统(86)---mtk平台上如何开启f2fs
  8. 《云计算:概念、技术与架构》一1.5 书写惯例
  9. [20171113]修改表结构删除列相关问题2.txt
  10. Javascript使用技巧-提高工作效率
  11. 美团监控系统mysql_美团MySQL数据库巡检系统的设计与应用
  12. oracle ebs fa_category_books,FA有用的脚本 - Oracle EBS R12 - ITPUB论坛-中国专业的IT技术社区...
  13. 理解FFT, STFT, 加窗的含义
  14. ubuntu16.04 将火狐浏览器语言设置成中文
  15. 【论文阅读|ICML2020】When Does Self-Supervision Help Graph Convolutional Networks?
  16. 中文作为参数传递乱码
  17. Office WORD WPS如何设置PPT播放全屏
  18. IMX6ULL 主频和时钟配置
  19. docker 阿里云使用记录
  20. 03-NodeMCU引脚和接线、点亮外部LED

热门文章

  1. html 背景图片自动旋转,CSS3 菱形拼图实现只旋转div 背景图片不旋转功能
  2. python的认识PPT
  3. python - 元组,字典,集合
  4. 《石碏大义灭亲(隐公三年、四年)》
  5. 图片格式怎么转换jpg?jpg格式怎么转换?
  6. 简单阐述一下BP的过程?
  7. 互联网架构三板斧之并发
  8. L4 U2 描述他人
  9. 值得收藏的一些HTML、JavaScript、ASP代码
  10. 问卷:单选题的选项转换成1,2,3,4...数值