机器学习算法分类

监督学习

目标值:类别--分类问题
目标值:连续型的数据--回归问题

分类模型

k近邻算法,贝叶斯分类,决策树与随机森林,逻辑回归,SVM,

回归模型

线性回归,岭回归

无监督学习

目标值:无

聚类模型

k-means

机器学习开发流程

  1. 获取数据
  2. 数据清洗
  3. 特征工程(特征值与目标值)
  4. 机器学习算法训练
  5. 模型评估(不好则重新开始)

分类算法

K近邻-KNN

用官方的话来说,所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居), 这K个实例的多数属于某个类,就把该输入实例分类到这个类中。多分类。

图1

如图1所示,有两类不同的样本数据,分别用蓝色的小正方形和红色的小三角形表示,而图正中间的那个绿色的圆所标示的数据则是待分类的数据。也就是说,现在, 我们不知道中间那个绿色的数据是从属于哪一类(蓝色小正方形or红色小三角形),下面,我们就要解决这个问题:给这个绿色的圆分类。
我们常说,物以类聚,人以群分,判别一个人是一个什么样品质特征的人,常常可以从他/她身边的朋友入手,所谓观其友,而识其人。我们不是要判别图1中那个绿色的圆是属于哪一类数据么,好说,从它的邻居下手。但一次性看多少个邻居呢?从图1中,你还能看到:

  • 如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于红色的三角形一类。
  • 如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,还是少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于蓝色的正方形一类。

于此我们看到,当无法判定当前待分类点是从属于已知分类中的哪一类时,我们可以依据统计学的理论看它所处的位置特征,衡量它周围邻居的权重,而把它归为(或分配)到权重更大的那一类。这就是K近邻算法的核心思想。

sklearn 实现

from sklearn import datasets 
#导入内置数据集模块 
from sklearn.neighbors import KNeighborsClassifier 
#导入sklearn.neighbors模块中KNN类
import numpy as np 
np.random.seed(0)
#设置随机种子,不设置的话默认是按系统时间作为参数,因此每次调用随机模块时产生的随机数都不一样设置后每次产生的一样
iris=datasets.load_iris() 
#导入鸢尾花的数据集,iris是一个类似于结构体的东西,内部有样本数据,如果是监督学习还有标签数据
iris_x=iris.data 
 #样本数据150*4二维数据,代表150个样本,每个样本4个属性分别为花瓣和花萼的长、宽
iris_y=iris.target 

indices = np.random.permutation(len(iris_x)) 
#permutation接收一个数作为参数(150),产生一个0-149一维数组,只不过是随机打乱的,当然她也可以接收一个一维数组作为参数,结果是直接对这个数组打乱
indices[:-10]

array([114,  62,  33, 107,   7, 100,  40,  86,  76,  71, 134,  51,  73,
        54,  63,  37,  78,  90,  45,  16, 121,  66,  24,   8, 126,  22,
        44,  97,  93,  26, 137,  84,  27, 127, 132,  59,  18,  83,  61,
        92, 112,   2, 141,  43,  10,  60, 116, 144, 119, 108,  69, 135,
        56,  80, 123, 133, 106, 146,  50, 147,  85,  30, 101,  94,  64,
        89,  91, 125,  48,  13, 111,  95,  20,  15,  52,   3, 149,  98,
         6,  68, 109,  96,  12, 102, 120, 104, 128,  46,  11, 110, 124,
        41, 148,   1, 113, 139,  42,   4, 129,  17,  38,   5,  53, 143,
       105,   0,  34,  28,  55,  75,  35,  23,  74,  31, 118,  57, 131,
        65,  32, 138,  14, 122,  19,  29, 130,  49, 136,  99,  82,  79,
       115, 145,  72,  77,  25,  81, 140, 142,  39,  58])
iris_x_train = iris_x[indices[:-10]]
 #随机选取140个样本作为训练数据集
iris_y_train = iris_y[indices[:-10]] 
#并且选取这140个样本的标签作为训练数据集的标签
iris_x_test = iris_x[indices[-10:]]
 #剩下的10个样本作为测试数据集
iris_y_test = iris_y[indices[-10:]] 
#并且把剩下10个样本对应标签作为测试数据及的标签
knn = KNeighborsClassifier() 
#定义一个knn分类器对象,n_neighbors=5 ,knn算法中指定以最近的几个最近邻样本具有投票权,默认参数为5
knn.fit(iris_x_train, iris_y_train) 
#调用该对象的训练方法,主要接收两个参数:训练数据集及其样本标签

knn.fit(iris_x_train, iris_y_train) 
#调用该对象的训练方法,主要接收两个参数:训练数据集及其样本标签
iris_y_predict = knn.predict(iris_x_test) 
 #调用该对象的测试方法,主要接收一个参数:测试数据集

probility=knn.predict_proba(iris_x_test)  
 #计算各测试样本基于概率的预测

score=knn.score(iris_x_test,iris_y_test,sample_weight=None)
#调用该对象的打分方法,计算出准确率
iris_y_predict
array([1, 2, 1, 0, 0, 0, 2, 1, 2, 0])
probility
array([[0. , 1. , 0. ],
       [0. , 0.4, 0.6],
       [0. , 1. , 0. ],
       [1. , 0. , 0. ],
       [1. , 0. , 0. ],
       [1. , 0. , 0. ],
       [0. , 0. , 1. ],
       [0. , 1. , 0. ],
       [0. , 0. , 1. ],
       [1. , 0. , 0. ]])
score
0.9

参考

Sklearn中的knn算法基本讲解_偏执灬的博客-CSDN博客_knn sklearn

朴素贝叶斯

基于统计学的贝叶斯分类方法以贝叶斯理论为基础,通过求解后验概率分布,预测样本属于某一类别的概率。贝叶斯分类的主要算法是贝叶斯公式:


贝叶斯公式

换一种表达方式:


贝叶斯公式

我们最终求的p(类别|特征)即可!就相当于完成了我们的任务。
from sklearn.naive_bayes import GaussianNB

gnb = GaussianNB()

gnb.fit(iris_x_train, iris_y_train) 

iris_y_predict = gnb.predict(iris_x_test) 
 #调用该对象的测试方法,主要接收一个参数:测试数据集

probility=gnb.predict_proba(iris_x_test)  
 #计算各测试样本基于概率的预测

score=gnb.score(iris_x_test,iris_y_test,sample_weight=None)
#调用该对象的打分方法,计算出准确率

参考

贝叶斯分类(通过通俗的例子轻松理解朴素贝叶斯与半朴素贝叶斯)月亮是蓝色的博客-CSDN博客贝叶斯分类

SVM

支持向量机(Support Vector Machine, SVM)是一类按监督学习(supervised learning)方式对数据进行二元分类的广义线性分类器(generalized linear classifier),其决策边界是对学习样本求解的最大边距超平面(maximum-margin hyperplane)

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from time import time
import numpy as np
import datetim

data = load_breast_cancer()
X = data.data       # (569, 30)
y = data.target     # (569,) 0 1

# 对数据进行标准化
X = StandardScaler().fit_transform(X)
cv = StratifiedShuffleSplit(n_splits=5, test_size=0.3, random_state=420) #分层抽样

for train_index, test_index in cv.split(X, y):
#     print("TRAIN:", train_index, "TEST:", test_index)#获得索引值
    X_train, X_test = X[train_index], X[test_index]#训练集对应的值
    y_train, y_test = y[train_index], y[test_index]#类别集对应的值
clf_svc = SVC(kernel="linear",probability=True)
clf_svc.fit(X_train,y_train)
# 导入模型并训练
iris_y_predict = clf_svc.predict(X_test) 
 #调用该对象的测试方法,主要接收一个参数:测试数据集
probility=clf_svc.predict_proba(X_test)  
 #计算各测试样本基于概率的预测
score=clf_svc.score(X_test,y_test,sample_weight=None)
#调用该对象的打分方法,计算出准确率

混淆矩阵(Confusion Matrix)

Confusion Matrix

混淆矩阵就是把所有类别的预测结果与真实结果按类别放置到了同一个表里,在这个表格中我们可以清楚看到每个类别正确识别的数量和错误识别的数量。
ROC曲线(receiver operating characteristic curve,简称ROC曲线),以TPR为y轴,以FPR为x轴,我们就直接得到了RoC曲线。从FPR和TPR的定义可以理解,TPR越高,FPR越小,我们的模型和算法就越高效。也就是画出来的RoC曲线越靠近左上越好。如下图左图所示。从几何的角度讲,RoC曲线下方的面积越大越大,则模型越优。所以有时候我们用RoC曲线下的面积,即AUC(Area Under Curve)值来作为算法和模型好坏的标准。

from sklearn.metrics import roc_curve, auc

y_score = clf_svc.decision_function(X_test)  #通过decision_function()计算得到的y_score的值,用在roc_curve()函数中
fpr, tpr, threshold = roc_curve(y_test, y_score) # 
roc_auc = auc(fpr,tpr)
plt.figure()  
lw = 2  
plt.figure(figsize=(10,10))  
plt.plot(fpr, tpr, color='darkorange',  
         lw=lw, label='ROC curve (area = %0.2f)' % roc_auc) ###假正率为横坐标,真正率为纵坐标做曲线  
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')  
plt.xlim([0.0, 1.0])  
plt.ylim([0.0, 1.05])  
plt.xlabel('False Positive Rate')  
plt.ylabel('True Positive Rate')  
plt.title('Receiver operating characteristic example')  
plt.legend(loc="lower right")  
plt.show() 
Roc

参考

  1. 机器学习:混淆矩阵、准确率、错误率、灵敏度、特异度、精准率、召回率、F-Measure、ROC曲线 & PR曲线SunshineSki的博客-CSDN博客混淆矩阵 灵敏度
  2. 机器学习之混淆矩阵 (baidu.com)
  3. sklearn之SVM,ROC曲线与AUC面积_thereisnospoon.的博客-CSDN博客

决策树

决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。
决策树是一种树形结构,其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出,最后每个叶节点代表一种分类结果。


决策树
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, class_weight=None, ccp_alpha=0.0)
# 导入需要的算法库和模块
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import graphviz
# 探索数据,也就是查看数据长什么样子
wine = load_wine()
print(wine.data.shape)   #(178, 13)
print(wine.target)
# 查看表长什么样子
import pandas as pd
table=pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)
print(table)
#查看表头的名字
print(wine.feature_names)
#查看表的分类
print(wine.target_names)
['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']
['class_0' 'class_1' 'class_2']
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data,wine.target,test_size=0.3)
print(Xtrain.shape)  #(124, 13)
print(Xtest.shape)   #(54, 13)
clf = tree.DecisionTreeClassifier(criterion="entropy")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest) #返回预测的准确度
print(score)
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
import graphviz
dot_data = tree.export_graphviz(clf
                                ,out_file = None
                                ,feature_names = feature_name
                                ,class_names=["琴酒","雪莉","贝尔摩德"]
                                ,filled=True  #颜色填充
                                ,rounded=True   #框框的圆角
                               ) 
graph = graphviz.Source(dot_data.replace("helvetica", "MicrosoftYaHei"))
graph.view()
[*zip(feature_name,clf.feature_importances_)]
[('酒精', 0.03473796489031354),
 ('苹果酸', 0.0),
 ('灰', 0.0),
 ('灰的碱性', 0.0),
 ('镁', 0.0),
 ('总酚', 0.0),
 ('类黄酮', 0.06831747799131759),
 ('非黄烷类酚类', 0.0),
 ('花青素', 0.0),
 ('颜色强度', 0.15799189175636455),
 ('色调', 0.0),
 ('od280/od315稀释葡萄酒', 0.4238563513218273),
 ('脯氨酸', 0.315096314040177)]

分类树参数列表

参考

sklearn专题一:决策树_Colorfully_lu的博客-CSDN博客_sklearn 决策树

随机森林

随机森林指的是利用多棵树对样本进行训练并预测的一种分类器。
随机选取不同的数据集是为了保证每个决策树看待问题的角度不同,以便输出相似但不相同的模型结果,再讲所有决策树结果整合在一起,作为输出结果,而这一训练方式,意味着很难过拟合,并且对噪音不敏感。

Random Forest

随机森林的优缺点

优点

  • 模型随机性强,不易过拟合;
  • 模型抗噪声性强,对异常点outliter不敏感;
  • 处理高维数据集相比较快,比决策树更快;
  • 树状结构,模型可解释性高,可以体现出每个特征的重要性;

缺点

  • 模型往往过于general,不具备正确处理过于复杂困难样本的能力,这是因为模型对异常点不敏感,随机森林不专注于解决困难样本;
  • 模型起点高,但天花板低;
class sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='sqrt', max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None)
# 导入基本库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier as dtc
from sklearn.ensemble import RandomForestClassifier as rfc
from sklearn.model_selection import cross_val_score
#决策树本身就是非常容易过拟合的算法,而集成模型的参数量/复杂度很难支持大规模网格搜索
#因此对于随机森林来说,一定要关注算法的过拟合情况
wine=load_wine()
x=pd.DataFrame(wine.data,columns=wine.feature_names)
y=wine.target
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3,random_state=1)
# 建模对比
clf_tree=dtc().fit(xtrain,ytrain)
clf_cf=rfc().fit(xtrain,ytrain)
score_tree=clf_tree.score(xtest,ytest)
score_cf=clf_cf.score(xtest,ytest)
print(score_tree,score_cf)
plt.rcParams['font.sans-serif'] = ['SimHei']
rfc_s = cross_val_score(rfc(),x,y,cv=10)
dtc_s = cross_val_score(dtc(),x,y,cv=10)
plt.plot(range(1,11),rfc_s,label = "RandomForest")
plt.plot(range(1,11),dtc_s,label = "Decision Tree")
plt.legend()
plt.title("随机森林和决策树在一组交叉验证下的效果对比")
plt.show()
效果对比

参数调整和决策树类似

参考

机器学习 | 随机森林 - 知乎 (zhihu.com)

神经网络-分类

人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。
神经网络
*class *sklearn.neural_network.MLPClassifier(*hidden_layer_sizes=(100,)*, *activation='relu'*, ***, *solver='adam'*, *alpha=0.0001*, *batch_size='auto'*, *learning_rate='constant'*, *learning_rate_init=0.001*, *power_t=0.5*, *max_iter=200*, *shuffle=True*, *random_state=None*, *tol=0.0001*, *verbose=False*, *warm_start=False*, *momentum=0.9*, *nesterovs_momentum=True*, *early_stopping=False*, *validation_fraction=0.1*, *beta_1=0.9*, *beta_2=0.999*, *epsilon=1e-08*, *n_iter_no_change=10*, *max_fun=15000*)[[source]](https://github.com/scikit-learn/scikit-learn/blob/36958fb24/sklearn/neural_network/_multilayer_perceptron.py#L793)
from sklearn.datasets import load_digits
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn import metrics

data = load_digits()
x = data.data
y = data.target
print(x.shape,y.shape)
stander = MinMaxScaler()
x = stander.fit_transform(x)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3)

clf = MLPClassifier(hidden_layer_sizes=(100,100))
clf.fit(x_train,y_train)
y_pred = clf.predict((x_test))
print("训练集评分:", clf.score(x_train,y_train))
print("测试集评分:", clf.score(x_test,y_test))
print("混淆矩阵:")
print(metrics.confusion_matrix(y_test,y_pred))
(1797, 64) (1797,)
训练集评分: 1.0
测试集评分: 0.975925925925926
混淆矩阵:
[[51  0  0  0  0  0  1  0  0  0]
 [ 0 49  0  0  0  0  0  0  1  0]
 [ 0  0 63  0  0  0  0  0  0  0]
 [ 0  0  0 55  0  2  0  2  0  0]
 [ 0  0  0  0 56  0  0  0  0  0]
 [ 0  0  0  0  0 46  0  0  0  0]
 [ 0  0  0  0  0  0 53  0  0  0]
 [ 0  0  0  0  0  0  0 56  0  2]
 [ 0  0  1  0  0  1  0  0 54  2]
 [ 0  0  0  0  0  1  0  0  0 44]]

参考

一文了解神经网络工作原理-51CTO.COM
神经网络③——sklearn参数介绍及应用数据小斑马的博客-CSDN博客神经网络sklearn
sklearn 神经网络MLPclassifier参数详解_九点澡堂子的博客-CSDN博客_mlpclassifier

分层采样

你的数据集很大时(尤其是和属性数相比),纯随机的取样方法通常可行;但如果数据集不大,就会有采样偏差的风险。当一个调查公司想要对 1000 个人进行调查,它们不是在电话亭里随机选 1000 个人出来。调查公司要保证这 1000 个人对人群整体有代表性。例如,美国人口的 51.3% 是女性,48.7% 是男性。所以在美国, 严谨的调查需要保证样本也是这个比例:513 名女性,487 名男性。这称作分层采样 (stratified sampling):将人群分成均匀的子分组,称为分层,从每个分层去取合适数量的实例,以保证测试集对总人数有代表性。如果调查公司采用纯随机采样,会有 12% 的概率导致采样偏差:女性人数少于 49%,或多于 54%。不管发生那种情况,调查结果都会严重偏差。
纯随机的取样方法,即没有对原数据集进行分层:

from sklearn.model_selection import train_test_split
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3,random_state=1)

分层采样,对原始数据进行分层

    # 分层抽样 训练测试
    from sklearn.model_selection import StratifiedShuffleSplit
    sss = StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=randoms)

    for train_index, test_index in sss.split(X, y):  # 这里循环的次数由n_splits决定,前面指定的5
            #print("TRAIN:", train_index, "TEST:", test_index)
            X_train, X_test = X[train_index], X[test_index]
            y_train, y_test = y[train_index], y[test_index]

交叉验证

交叉验证是在机器学习建立模型和验证模型参数时常用的办法,一般被用于评估一个机器学习模型的表现。更多的情况下,我们也用交叉验证来进行模型选择(model selection)
交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。在此基础上可以得到多组不同的训练集和测试集,某次训练集中的某样本在下次可能成为测试集中的样本,即所谓“交叉”。
那么什么时候才需要交叉验证呢?交叉验证用在数据不是很充足的时候。如果数据样本量小于一万条,我们就会采用交叉验证来训练优化选择模型。如果样本大于一万条的话,我们一般随机的把数据分成三份,一份为训练集(Training Set),一份为验证集(Validation Set),最后一份为测试集(Test Set)。用训练集来训练模型,用验证集来评估模型预测的好坏和选择模型及其对应的参数。把最终得到的模型再用于测试集,最终决定使用哪个模型以及对应参数。

Cross-Validation

k折交叉验证 k-fold cross validation

首先随机地将数据集切分为 k 个互不相交的大小相同的子集;
然后将 k-1 个子集当成训练集训练模型,剩下的 (held out) 一个子集当测试集测试模型;将上一步对可能的 k 种选择重复进行 (每次挑一个不同的子集做测试集);这样就训练了 k 个模型,每个模型都在相应的测试集上计算测试误差,得到了 k 个测试误差,对这 k 次的测试误差取平均便得到一个交叉验证误差。这便是交叉验证的过程。

from sklearn.model_selection import KFold
from sklearn.datasets import load_iris
from sklearn.linear_model import LinearRegression
import numpy as np
import pandas as pd

KF = KFold(n_splits=5)
X, Y = load_iris().data, load_iris().target
alg = LinearRegression()
# 这里想强行使用DataFrame的数据格式,因为以后大家读取数据使用都是csv格式
# 所以必不可免要用 iloc
X, Y = pd.DataFrame(X), pd.DataFrame(Y)
# split():Generate indices to split data into training and test set.
for train_index, test_index in KF.split(X):
    print("TRAIN:", train_index, "TEST:", test_index)
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    y_train, y_test = Y.iloc[train_index], Y.iloc[test_index]
    alg.fit(X_train, y_train)
sklearn.model_selection.cross_val_score(estimator, X, y=None, *, groups=None, scoring=None, cv=None, n_jobs=None, verbose=0, fit_params=None, pre_dispatch='2*n_jobs', error_score=nan)

参数:
estimator:模型算法对象。比如lin_reg.
X : 训练样本。
y:样本标签。
cv : int, cross-validation generator or an iterable, default=None. 确定交叉验证的数据集划分策略。
cross-validation generator的话就是1.中讲的那些放方法,所以可以传kf,loo,lpo,
int的话,就是指几折,然后用普通的kfold.

# 使用交叉验证评估模型
lin_reg = LinearRegression()
# 先划分训练集和测试集,75%训练
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, shuffle=True, random_state=0)
# 10折交叉验证评分
score = cross_val_score(estimator=lin_reg, X=X_train, y=y_train, cv=10)
print('交叉验证评分:\n', score, sep='')
# cross_val_score这一个函数干了很多事情,划分数据集、对每个划分进行了训练、对每个划分进行了测试评分。

交叉验证可以有效评估模型的质量
交叉验证可以有效选择在数据集上表现最好的模型
交叉验证可以有效避免过拟合和欠拟合
 • 欠拟合(Underfitting)
  是指模型不能获取数据集的主要信息,在训练集及测试集上的表示都十分糟糕。
 • 过拟合(Overfitting)
  是指模型不仅获取了数据集的信息还提取了噪声数据的信息是的模型在训练集有非常好的表现但在测试集上的表现及其糟糕。

参考

机器学习 交叉验证 sklearn_Michael_Flemming的博客-CSDN博客_sklearn的交叉验证
交叉验证(Cross-Validation)南有芙蕖的博客-CSDN博客交叉验证

网格搜索 GridSearch

网格搜索算法是一种通过遍历给定的参数组合来优化模型表现的方法。它是一种穷举方法。给定一系列超参,然后再所有超参组合中穷举遍历,从所有组合中选出最优的一组超参数,其实就是暴力方法在全部解中找最优解。
使用内置乳腺癌数据来训练支持向量分类(SVC)。可以通过load_breast_cancer函数获取数据:

import pandas as pd
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
df_X = pd.DataFrame(cancer['data'], columns=cancer['feature_names'])
df_X.head()
df_y = pd.DataFrame(cancer['target'], columns=['Cancer'])
df_y.head()
# train test split 
from sklearn.model_selection import train_test_split 
import numpy as np
X_train, X_test, y_train, y_test = train_test_split(df_X, np.ravel(df_y), test_size=0.3)

我们将训练支持向量分类器(SVC) 模型。正则化参数C和核系数gamma是 SVC 中最重要的两个超参数:

正则化参数C决定了正则化的强度。
核系数gamma控制核的宽度。SVC默认使用径向基函数 (RBF)核(也称为高斯核)。

最优值C和gamma是比较难找得到的。最简单的解决方案是尝试一堆组合,看看哪种组合效果最好。这种创建参数“网格”并尝试所有可能组合的方法称为网格搜索。
这种方法非常常见,所以Scikit-learn在GridSearchCV中内置了这种功能。CV 代表交叉验证,这是另一种评估和改进机器学习模型的技术。

GridSearchCV需要一个描述准备尝试的参数和要训练的模型的字典。网格搜索的参数网格定义为字典,其中键是参数,值是要测试的一系列设置值。下面动手试试,首先定义候选参数C和gamma,如下所示:

param_grid = { 
  'C': [0.1, 1, 10, 100, 1000], 
  'gamma': [1, 0.1, 0.01, 0.001, 0.0001] 
}

接下来创建一个GridSearchCV对象,并使用训练数据进行训练模型。

from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
 
grid = GridSearchCV(
    SVC(), 
    param_grid, 
    refit=True, 
    verbose=3
)

一旦训练完成后,我们可以通过GridSearchCV的best_params_属性查看搜索到的最佳参数,并使用best_estimator_属性查看最佳模型:

# 找到最好的参数
grid.best_params_
# 找到最好的模型
grid.best_estimator_

训练完成后,现在选择并采用该网格搜索到的最佳模型,并使用测试集进行预测

# 使用最好的估计器进行预测
grid_predictions = grid.predict(X_test)

参考

网格搜索、随机搜索和贝叶斯搜索实用教程_风度78的博客-CSDN博客

回归

多元线性回归 LinearRegression

线性回归是机器学习中最简单的回归算法,多元线性回归指的就是一个样本有多个特征的线性回归问题。对于一个n有 i 个特征的样本 而言,它的回归结果可以写作一个几乎人人熟悉的方程:


线性回归
class sklearn.linear_model.LinearRegression(*, fit_intercept=True, normalize='deprecated', copy_X=True, n_jobs=None, positive=False)

没有对我们的模型有不可替代作用的参数,这说明,线性回归的性能,往往取决于数据本身,而并非是我们的调参能力,线性回归也因此对数据有着很高的要求.

from sklearn.linear_model import LinearRegression as LR
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.datasets import fetch_california_housing as fch #加利福尼亚房屋价值数据集
import pandas as pd
housevalue = fch() #会需要下载,大家可以提前运行试试看
X = pd.DataFrame(housevalue.data) #放入DataFrame中便于查看
y = housevalue.target
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)
# 恢复索引
for i in [Xtrain, Xtest]:
      i.index = range(i.shape[0])
Xtrain.shape
reg = LR().fit(Xtrain, Ytrain)
yhat = reg.predict(Xtest)
yhat
reg.coef_
[*zip(Xtrain.columns,reg.coef_)]
reg.intercept_

评估指标

MSE :
sklearn中使用RSS的变体,均方误差MSE(mean squared error)来衡量我们的预测值和真实值的差异:

from sklearn.metrics import mean_squared_error as MSE
MSE(yhat,Ytest)

对于某些拟合模型,如果我们使用MSE来对它进行判断,它的MSE会很小,当大部分样本其实都被完美拟合了,少数样本的真实值和预测值的巨大差异在被均分到每个样本上之后,MSE就会很小。但这样的拟合结果必然不是一个好结果,因为一旦我的新样本是处于拟合曲线的后半段的,我的预测结果必然会有巨大的偏差,而这不是我们希望看到的。所以,我们希望找到新的指标,除了判断预测的数值是否正确之外,还能够判断我们的模型是否拟合了足够多的,数值之外的信息。

R^2:
可解释性方差分数(explained_variance_score,EVS):

from sklearn.metrics import r2_score
r2_score(Ytest,yhat)
#或者直接指定参数
r2_score(y_true = Ytest,y_pred = yhat)

岭回归

class sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,
normalize=False, copy_X=True,max_iter=None, tol=0.001, solver=auto’ ,
random_state=None)
from sklearn.linear_model import Ridge
reg = Ridge(alpha=1).fit(Xtrain, Ytrain)
reg.score(Xtest,Ytest)
#交叉验证下,与线性回归相比,岭回归的结果如何变化?
import numpy as np
alpharange =np.arange(1,1001,100)
ridge ,lr=[],[]
for alpha in alpharange:
    reg=Ridge(alpha=alpha)
    linear=LR()
    regs=cross_val_score(reg,X,y,cv=5,scoring='r2').mean()
    linears=cross_val_score( linear,X,y,cv=5,scoring='r2').mean()
    ridge.append(regs)
    lr.append(linears)
plt.plot(alpharange,ridge,color="red",label="Ridge")
plt.plot(alpharange,lr,color="blue",label="LR")
plt.legend()
plt.show()

对比

Ridge专门的选择最好alpha的交叉验证

class sklearn. linear_model. Ridgecv(alphas=(0.1,1.0,10.0), fit
intercept=True, normalize=False,scoring=None,cv=None,store_cv _values=False)
from sklearn.linear_model import RidgeCV
Ridge_=RidgeCV(alphas=np. arange(1,1001,100)
                 #, scoring="neg_mean_squared_error"
                 , store_cv_values=True
                  #, cv=5
              ). fit(X,y)
#不交叉验证的结果              
Ridge_.score(X,y)
#每个alpha下的结果
Ridge_.cv_values_.mean(axis=0)
# 选择的最佳值
Ridge_.alpha_

多项式回归

普遍的用于解决"线性回归只能处理线性数据"问题的手段

class sklearn.preprocessing.Po1ynomialFeatures(degree=2,
interaction_only=False, include_bias=True)
参数
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
 
d=5#多项式维度
rnd=np.random.RandomState(40)#设置随机数种子
X = rnd.uniform(-3, 3, size=100) #random.uniform,从输入的任意两个整数中取出size个随机数
#生成y的思路:先使用NumPy中的函数生成一个sin函数图像,然后再人为添加噪音
y = np.sin(X) + rnd.normal(size=len(X)) / 3 #random.normal,生成size个服从正态分布的随机数
X = X.reshape(-1, 1)
line = np.linspace(-3, 3, 1000, endpoint=False).reshape(-1, 1)#测试集数据
line_=PolynomialFeatures(degree=d).fit_transform(line)
 
LinearR = LinearRegression().fit(X, y)
X_=PolynomialFeatures(degree=d).fit_transform(X)#对数据进行多项式处理 重要!!!
LinearR_=LinearRegression().fit(X_, y)

参考

sklearn 线性回归_kingsure001的博客-CSDN博客_sklearn 线性回归
机器学习sklearn-多项式回归_kongqing23的博客-CSDN博客_sklearn多项式回归

其他回归模型

SVR

SVM 回归算法称为支持向量回归或SVR。支持向量回归是一种监督学习算法,用于预测离散值。支持向量回归使用与 SVM 相同的原理。SVR 背后的基本思想是找到最佳拟合线。在 SVR 中,最佳拟合线是点数最多的超平面。

class sklearn.svm.SVR(*, kernel='rbf', degree=3, gamma='scale', coef0=0.0, tol=0.001, C=1.0, epsilon=0.1, shrinking=True, cache_size=200, verbose=False, max_iter=-1)
from sklearn.svm import SVR
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
import numpy as np

n_samples, n_features = 10, 5
rng = np.random.RandomState(0)
y = rng.randn(n_samples)
X = rng.randn(n_samples, n_features)
regr = make_pipeline(StandardScaler(), SVR(C=1.0, epsilon=0.2))
regr.fit(X, y)

参考

机器学习笔记 - 什么是支持向量回归(SVR)?坐望云起的博客-CSDN博客支持向量机回归

RandomForestRegressor

与决策树回归的参数类似

class sklearn.ensemble.RandomForestRegressor(n_estimators=100, *, criterion='squared_error', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=1.0, max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, ccp_alpha=0.0, max_samples=None)
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import make_regression
X, y = make_regression(n_features=4, n_informative=2,
                       random_state=0, shuffle=False)
regr = RandomForestRegressor(max_depth=2, random_state=0)
regr.fit(X, y)

print(regr.predict([[0, 0, 0, 0]]))

参考

sklearn.ensemble.RandomForestRegressor

神经网络-回归

*class *sklearn.neural_network.MLPRegressor(*hidden_layer_sizes=(100,)*, *activation='relu'*, ***, *solver='adam'*, *alpha=0.0001*, *batch_size='auto'*, *learning_rate='constant'*, *learning_rate_init=0.001*, *power_t=0.5*, *max_iter=200*, *shuffle=True*, *random_state=None*, *tol=0.0001*, *verbose=False*, *warm_start=False*, *momentum=0.9*, *nesterovs_momentum=True*, *early_stopping=False*, *validation_fraction=0.1*, *beta_1=0.9*, *beta_2=0.999*, *epsilon=1e-08*, *n_iter_no_change=10*, *max_fun=15000*)[[source]](https://github.com/scikit-learn/scikit-learn/blob/36958fb24/sklearn/neural_network/_multilayer_perceptron.py#L1266) [](https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPRegressor.html#sklearn.neural_network.MLPRegressor "Permalink to this definition")
data_ = [
         [ -0.017612,14.053064,14.035452],[ -1.395634, 4.662541, 3.266907],[ -0.752157, 6.53862,5.786463],[ -1.322371, 7.152853, 5.830482],
         [0.423363,11.054677,11.47804 ],[0.406704, 7.067335, 7.474039],[0.667394,12.741452,13.408846],[ -2.46015,6.866805, 4.406655],
         [0.569411, 9.548755,10.118166],[ -0.026632,10.427743,10.401111],[0.850433, 6.920334, 7.770767],[1.347183,13.1755,14.522683],
         [1.176813, 3.16702,4.343833],[ -1.781871, 9.097953, 7.316082],[ -0.566606, 5.749003, 5.182397],[0.931635, 1.589505, 2.52114 ],
         [ -0.024205, 6.151823, 6.127618],[ -0.036453, 2.690988, 2.654535],[ -0.196949, 0.444165, 0.247216],[1.014459, 5.754399, 6.768858],
         [1.985298, 3.230619, 5.215917],[ -1.693453,-0.55754, -2.250993],[ -0.576525,11.778922,11.202397],[ -0.346811,-1.67873, -2.025541],
         [ -2.124484, 2.672471, 0.547987],[1.217916, 9.597015,10.814931],[ -0.733928, 9.098687, 8.364759],[1.416614, 9.619232,11.035846],
         [1.38861,9.341997,10.730607],[0.317029,14.739025,15.056054]
]

data1 = np.array(data_)
print(data1)
X = data1[:, 0:2]
Y = data1[:, 2]
scaler = StandardScaler() # 标准化转换
scaler.fit(X)  # 训练标准化对象
X = scaler.transform(X)   # 转换数据集

clf = MLPRegressor(solver='lbfgs',alpha=1e-5, hidden_layer_sizes=(5,2), random_state=1)
clf.fit(X,Y)
pred = clf.predict([[0.317029, 14.739025]])
print('回归预测结果:', pred)
[[-0.017612 14.053064 14.035452]
 [-1.395634  4.662541  3.266907]
 [-0.752157  6.53862   5.786463]
 [-1.322371  7.152853  5.830482]
 [ 0.423363 11.054677 11.47804 ]
 [ 0.406704  7.067335  7.474039]
 [ 0.667394 12.741452 13.408846]
 [-2.46015   6.866805  4.406655]
 [ 0.569411  9.548755 10.118166]
 [-0.026632 10.427743 10.401111]
 [ 0.850433  6.920334  7.770767]
 [ 1.347183 13.1755   14.522683]
 [ 1.176813  3.16702   4.343833]
 [-1.781871  9.097953  7.316082]
 [-0.566606  5.749003  5.182397]
 [ 0.931635  1.589505  2.52114 ]
 [-0.024205  6.151823  6.127618]
 [-0.036453  2.690988  2.654535]
 [-0.196949  0.444165  0.247216]
 [ 1.014459  5.754399  6.768858]
 [ 1.985298  3.230619  5.215917]
 [-1.693453 -0.55754  -2.250993]
 [-0.576525 11.778922 11.202397]
 [-0.346811 -1.67873  -2.025541]
 [-2.124484  2.672471  0.547987]
 [ 1.217916  9.597015 10.814931]
 [-0.733928  9.098687  8.364759]
 [ 1.416614  9.619232 11.035846]
 [ 1.38861   9.341997 10.730607]
 [ 0.317029 14.739025 15.056054]]
回归预测结果: [24.30993116]

聚类

K-means

k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是,预将数据分为K组,则随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。

*class *sklearn.cluster.KMeans(*n_clusters=8*, ***, *init='k-means++'*, *n_init=10*, *max_iter=300*, *tol=0.0001*, *verbose=0*, *random_state=None*, *copy_x=True*, *algorithm='lloyd'*)[[source]](https://github.com/scikit-learn/scikit-learn/blob/36958fb24/sklearn/cluster/_kmeans.py#L1126) [](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans "Permalink to this definition")
import numpy as np
import matplotlib.pyplot as plt

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

plt.figure(figsize=(12, 12))

n_samples = 1500
random_state = 170
X, y = make_blobs(n_samples=n_samples, random_state=random_state)

# Incorrect number of clusters
y_pred = KMeans(n_clusters=2, random_state=random_state).fit_predict(X)

plt.subplot(221)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.title("Incorrect Number of Blobs")

# Anisotropicly distributed data
transformation = [[0.60834549, -0.63667341], [-0.40887718, 0.85253229]]
X_aniso = np.dot(X, transformation)
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_aniso)

plt.subplot(222)
plt.scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)
plt.title("Anisotropicly Distributed Blobs")

# Different variance
X_varied, y_varied = make_blobs(
    n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state
)
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_varied)

plt.subplot(223)
plt.scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)
plt.title("Unequal Variance")

# Unevenly sized blobs
X_filtered = np.vstack((X[y == 0][:500], X[y == 1][:100], X[y == 2][:10]))
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_filtered)

plt.subplot(224)
plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)
plt.title("Unevenly Sized Blobs")

plt.show()

聚类

参考

sklearn聚类算法之Kmeans_GallopZhang的博客-CSDN博客_kmeans聚类 sklearn

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容