今天给大家介绍提升方法(Boosting), 提升算法是一种可以用来减小监督式学习中偏差的机器学习算法。
面对的问题是迈可·肯斯(Michael Kearns)提出的:一组“弱学习者”的集合能否生成一个“强学习者”?
弱学习者一般是指一个分类器,它的结果只比随机分类好一点点。强学习者指分类器的结果非常接近真值。
大多数提升算法包括由迭代使用弱学习分类器组成,并将其结果加入一个最终的成强学习分类器。加入的过程中,通常根据它们的分类准确率给予不同的权重。加和弱学习者之后,数据通常会被重新加权,来强化对之前分类错误数据点的分类。
提升算法有种三个臭皮匠顶个诸葛亮的意思。在这里将使用微软的LightGBM这个提升算法,来预测分子的一个属性,叫做耦合常数。
导入需要的库
import os
import time
import datetime
import json
import gc
from numba import jit
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from tqdm import tqdm_notebook
from sklearn.preprocessing import StandardScaler
from sklearn.svm import NuSVR, SVR
from sklearn.metrics import mean_absolute_error
pd.options.display.precision = 15
import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold, KFold, RepeatedKFold
from sklearn import metrics
from sklearn import linear_model
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
from IPython.display import HTML
import altair as alt
from altair.vega import v5
from IPython.display import HTML
import networkx as nx
import matplotlib.pyplot as plt
%matplotlib inline
alt.renderers.enable('notebook')
读取数据
读取需要使用的csv文件,
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
structures = pd.read_csv('structures.csv')
csv文件中包含了以下这些数据,首先看下训练集的数据,从pandas显示的数据来看,训练集的csv包含了,分子名,原子index,化学键类型和训练集给出的耦合常数。
train.head()
在测试集数据中,除了耦合常数的数据其他的数据跟训练集的数据是一致的。
test.head()
再来看下structures的数据,也就是原子的数据,其中包含了,原子的索引,这个原子在哪个分子中,和它的空间坐标位置,这些数据后续将会用来做特征挖掘。
structures.head()
可数据化的数据
数据可视化一直是机器学习的重点,一个好的数据可视化,可以帮助我们理解数据的分布、形态以及特性。
首先来看下耦合常数在已有的数据集中分布,这里展示了耦合常数的直方图,以及每个化学键类型下的耦合常数的数据大小的分布情况。
fig, ax = plt.subplots(figsize = (18, 6))
plt.subplot(1, 2, 1);
plt.hist(train['scalar_coupling_constant'], bins=20);
plt.title('Basic scalar_coupling_constant histogram');
plt.subplot(1, 2, 2);
sns.violinplot(x='type', y='scalar_coupling_constant', data=train);
plt.title('Violinplot of scalar_coupling_constant by type');
再来看下已有的数据,根据不同的化学键类型的原子连接形态。
从图表中可以发现,不同给的化学键类型,有着不同的形态,其中2JHH这个化学键的形态最为特别。
fig, ax = plt.subplots(figsize = (20, 12))
for i, t in enumerate(train['type'].unique()):
train_type = train.loc[train['type'] == t]
G = nx.from_pandas_edgelist(train_type, 'atom_index_0', 'atom_index_1', ['scalar_coupling_constant'])
plt.subplot(2, 4, i + 1);
nx.draw(G, with_labels=True);
plt.title(f'Graph for type {t}')