决策树(Decision Tree,DT)

文章目录

    • 1. 决策树模型与学习
    • 2. 特征选择
      • 2.1 特征选择Python代码
    • 3. 决策树的生成
      • 3.1 Python代码
    • 4. 决策树的剪枝
    • 5. CART 算法
    • 6. sklearn 例子
      • 6.1 书上贷款例子
      • 6.2 鸢尾花 及 决策树可视化
    • 附. 本文完整代码

决策树(decision tree)是一种基本的分类与回归方法。

  • 分类问题中,基于特征对实例进行分类的过程。
  • 优点:模型具有可读性,分类速度快。
  • 学习:利用训练数据,根据损失函数最小化的原则建立决策树模型。
  • 预测:对新的数据,利用决策树模型进行分类。

决策树学习通常包括3个步骤:特征选择决策树生成决策树修剪

Quinlan在1986年提出的ID3算法、1993年提出的C4.5算法
Breiman等人在1984年提出的CART算法

1. 决策树模型与学习

决策树由结点(node)和有向边(directed edge)组成。

  • 内部结点(internal node)和叶结点(leaf node)。
  • 内部结点表示一个特征或属性,结点表示一个
  • 用决策树分类,从根结点开始,对实例的某一特征进行测试,根据测试结果,将实例分配到其子结点;这时,每一个子结点对应着该特征的一个取值。
  • 递归地对实例进行测试并分配,直至达到叶结点。最后将实例分到叶结点的类中。
    在这里插入图片描述

决策树学习本质:从训练数据集中归纳出一组分类规则。

  • 需要一个与训练数据矛盾较小的决策树,同时具有很好的泛化能力。
  • 决策树学习的损失函数:通常是正则化的极大似然函数。
  • 决策树学习的策略:损失函数为目标函数的最小化。

2. 特征选择

决策树训练时高度太高,对训练数据准确率高,但泛化能力差,需要剪枝。

常用的准则

(1)样本集合DDD对特征AAA信息增益(ID3)

g(D,A)=H(D)−H(D∣A)g(D, A)=H(D)-H(D|A)g(D,A)=H(D)H(DA)

H(D)=−∑k=1K∣Ck∣∣D∣log⁡2∣Ck∣∣D∣H(D)=-\sum_{k=1}^{K} \frac{\left|C_{k}\right|}{|D|} \log _{2} \frac{\left|C_{k}\right|}{|D|}H(D)=k=1KDCklog2DCk

H(D∣A)=∑i=1n∣Di∣∣D∣H(Di)H(D | A)=\sum_{i=1}^{n} \frac{\left|D_{i}\right|}{|D|} H\left(D_{i}\right)H(DA)=i=1nDDiH(Di)

其中,H(D)H(D)H(D)是数据集DDD的熵,H(Di)H(D_i)H(Di)是数据集DiD_iDi的熵,H(D∣A)H(D|A)H(DA)是数据集DDD对特征AAA的条件熵。 DiD_iDiDDD中特征AAA取第iii个值的样本子集,CkC_kCkDDD中属于第kkk类的样本子集。nnn是特征AAA取值的个数,KKK是类的个数。

  • 熵越大,随机变量的不确定性就越大
  • 信息增益(information gain)表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。
  • 选择信息增益 大的

(2)样本集合DDD对特征AAA信息增益比(C4.5)

gR(D,A)=g(D,A)HA(D)g_{R}(D, A)=\frac{g(D, A)}{H_A(D)}gR(D,A)=HA(D)g(D,A)

其中,g(D,A)g(D,A)g(D,A)是信息增益,HA(D)H_A(D)HA(D)是数据集DDD关于特征AAA的熵。

(3)样本集合DDD 基尼指数(CART)

Gini⁡(D)=1−∑k=1K(∣Ck∣∣D∣)2\operatorname{Gini}(D)=1-\sum_{k=1}^{K}\left(\frac{\left|C_{k}\right|}{|D|}\right)^{2}Gini(D)=1k=1K(DCk)2

特征AAA条件下集合DDD的基尼指数:

Gini⁡(D,A)=∣D1∣∣D∣Gini⁡(D1)+∣D2∣∣D∣Gini⁡(D2)\operatorname{Gini}(D, A)=\frac{\left|D_{1}\right|}{|D|} \operatorname{Gini}\left(D_{1}\right)+\frac{\left|D_{2}\right|}{|D|} \operatorname{Gini}\left(D_{2}\right)Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)

  • 基尼指数表示集合D的不确定性,基尼指数 Gini(D,A)Gini(D,A)Gini(D,A) 表示经A=aA=aA=a分割后集合DDD的不确定性。
  • 基尼指数值越大,样本集合的不确定性也就越大,这一点与熵相似。
  • 选择 基尼指数 小的

2.1 特征选择Python代码

def get_data():datasets = [['青年', '否', '否', '一般', '否'],['青年', '否', '否', '好', '否'],['青年', '是', '否', '好', '是'],['青年', '是', '是', '一般', '是'],['青年', '否', '否', '一般', '否'],['中年', '否', '否', '一般', '否'],['中年', '否', '否', '好', '否'],['中年', '是', '是', '好', '是'],['中年', '否', '是', '非常好', '是'],['中年', '否', '是', '非常好', '是'],['老年', '否', '是', '非常好', '是'],['老年', '否', '是', '好', '是'],['老年', '是', '否', '好', '是'],['老年', '是', '否', '非常好', '是'],['老年', '否', '否', '一般', '否'],]labels = [u'年龄', u'有工作', u'有自己的房子', u'信贷情况', u'分类']# 字符串前加 u, 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止乱码return datasets, labels;
# ---------书上贷款例子-----------------
datasets, labels = get_data()def cal_entropy(datasets):  # 经验熵H(D)data_len = len(datasets)label_count = {}for i in range(data_len):label = datasets[i][-1]if label not in label_count:label_count[label] = 0label_count[label] += 1entropy = -sum([(p / data_len) * log(p / data_len, 2) for p in label_count.values()])return entropydef cond_entropy(datasets, axis=0):  # 经验条件熵H(D|A)data_len = len(datasets)feature_set = {}for i in range(data_len):feature = datasets[i][axis]if feature not in feature_set:feature_set[feature] = []feature_set[feature].append(datasets[i])cond_ent = sum([(len(p) / data_len) * cal_entropy(p) for p in feature_set.values()])return cond_entdef info_gain(entropy, cond_ent):  # 信息增益return entropy - cond_entdef info_gain_train(datasets):	# 基于特征信息增益的特征选择count = len(datasets[0]) - 1entropy = cal_entropy(datasets)best_feature = []for i in range(count):info_gain_i = info_gain(entropy, cond_entropy(datasets, axis=i))best_feature.append((i, info_gain_i))print("特征({})- info_gain - {:.3f}".format(labels[i], info_gain_i))best_feature_i = max(best_feature, key=lambda x: x[-1])print("特征({})的信息增益最大,选为根节点的特征".format(labels[best_feature_i[0]]))info_gain_train(np.array(datasets))
特征(年龄)- info_gain - 0.083
特征(有工作)- info_gain - 0.324
特征(有自己的房子)- info_gain - 0.420
特征(信贷情况)- info_gain - 0.363
特征(有自己的房子)的信息增益最大,选为根节点的特征

3. 决策树的生成

通常使用信息增益最大、信息增益比最大或基尼指数最小作为特征选择的准则。

决策树的生成往往通过计算信息增益或其他指标,从根结点开始,递归地产生决策树。
这相当于用信息增益或其他准则不断地选取局部最优的特征,或将训练集分割为能够基本正确分类的子集。

  • ID3算法只有树的生成,所以该算法生成的树容易产生过拟合
  • C4.5算法与ID3算法相似,进行了改进。C4.5在生成的过程中,用信息增益比来选择特征。

3.1 Python代码

class Node():def __init__(self, root=True, label=None, feature_name=None, feature=None):self.root = rootself.label = labelself.feature_name = feature_nameself.feature = featureself.tree = {}self.result = {'label:': self.label,'feature:': self.feature,'tree:': self.tree}def __repr__(self):  # 类似str方法,更侧重程序员调试print('{}'.format(self.result))def add_node(self, val, node):self.tree[val] = nodedef predict(self, features):if self.root is True:return self.labelreturn self.tree[features[self.feature]].predict(features)class DTree():def __init__(self, epsilon=0.1):  # 信息增益阈值, < epsilon 时,结束决策树展开self.epsilon = epsilonself._tree = {}@staticmethoddef cal_entropy(datasets):  # 经验熵H(D)data_len = len(datasets)label_count = {}for i in range(data_len):label = datasets[i][-1]if label not in label_count:label_count[label] = 0label_count[label] += 1entropy = -sum([(p / data_len) * log(p / data_len, 2) for p in label_count.values()])return entropydef cond_entropy(self, datasets, axis=0):  # 经验条件熵H(D|A)data_len = len(datasets)feature_set = {}for i in range(data_len):feature = datasets[i][axis]if feature not in feature_set:feature_set[feature] = []feature_set[feature].append(datasets[i])cond_ent = sum([(len(p) / data_len) * self.cal_entropy(p) for p in feature_set.values()])return cond_ent@staticmethoddef info_gain(entropy, cond_ent):  # 信息增益return entropy - cond_entdef info_gain_train(self, datasets):  # 基于特征信息增益的特征选择count = len(datasets[0]) - 1entropy = self.cal_entropy(datasets)best_feature = []for i in range(count):info_gain_i = info_gain(entropy, cond_entropy(datasets, axis=i))best_feature.append((i, info_gain_i))print("特征({})- info_gain - {:.3f}".format(labels[i], info_gain_i))best_feature_i = max(best_feature, key=lambda x: x[-1])return best_feature_idef train(self, train_data):''':input: 数据集D(DataFrame格式),特征集A,阈值eta:return: 决策树DT'''_, y_train, features = train_data.iloc[:, :-1], train_data.iloc[:, -1], train_data.columns[:-1]# 1. 若所有D实例都属于同一分类,不用分了,直接返回那个类if len(y_train.value_counts()) == 1:return Node(root=True, label=y_train.iloc[0])# 2. 若没有特征A,返回D中数量最多的分类if len(features) == 0:return Node(root=True, label=y_train.value_counts().sort_values(ascending=False).index[0])# 3. 计算最大信息增益,取为特征max_feature, max_info_gain = self.info_gain_train(np.array(train_data))max_feature_name = features[max_feature]# 4. 如果信息增益小于阈值epsilon,置为单节点,将实例数最大的类作为节点标记if max_info_gain < self.epsilon:return Node(root=True, label=y_train.value_counts().sort_values(ascending=False).index[0])# 5. 构建Ag子集node_tree = Node(root=False, feature_name=max_feature_name, feature=max_feature)feature_list = train_data[max_feature_name].value_counts().indexfor f in feature_list:sub_train_df = train_data.loc[train_data[max_feature_name] == f].drop([max_feature_name], axis=1)# 6. 递归生成树sub_tree = self.train(sub_train_df)node_tree.add_node(f, sub_tree)return node_treedef fit(self, train_data):self._tree = self.train(train_data)return self._treedef predict(self, X_test):return self._tree.predict(X_test)train_data = pd.DataFrame(datasets, columns=labels)
dt = DTree()
tree = dt.fit(train_data)
print(dt.predict(['老年', '否', '否', '一般']))
print(dt.predict(['青年', '否', '是', '一般']))
print(dt.predict(['中年', '是', '否', '好']))
print(dt.predict(['老年', '否', '是', '一般']))

4. 决策树的剪枝

学习时,过多考虑准确性,树复杂,过拟合,泛化能力差,需要剪枝。

方法:极小化决策树整体损失函数

5. CART 算法

分类与回归树(classification and regression tree,CART)模型

  • 二叉树
  • 左分支,是;右分支,否
  • (1)决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大;
    (2)决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,这时用损失函数最小作为剪枝的标准。

6. sklearn 例子

sklearn.tree.DecisionTreeClassifier

class sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='best',max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None,class_weight=None, presort='deprecated', ccp_alpha=0.0)
  • 特征选择标准:
criterion{“gini”, “entropy”}, default=”gini”
  • 择优划分、树的最大深度、最小划分几类、叶子节点个数等参数

6.1 书上贷款例子

# ---------书上贷款例子-----------------
datasets, labels = get_data()
train_data = np.array(pd.DataFrame(datasets, columns=labels))
X_train, y_train = train_data[:, :-1], train_data[:, -1:]
encoder = preprocessing.OrdinalEncoder()    # 将字符转成浮点
encoder.fit(X_train)    # 先拟合
X_train = encoder.transform(X_train)    # 转换成数字
A = encoder.transform([['青年', '否', '是', '一般']])
B = encoder.transform([['中年', '是', '否', '好']])
C = encoder.transform([['老年', '否', '是', '一般']])encoder = preprocessing.OrdinalEncoder()
encoder.fit(y_train)
y_train = encoder.transform(y_train)
# sklearn 决策树
clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
print(encoder.inverse_transform([clf.predict(A)]))
print(clf.predict_proba(B))
print(clf.predict_proba(C))
[['是']]
[[0. 1.]]
[[0. 1.]]

6.2 鸢尾花 及 决策树可视化

# ------------鸢尾花---------------
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
data = np.array(df.iloc[:100, [0, 1, -1]])
X = data[:, :2]
y = data[:, -1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
clf = DecisionTreeClassifier()
print(clf)
clf.fit(X_train, y_train)
print(clf.score(X_test, y_test))# --------------决策树可视化-------------
# 需要安装graphviz,添加path,可视化决策树
with open('mytree.dot', 'w', encoding='utf-8') as f:dot_data = export_graphviz(clf, out_file=None, feature_names=df.columns[:2],filled=True, rounded=True, special_characters=True, class_names=iris.target_names[0:2])
dot = graphviz.Source(dot_data)
dot.view()
# 写入png , pdf
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png('tree.png')
# cmd: dot -Tpdf tree.dot -o output.pdf,dot -Tpng tree.dot -o output.png

决策树可视化
在这里插入图片描述

附. 本文完整代码

# -*- coding:utf-8 -*-
# @Python Version: 3.7
# @Time: 2020/3/13 19:36
# @Author: Michael Ming
# @Website: https://michael.blog.csdn.net/
# @File: 5.decisionTree.py
# @Reference: https://github.com/fengdu78/lihang-codeimport pandas as pd
import numpy as np
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from collections import Counter
import math
from math import log
import pprint
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import graphviz
import pydotplusdef get_data():datasets = [['青年', '否', '否', '一般', '否'],['青年', '否', '否', '好', '否'],['青年', '是', '否', '好', '是'],['青年', '是', '是', '一般', '是'],['青年', '否', '否', '一般', '否'],['中年', '否', '否', '一般', '否'],['中年', '否', '否', '好', '否'],['中年', '是', '是', '好', '是'],['中年', '否', '是', '非常好', '是'],['中年', '否', '是', '非常好', '是'],['老年', '否', '是', '非常好', '是'],['老年', '否', '是', '好', '是'],['老年', '是', '否', '好', '是'],['老年', '是', '否', '非常好', '是'],['老年', '否', '否', '一般', '否'],]labels = [u'年龄', u'有工作', u'有自己的房子', u'信贷情况', u'分类']# 字符串前加 u, 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止乱码return datasets, labels;# ---------书上贷款例子-----------------
datasets, labels = get_data()
train_data = np.array(pd.DataFrame(datasets, columns=labels))
X_train, y_train = train_data[:, :-1], train_data[:, -1:]
encoder = preprocessing.OrdinalEncoder()  # 将字符转成浮点
encoder.fit(X_train)  # 先拟合
X_train = encoder.transform(X_train)  # 转换成数字
A = encoder.transform([['青年', '否', '是', '一般']])
B = encoder.transform([['中年', '是', '否', '好']])
C = encoder.transform([['老年', '否', '是', '一般']])encoder = preprocessing.OrdinalEncoder()
encoder.fit(y_train)
y_train = encoder.transform(y_train)
# sklearn 决策树
clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
print(encoder.inverse_transform([clf.predict(A)]))
print(clf.predict_proba(B))
print(clf.predict_proba(C))# --------------决策树可视化-------------
# 需要安装graphviz,添加path,可视化决策树
with open('mytree.dot', 'w', encoding='utf-8') as f:dot_data = export_graphviz(clf, out_file=None, feature_names=clf.feature_importances_,filled=True, rounded=True, special_characters=True)
dot = graphviz.Source(dot_data)
# dot.view()
# 写入png , pdf
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png('tree.png')# cmd: dot -Tpdf tree.dot -o output.pdf,dot -Tpng tree.dot -o output.png# -----------自编程,抄一遍---------------
# ----特征选择,基于信息增益----
def cal_entropy(datasets):  # 经验熵H(D)data_len = len(datasets)label_count = {}for i in range(data_len):label = datasets[i][-1]if label not in label_count:label_count[label] = 0label_count[label] += 1entropy = -sum([(p / data_len) * log(p / data_len, 2) for p in label_count.values()])return entropydef cond_entropy(datasets, axis=0):  # 经验条件熵H(D|A)data_len = len(datasets)feature_set = {}for i in range(data_len):feature = datasets[i][axis]if feature not in feature_set:feature_set[feature] = []feature_set[feature].append(datasets[i])cond_ent = sum([(len(p) / data_len) * cal_entropy(p) for p in feature_set.values()])return cond_entdef info_gain(entropy, cond_ent):  # 信息增益return entropy - cond_entdef info_gain_train(datasets):  # 基于特征信息增益的特征选择count = len(datasets[0]) - 1entropy = cal_entropy(datasets)best_feature = []for i in range(count):info_gain_i = info_gain(entropy, cond_entropy(datasets, axis=i))best_feature.append((i, info_gain_i))print("特征({})- info_gain - {:.3f}".format(labels[i], info_gain_i))best_feature_i = max(best_feature, key=lambda x: x[-1])print("特征({})的信息增益最大,选为根节点的特征".format(labels[best_feature_i[0]]))info_gain_train(np.array(datasets))# -------ID3算法生成决策树---------class Node():def __init__(self, root=True, label=None, feature_name=None, feature=None):self.root = rootself.label = labelself.feature_name = feature_nameself.feature = featureself.tree = {}self.result = {'label:': self.label,'feature:': self.feature,'tree:': self.tree}def __repr__(self):  # 类似str方法,更侧重程序员调试print('{}'.format(self.result))def add_node(self, val, node):self.tree[val] = nodedef predict(self, features):if self.root is True:return self.labelreturn self.tree[features[self.feature]].predict(features)class DTree():def __init__(self, epsilon=0.1):  # 信息增益阈值, < epsilon 时,结束决策树展开self.epsilon = epsilonself._tree = {}@staticmethoddef cal_entropy(datasets):  # 经验熵H(D)data_len = len(datasets)label_count = {}for i in range(data_len):label = datasets[i][-1]if label not in label_count:label_count[label] = 0label_count[label] += 1entropy = -sum([(p / data_len) * log(p / data_len, 2) for p in label_count.values()])return entropydef cond_entropy(self, datasets, axis=0):  # 经验条件熵H(D|A)data_len = len(datasets)feature_set = {}for i in range(data_len):feature = datasets[i][axis]if feature not in feature_set:feature_set[feature] = []feature_set[feature].append(datasets[i])cond_ent = sum([(len(p) / data_len) * self.cal_entropy(p) for p in feature_set.values()])return cond_ent@staticmethoddef info_gain(entropy, cond_ent):  # 信息增益return entropy - cond_entdef info_gain_train(self, datasets):  # 基于特征信息增益的特征选择count = len(datasets[0]) - 1entropy = self.cal_entropy(datasets)best_feature = []for i in range(count):info_gain_i = info_gain(entropy, cond_entropy(datasets, axis=i))best_feature.append((i, info_gain_i))print("特征({})- info_gain - {:.3f}".format(labels[i], info_gain_i))best_feature_i = max(best_feature, key=lambda x: x[-1])return best_feature_idef train(self, train_data):''':input: 数据集D(DataFrame格式),特征集A,阈值eta:return: 决策树DT'''_, y_train, features = train_data.iloc[:, :-1], train_data.iloc[:, -1], train_data.columns[:-1]# 1. 若所有D实例都属于同一分类,不用分了,直接返回那个类if len(y_train.value_counts()) == 1:return Node(root=True, label=y_train.iloc[0])# 2. 若没有特征A,返回D中数量最多的分类if len(features) == 0:return Node(root=True, label=y_train.value_counts().sort_values(ascending=False).index[0])# 3. 计算最大信息增益,取为特征max_feature, max_info_gain = self.info_gain_train(np.array(train_data))max_feature_name = features[max_feature]# 4. 如果信息增益小于阈值epsilon,置为单节点,将实例数最大的类作为节点标记if max_info_gain < self.epsilon:return Node(root=True, label=y_train.value_counts().sort_values(ascending=False).index[0])# 5. 构建Ag子集node_tree = Node(root=False, feature_name=max_feature_name, feature=max_feature)feature_list = train_data[max_feature_name].value_counts().indexfor f in feature_list:sub_train_df = train_data.loc[train_data[max_feature_name] == f].drop([max_feature_name], axis=1)# 6. 递归生成树sub_tree = self.train(sub_train_df)node_tree.add_node(f, sub_tree)return node_treedef fit(self, train_data):self._tree = self.train(train_data)return self._treedef predict(self, X_test):return self._tree.predict(X_test)train_data = pd.DataFrame(datasets, columns=labels)
dt = DTree()
tree = dt.fit(train_data)
print(dt.predict(['老年', '否', '否', '一般']))
print(dt.predict(['青年', '否', '是', '一般']))
print(dt.predict(['中年', '是', '否', '好']))
print(dt.predict(['老年', '否', '是', '一般']))# ------------鸢尾花---------------
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
data = np.array(df.iloc[:100, [0, 1, -1]])
X = data[:, :2]
y = data[:, -1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
clf = DecisionTreeClassifier()
print(clf)
clf.fit(X_train, y_train)
print(clf.score(X_test, y_test))
# --------------决策树可视化-------------
# 需要安装graphviz,添加path,可视化决策树
with open('mytree.dot', 'w', encoding='utf-8') as f:dot_data = export_graphviz(clf, out_file=None, feature_names=df.columns[:2],filled=True, rounded=True, special_characters=True, class_names=iris.target_names[0:2])
dot = graphviz.Source(dot_data)
dot.view()
# 写入png , pdf
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png('tree.png')
# cmd: dot -Tpdf tree.dot -o output.pdf,dot -Tpng tree.dot -o output.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/477086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用模板快速编写测试用例

在高速发展的互联网公司&#xff0c;由于产品的开发迭代太快&#xff0c;产品测试经常遇到以下几个问题&#xff1a; 1. 如何在快速的产品开发迭代中迅速地完成对产品功能的测试&#xff1f; 2. 面对用户众多、环境多样&#xff0c;如何尽可能地测试全面&#xff1f; 3. 公司扩…

最新!Kaggle所有竞赛开源方案和Top思路汇总,共477场竞赛!

数据竞赛能帮助我们快速提升数据分析和建模能力&#xff0c;非常多的朋友也非常希望学习Top比赛的方案。之前也有非常多的朋友问我某某竞赛的方案有没有&#xff0c;有时我不是很忙的时候就会把对应的竞赛中把Top的链接找出来一起整理发过去&#xff0c;但也有的时候可能会比较…

LeetCode 65. 有效数字(逻辑题,难)

1. 题目 验证给定的字符串是否可以解释为十进制数字。 例如: "0" > true " 0.1 " > true "abc" > false "1 a" > false "2e10" > true " -90e3 " > true " 1e" > false "…

Mock Server实践

背景 在美团服务端测试中&#xff0c;被测服务通常依赖于一系列的外部模块&#xff0c;被测服务与外部模块间通过REST API或是Thrift调用来进行通信。要对被测服务进行系统测试&#xff0c;一般做法是&#xff0c;部署好所有外部依赖模块&#xff0c;由被测服务直接调用。然而有…

美团上交开源PromptDet:无需标注,开放世界的目标检测器

文 | 冯承健源 | 极市平台本文提出了一个开放世界的目标检测器PromptDet&#xff0c;它能够在没有任何手动标注的情况下检测新类别&#xff08;如下图绿色检测框&#xff09;&#xff0c;其中提出区域prompt学习方法和针对网络图像的自训练方法&#xff0c;性能表现SOTA。主页&…

Docker系列之二:基于容器的自动构建

自动构建系统是从美团的自动部署系统发展出来的一个新功能。每当开发人员提交代码到仓库后&#xff0c;系统会自动根据开发人员定制的构建配置&#xff0c;启动新的Docker容器&#xff0c;在其中对源代码进行构建&#xff08;build&#xff09;&#xff0c;包括编译&#xff08…

剑指Offer - 面试题56 - I. 数组中数字出现的次数(异或,分组)

1. 题目 一个整型数组 nums 里除两个数字之外&#xff0c;其他数字都出现了两次。请写程序找出这两个只出现一次的数字。 要求时间复杂度是O(n)&#xff0c;空间复杂度是O(1)。 示例 1&#xff1a; 输入&#xff1a;nums [4,1,4,6] 输出&#xff1a;[1,6] 或 [6,1]示例 2&a…

自动驾驶技术简史

文 | Bernard_Han自动驾驶是一个最近在产业界炙手可热的关键词。无论是与人工智能相关的顶级会议还是各大造车厂商甚至各大投资商都为这个成长初期的蓝海产业下注了美好的未来。但是“汽车自动化”的理论与自动驾驶不同&#xff0c;提出至今已有近百年的历史。从最初的遥控到如…

你是什么时候对深度学习失去信心的?

文 | 霍华德源 | 知乎最近几天在知乎上有个问题火了&#xff1a;你是什么时候对深度学习失去信心的&#xff1f;在此推荐一下知乎大V霍华德的回答&#xff0c;以下为原回答。对于深度学习的现状&#xff0c;工业界还是很清楚的。如果没有变革性的突破&#xff0c;弱人工智能时代…

OpenTSDB 造成 Hbase 整点压力过大问题的排查和解决

业务背景 OpenTSDB 是一款非常适合存储海量时间序列数据的开源软件&#xff0c;使用 HBase 作为存储让它变的非常容易扩展。我们在建设美团性能监控平台的过程中&#xff0c;每天需要处理数以亿计的数据&#xff0c;经过几番探索和调研&#xff0c;最终选取了 OpenTSDB 作为数据…

LintCode 183. 木材加工(二分查找)

1. 题目 有一些原木&#xff0c;现在想把这些木头切割成一些长度相同的小段木头&#xff0c;需要得到的小段的数目至少为 k。当然&#xff0c;我们希望得到的小段越长越好&#xff0c;你需要计算能够得到的小段木头的最大长度。 样例 1 输入: L [232, 124, 456] k 7 输出: …

AC算法在美团上单系统的应用

1.背景 在美团&#xff0c;为了保证单子质量&#xff0c;需要对上单系统创建的每一个产品进行审核。为了提高效率&#xff0c;审核人员积累提炼出了一套关键词库&#xff0c;先基于该词库进行自动审核过滤&#xff0c;对于不包括这些关键词的产品信息不再需要进行人工审核。因此…

LintCode 600. 包裹黑色像素点的最小矩形(BFS)

1. 题目 一个由二进制矩阵表示的图&#xff0c;0 表示白色像素点&#xff0c;1 表示黑色像素点。 黑色像素点是联通的&#xff0c;即只有一块黑色区域。 像素是水平和竖直连接的&#xff0c;给一个黑色像素点的坐标 (x, y) &#xff0c;返回囊括所有黑色像素点的矩阵的最小面积…

浙大、阿里提出DictBERT,字典描述知识增强的预训练语言模型

文 | 刘聪NLP源 | NLP工作站写在前面大家好&#xff0c;我是刘聪NLP。今天给大家带来一篇IJCAI2022浙大和阿里联合出品的采用对比学习的字典描述知识增强的预训练语言模型-DictBERT&#xff0c;全名为《Dictionary Description Knowledge Enhanced Language Model Pre-training…

LintCode 207. 区间求和 II(线段树)

1. 题目 在类的构造函数中给一个整数数组, 实现两个方法 query(start, end) 和 modify(index, value): 对于 query(start, end), 返回数组中下标 start 到 end 的 和。对于 modify(index, value), 修改数组中下标为 index 上的数为 value. 样例1 输入: [1,2,7,8,5] [query(0…

深入解析String#intern

在 JAVA 语言中有8中基本类型和一种比较特殊的类型String。这些类型为了使他们在运行过程中速度更快&#xff0c;更节省内存&#xff0c;都提供了一种常量池的概念。常量池就类似一个JAVA系统级别提供的缓存。 8种基本类型的常量池都是系统协调的&#xff0c;String类型的常量池…

想通这点,治好 AI 打工人的精神内耗

文 | 天于刀刀受到疫情影响&#xff0c;今年公司的校招生报道日还未到来&#xff0c;23 年的秋招提前批就已经是如火如荼地开展。而诸神黄昏算法岗&#xff0c;作为招聘中最靓眼的仔&#xff0c;简历门槛早已是硕士打底博士起步&#xff0c;项目竞赛多多益善的情况了。面临着今…

DHL

有句俗语谓&#xff1a;“不看不知道&#xff0c;一看吓一跳”&#xff0c;这次通过“中外运-敦豪”的一次快递&#xff0c;亲身感受到这种“吓一跳”的滋味。 MS 总部从 1 月 26 日寄出 MVP Award 快递包之后&#xff0c;在随后的电子邮件中给出了每个人的 DHL 快件追踪号&…

数据结构--树--线段树(Segment Tree)

文章目录1. 概念2. 建树3. 查询4. 修改5. 完整代码及测试上图 from 熊掌搜索 类似数据结构&#xff1a;树状数组 1. 概念 线段树是一种二叉树&#xff0c;是用来表示一个区间的树&#xff1a; 常常用来查询区间的&#xff1a;和、最小值、最大值树结点中存放不是普通二叉树的…

神经网络可视化有3D版本了,美到沦陷!(已开源)

源 |量子位做计算机视觉&#xff0c;离不开CNN。可是&#xff0c;卷积、池化、Softmax……究竟长啥样&#xff0c;是怎样相互连接在一起的&#xff1f;对着代码凭空想象&#xff0c;多少让人有点头皮微凉。于是&#xff0c;有人干脆用Unity给它完整3D可视化了出来。还不光是有个…