文章目录

  • 1、决策树简介
  • 2、西瓜数据集的ID3算法实现
    • 2.1、ID3算法简介
    • 2.2、建立决策树
      • 2.2.1、步骤
      • 2.2.2、代码实现
  • 3、西瓜数据集的C4.5算法实现
    • 3.1、C4.5算法简介
    • 3.2、实现过程
  • 3、西瓜数据集的CART算法实现
    • 3.1、CART算法简介
    • 3.2、步骤简叙
    • 3.3、算法实现

1、决策树简介

决策树算法是一种逼近离散函数值的方法。 它是一种典型的 分类方法 ,首先对数据进行处理,利用归纳算法生成可读的规则和决策树,然后使用决策对新数据进行分析。 本质上决策树是通过一系列规则对数据进行分类的过程。其使用算法ID3, C4.5和C5.0生成树算法使用熵。这一度量是基于信息学理论中熵的概念
    决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。

2、西瓜数据集的ID3算法实现

2.1、ID3算法简介

ID3算法是一种贪心算法,用来构造决策树。ID3算法起源于概念学习系统(CLS),以信息熵的下降速度为选取测试属性的标准,即在每个节点选取还尚未被用来划分的具有最高信息增益的属性作为划分标准,然后继续这个过程,直到生成的决策树能完美分类训练样例。

2.2、建立决策树

2.2.1、步骤

进行数据集的导入——>调用函数获取数据——>计算初始信息熵值,即未分类之前的信息熵——>查看初始信息熵——>获取每个特征值的数量,这是为后面计算信息增益做准备——>计算信息增益来确定最好的数据集划分——>判断各个样本集的各个属性是否一致——>绘制决策树(字典)——>调用函数并打印字典决策树——>绘制可视化决策树

2.2.2、代码实现
import numpy as np
import pandas as pd
import math
import collections#导入数据
def import_data():data = pd.read_csv('watermalon.txt')data.head(10)data=np.array(data).tolist()# 特征值列表labels = ['色泽', '根蒂', '敲击', '纹理', '脐部', '触感']# 特征对应的所有可能的情况labels_full = {}for i in range(len(labels)):labelList = [example[i] for example in data]uniqueLabel = set(labelList)labels_full[labels[i]] = uniqueLabelreturn data,labels,labels_full#调用函数获取数据
data,labels,labels_full=import_data()#计算初始的信息熵,就是不分类之前的信息熵值
def calcShannonEnt(dataSet):"""计算给定数据集的信息熵(香农熵):param dataSet::return:"""# 计算出数据集的总数numEntries = len(dataSet)# 用来统计标签labelCounts = collections.defaultdict(int)# 循环整个数据集,得到数据的分类标签for featVec in dataSet:# 得到当前的标签currentLabel = featVec[-1]# # 如果当前的标签不再标签集中,就添加进去(书中的写法)# if currentLabel not in labelCounts.keys():#     labelCounts[currentLabel] = 0## # 标签集中的对应标签数目加一# labelCounts[currentLabel] += 1# 也可以写成如下labelCounts[currentLabel] += 1# 默认的信息熵shannonEnt = 0.0for key in labelCounts:# 计算出当前分类标签占总标签的比例数prob = float(labelCounts[key]) / numEntries# 以2为底求对数shannonEnt -= prob * math.log2(prob)return shannonEnt#查看初始信息熵
print(calcShannonEnt(data)) # 输出为:0.9975025463691153#获取每个特征值的数量,这是为后面计算信息增益做准备
def splitDataSet(dataSet, axis, value):"""按照给定的特征值,将数据集划分:param dataSet: 数据集:param axis: 给定特征值的坐标:param value: 给定特征值满足的条件,只有给定特征值等于这个value的时候才会返回:return:"""# 创建一个新的列表,防止对原来的列表进行修改retDataSet = []# 遍历整个数据集for featVec in dataSet:# 如果给定特征值等于想要的特征值if featVec[axis] == value:# 将该特征值前面的内容保存起来reducedFeatVec = featVec[:axis]# 将该特征值后面的内容保存起来,所以将给定特征值给去掉了reducedFeatVec.extend(featVec[axis + 1:])# 添加到返回列表中retDataSet.append(reducedFeatVec)return retDataSet#计算信息增益来确定最好的数据集划分
def chooseBestFeatureToSplit(dataSet, labels):"""选择最好的数据集划分特征,根据信息增益值来计算:param dataSet::return:"""# 得到数据的特征值总数numFeatures = len(dataSet[0]) - 1# 计算出基础信息熵baseEntropy = calcShannonEnt(dataSet)# 基础信息增益为0.0bestInfoGain = 0.0# 最好的特征值bestFeature = -1# 对每个特征值进行求信息熵for i in range(numFeatures):# 得到数据集中所有的当前特征值列表featList = [example[i] for example in dataSet]# 将当前特征唯一化,也就是说当前特征值中共有多少种uniqueVals = set(featList)# 新的熵,代表当前特征值的熵newEntropy = 0.0# 遍历现在有的特征的可能性for value in uniqueVals:# 在全部数据集的当前特征位置上,找到该特征值等于当前值的集合subDataSet = splitDataSet(dataSet=dataSet, axis=i, value=value)# 计算出权重prob = len(subDataSet) / float(len(dataSet))# 计算出当前特征值的熵newEntropy += prob * calcShannonEnt(subDataSet)# 计算出“信息增益”infoGain = baseEntropy - newEntropy#print('当前特征值为:' + labels[i] + ',对应的信息增益值为:' + str(infoGain)+"i等于"+str(i))#如果当前的信息增益比原来的大if infoGain > bestInfoGain:# 最好的信息增益bestInfoGain = infoGain# 新的最好的用来划分的特征值bestFeature = i#print('信息增益最大的特征为:' + labels[bestFeature])return bestFeature#判断各个样本集的各个属性是否一致
def judgeEqualLabels(dataSet):"""判断数据集的各个属性集是否完全一致:param dataSet::return:"""# 计算出样本集中共有多少个属性,最后一个为类别feature_leng = len(dataSet[0]) - 1# 计算出共有多少个数据data_leng = len(dataSet)# 标记每个属性中第一个属性值是什么first_feature = ''# 各个属性集是否完全一致is_equal = True# 遍历全部属性for i in range(feature_leng):# 得到第一个样本的第i个属性first_feature = dataSet[0][i]# 与样本集中所有的数据进行对比,看看在该属性上是否都一致for _ in range(1, data_leng):# 如果发现不相等的,则直接返回Falseif first_feature != dataSet[_][i]:return Falsereturn is_equal#绘制决策树(字典)
def createTree(dataSet, labels):"""创建决策树:param dataSet: 数据集:param labels: 特征标签:return:"""# 拿到所有数据集的分类标签classList = [example[-1] for example in dataSet]# 统计第一个标签出现的次数,与总标签个数比较,如果相等则说明当前列表中全部都是一种标签,此时停止划分if classList.count(classList[0]) == len(classList):return classList[0]# 计算第一行有多少个数据,如果只有一个的话说明所有的特征属性都遍历完了,剩下的一个就是类别标签,或者所有的样本在全部属性上都一致if len(dataSet[0]) == 1 or judgeEqualLabels(dataSet):# 返回剩下标签中出现次数较多的那个return majorityCnt(classList)# 选择最好的划分特征,得到该特征的下标bestFeat = chooseBestFeatureToSplit(dataSet=dataSet, labels=labels)print(bestFeat)# 得到最好特征的名称bestFeatLabel = labels[bestFeat]print(bestFeatLabel)# 使用一个字典来存储树结构,分叉处为划分的特征名称myTree = {bestFeatLabel: {}}# 将本次划分的特征值从列表中删除掉del(labels[bestFeat])# 得到当前特征标签的所有可能值featValues = [example[bestFeat] for example in dataSet]# 唯一化,去掉重复的特征值uniqueVals = set(featValues)# 遍历所有的特征值for value in uniqueVals:# 得到剩下的特征标签subLabels = labels[:]subTree = createTree(splitDataSet(dataSet=dataSet, axis=bestFeat, value=value), subLabels)# 递归调用,将数据集中该特征等于当前特征值的所有数据划分到当前节点下,递归调用时需要先将当前的特征去除掉myTree[bestFeatLabel][value] = subTreereturn myTree#调用函数并打印,就可以看到一个字典类型的树了
mytree=createTree(data,labels)
print(mytree)#绘制可视化树
import matplotlib.pylab as plt
import matplotlib# 能够显示中文
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.serif'] = ['SimHei']# 分叉节点,也就是决策节点
decisionNode = dict(boxstyle="sawtooth", fc="0.8")# 叶子节点
leafNode = dict(boxstyle="round4", fc="0.8")# 箭头样式
arrow_args = dict(arrowstyle="<-")def plotNode(nodeTxt, centerPt, parentPt, nodeType):"""绘制一个节点:param nodeTxt: 描述该节点的文本信息:param centerPt: 文本的坐标:param parentPt: 点的坐标,这里也是指父节点的坐标:param nodeType: 节点类型,分为叶子节点和决策节点:return:"""createPlot.ax1.annotate(nodeTxt, xy=parentPt, xycoords='axes fraction',xytext=centerPt, textcoords='axes fraction',va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)def getNumLeafs(myTree):"""获取叶节点的数目:param myTree::return:"""# 统计叶子节点的总数numLeafs = 0# 得到当前第一个key,也就是根节点firstStr = list(myTree.keys())[0]# 得到第一个key对应的内容secondDict = myTree[firstStr]# 递归遍历叶子节点for key in secondDict.keys():# 如果key对应的是一个字典,就递归调用if type(secondDict[key]).__name__ == 'dict':numLeafs += getNumLeafs(secondDict[key])# 不是的话,说明此时是一个叶子节点else:numLeafs += 1return numLeafsdef getTreeDepth(myTree):"""得到数的深度层数:param myTree::return:"""# 用来保存最大层数maxDepth = 0# 得到根节点firstStr = list(myTree.keys())[0]# 得到key对应的内容secondDic = myTree[firstStr]# 遍历所有子节点for key in secondDic.keys():# 如果该节点是字典,就递归调用if type(secondDic[key]).__name__ == 'dict':# 子节点的深度加1thisDepth = 1 + getTreeDepth(secondDic[key])# 说明此时是叶子节点else:thisDepth = 1# 替换最大层数if thisDepth > maxDepth:maxDepth = thisDepthreturn maxDepthdef plotMidText(cntrPt, parentPt, txtString):"""计算出父节点和子节点的中间位置,填充信息:param cntrPt: 子节点坐标:param parentPt: 父节点坐标:param txtString: 填充的文本信息:return:"""# 计算x轴的中间位置xMid = (parentPt[0]-cntrPt[0])/2.0 + cntrPt[0]# 计算y轴的中间位置yMid = (parentPt[1]-cntrPt[1])/2.0 + cntrPt[1]# 进行绘制createPlot.ax1.text(xMid, yMid, txtString)def plotTree(myTree, parentPt, nodeTxt):"""绘制出树的所有节点,递归绘制:param myTree: 树:param parentPt: 父节点的坐标:param nodeTxt: 节点的文本信息:return:"""# 计算叶子节点数numLeafs = getNumLeafs(myTree=myTree)# 计算树的深度depth = getTreeDepth(myTree=myTree)# 得到根节点的信息内容firstStr = list(myTree.keys())[0]# 计算出当前根节点在所有子节点的中间坐标,也就是当前x轴的偏移量加上计算出来的根节点的中心位置作为x轴(比如说第一次:初始的x偏移量为:-1/2W,计算出来的根节点中心位置为:(1+W)/2W,相加得到:1/2),当前y轴偏移量作为y轴cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)# 绘制该节点与父节点的联系plotMidText(cntrPt, parentPt, nodeTxt)# 绘制该节点plotNode(firstStr, cntrPt, parentPt, decisionNode)# 得到当前根节点对应的子树secondDict = myTree[firstStr]# 计算出新的y轴偏移量,向下移动1/D,也就是下一层的绘制y轴plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD# 循环遍历所有的keyfor key in secondDict.keys():# 如果当前的key是字典的话,代表还有子树,则递归遍历if isinstance(secondDict[key], dict):plotTree(secondDict[key], cntrPt, str(key))else:# 计算新的x轴偏移量,也就是下个叶子绘制的x轴坐标向右移动了1/WplotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW# 打开注释可以观察叶子节点的坐标变化# print((plotTree.xOff, plotTree.yOff), secondDict[key])# 绘制叶子节点plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)# 绘制叶子节点和父节点的中间连线内容plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))# 返回递归之前,需要将y轴的偏移量增加,向上移动1/D,也就是返回去绘制上一层的y轴plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalDdef createPlot(inTree):"""需要绘制的决策树:param inTree: 决策树字典:return:"""# 创建一个图像fig = plt.figure(1, facecolor='white')fig.clf()axprops = dict(xticks=[], yticks=[])createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)# 计算出决策树的总宽度plotTree.totalW = float(getNumLeafs(inTree))# 计算出决策树的总深度plotTree.totalD = float(getTreeDepth(inTree))# 初始的x轴偏移量,也就是-1/2W,每次向右移动1/W,也就是第一个叶子节点绘制的x坐标为:1/2W,第二个:3/2W,第三个:5/2W,最后一个:(W-1)/2WplotTree.xOff = -0.5/plotTree.totalW# 初始的y轴偏移量,每次向下或者向上移动1/DplotTree.yOff = 1.0# 调用函数进行绘制节点图像plotTree(inTree, (0.5, 1.0), '')# 绘制plt.show()if __name__ == '__main__':createPlot(mytree)


    图中第一行数字为初始信息熵:0.9975025463691153
    中间为字典决策树
    最下面为可视化决策树

但是这里树少了一些标签,我们可以补全树之后再次输出

def makeTreeFull(myTree, labels_full, default):"""将树中的不存在的特征标签进行补全,补全为父节点中出现最多的类别:param myTree: 生成的树:param labels_full: 特征的全部标签:param parentClass: 父节点中所含最多的类别:param default: 如果缺失标签中父节点无法判断类别则使用该值:return:"""# 这里所说的父节点就是当前根节点,把当前根节点下不存在的特征标签作为子节点# 拿到当前的根节点root_key = list(myTree.keys())[0]# 拿到根节点下的所有分类,可能是子节点(好瓜or坏瓜)也可能不是子节点(再次划分的属性值)sub_tree = myTree[root_key]# 如果是叶子节点就结束if isinstance(sub_tree, str):return# 找到使用当前节点分类下最多的种类,该分类结果作为新特征标签的分类,如:色泽下面没有浅白则用色泽中有的青绿分类作为浅白的分类root_class = []# 把已经分好类的结果记录下来for sub_key in sub_tree.keys():if isinstance(sub_tree[sub_key], str):root_class.append(sub_tree[sub_key])# 找到本层出现最多的类别,可能会出现相同的情况取其一if len(root_class):most_class = collections.Counter(root_class).most_common(1)[0][0]else:most_class = None# 当前节点下没有已经分类好的属性# print(most_class)# 循环遍历全部特征标签,将不存在标签添加进去for label in labels_full[root_key]:if label not in sub_tree.keys():if most_class is not None:sub_tree[label] = most_classelse:sub_tree[label] = default# 递归处理for sub_key in sub_tree.keys():if isinstance(sub_tree[sub_key], dict):makeTreeFull(myTree=sub_tree[sub_key], labels_full=labels_full, default=default)
makeTreeFull(mytree,labels_full,default='未知')
createPlot(mytree)

完整的决策树

3、西瓜数据集的C4.5算法实现

3.1、C4.5算法简介

C4.5算法是由Ross Quinlan开发的用于产生决策树的算法。该算法是对Ross Quinlan之前开发的ID3算法的一个扩展。C4.5算法产生的决策树可以被用作分类目的,因此该算法也可以用于统计分类。
    C4.5算法与ID3算法一样使用了信息熵的概念,并和ID3一样通过学习数据来建立决策树。

3.2、实现过程

C4.5算法和ID3算法区别不是非常大,所以在这里直接在计算信息增益后面加一个计算信息增益率的函数即可

def chooseBestFeatureToSplit_4(dataSet, labels):"""选择最好的数据集划分特征,根据信息增益值来计算:param dataSet::return:"""# 得到数据的特征值总数numFeatures = len(dataSet[0]) - 1# 计算出基础信息熵baseEntropy = calcShannonEnt(dataSet)# 基础信息增益为0.0bestInfoGain = 0.0# 最好的特征值bestFeature = -1# 对每个特征值进行求信息熵for i in range(numFeatures):# 得到数据集中所有的当前特征值列表featList = [example[i] for example in dataSet]# 将当前特征唯一化,也就是说当前特征值中共有多少种uniqueVals = set(featList)# 新的熵,代表当前特征值的熵newEntropy = 0.0# 遍历现在有的特征的可能性for value in uniqueVals:# 在全部数据集的当前特征位置上,找到该特征值等于当前值的集合subDataSet = splitDataSet(dataSet=dataSet, axis=i, value=value)# 计算出权重prob = len(subDataSet) / float(len(dataSet))# 计算出当前特征值的熵newEntropy += prob * calcShannonEnt(subDataSet)# 计算出“信息增益”infoGain = baseEntropy - newEntropyinfoGain = infoGain/newEntropy#print('当前特征值为:' + labels[i] + ',对应的信息增益值为:' + str(infoGain)+"i等于"+str(i))#如果当前的信息增益比原来的大if infoGain > bestInfoGain:# 最好的信息增益bestInfoGain = infoGain# 新的最好的用来划分的特征值bestFeature = i#print('信息增益最大的特征为:' + labels[bestFeature])return bestFeature

然后查看字典决策树
mytree_4=createTree_4(data,labels) print(mytree_4)

同样的方法补齐决策树之后查看可视化决策树

3、西瓜数据集的CART算法实现

3.1、CART算法简介

CART算法是一种二分递归分割技术,把当前样本划分为两个子样本,使得生成的每个非叶子结点都有两个分支,因此CART算法生成的决策树是结构简洁的二叉树。由于CART算法构成的是一个二叉树,它在每一步的决策时只能是“是”或者“否”,即使一个feature有多个取值,也是把数据分为两部分。

3.2、步骤简叙

首先选一个自变量,再选取的一个值,把维空间划分为两部分,一部分的所有点都满足,另一部分的所有点都满足,对非连续变量来说属性值的取值只有两个,即等于该值或不等于该值。
    然后递归处理,将上面得到的两部分按步骤一重新选取一个属性继续划分,直到把整个维空间都划分完。在划分时候有一个问题,它是按照什么标准来划分的 ? 对于一个变量属性来说,它的划分点是一对连续变量属性值的中点。假设个样本的集合一个属性有个连续的值,那么则会有个分裂点,每个分裂点为相邻两个连续值的均值。每个属性的划分按照能减少的杂质的量来进行排序,而杂质的减少量定义为划分前的杂质减去划分后的每个节点的杂质量划分所占比率之和。而杂质度量方法常用Gini指标,假设一个样本共有类,那么一个节点的Gini不纯度可定义为

其中pi表示属于第i类的概率,当Gini(A)=0时,所有样本属于同类,所有类在节点中以等概率出现时,Gini(A)最大化,此时Pi 有了上述理论基础,实际的递归划分过程是这样的:如果当前节点的所有样本都不属于同一类或者只剩下一个样本,那么此节点为非叶子节点,所以会尝试样本的每个属性以及每个属性对应的分裂点,尝试找到杂质变量最大的一个划分,该属性划分的子树即为最优分支

3.3、算法实现

首先读取西瓜数据集的数据

import pandas as pd
import numpy as np
from sklearn import tree
import graphviz
df = pd.read_csv('watermalon.txt')
df.head(10)

然后将特征值数字化

df['色泽']=df['色泽'].map({'浅白':1,'青绿':2,'乌黑':3})
df['根蒂']=df['根蒂'].map({'稍蜷':1,'蜷缩':2,'硬挺':3})
df['敲声']=df['敲声'].map({'清脆':1,'浊响':2,'沉闷':3})
df['纹理']=df['纹理'].map({'清晰':1,'稍糊':2,'模糊':3})
df['脐部']=df['脐部'].map({'平坦':1,'稍凹':2,'凹陷':3})
df['触感'] = np.where(df['触感']=="硬滑",1,2)
df['好瓜'] = np.where(df['好瓜']=="是",1,0)
x_train=df[['色泽','根蒂','敲声','纹理','脐部','触感']]
y_train=df['好瓜']

训练得到树,并且进行可视化输出

# 构建模型并训练
gini=tree.DecisionTreeClassifier()
gini=gini.fit(x_train,y_train)
#实现决策树的可视化
gini_data = tree.export_graphviz(gini
,feature_names=labels
,class_names=["好瓜","坏瓜"]
,filled=True
,rounded=True
)
gini_graph = graphviz.Source(gini_data)
gini_graph


参考:https://blog.csdn.net/junseven164/article/details/120972814

使用决策树算法预测西瓜的好坏相关推荐

  1. 【实用算法教学】——教你使用决策树算法预测NBA获胜球队

    本文介绍一种分类算法--决策树,用它预测NBA篮球赛的获胜球队.比起其他算法,决 策树有很多优点,其中最主要的一个优点是决策过程是机器和人都能看懂的,我们使用机器学习 到的模型就能完成预测任务.正如我 ...

  2. Python中应用决策树算法预测客户等级

    ​机器学习越来越多地在企业应用,本文跟大家分享一个采用python,应用决策树算法对跨国食品超市顾客等级进行预测的具体案例.如果想先行了解决策树算法原理,可以阅读文章决策树-ID3算法和C4.5算法. ...

  3. 决策树算法预测NBA赛事结果

    决策树算法介绍 决策树(decision tree)是一个树结构(可以是二叉树或非二叉树). 其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类 ...

  4. 5-2 决策树算法预测销量高低代码

    #-*- coding: utf-8 -*- import pandas as pdinputfile = '../data/sales_data.xls' data = pd.read_excel( ...

  5. 原理+代码|深入浅出决策树算法

    大家好,我是芒果,近期在工作场景中使用了决策树分类算法,对决策树算法的原理和实战又重新复习了一下,于是就有了这篇文章- 决策树也是经典的机器学习算法之一,在这里挖个坑,希望后续有机会能继续写随机森林. ...

  6. 浅谈决策树算法以及matlab实现ID3算法

    决策树方法在分类.预测.规则提取等领域有着广泛的应用.在20世纪70年代后期和80年代初期,机器学习研究者J.Ross Quinilan提出了ID3算法以后,决策树在机器学习.数据挖掘领域得到极大的发 ...

  7. scikit-learn决策树算法(鸢尾花数据集、餐饮饭店销量)

    文章目录 实验三.scikit-learn决策树算法 一.实验目的 1. 熟悉掌握决策树的原理 2. 使用scikit-learn库中的对应函数实现决策树分类. 二.能力图谱 三.实验工具 1. An ...

  8. 机器学习算法——决策树算法详细介绍,并使用sklearn实现案例预测,可视化决策树

    目录 一.决策树算法简介 二.决策树分类原理 1.熵 1.1 概念 1.2 案例 2.决策树的划分依据一:信息增益 2.1 概念 2.2 案例: 3.决策树的划分依据二:信息增益率 3.1 概念 3. ...

  9. 房价预测(基于决策树算法)

    预测波士顿房价 第一步. 导入数据 在这个项目中,将使用波士顿房屋信息数据来训练和测试一个模型,并对模型的性能和预测能力进行评估.我们希望可以通过该模型实现对房屋的价值预估,提高房地产经纪人的工作效率 ...

最新文章

  1. 好程序员web前端分享值得参考的css理论:OOCSS、SMACSS与BEM
  2. python html 语法高亮,在Python中使用doxygen样式文档字符串的Vim语法高亮显示
  3. colpick-jQuery颜色选择器使用说明
  4. am335x LCD参数更改
  5. 【ABAP】SAP供应商自定义决裁生成实现
  6. lintcode:形状工厂
  7. 2 安装失败_写bug日记2:PYTORCH GEOMETRIC安装失败的问题(未解决)
  8. 架构设计:文件服务的设计与实现
  9. 将 .qrc文件转换成 .py文件的解决方法
  10. recv( )函数返回值说明
  11. A8板卡AM3352移植环境搭建记录
  12. AIR202/208使用AT指令方式连接MQTT调试笔记
  13. 在线html5行情,Html5版本的全套股票行情图
  14. 用python打开文件然后写个欢迎代码
  15. linux 修改 bcast,Linux下修改MAC地址
  16. flowchart流程图编程语言下载_flowchart.net
  17. 关于 Alpine Docker 镜像漏洞 CVE-2019-5021
  18. oracle登陆不了账号被锁定,轻松解决数据库账号被锁定问题
  19. gm 1 n 模型matlab,灰色预测模型GM1,n模型的matlab源...
  20. 抗TNF治疗改变JIA患者PBMC基因表达谱,可预测疗效

热门文章

  1. 新西兰公民在中国大陆境内在线申请护照注意事项
  2. Linux: meld软件使用
  3. 微服务项目实战-易买网网页(电商)二、MybatisPlus与微服务注册
  4. 量子点太阳能电池《一》
  5. 浏览记录-history
  6. 关于软件定时器的一些讨论
  7. git上传到阿里云code
  8. 医依通小程序项目总结
  9. 传手机ODM厂商拿到三星大单 将带动产业链走出寒冬?
  10. OpenGL第十讲——像素图