有位同事最近用术语“欠拟合”来指代命名实体识别(NER)模型,该模型缺少应该标记的实体。
我得纠正一下。 这实际上并不是欠拟合,但是我明白为何有人会这么想。
那么,对于这个问题而言,什么是不合适的,或者是过度拟合的呢?
让我们训练一些欠缺数据并拟合过度的模型!
我们将从使用sklearn的“ make_classification”功能生成数据集开始。 每个数据点将具有2个要素(因此易于绘制)和一个标签。
from sklearn.datasets import make_classification# We didn't need to display all params but I like to see defaults# I've edited some of theseX,y = make_classification( n_samples=30, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2, weights=None, flip_y=0.01, class_sep=1.0, hypercube=True, shift=0.0, scale=1.0, shuffle=True, random_state=None)# Split examples by class (positive/negative) to give diff colorspos_feat0 = []pos_feat1 = []neg_feat0 = []neg_feat1 = []for idx,klass in enumerate(y): if klass == 1: pos_feat0.append(X[idx][0]) pos_feat1.append(X[idx][1]) else: neg_feat0.append(X[idx][0]) neg_feat1.append(X[idx][1]) # And plot themimport matplotlib.pyplot as pltplt.scatter(pos_feat0,pos_feat1, c='blue')plt.scatter(neg_feat0,neg_feat1, c='red'))
大功告成。 我们得到数据了。
现在,我们将介绍欠拟合和过拟合的定义,然后有目的地选择将数据欠拟合和过拟合的算法。
欠拟合
根据维基百科:
当统计模型无法充分捕获数据的基础结构时,就会发生欠拟合。
翻译: 模型在数据中无法找到一个可靠的模式。 这并不意味着没有模式。 只是该模型找不到正确的模式。
from sklearn.linear_model import SGDClassifiermodel = SGDClassifier()model.fit(X, y)# set min and max values for the x and y axesx_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1a = np.arange(x_min, x_max, 0.1)b = np.arange(y_min, y_max, 0.1)# build a grid of each unique combination of x and yxx, yy = np.meshgrid(a, b)# make predictions for every combination of x and y on that gridZ = model.predict(np.c_[xx.ravel(), yy.ravel()])Z = Z.reshape(xx.shape)# draw the classification boundaryplt.contourf(xx, yy, Z, alpha=0.4)# adds the points from our training dataplt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k')plt.show()
该模型并不擅长绘制决策边界,它无法利用特征来确定示例的类型。
过拟合
根据维基百科释义:
过于紧密或完全对应于特定数据集的分析结果,由此可能无法拟合其它数据或可靠地预测未来的观察结果。
翻译: 该模型学习输入的示例,但不能推广到其它示例。
from sklearn.tree import DecisionTreeClassifiermodel = DecisionTreeClassifier(max_depth=4)model.fit(X, y)# set min and max values for the x and y axesx_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1a = np.arange(x_min, x_max, 0.1)b = np.arange(y_min, y_max, 0.1)# build a grid of each unique combination of x and yxx, yy = np.meshgrid(a, b)# make predictions for every combination of x and y on that gridZ = model.predict(np.c_[xx.ravel(), yy.ravel()])Z = Z.reshape(xx.shape)# draw the classification boundaryplt.contourf(xx, yy, Z, alpha=0.4)# adds the points in our training dataplt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k')plt.show()
漂亮。 又一个糟糕的模型。 它在目标示例的周围绘制了边界,但是其发现的模式毫无意义,很可能在新的示例。
让我们拟合数据、寻找乐趣吧!
odel import LinearRegression,LogisticRegressionmodel = LogisticRegression()model.fit(X, y)# set min and max values for the x and y axesx_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1a = np.arange(x_min, x_max, 0.1)b = np.arange(y_min, y_max, 0.1)# build a grid of each unique combination of x and yxx, yy = np.meshgrid(a, b)# make predictions for every combination of x and y on that gridZ = model.predict(np.c_[xx.ravel(), yy.ravel()])Z = Z.reshape(xx.shape)# draw the classification boundaryplt.contourf(xx, yy, Z, alpha=0.4)# adds the points in our training dataplt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k')plt.title(''Underfitting')plt.show()'Underfitting')plt.show()
虽然不完美,但比前两种方法好多了。
现在你看到了。 欠拟合,过拟合,还有计划拟合。
我们有意选择了一个简单的双特征数据集,因此你可以在图表上看到决策边界。
具有成千上万个特征的真实示例需要采用更数字化的方法来衡量欠拟合和过拟合,这就是下次我要讲到的了~