乳腺癌细胞挖掘

  • 如何实现精准治疗和诊断预测?
    • 前置:Sklearn 建模
    • 下载:临床数据
    • 机器学习建模
      • 1.癌细胞特征因子挖掘
        • 特征选取(Feature Engineering)
          • 模型法
          • 比例法
          • 方差法
          • KBest
      • 2.乳腺癌细胞分类器构造
        • 逻辑回归 - logistic regression
          • 逻辑回归的优点、缺点
        • 支持向量 SVM
          • SVM 的优点、缺点
        • 神经网络 - neural network
          • 神经网络的优点、缺点
        • 最近邻 k-Nearest Neighbors
          • KNN 的优点、缺点
        • 决策树 - decision tree
          • 决策树的优点、缺点
        • 随机森林 - random forest
          • 随机森林的优点、缺点
        • XGBoost
          • XGBoost 优点、缺点
        • CatBoost
          • CatBoost 的优点、缺点
        • LightGBM
          • LightGBM 的优点、缺点
      • 3.乳腺癌细胞预测
      • 4.模型验证
    • RDKit 化学分子溶解度模型
      • 转换为可计算问题:化学分子式转换为数字
      • 采用哪种算法建模:随机森林和高斯回归
    • 乳腺医学院
      • 特殊:乳腺健康其实是一个全身性问题
      • 不适:乳房疼痛、乳腺结节、乳腺增生,要紧否
      • 重建:治疗前、后的规范生活
      • 前沿:新疗法的利与弊
        • 生化黑客,是怎么黑进人体的?

如何实现精准治疗和诊断预测?

2020年,乳腺癌已成为全球发病率最高的癌症,名副其实的“红颜第一杀手”。

  • 诊断预测,需要真实的临床数据、机器学习的算法来搭建疾病预测模型。

  • 乳腺医学院是一张作战地图,可以帮您填满预防、对抗TA的弹药库,实现精准治疗

前置:Sklearn 建模

S k l e a r n Sklearn Sklearn 有 S k l e a n Sklean Sklean 的套路:

  • 数据读取
  • 数据划分
  • 模型训练
  • 模型预测
  • 模型验证
  • 保存模型

数据读取:一般是从 excel 文件、csv 文件中读取数据,excel 文件大概可以保存 100 万条数据,csv 本身没有数据量限制,但是使用Excel打开的时候就只能显示对应Excel版本最大的行数。

# 读取 excel 文件代码示例
import pandas as pd
filename = ("test.xlsx") # excel文件是以 .xlsx 为结尾的
data = pd.read_excel(filename) # 读取 excel 数据
# 读取 csv 文件代码示例
import pandas as pd
filename = ("test.csv") # csv文件是以 .csv 为结尾的
data = pd.read_csv(filename) # 读取 csv 数据

数据划分:数据划分有俩个阶段。

  • 1.先将数据划分为变量X和标签y俩部分;
  • 2.将上一步得到的数据划分为训练集和数据集俩部分。

第一步,X是一般变量,y是目标变量,举个例子:

  • 一般变量可以有很多个,如收入、年龄、贷款次数等;
  • 目标变量只有一个,就是我们预测的结果,是好客户,还是坏客户。

第二步,把所有数据按照七三分为训练数据、测试数据。

  • 训练数据用于训练模型,占70%
  • 测试数据测试模型性能,占30%
# 将数据划分为变量x和标签y俩部分
data = pd.read_excel(filename)
X = data.loc[:, "var1":"var3"]  # x通常为多个变量,读取var1到var3之间的所有变量
y = data["target"]# 将上一步得到的数据划分为训练集和测试集俩部分
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
# random_state是随机数种子,用于调参,test_size=0.3代表测试集占30%

模型训练:一般模型通常就是分类器模型、回归类模型。

不同算法的模型不同,以逻辑回归举例。

from sklearn.linear_model import LogisticRegression
# 导入逻辑回归包classifier = LogisticRegression()
# 生成一个模型对象classifier.fit(X_train, y_train)
# fit函数训练模型,俩个参数为训练集的X和y数据

模型预测:经过训练集训练出来的模型,现在交给测试集测试。

测试函数:predict(X_test)、predict_proba(X_test)

  • predict预测的是一个二分类的结果,0或者1;
  • predict_proba预测的是0和1的概率;
predictions = classifier.predict(X_test)
predictions1 = classifier.predict_proba(X_test)

模型验证:评估模型是否合格。

模型评估的结果:欠拟合、过拟合、拟合较好。

模型验证的指标:accuracy、precision、recall、f1-score、AUC、KS、logloss

  • accuracy:常用,简单的模型都是用这个
  • accuracy、precision、recall、f1-score:这四个都可以统称为混淆矩阵
  • AUC、KS:实战中的金融模型用的多,结果在0和1之间,越接近1模型预测就越好
  • logloss:用的很少

验证模型需要综合来看,不能只看一个指标,容易被误导。

如果只用accuracy这个模型准确率是0.999,但这其实是数据不平衡造成的,如果用f1-score测试分数就不会这么离谱。

from sklearn import metrics
# 导入混淆矩阵的包
from sklearn.metrics import roc_curve, auc,roc_auc_score
# 导入绘制ROC曲线、计算ROC值的包
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_scorey_true=y_test
y_pred=classifier.predict(X_test)
accuracyScore = accuracy_score(y_true, y_pred)
print('model accuracy is:',accuracyScore)# precision,TP/(TP+FP) (真阳性)/(真阳性+假阳性)
precision=precision_score(y_true, y_pred)
print('model precision is:',precision)# recall(sensitive)敏感度,(TP)/(TP+FN)
sensitivity=recall_score(y_true, y_pred)
print('model sensitivity is:',sensitivity)# F1 = 2 x (精确率 x 召回率) / (精确率 + 召回率)
# F1 分数会同时考虑精确率和召回率,以便计算新的分数。可将 F1 分数理解为精确率和召回率的加权平均值,其中 F1 分数的最佳值为 1、最差值为 0:
f1Score=f1_score(y_true, y_pred)
print("f1_score:",f1Score)

保存模型:遇到大量数据时,训练模型可能需要几天,就需要保存模型

# 保存模型
import pickle
# 导入保存模型的包
save_classifier = open("model.pickle","wb")
# classifier是之前训练的模型
pickle.dump(classifier, save_classifier)
save_classifier.close()#导入模型包
classifier_f = open("model.pickle", "rb")
classifier = pickle.load(classifier_f)
classifier_f.close()

下载:临床数据

数据地址-1:https://download.csdn.net/download/qq_41739364/15403453,来自加利福尼亚大学尔湾分校。


大概有五份数据:



返回首页,点击 Data Set Description

比较重要的一段描述:

7. Attribute information
# 癌细胞属性定义1) ID number
2) Diagnosis (M = malignant, B = benign)
# M 是 malignant 的缩写,代表恶性
# B 是 benign 的缩写,代表良性3-32)
Ten real-valued features are computed for each cell nucleus:a) radius (mean of distances from center to points on the perimeter)# radius:半径b) texture (standard deviation of gray-scale values)# texture:灰度值的标准方差c) perimeter# perimeter:周长d) area# area:面积e) smoothness (local variation in radius lengths)# smoothness:平滑度(半径长度的局部变化)f) compactness (perimeter^2 / area - 1.0)# compactness:紧致度(周长的平方 / 面积 - 1.0)g) concavity (severity of concave portions of the contour)# concavity:凹度(轮廓凹面部分的严重程度)h) concave points (number of concave portions of the contour)# concave points:凹面点(轮廓凹面部分的数量)i) symmetry # 对称性j) fractal dimension ("coastline approximation" - 1)# 分形维数

这份数据来源于,1995年美国威斯康辛临床真实数据。

  • 样本量是 569 个,很少,现在数据挖掘,样本量大概在 xxx T 左右;
  • 维度 30

数量虽然很少,但只要对大数据进行随机抽样,他们得到的结果的误差大概 5% 左右。

虽然我很想说 5% 不影响预测结果,但5%差距真的很大了,因为在竞赛里你差千分之一,名次可能就落后几百名… …虽然数据不够,但是当作练手,也是很好的。


机器学习建模


1.癌细胞特征因子挖掘

癌细胞和正常细胞的区别在哪里呢?

  • Normal 是正常细胞,Cancer 是癌症细胞。

癌细胞最突出的五个特征:

  • 外表形态(area、radius、perimeter、concave)
  • 误差(error)
  • 平滑度(smoothness)
  • 灰度值标准差(texture)
  • 对称性(symmetry)


外在形态是最重要的判断因素:


特征选取(Feature Engineering)

特征选取可以减低算法的复杂度,去掉无意义的数据,提升性价比。

我们使用以下四种方法:

  • 模型法
  • 比例法
  • 方差法
  • KBest(选择k个最好的变量)

每种方法都有一定的局限性,需要尝试对比多种方法。

模型法

模型法,比如通过随机森林、xgboost进行变量的权重的统计。

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegressionfrom sklearn.datasets import load_breast_cancer
# 导入乳腺癌细胞数据包
from sklearn.model_selection import train_test_split
# 导入分割数据集的方法cancer=load_breast_cancer()
data=cancer.data
df_data=pd.DataFrame(data)
# 读取数据X, y = cancer.data, cancer.target
X_train, X_test, y_train, y_test=train_test_split(X,y,test_size=0.3,random_state=0)
# 划分数据集和训练集from sklearn.feature_selection import SelectFromModel
# 选用模型变量选取的方法from sklearn.ensemble import RandomForestClassifier
# 导入随机森林的分类器select=SelectFromModel(RandomForestClassifier(n_estimators=1000, random_state=42))
# 生成select对象,随机森林分类器有几个参数,n_estimators表示树的棵树,random_state表示种子数select.fit(X_train, y_train)
# 用select对象训练数据X_train_selected=select.transform(X_train)
X_test_selected=select.transform(X_test)
# 再对解释数据的训练集、数据集进行选取print("X_train.shape:", X_train.shape)
print("X_train_selected.shape:", X_train_selected.shape)
# 查看模型选取了哪些变量,输出为从30个变量中选取了11个,我们也可以可视化出来mask = select.get_support()
# 返回被选中特征和没被选中特征的掩码或者整数索引
plt.matshow(mask.reshape(1, -1), cmap='gray_r')
# plt.matshow画混淆矩阵图,可视化选取的变量(图中黑色的部分就是选取的变量,白色为剔除的变量)# 筛选(选取)了变量
clf_selectVariables=LogisticRegression()
clf_selectVariables.fit(X_train_selected,y_train)# 没有筛选(选取)变量
clf1=LogisticRegression()
clf1.fit(X_train,y_train)print("model score without selection:",clf1.score(X_test,y_test))
print("model score after selection:",clf_selectVariables.score(X_test_selected,y_test))
# 对比俩份结果,发现筛选后对模型也一定损失,但还好,不影响预测

输出结果:

X_train.shape: (398, 30)
X_train_selected.shape: (398, 11)model score without selection: 0.9590643274853801
model score after selection: 0.9473684210526315
比例法

比例法,是按照比例来选取变量。

选择变量的比例,很简单:

select = SelectPercentile(percentile = 50)
# 选取前百分之几的变量(分数从高到低,参数percentile默认10%)

完整代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SelectPercentile
from sklearn.ensemble import RandomForestClassifierfrom sklearn.datasets import load_breast_cancer
# 导入乳腺癌细胞数据包
from sklearn.model_selection import train_test_split
# 导入分割数据集的方法# 读取数据
cancer=load_breast_cancer()
data=cancer.data
df_data=pd.DataFrame(data)# 添加噪声数据,就是无用的、随机生成的变量
rng=np.random.RandomState(42)
noise=rng.normal(size=(len(cancer.data),50))
X_w_noise=np.hstack([cancer.data, noise]) # 把随机数据添加到数据集后面
df_X_w_noise=pd.DataFrame(X_w_noise)X, y = cancer.data,cancer.target
X_train, X_test, y_train, y_test=train_test_split(X_w_noise,y,test_size=0.3,random_state=0)# 选择前百分之几十的变量(分数由高到低)
select=SelectPercentile(percentile=50)
select.fit(X_train,y_train)
X_train_selected=select.transform(X_train)
X_test_selected=select.transform(X_test)print("X_train.shape:",X_train.shape)
print("X_train_selected.shape:",X_train_selected.shape)mask = select.get_support()   # 返回被选中特征和没被选中特征的掩码或者整数索引
plt.matshow(mask.reshape(1, -1), cmap='gray_r')   # plt.matshow画混淆矩阵图# 筛选了变量
clf=LogisticRegression()
clf.fit(X_train_selected,y_train)# 没有筛选变量
clf1=LogisticRegression()
clf1.fit(X_train,y_train)print("model score without selection:",clf1.score(X_test,y_test))
print("model score after selection:",clf.score(X_test_selected,y_test))
# 对比俩个结果,发现筛选后的结果更好

输出结果:

X_train.shape: (398, 80)
X_train_selected.shape: (398, 40)model score without selection: 0.9064327485380117
model score after selection: 0.9532163742690059
方差法

方差筛选法,是对变量进行一个一个的比较分析(单变量分析),比较每个变量和目标变量是否有显著差异。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import lightgbm as lgb
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifierfrom sklearn.feature_selection import f_classif
# 导入方差法
from sklearn.datasets import load_breast_cancer
# 导入乳腺癌细胞数据包
from sklearn.model_selection import train_test_split
# 导入分割数据集的方法cancer=load_breast_cancer()
data=cancer.data
df_data=pd.DataFrame(data)X, y = cancer.data,cancer.target
X_train, X_test, y_train, y_test=train_test_split(X,y,test_size=0.3,random_state=0)# 选择前百分之几十的变量(分数由高到低),默认变量个数是10
select=f_classif(X, y)print(select)
# 这个select对象有点特殊,是元祖

输出结果:

array([6.46981021e+02, 1.18096059e+02, 6.97235272e+02, 5.73060747e+02,8.36511234e+01, 3.13233079e+02, 5.33793126e+02, 8.61676020e+02,6.95274435e+01, 9.34592949e-02, 2.68840327e+02, 3.90947023e-02,2.53897392e+02, 2.43651586e+02, 2.55796780e+00, 5.32473391e+01,3.90144816e+01, 1.13262760e+02, 2.41174067e-02, 3.46827476e+00,8.60781707e+02, 1.49596905e+02, 8.97944219e+02, 6.61600206e+02,1.22472880e+02, 3.04341063e+02, 4.36691939e+02, 9.64385393e+02,1.18860232e+02, 6.64439606e+01]), array([8.46594057e-096, 4.05863605e-025, 8.43625104e-101, 4.73456431e-088,1.05185036e-018, 3.93826311e-056, 9.96655576e-084, 7.10115016e-116,5.73338403e-016, 7.59936804e-001, 9.73894866e-050, 8.43332029e-001,1.65190518e-047, 5.89552139e-046, 1.10296609e-001, 9.97599465e-013,8.26017617e-010, 3.07230877e-024, 8.76641818e-001, 6.30735508e-002,8.48229192e-116, 1.07805749e-030, 5.77139714e-119, 2.82884770e-097,6.57514363e-026, 7.06981635e-055, 2.46466396e-072, 1.96909971e-124,2.95112058e-025, 2.31643245e-015])

第一个数组是每个变量的方差值,值越大就越有关系。值越小就越没有意义。

第二个数组是P值,一般P>0.05说明无显著意义。

按照上述情况,可以把那么无意义的数据清洗掉。

共有5个变量的方差值太小,P值>0.05,不符合要求。

  • fractal dimension error
  • symmetry error
  • smoothness error
  • texture error
  • mean fractal dimension

您可以手动删除这些列,并把删除列后的文件命名为 方差筛选后变量.xlsx

import lightgbm as lgb
from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn.datasets import load_breast_cancercancer=load_breast_cancer()
# 筛选变量后表现
df=pd.read_excel("方差筛选后变量.xlsx")
X=df.values
y=cancer.target
train_x, test_x, y_train, y_test=train_test_split(X,y,test_size=0.3,random_state=0)
lg = lgb.LGBMClassifier()
lg.fit(train_x, y_train)
print("after AVNO feature selection,accuracy on the training subset:{:.3f}".format(lg.score(train_x,y_train)))
print("after AVNO feature selection,accuracy on the test subset:{:.3f}".format(lg.score(test_x,y_test)))X1, y = cancer.data,cancer.target
train_x1, test_x1, y_train1, y_test1=train_test_split(X1,y,test_size=0.3,random_state=0)
lg1 = lgb.LGBMClassifier()
lg1.fit(train_x1, y_train1)
print("accuracy on the training subset:{:.3f}".format(lg1.score(train_x1,y_train1)))
print("accuracy on the test subset:{:.3f}".format(lg1.score(test_x1,y_test1)))

输出结果:

after AVNO feature selection,accuracy on the training subset:1.000
after AVNO feature selection,accuracy on the test subset:0.982accuracy on the training subset:1.000
accuracy on the test subset:0.982

发现删除这5个变量前后的训练结果并没有不同,都是 0.982,数据维度更小了,但对预测结果完全没有影响,不得不说,方差法真的是一种很好的变量筛选方法。

KBest

KBest,选择你想要的K个变量。

import lightgbm as lgb
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import SelectKBest
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegressioncancer=load_breast_cancer()
data=cancer.data
df_data=pd.DataFrame(data)X, y = cancer.data,cancer.target
X_train, X_test, y_train, y_test=train_test_split(X,y,test_size=0.3,random_state=0)#(分数由高到低)
select=SelectKBest(k=15) # 默认变量个数是10
select.fit(X_train,y_train)
X_train_selected=select.transform(X_train)
X_test_selected=select.transform(X_test)print("X_train.shape:",X_train.shape)
print("X_train_selected.shape:",X_train_selected.shape)mask = select.get_support()   # 返回被选中特征和没被选中特征的掩码或者整数索引
plt.matshow(mask.reshape(1, -1), cmap='gray_r')   # plt.matshow画混淆矩阵图# 筛选了变量
clf=LogisticRegression()
clf.fit(X_train_selected,y_train)# 没有筛选变量
clf1=LogisticRegression()
clf1.fit(X_train,y_train)print("model score without selection:",clf1.score(X_test,y_test))
print("model score after selection:",clf.score(X_test_selected,y_test))

输出结果:

X_train.shape: (398, 30)
X_train_selected.shape: (398, 15)model score without selection: 0.9590643274853801(默认, k=10)
model score after selection: 0.9473684210526315(k=15)

2.乳腺癌细胞分类器构造

运用各种算法来构造分类器。


逻辑回归 - logistic regression

简单介绍一下,逻辑回归。

大概只需要学习 4 4 4个地方,逻辑回归就掌握了。

  • sigmoid函数:计算二分类概率,0.5为阈值
  • Maximum likehood:最大似然估计
  • 梯度上升和梯度下降(Z最优化问题):如何实现最大似然估计
  • 随机梯度上升(解决大数据计算,优化性能):梯度上升的升级版本

逻辑回归的公式:

逻辑回归简化公式:

逻辑回归就是一个线性的函数,只是用sigmoid函数加壳,就可以处理分类的问题。

逻辑回归并不是真正的回归,但本质是回归,处理的问题是分类,是从线性回归中衍生出来的分类策略。

举个例子:


但是上面的函数不连续,我们希望有一个单调可微的函数,于是就找到了sigmoid函数。

from pylab import *
t = arange(-10, 10, 0.1) # 取值范围:[-10, 10],间隔:0.1
s = 1/(1+exp(-t))        # sigmoid函数公式plot(t, s)
plt.xlabel("x")
plt.ylabel("sigmoid(x)")
plt.show()                   # 绘图

输出结果:

Text(0, 0.5, 'sigmoid(x)')


这个曲线就是sigmoid函数,是研究人口增长的时候命名的,描述了生物种群先指数增长,而后增长放缓,最后数量趋于一个极限值的这条。

有了sigmoid函数之后,由于其值的范围[0, 1],可以将其算出来的结果划分到某个类比,一般大于0.5,会划分为1,小于0.5划分为0。

接着说,最大似然估计。

最大似然估计,是一个最优化问题,是通过比较所有的超平面后,找到一个超平面,让逻辑似然最大化。

实现的方法有:梯度上升、梯度下降,处理最优化问题。

求目标的梯度函数:比如爬山,用最少的步数实现算法。

梯度的物理含义可以这样理解,如果你去登山,怎样沿着最陡的方向,最快地爬到山顶呢?

梯度函数这个工具可以告诉你在任意一点,往不同方向走的上升速度是不一样的,因此你很容易找到前进的目标。

很多时候,我们都面临在限制要素中作选择的问题。

我们总想全方位改进自己,但是人的精力和资源有限,因此在某一时刻,可能只能向一个方向努力。

希望梯度这个概念在你选择方向时能够给你启发。

很多人从直觉出发,觉得该补短板,另一些人则觉得,该把长板变得更长。

第一类人会和你讲木桶理论,第二类人会和你讲长板理论,每一类都有很多成功的例子,也有很多失败的教训。

于是很多人就不知道该用哪一个理论了。事实上你学了梯度理论后,就很容易作决断了,那就是在任何时刻算出梯度,而后沿着最陡,但是收益最大的路径前进就好

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancerfrom sklearn.linear_model import LogisticRegression
# 导入逻辑回归的包cancer=load_breast_cancer()
x_train,x_test,y_train,y_test=train_test_split(cancer.data,cancer.target,random_state=0)# 默认参数
logist=LogisticRegression()
logist.fit(x_train,y_train)
print("accuracy on the training subset:{:.3f}".format(logist.score(x_train,y_train)))  # 训练数据的准确性
print("accuracy on the test subset:{:.3f}".format(logist.score(x_test,y_test)))        # 测试数据的准确性# 正则化l1
#logist2=LogisticRegression(C=1,penalty='l1',tol=0.01) # sklearn0.18版本以前的,可以直接这样写
logist2=LogisticRegression(C = 1, penalty = 'l1',solver='liblinear')
logist2.fit(x_train,y_train)
print("accuracy on the training subset:{:.3f}".format(logist2.score(x_train,y_train))) # 训练数据的准确性
print("accuracy on the test subset:{:.3f}".format(logist2.score(x_test,y_test)))       # 测试数据的准确性# 正则化l2
logist3=LogisticRegression(C=1,penalty='l2',tol=0.01)
logist3.fit(x_train,y_train)
print("accuracy on the training subset:{:.3f}".format(logist3.score(x_train,y_train))) # 训练数据的准确性
print("accuracy on the test subset:{:.3f}".format(logist3.score(x_test,y_test)))       # 测试数据的准确性# 对比以上三个,默认参数、l1、l2,哪个的准确性最高就用哪个

输出结果:

accuracy on the training subset:0.958
accuracy on the test subset:0.951accuracy on the training subset:0.962
accuracy on the test subset:0.958accuracy on the training subset:0.958
accuracy on the test subset:0.951

L1最好。

逻辑回归的优点、缺点

优点:
(1)训练速度较快,分类的时候,计算量仅仅只和特征的数目相关;
(2)简单易理解,模型的可解释性非常好,从特征的权重可以看到不同的特征对最后结果的影响;
(3)适合二分类问题,不需要缩放输入特征;
(4)内存资源占用小,因为只需要存储各个维度的特征值;

缺点:
(1)不能用Logistic回归去解决非线性问题,因为Logistic的决策面试线性的;
(2)对多重共线性数据较为敏感;
(3)很难处理数据不平衡的问题;
(4)准确率并不是很高,因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布;
(5)逻辑回归本身无法筛选特征,有时会用gbdt来筛选特征,然后再上逻辑回归


支持向量 SVM

svm简单来说,就是选择最佳的超平面。


第一步,用一条直线一直在平面上扫描,直到把图中的圆圈和方形完全切割开,比如上图的直线Z1、直线Z2都做到了(事实上在Z1、Z2之间还有很多直线也可以)。

第二步,比较Z1、Z2,哪个切割的最好,即Z1、Z2之间的距离最大,就选哪个。

那怎么求距离呢?

可以用拉格朗日乘数法,但是这里不涉及具体的原理,一笔带过。

from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as pltcancer=load_breast_cancer()
data=cancer.data
featureNames=cancer.feature_names
X_train,x_test,y_train,y_test = train_test_split(cancer.data,cancer.target,stratify=cancer.target,random_state=42)svm=SVC()
svm.fit(X_train,y_train)# 得分
print("accuracy on the training subset:{:.3f}".format(svm.score(X_train,y_train)))
print("accuracy on the test subset:{:.3f}".format(svm.score(x_test,y_test)))#观察数据是否标准化
plt.plot(X_train.min(axis=0),'o',label='Min')
plt.plot(X_train.max(axis=0),'v',label='Max')
plt.xlabel('Feature Index')
plt.ylabel('Feature magnitude in log scale')
plt.yscale('log')
plt.legend(loc='upper right')
plt.show()from sklearn import preprocessing
# 导入预处理的包X_train_scaled = preprocessing.scale(X_train)  # 预处理训练集
x_test_scaled = preprocessing.scale(x_test)    # 预处理数据集
svm1=SVC()
svm1.fit(X_train_scaled,y_train)# 测试得分
print("accuracy on the scaled training subset:{:.3f}".format(svm1.score(X_train_scaled,y_train)))
print("accuracy on the scaled test subset:{:.3f}".format(svm1.score(x_test_scaled,y_test)))#观察数据是否标准化
plt.plot(X_train_scaled.min(axis=0),'o',label='Min')
plt.plot(X_train_scaled.max(axis=0),'v',label='Max')
plt.xlabel('Feature Index')
plt.ylabel('Feature magnitude in log scale')
plt.yscale('log')
plt.legend(loc='upper right')
plt.show()

输出结果:

accuracy on the training subset:0.918
accuracy on the test subset:0.923

accuracy on the scaled training subset:0.979
accuracy on the scaled test subset:0.972

SVM 的优点、缺点

优点:

  • 支持多维空间
  • 不同核函数用于不同决策函数
  • 可处理多维数据分类,小样本数据也可以工作,非常灵活

缺点:

  • 如果数据特征(维度)大于样本量,表现极差
  • 支持向量机不提供概率区间的估计
  • 找到准确的核函数和C参数,gamma参数需要很大计算量
  • 高维度,大样本表现较差,需要预处理和调参
  • 很难监控和可视化

神经网络 - neural network

人工神经网络的确是,和生物神经网络一样。

但生物神经网络是经过千亿年的演化,目前人工神经网络无法达到那种层次。

  • 人工神经网络:通过正反馈和负反馈创建和删除神经元
  • 生物神经网络:通过刺激产生新的连接,信号通过新的连接传递产生反馈
from sklearn.neural_network import MLPClassifier
# 标准化数据,否则神经网络不准确,和SVM类似from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_splitimport mglearn
import matplotlib.pyplot as plt
import numpy as npmglearn.plots.plot_logistic_regression_graph()
mglearn.plots.plot_single_hidden_layer_graph()cancer = load_breast_cancer()
X_train,x_test,y_train,y_test = train_test_split(cancer.data,cancer.target,stratify=cancer.target,random_state=42)mlp = MLPClassifier(random_state=42)
mlp.fit(X_train, y_train)
print("accuracy on the trainging subset:{:.3f}".format(mlp.score(X_train, y_train)))
print("accuracy on the testing subset:{:.3f}".format(mlp.score(x_test, y_test)))scaler = StandardScaler()
x_train_scaled = scaler.fit(X_train).transform(X_train)
x_test_scaled = scaler.fit(x_test).transform(x_test)mlp_scaled = MLPClassifier(max_iter=1000, random_state=42)
mlp_scaled.fit(x_train_scaled, y_train)
print("accuracy on the trainging subset:{:.3f}".format(mlp_scaled.score(x_train_scaled, y_train)))
print("accuracy on the testing subset:{:.3f}".format(mlp_scaled.score(x_test_scaled, y_test)))mlp_scaled2 = MLPClassifier(max_iter=1000, alpha=1, random_state=42)
mlp_scaled2.fit(x_train_scaled, y_train)
print("accuracy on the trainging subset:{:.3f}".format(mlp_scaled2.score(x_train_scaled, y_train)))
print("accuracy on the testing subset:{:.3f}".format(mlp_scaled2.score(x_test_scaled, y_test)))# 绘图(热图)
plt.figure(figsize=(20,5))
plt.imshow(mlp_scaled.coefs_[0], interpolation="None", cmap="GnBu")
plt.yticks(range(30), cancer.feature_names)
plt.xlabel("columns in weight matrix")
plt.ylabel("input feature")
plt.colorbar()

输出结果:

accuracy on the trainging subset:0.939
accuracy on the testing subset:0.916accuracy on the trainging subset:0.998
accuracy on the testing subset:0.979accuracy on the trainging subset:0.988
accuracy on the testing subset:0.979

神经网络的优点、缺点

优点:

(1)具有自学习功能。例如实现图像识别时,只在先把许多不同的图像样板和对应的应识别的结果输入人工神经网络,网络就会通过自学习功能,慢慢学会识别类似的图像。自学习功能对于预测有特别重要的意义。预期未来的人工神经网络计算机将为人类提供经济预测、市场预测、效益预测,其应用前途是很远大的。

(2)具有联想存储功能。用人工神经网络的反馈网络就可以实现这种联想。

(3)具有高速寻找优化解的能力。寻找一个复杂问题的优化解,往往需要很大的计算量,利用一个针对某问题而设计的反馈型人工神经网络,发挥计算机的高速运算能力,可能很快找到优化解。

缺点:

(1)最严重的问题是没能力来解释自己的推理过程和推理依据。

(2)不能向用户提出必要的询问,而且当数据不充分的时候,神经网络就无法进行工作。

(3)把一切问题的特征都变为数字,把一切推理都变为数值计算,其结果势必是丢失信息。

(4)理论和学习算法还有待于进一步完善和提高。


最近邻 k-Nearest Neighbors

啥都不用说,秀出你的代码。

关于KNN,记录在:k近邻算法(k-Nearest Neighbors,kNN)

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_splitfrom sklearn.neighbors import KNeighborsClassifier
# 调用 kNN 算法,需要导入 KNeighborsClassifier 类cancer=load_breast_cancer()
data=cancer.data
featureNames=cancer.feature_names
X_train,x_test,y_train,y_test = train_test_split(cancer.data,cancer.target,stratify=cancer.target,random_state=42)kNN_classifier = KNeighborsClassifier(n_neighbors = 3)
# 创建一个类的实例,参数n_neighbors是 k值kNN_classifier.fit(X_train, y_train)
# 数据集拟合fitprint("accuracy on the training subset:{:.3f}".format(kNN_classifier.score(X_train, y_train)))
print("accuracy on the test subset:{:.3f}".format(kNN_classifier.score(x_test, y_test)))# 自动调参,找出最优k,枚举 k 从1到11,大概k等于7时,效果最好。
import matplotlib.pyplot as plt
training_accuracy = []
testing_accuracy = []
neighbors_settings = range(1, 11)
for k in neighbors_settings:clf = KNeighborsClassifier(k)clf.fit(X_train, y_train)training_accuracy.append(clf.score(X_train, y_train))testing_accuracy.append(clf.score(x_test, y_test))plt.plot(neighbors_settings, training_accuracy, label="Accuracy of trainings set") # 蓝色线条
plt.plot(neighbors_settings, testing_accuracy, label="Accuracy of testings set") # 橙色线条
plt.xlabel("Number of Neighbors")
plt.ylabel("Accuracy")
plt.legend()

输出结果:

accuracy on the training subset:0.951
accuracy on the test subset:0.930

KNN 的优点、缺点

优点:

(1)简单,易于理解,易于实现,无需估计参数。

(2)训练时间为零。它没有显示的训练,不像其它有监督的算法会用训练集train一个模型(也就是拟合一个函数),然后验证集或测试集用该模型分类。KNN只是把样本保存起来,收到测试数据时再处理,所以KNN训练时间为零。

(3)KNN可以处理分类问题,同时天然可以处理多分类问题,适合对稀有事件进行分类。

(4)特别适合于多分类问题(multi-modal,对象具有多个类别标签), KNN比SVM的表现要好。

(5)KNN还可以处理回归问题,也就是预测。

(6)和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感。

缺点:

(1)计算量太大,尤其是特征数非常多的时候。每一个待分类文本都要计算它到全体已知样本的距离,才能得到它的第K个最近邻点。

(2)可理解性差,无法给出像决策树那样的规则。

(3)是慵懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢。

(4)样本不平衡的时候,对稀有类别的预测准确率低。当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。

(5)对训练数据依赖度特别大,对训练数据的容错性太差。如果训练数据集中,有一两个数据是错误的,刚刚好又在需要分类的数值的旁边,这样就会直接导致预测的数据的不准确。


决策树 - decision tree

决策树的难点:如何排序根结点。

首先,把最重要的结点放到最前面(根结点)。

因为变量太多了,找到就很难。

排在第一的结点,代表熵值最小(不确定性最小)。

实现决策树的三种算法:

  • ID3:信息增益
  • C4.5:信息增益率(解决ID3的排序问题,考虑自身熵)
  • CART:使用 GINI 系数来当做衡量标准(目前最流行)

决策剪枝:避免决策树过大,过度拟合,所以限制深度(叶子结点数)

剪枝策略:

  • 预剪枝:边建立决策树,边进行剪枝

  • 后剪枝:当建立完决策树后,再进行剪枝

import csv, pandas as pd
import matplotlib.pyplot as plt
import numpy as np
#import pydotplus
from IPython.display import Image
import graphviz
from sklearn.tree import export_graphviz
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_splitcancer = load_breast_cancer()
featureNames = cancer.feature_names
X_train, x_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=42)# 自动调参,发现第5个最大
list_average_accuracy = []
depth = range(1, 30)
for i in depth:tree = DecisionTreeClassifier(max_depth=i, random_state=0)tree.fit(X_train, y_train)accuracy_training = tree.score(X_train, y_train)accuracy_testing = tree.score(x_test, y_test)average_accuracy = (accuracy_training + accuracy_testing) / 2.0list_average_accuracy.append(average_accuracy)print(i, average_accuracy)max_value = max(list_average_accuracy) # 取出最大值
best_depth = list_average_accuracy.index(max_value)+1 # 取最大值的下标,下标从0开始,加一best_tree = DecisionTreeClassifier(max_depth=best_depth, random_state=0)
best_tree.fit(X_train, y_train)
accuracy_training = best_tree.score(X_train, y_train)
accuracy_testing = best_tree.score(x_test, y_test)
print("accuracy on the trainging subset:{:.3f}".format(best_tree.score(X_train, y_train)))
print("accuracy on the testing subset:{:.3f}".format(best_tree.score(x_test, y_test)))# 绘图,显示因子重要性
n_features = cancer.data.shape[1]
plt.barh(range(n_features), best_tree.feature_importances_, align="center")
plt.yticks(np.arange(n_features), cancer.feature_names)
plt.title("Decision Tree:")
plt.xlabel("Feature Importance")
plt.ylabel("Feature")
plt.show()

输出结果:

accuracy on the trainging subset:0.995
accuracy on the testing subset:0.951


可视化之后,可以看到最重要的几个因子。

我们还可以在上面的代码结尾处,加一句:

export_graphviz(best_tree, out_file="cancertree.dot", class_names=['malignant', 'benign'], feature_names=cancer.feature_names, impurity=False, filled=True)

会得到这样一份文件:

digraph Tree {node [shape=box, style="filled", color="black"] ;
0 [label="worst radius <= 16.795\nsamples = 426\nvalue = [159, 267]\nclass = benign", fillcolor="#afd7f4"] ;
1 [label="worst concave points <= 0.136\nsamples = 284\nvalue = [25, 259]\nclass = benign", fillcolor="#4ca6e8"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="radius error <= 1.048\nsamples = 252\nvalue = [4, 248]\nclass = benign", fillcolor="#3c9fe5"] ;
1 -> 2 ;
3 [label="smoothness error <= 0.003\nsamples = 251\nvalue = [3, 248]\nclass = benign", fillcolor="#3b9ee5"] ;
2 -> 3 ;
4 [label="mean texture <= 19.9\nsamples = 4\nvalue = [1, 3]\nclass = benign", fillcolor="#7bbeee"] ;
3 -> 4 ;
5 [label="samples = 3\nvalue = [0, 3]\nclass = benign", fillcolor="#399de5"] ;
4 -> 5 ;
6 [label="samples = 1\nvalue = [1, 0]\nclass = malignant", fillcolor="#e58139"] ;
4 -> 6 ;
7 [label="area error <= 48.7\nsamples = 247\nvalue = [2, 245]\nclass = benign", fillcolor="#3b9ee5"] ;
3 -> 7 ;
8 [label="samples = 243\nvalue = [1, 242]\nclass = benign", fillcolor="#3a9de5"] ;
7 -> 8 ;
9 [label="samples = 4\nvalue = [1, 3]\nclass = benign", fillcolor="#7bbeee"] ;
7 -> 9 ;
10 [label="samples = 1\nvalue = [1, 0]\nclass = malignant", fillcolor="#e58139"] ;
2 -> 10 ;
11 [label="worst texture <= 25.62\nsamples = 32\nvalue = [21, 11]\nclass = malignant", fillcolor="#f3c3a1"] ;
1 -> 11 ;
12 [label="mean smoothness <= 0.123\nsamples = 12\nvalue = [3, 9]\nclass = benign", fillcolor="#7bbeee"] ;
11 -> 12 ;
13 [label="worst concave points <= 0.138\nsamples = 10\nvalue = [1, 9]\nclass = benign", fillcolor="#4fa8e8"] ;
12 -> 13 ;
14 [label="samples = 1\nvalue = [1, 0]\nclass = malignant", fillcolor="#e58139"] ;
13 -> 14 ;
15 [label="samples = 9\nvalue = [0, 9]\nclass = benign", fillcolor="#399de5"] ;
13 -> 15 ;
16 [label="samples = 2\nvalue = [2, 0]\nclass = malignant", fillcolor="#e58139"] ;
12 -> 16 ;
17 [label="worst symmetry <= 0.268\nsamples = 20\nvalue = [18, 2]\nclass = malignant", fillcolor="#e88f4f"] ;
11 -> 17 ;
18 [label="worst area <= 753.05\nsamples = 3\nvalue = [1, 2]\nclass = benign", fillcolor="#9ccef2"] ;
17 -> 18 ;
19 [label="samples = 2\nvalue = [0, 2]\nclass = benign", fillcolor="#399de5"] ;
18 -> 19 ;
20 [label="samples = 1\nvalue = [1, 0]\nclass = malignant", fillcolor="#e58139"] ;
18 -> 20 ;
21 [label="samples = 17\nvalue = [17, 0]\nclass = malignant", fillcolor="#e58139"] ;
17 -> 21 ;
22 [label="texture error <= 0.473\nsamples = 142\nvalue = [134, 8]\nclass = malignant", fillcolor="#e78945"] ;
0 -> 22 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
23 [label="samples = 5\nvalue = [0, 5]\nclass = benign", fillcolor="#399de5"] ;
22 -> 23 ;
24 [label="worst concavity <= 0.191\nsamples = 137\nvalue = [134, 3]\nclass = malignant", fillcolor="#e6843d"] ;
22 -> 24 ;
25 [label="mean texture <= 21.35\nsamples = 5\nvalue = [2, 3]\nclass = benign", fillcolor="#bddef6"] ;
24 -> 25 ;
26 [label="samples = 3\nvalue = [0, 3]\nclass = benign", fillcolor="#399de5"] ;
25 -> 26 ;
27 [label="samples = 2\nvalue = [2, 0]\nclass = malignant", fillcolor="#e58139"] ;
25 -> 27 ;
28 [label="samples = 132\nvalue = [132, 0]\nclass = malignant", fillcolor="#e58139"] ;
24 -> 28 ;
}

以树的形式可视化,重要的结点就越在上面:

这是dot语言,不止Python可以调用,任何编程语言都可以。

我在图论专栏也用过,关于dot语言,请查看《1. 图的分类与建模、跨语言可视化》

如果想快速上手的话,只需要下载一个软件:

把上面那个dot语言的文件,命名为 xx.dot,就可以打开了。

决策树的优点、缺点

优点:

  • 可读性强,形成树结构图表,利于解释和分析
  • 可以变量筛选

缺点:

  • 运用贪婪算法,得到的是局部最佳值,容易造成过度拟合,最后得到有偏见的树(修剪枝叶,标准化预处理)

随机森林 - random forest

随机森林就是由多个决策树组合而成的投票机制。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancertrees=10000 # 生成10000棵树
cancer=load_breast_cancer()
x_train,x_test,y_train,y_test=train_test_split(cancer.data,cancer.target,random_state=0)
forest=RandomForestClassifier(n_estimators=trees,random_state=0)
# n_estimators表示树的个数,测试中100颗树足够
forest.fit(x_train,y_train)print("random forest with %d trees:"%trees)
print("accuracy on the training subset:{:.3f}".format(forest.score(x_train,y_train)))
print("accuracy on the test subset:{:.3f}".format(forest.score(x_test,y_test)))
print('Feature importances:{}'.format(forest.feature_importances_))n_features=cancer.data.shape[1]
plt.barh(range(n_features),forest.feature_importances_,align='center')
plt.yticks(np.arange(n_features),cancer.feature_names)
plt.title("random forest with %d trees:"%trees)
plt.xlabel('Feature Importance')
plt.ylabel('Feature')
plt.show()

输出结果:

random forest with 10000 trees:
accuracy on the training subset:1.000
accuracy on the test subset:0.972


发现对比单一的决策树的可视化,随机森林可视化会更恰当。

随机森林的优点、缺点

优点:

  • 可用于分类和回归
  • 处理缺失值,并不影响准确性
  • 模型不会过度拟合
  • 可用于高维度,大数据
  • 同盾用的就是随机森林
  • 有效并被广泛使用,默认参数表现良好,不需要正则化处理数据,蒙特卡洛随机处理效果比单个树好

缺点:

  • 分类效果很好,但回归效果更好
  • 此算法是一个黑箱,很难改动参数
  • 高维度,小数据表现较差
  • 不能像树一样可视化
  • 耗时间长,CPU资源占用多

XGBoost

XGBoost是树的提升,集成方法。TA里面的树是线性相互依赖的,后面的树解决前面树损失的问题。

提升就是每一步都产生一个弱预测模型,而后加权累加到总模型中,每一步弱预测模型生成的依据都是损失函数的负梯度方向,这样若干步以后就可以达到逼近损失函数局部最小值的目标,XGBoost体现的就是微积分的思想呀!!

XGBoost官网:https://xgboost.readthedocs.io/en/latest/

  • Windows系统XGBoost下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#xgboost,具体怎么安装可以百度一下

  • MAC系统在Anaconda中安装XGBoost:https://blog.csdn.net/weixin_44750583/article/details/103841216

  • XGBoost调参指南:《完整的机器学习指南,用于Python中的梯度增强(GBM)中的参数调整》

XGBoost常见模型参数:

  • booster:默认 gbtree 效果好(linear booster很少用到)
  • gbtree:基树的模型
  • gbliner:线性模型
  • silent [默认0]
  • nthread[默认值为最大可能的线程数]
  • eta [默认0.3]:学习率,典型为 0.01-0.2
  • min_child_weight[默认1]:决定最小叶子节点样本权重和值较大,避免过拟合值过高,会导致欠拟合
  • max_depth [默认6]
  • gamma [默认0]:指定了节点分裂所需的最小损失函数下降值。这个参数的值越大算法越保守
  • subsample [默认1]:对每棵树,随机采样的比例减小,算法保守,避免过拟合。值设置得过小,它会导致拟合典型值:0.5-1
  • colsample_bytree[默认1]:每棵随机采样的列数的占比
  • colsample_bylevel[默认1]:树的每一级的每一次分裂,对列数的采样的占比
  • lambda[默认1]:权重的L2正则化项
  • alpha[默认1]:权重的L1正则化项
  • scale_pos_weight[默认1]:在各类别样本十分不平衡时,参数设定为一个正值,可以使算法更快收敛
  • objective[默认reg:linear]:最小化的损失函数
  • binary: logistic 二分类的逻辑回归,返回预测的概率(不是类别)
  • multi:softmax使用 softmax 的多分类器,返回预测的类别(不是概率)在这种情况下,你还需要多设一个参数:num_class(类别数目)。 multi: softprob和 multi: softmax参数一样,但是返回的是每个数据属于各个类别的概率
  • eval_metric[默认值取决于objective参数的取值],对于回归问题,默认值是rmse,对于分类问题,默认值是 error典型值有:rmse均方根误差、mae平均绝对误差、logloss负对数似然函数值、error二分类错误率、merror多分类错误率、mlogloss多分类、logloss损失函数、auc曲线下面秩
  • seed(默认0)随机数的种子设置它可以复现随机数据的结果
from xgboost import XGBClassifier
# 导入xgboost包from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_splitcancer=load_breast_cancer()
x_train,x_test,y_train,y_test=train_test_split(cancer.data,cancer.target,random_state=0)clf = XGBClassifier()
clf.fit(x_train, y_train)
print("accuracy on the trainging subset:{:.3f}".format(clf.score(x_train, y_train)))
print("accuracy on the testing subset:{:.3f}".format(clf.score(x_test, y_test)))

输出结果:

accuracy on the trainging subset:1.000
accuracy on the testing subset:0.979
XGBoost 优点、缺点

优点:

  • 精度更高: GBDT 只用到一阶泰勒展开,而 XGBoost 对损失函数进行了二阶泰勒展开。XGBoost 引入二阶导一方面是为了增加精度,另一方面也是为了能够自定义损失函数,二阶泰勒展开可以近似大量损失函数;

  • 灵活性更强: GBDT 以 CART 作为基分类器,XGBoost 不仅支持 CART 还支持线性分类器,使用线性分类器的 XGBoost 相当于带 L 1 L1 L1 和 L 2 L2 L2 正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。此外,XGBoost 工具支持自定义损失函数,只需函数支持一阶和二阶求导;

  • 正则化: XGBoost 在目标函数中加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、叶子节点权重的 L 2 L2 L2 范式。正则项降低了模型的方差,使学习出来的模型更加简单,有助于防止过拟合,这也是XGBoost优于传统GBDT的一个特性。

  • Shrinkage(缩减): 相当于学习速率。XGBoost 在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。传统GBDT的实现也有学习速率;

  • 列抽样: XGBoost 借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算。这也是XGBoost异于传统GBDT的一个特性;

  • 缺失值处理: 对于特征的值有缺失的样本,XGBoost 采用的稀疏感知算法可以自动学习出它的分裂方向;

  • XGBoost工具支持并行: boosting不是一种串行的结构吗?怎么并行的?注意XGBoost的并行不是tree粒度的并行,XGBoost也是一次迭代完才能进行下一次迭代的(第 t t t 次迭代的代价函数里包含了前面 t − 1 t-1 t−1 次迭代的预测值)。XGBoost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),XGBoost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

  • 可并行的近似算法: 树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以XGBoost还提出了一种可并行的近似算法,用于高效地生成候选的分割点。

缺点:

  • 虽然利用预排序和近似算法可以降低寻找最佳分裂点的计算量,但在节点分裂过程中仍需要遍历数据集;

  • 预排序过程的空间复杂度过高,不仅需要存储特征值,还需要存储特征对应样本的梯度统计值的索引,相当于消耗了两倍的内存。


CatBoost

  • catboost官网文档:https://catboost.ai/
  • catboost GPU官方文档:https://catboost.ai/docs/features/training-on-gpu.html
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_splitimport catboost as cbcancer=load_breast_cancer()
X, y = cancer.data,cancer.target
train_x, test_x, train_y, test_y=train_test_split(X,y,test_size=0.3,random_state=0)clf=cb.CatBoostClassifier()
clf.fit(train_x,train_y)
print("accuracy on the training subset:{:.3f}".format(clf.score(train_x,train_y)))
print("accuracy on the test subset:{:.3f}".format(clf.score(test_x,test_y)))

输出结果:

accuracy on the training subset:1.000
accuracy on the test subset:0.965
CatBoost 的优点、缺点
  • 少量或无需调参,默认参数效果非常好

  • 支持分类变量

  • 支持GPU

  • 减少过度拟合,大概1-2%


LightGBM

LightGBM 是一种使用基于树算法的梯度提升框架。

  • LightGBM 官网:https://lightgbm.readthedocs.io/en/latest/index.html。
  • LightGBM Python 快速入门:https://lightgbm.readthedocs.io/en/latest/Python-Intro.html
  • LightGBM 调参:https://lightgbm.readthedocs.io/en/latest/Parameters.html

决策树算法通常是按照树的深度逐级生成树的,从根结点开始,一层一层的生长。

LightGBM 并不是按照次序生长,TA是最佳优先,选择的是收益最高的叶子结点生长。

叶子生长的方式可能会导致过度拟合,因此 LightGBM 包含 max_depth 限制树的深度。

为了使用叶子树获得更好的效果,有一些参数是重点:

  • num_leaves 这是控制树模型复杂性的主要参数。

    从理论上讲,我们可以设置获得与深度树相同数量的叶子,但是,这种简单的转换在实践中并不好。

    原因是对于固定数量的叶子,叶子树通常比深度方式树深的多,无约束的深度会导致过度拟合。

    因此,当试图调整时,我们应该让TA小于,例如,当深度方向树可以获得良好的准确度,但设置为可能导致过度拟合,并将其设置为或可能比深度方式获取更好的准确。

  • min_data_in_leaf 这是防止叶子树过度拟合的一个非常重要的参数。其最佳值取决于训练样本的数量和 num_leaves

    将其设置为较大的值可以避免树长的太深,但可能导致不合适。

    实际上,将其设置为数百或数千对于大型数据集就足够了。

  • max_depth 显示限制树的深度。

如何处理速度、准确性、过度拟合?

一、提树提提速

  • 使用套装 bagging_fractionbagging_freq
  • 使用特征子采样 feature_fraction
  • 参数 max_bin 设置的小一些
  • 使用 save_binary 加快今后的学习数据加载
  • 使用并行学习

二、更好的准确性

  • 参数 max_bin 设置的大一些(但可能会慢一些)
  • 参数 learning_rate 设置小一些,而 num_iterations 设置大一些
  • 参数 num_leaves 设置也大一些(但可能导致过度拟合)
  • 使用更大的训练数据
  • 尝试 dart

三、处理过度拟合

  • 参数 max_bin 设置的小一些
  • 参数 num_leaves 设置也小一些
  • 使用 min_data_in_leafmin_sum_hessian_in_leaf
  • 使用套装 bagging_fractionbagging_freq
  • 按设置使用要素子采样 feature_fraction
  • 使用更大的训练数据
  • 尝试 lambda_l1lambda_l2,并 min_gain_to_split 进行正则化
  • 参数 max_depth 设置的小一些
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_splitimport lightgbm as lgbcancer=load_breast_cancer()
X, y = cancer.data,cancer.target
train_x, test_x, train_y, test_y=train_test_split(X,y,test_size=0.3,random_state=0)clf=lgb.LGBMClassifier()
clf.fit(train_x,train_y)
print("accuracy on the training subset:{:.3f}".format(clf.score(train_x,train_y)))
print("accuracy on the test subset:{:.3f}".format(clf.score(test_x,test_y)))

输出结果:

accuracy on the training subset:1.000
accuracy on the test subset:0.982

LightGBM 和 XGBoost 的结构差异:

  • LightGBM 基于梯度的单边采样
  • XGBoost 通过预分类算法和直方图

所以,LightGBM 速度要快很多。

LightGBM 的优点、缺点

3.乳腺癌细胞预测


4.模型验证


RDKit 化学分子溶解度模型

RDKit 官网:http://www.rdkit.org

打开终端,输入命令即可完成下载:

  • conda install -c conda-forge rdkit

首先,下载化学分子式数据 smi_sol.dat

  • https://download.csdn.net/download/qq_41739364/15646968

数据是 .dat 格式,可以用文本编辑器打开,也可以用 Pandas 读取:

data = pd.read_table('smi_sol.dat', sep=' ')
# 读入数据,pandas的read_table可读取dat文件,TXT可打开dat文件

稍稍介绍一下,这份数据:

  • name:一串数字来编号
  • smiles:化学分子式
  • solubility:分子的溶解度

化学分子式:

我们可以把这些化学分子式可视化:

from rdkit import Chemsmi='C1=CC(=C(C=C1CCN)O)O' # 多巴胺的化学分子式,注意全后面的不是数字0,而是字母O
mol = Chem.MolFromSmiles(smi)
mol                        # 不能写成 print(mol)


在结尾处,加上这一句可以保存:

Chem.Draw.MolToFile(mol, '多巴胺.png')

溶解度是什么?


我们能否用机器学习建模预测分子溶解度呢?

当然可以,但有俩个问题。

  • 这个数据不可计算,你看看化学分子式 smiles 这是啥!

  • 采用哪种算法建模呢?

我们一个一个的看吧。

转换为可计算问题:化学分子式转换为数字

数据不可计算… …最需要考虑的一个问题就是,如何把那个领域的问题转化为信息或者数学问题,这也正是大部分计算机科学家做的事情。

  • 化学分子式转换为数字 — 可计算,便是解决这个问题的核心


图中每个小图上面的是化学分子式,下面长长的数字是把化学分子式传化为矩阵的数字了。

# 计算描述符,定义描述符计算函数
def get_fps(mol):calc = MoleculeDescriptors.MolecularDescriptorCalculator([x[0] for x in Descriptors._descList])ds = np.asarray(calc.CalcDescriptors(mol))arr = Fingerprinter.FingerprintMol(mol)[0]  # Fingerprinter化学指纹return np.append(arr,ds)# 而后调用get_fps,把每个分子形式转换为数字

采用哪种算法建模:随机森林和高斯回归

对于采用哪种算法建模,我们可以看一下 S k l e a r n Sklearn Sklearn 的路线图。

  • https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html

从 START 开始,经过一项一项的判断,最后到了 regression(回归)。

但是TA的回归算法并没有写全,省略了很多。

我们可以在多算法比较,以高斯算法和随机森林举例。

# 随机森林
from rdkit import Chem, DataStructs
from rdkit.Chem import AllChem
from rdkit.ML.Descriptors import MoleculeDescriptors
from rdkit.Chem import Descriptors
from rdkit.Chem.EState import Fingerprinter
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
from sklearn.ensemble import RandomForestRegressor# 计算描述符,定义描述符计算函数
def get_fps(mol):calc = MoleculeDescriptors.MolecularDescriptorCalculator([x[0] for x in Descriptors._descList])ds = np.asarray(calc.CalcDescriptors(mol))arr = Fingerprinter.FingerprintMol(mol)[0]  # Fingerprinter化学指纹return np.append(arr,ds)# 读入数据,pandas的read_table可读取dat文件,TXT可打开dat文件
data = pd.read_table('smi_sol.dat', sep=' ')
data.to_excel("all_data.xlsx")# 增加结构和描述符属性
# Mol为分子式结构
# Chem.MolFromSmiles把smiles字符串形式转换为分子式
data['Mol'] = data['smiles'].apply(Chem.MolFromSmiles)data['Descriptors'] = data['Mol'].apply(get_fps) # 调用get_fps,分子形式转换为数学指纹# 查看前五行
data.head(5)# 转换为numpy数组
X = np.array(list(data['Descriptors']))df_x=pd.DataFrame(X)
df_x.to_excel("data.xlsx")y = data['solubility'].values
df_y=pd.DataFrame(y)
df_y.to_excel("label.xlsx")# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 随机森林模型
rf = RandomForestRegressor(n_estimators=100)
rf.fit(X_train, y_train)# 模型校验
y_pred = rf.predict(X)
rms = (np.mean((y - y_pred)**2))**0.5    # RMS是针对回归模型的验证指标,值越小,性能越好
print ("RF RMS", rms)# 数据可视化
print ("RF r^2 score",r2_score(y,y_pred))
plt.scatter(y_train,rf.predict(X_train), label = 'Train', c='blue')
plt.title('RF Predictor')
plt.xlabel('Measured Solubility')
plt.ylabel('Predicted Solubility')
plt.scatter(y_test,rf.predict(X_test),c='lightgreen', label='Test', alpha = 0.8)
plt.legend(loc=4)
plt.show()df_validation=pd.DataFrame({"test":y,"predict":y_pred})
df_validation.to_excel("validation.xlsx")

输出结果:

RF RMS 0.37978871635473194
RF r^2 score 0.9651924909117522

# 高斯算法
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
from sklearn import gaussian_process
from sklearn.gaussian_process.kernels import Matern, WhiteKernel, ConstantKernel, RBF# 读入数据
data = pd.read_excel('data.xlsx') # 就是 随机森林 产生的 data.xlsx
y =  pd.read_excel('label.xlsx')  # 就是 随机森林 产生的 label.xlsx
# P.S. 考虑到独立性,另外提供下载地址:
# data.xlsx:https://download.csdn.net/download/qq_41739364/15649188
# label.xlsx:https://blog.csdn.net/qq_41739364/article/details/113818246st = StandardScaler()
X = st.fit_transform(data)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)kernel=1.0 * RBF(length_scale=1) + WhiteKernel(noise_level=1)
gp = gaussian_process.GaussianProcessRegressor(kernel=kernel)
gp.fit(X_train, y_train)y_pred, sigma = gp.predict(X_test, return_std=True)
rms = (np.mean((y_test - y_pred)**2))**0.5
print ("GP RMS", rms)
print ("GP r^2 score",r2_score(y_test,y_pred))plt.scatter(y_train,gp.predict(X_train), label = 'Train', c='blue')
plt.title('GP Predictor')
plt.xlabel('Measured Solubility')
plt.ylabel('Predicted Solubility')
plt.scatter(y_test,gp.predict(X_test),c='lightgreen', label='Test', alpha = 0.8)
plt.legend(loc=4)
plt.savefig('GP Predictor.png', dpi=300)
plt.show()

输出结果:

# 有点久,需要多等一下
GP RMS label    0.648551
GP r^2 score 0.8929082532463823

对比高斯算法、随机森林的可视化,紫色、绿色的点基本重合,就代表预测越好,高斯算法的点更分散,说明随机森林更胜一筹。


乳腺医学院

2020年,乳腺癌已成为全球发病率最高的癌症,名副其实的“红颜第一杀手”,但乳腺癌并不可怕。

虽然TA的发病率、死亡情况都位居第一,但乳腺癌如果早期发现,经过规范治疗,患者的五年生存期可以达到90%以上。

大量的乳腺癌幸存者,可以做到长期无瘤生存或者带瘤生存… …而且她们中很多人回归了正常的生活和工作。

乳腺医学院就是一张作战地图,可以帮您填满预防、对抗TA的弹药库。

乳腺、乳腺,乳腺是在哪里呀?

这是一张人体剖面图,图中的一串一串的葡萄就是乳腺了。

乳腺健康,主要是乳房里的 葡萄

红颜第一杀手:乳腺癌细胞挖掘相关推荐

  1. python乳腺癌细胞挖掘

    随着人们生活水平提高,大家不仅关注如何生活,而且关注如何生活得更好.在这个背景下,精准治疗和预测诊断成为当今热门话题. 据权威医学资料统计,全球大约每13分钟就有一人死于乳腺癌,乳腺癌已成为威胁当代人 ...

  2. python机器学习-sklearn挖掘乳腺癌细胞(五)

    python机器学习-sklearn挖掘乳腺癌细胞( 博主亲自录制) 网易云观看地址 https://study.163.com/course/introduction.htm?courseId=10 ...

  3. Nature | 癌细胞喜好夜间行动!研究表明乳腺癌细胞在睡眠期间加速扩散转移

    日出而作,日落而息,是人类生活的基本自然规律,也是昼夜节律的一种.睡眠对人类健康有着至关重要的作用.已有研究证据表明,睡眠与疾病的发展有关,特别是代谢和精神紊乱. 癌症是对人类健康最大的威胁之一.对很 ...

  4. 乳腺癌细胞数据分析Logistic回归模型

    Breast_cancer_cells & Logistic_Regression 数据集以及源代码资源包: 链接:https://pan.baidu.com/s/1VIjTjtSa1Jngq ...

  5. 检测乳腺癌细胞中的有丝分裂(3)

    今天看的文章题目是<A Gamma-Gaussian Mixture Model for Detection of Mitotic Cells in Breast Cancer Histopat ...

  6. python获取当前日期的前一天爆炸_python蒙特卡洛脚本模拟—挑战者号爆炸概率

    python机器学习-乳腺癌细胞挖掘(博主亲自录制视频) 机器学习,统计分项目联系:QQ:231469242 数据 https://github.com/thomas-haslwanter/stats ...

  7. 从0到1Python数据科学之旅

    时值蚂蚁上市之际,马云在上海滩发表演讲.马云的核心逻辑其实只有一个,在全球数字经济时代,有且只有一种金融优势,那就是基于消费者大数据的纯信用! 我们不妨称之为数据信用,它比抵押更靠谱,它比担保更保险, ...

  8. python 卡方检验批量筛选_卡方检验(python代码实现)

    医药统计项目QQ:231469242 分类变量检验方法 卡方分布绘图 如果多个符合正态分布的独立随机变量z1,z2,z3.....zk, z1+z2+z3+....z_k呈现卡方分布,自由度k. 有几 ...

  9. python异常值检测常见方法_outlier异常值检验原理和处理方法

    Before we tackle how to handle them, let's quickly define what an outlier is. An outlier is any data ...

最新文章

  1. matplotlib 散点图_Python学习 —— matplotlib绘制三维曲线图和三维散点图
  2. 250相当于什么显卡_2K(4K)144hz显示器需要什么显卡来带? 本文将给你答案。
  3. flask连接不到mysql数据库,即使使用了python flask mysql,也无法将数据提交到数据库(使用python flask mysql)连接.提交()...
  4. 透明位图的显示(TransparentBlt函数)
  5. VMware下安装CentOS7 无法通过桥接模式进行联网
  6. UI5 EventBus
  7. 电脑安装系统出错蓝屏报错为 STOP 0xc0000020 ,什么原因?
  8. java16进制取前几位_16位16进制数怎么取前8位和后8位
  9. Spark 0.9.0启动脚本——sbin/start-slaves.sh
  10. Pywinauto在Windows Twain Driver自动化测试中的应用研究
  11. 计算机等级考试四级信息安全工程师
  12. ECharts官网实例
  13. 常见的数值积分方法 (欧拉、中值、龙格-库塔,【常用于IMU中】)
  14. vb/vb.net开发技巧荟萃(七)
  15. win7打开chm文件显示“已取消到该网页导航”
  16. 过滤器(Filter)和拦截器(interceptor)区别
  17. go 错误处理与测试
  18. 用户文件下载服务解决方案
  19. @5-1 CCF 2019-12-1 报数
  20. 计算机 计算能力测试题,高中数学计算能力训练题.doc

热门文章

  1. oracle分页怎么查询,oracle简单查询之分页查询
  2. Bitcherry BCHC解决信任危机 助力社交电商站上新风口
  3. 动态生成 iframe;销毁 iframe,释放内存
  4. Region proposals 是什么?如何提取?
  5. 关于网络请求报错:CLEARTEXT communication to xx.xx.xx.xx not permitted by network security policy
  6. PLC与上位机的socket通讯——上位机C#程序(二)
  7. DirectDraw动画编程
  8. DirectX简介 第二篇 DirectDraw简介
  9. python爬虫实例教程-python动态爬虫的实例分享
  10. 怎么解决java.exe闪退_解决Eclipse闪退问题的方法总结