Python机器学习----机器学习算法
sklearn数据集
数据集划分
sklearn机器学习算法的实现-估计器
在sklearn中,估计器(estimator)是一个重要的角色,分类器和回归器都属于estimator,是一类实现了算法的API
-
1、用于分类的估计器:
- sklearn.neighbors k-近邻算法
- sklearn.naive_bayes 贝叶斯
- sklearn.linear_model.LogisticRegression 逻辑回归
-
2、用于回归的估计器:
- sklearn.linear_model.LinearRegression 线性回归
- sklearn.linear_model.Ridge 岭回归
k近邻算法(需要做标准化处理)
根据你的“邻居”来推断出你的类别,使用的是欧式距离。
定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
sklearn k-近邻算法API:sklearn.neighbors.KNeighborsClassifier
- KNeighborsClassifier(n_neighbors=5,algorithm=‘auto’)
- n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数
- algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法:‘ball_tree’将会使用 BallTree,‘kd_tree’将使用 KDTree。‘auto’将尝试根据传递给fit方法的值来决定最合适的算法。 (不同实现方式影响效率)
k值的影响:
- k值取很小:容易受异常点影响
- k值取很大:容易受最近数据太多导致比例变化
优点:
简单,易于理解,易于实现,无需估计参数,无需训练
缺点:
懒惰算法,对测试样本分类时的计算量大,内存开销大,时间复杂度很高,必须指定K值,K值选择不当则分类精度不能保证
朴素贝叶斯
sklearn朴素贝叶斯实现API:sklearn.naive_bayes.MultinomialNB
- sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
- 朴素贝叶斯分类
- alpha:拉普拉斯平滑系数(一般取1)
mlt = MultinomialNB(alpha=1.0)
print(x_train.toarray())
mlt.fit(x_train, y_train)
y_predict = mlt.predict(x_test)
朴素贝叶斯分类优缺点
- 优点:
- 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。
- 对缺失数据不太敏感,算法也比较简单,常用于文本分类。
- 分类准确度高,速度快
- 不需要调参
- 缺点:
- 需要知道先验概率P(F1,F2,…|C),因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。
- 训练***对结果影响特别大
- 假设文章中词语是独立的,不靠谱
分类评估
- 精确率:预测结果为正例样本中真实为正例的比例(查得准)
- 召回率:真实为正例的样本中预测结果为正例的比例(查的全,对正样本的区分能力) — 用的比较多
其他分类标准,F1-score,反映了模型的稳健型
分类模型评估API:sklearn.metrics.classification_report
- sklearn.metrics.classification_report(y_true, y_pred, target_names=None)
- y_true:真实目标值
- y_pred:估计器预测目标值
- target_names:目标类别名称
- return:每个类别精确率与召回率
模型的选择与调优
交叉验证
为了让被评估的模型更加准确可信
交叉验证过程:
交叉验证:将拿到的数据,分为训练和验证集。以下图为例:将数据分
成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同
的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉
验证。
如图:
超参数搜索-网格搜索
通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
超参数搜索-网格搜索API:sklearn.model_selection.GridSearchCV
- sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
- 对估计器的指定参数值进行详尽搜索
- estimator:估计器对象
- param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
- cv:指定几折交叉验证(一般都是10)
- fit:输入训练数据
- score:准确率
- 结果分析:
- best_score_:在交叉验证中测试的最好结果
- best_estimator_:最好的参数模型
- cv_results_:每次交叉验证后的测试集准确率结果和训练集准确率结果
决策树
常见算法:
-
ID3:信息增益 最大的准则
-
C4.5:信息增益比 最大的准则
-
CART
- 回归树: 平方误差 最小
- 分类树: 基尼系数 最小的准则 在sklearn中默认选择划分的原则
基尼系数:划分更加仔细
-
sklearn决策树API:sklearn.tree.DecisionTreeClassifier
- sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
- 决策树分类器
- criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’
- max_depth:树的深度大小
- random_state:随机数种子
- method:
- decision_path:返回决策树的路径
- sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
from sklearn.feature_extraction import DictVectorizer
import pandas as pd
# 获取数据
titan = pd.read_csv("C:/Users/正好/Desktop/aaa.csv")
# 处理数据,找出特征值和目标值
x = titan[['pclass', 'age', 'sex']]
y = titan['survived']
# 缺失值处理
x['age'].fillna(x['age'].mean(), inplace=True)
#先分割数据集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x, y ,test_size=0.25)
# 进行处理(特征工程)特征-》类别-》one_hot编码
dict = DictVectorizer(sparse=False)
x_train = dict.fit_transform(x_train.to_dict(orient="records"))#将数据转换成字典
x_test = dict.transform(x_test.to_dict(orient="records"))
# 用决策树进行预测
from sklearn.tree import DecisionTreeClassifier
dec = DecisionTreeClassifier()
dec.fit(x_train,y_train)
print("这个是默认情况下测试集的准确率:", dec.score(x_test,y_test))
这个是默认情况下测试集的准确率: 0.8085106382978723
决策树的结构、本地保存
sklearn.tree.export_graphviz() 该函数能够导出DOT格式
tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])
from sklearn.tree import export_graphviz
import graphviz
import pydotplus
from IPython.display import Image
# export_graphviz(dec,out_file='./tree.dot',feature_names=dict.get_feature_names())
dot_data = export_graphviz(dec, out_file=None,
feature_names=dict.get_feature_names(),
filled=True, rounded=True,
special_characters=True)
graph = graphviz.Source(dot_data)
graph
graph.render(r'iris')
决策树的优缺点以及改进
- 优点:
- 简单的理解和解释,树木可视化。
- 需要很少的数据准备,其他技术通常需要数据归一化
- 缺点:
- 决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。
- 决策树可能不稳定,因为数据的小变化可能会导致完全不同的树被生成
- 改进:
- 减枝cart算法
- 随机森林
随机森林
定义:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
学习算法
根据下列算法而建造每棵树:
- 用N来表示训练用例(样本)的个数,M表示特征数目。
- 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
- 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
单个树建⽴过程:
- N个样本, M个特征
- 1、随机在N个样本当中选择⼀个样本,重复N次 样本有可能重复
- 2、随机在M个特征当中选出m个特征 m取值
- 建⽴10颗决策树,样本,特征⼤多不⼀样,随机有放回的抽样 bootstrap
为什么要随机抽样训练集?
- 如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的
为什么要有放回地抽样?
- 如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。
随机森林API:
- class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’,max_depth=None, bootstrap=True, random_state=None)
- 随机森林分类器
- n_estimators:integer,optional(default = 10) 森林里的树木数量—120,200,300,500,1200
- criteria:string,可选(default =“gini”)分割特征的测量方法
- max_depth:integer或None,可选(默认=无)树的最大深度 — 5,8,15,25,30
- max_features : auto,sqrt,log2,None,树的最大特征数
- bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样
# 进行随机森林超参数调优
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
# param = {"n_estimators": [120, 200, 300, 500, 800, 1200],
# "max_depth": [5, 8, 15, 25, 30],
# "max_features":["auto","sqrt","log2","None"]}
param = {"n_estimators": [120, 200,1200],
"max_depth": [5,30]}
rf = RandomForestClassifier()
gc = GridSearchCV(rf,param_grid=param,cv=10)
gc.fit(x_train, y_train)
print("准确率:", gc.score(x_test, y_test))
print("查看选择的参数模型:", gc.best_params_)
准确率: 0.8389057750759878
查看选择的参数模型: {‘max_depth’: 5, ‘n_estimators’: 200}
随机森林的优点:
- 在当前所有算法中,具有极好的准确率
- 能够有效地运行在大数据集上(特征多,数据多)
- 能够处理具有高维特征的输入样本,而且不需要降维
- 能够评估各个特征在分类问题上的重要性
- 对于缺省值问题也能够获得很好得结果
模型的保存
-
API:from sklearn.externals import joblib
-
保存:joblib.dump(lr, ‘lr.model’)(lr是一个模型)
-
加载:lr = joblib.load(‘lr.model’)
逻辑回归
sklearn逻辑回归API:sklearn.linear_model.LogisticRegression
- sklearn.linear_model.LogisticRegression(penalty=‘l2’, C = 1.0)
- Logistic回归分类器
- coef_:回归系数
选择目标少的作为判定值
# 构建列名,读取数据
column = ['Sample code number','Clump Thickness', 'Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion', 'Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class']
data = pd.read_csv("C:/Users/正好/Desktop/breast-cancer-wisconsin.data",names=column)
# 缺失值处理
import numpy as np
data = data.replace(to_replace = '?',value = np.nan)
data = data.dropna()
# 进行数据分割
x_train,x_test,y_train,y_test = train_test_split(data[column[1:10]],data[column[10]],test_size = 0.25)
# 进行数据标准化
from sklearn.preprocessing import StandardScaler
std = StandardScaler()
x_test = std.fit_transform(x_test)
x_train = std.transform(x_train)
# 逻辑回归预测
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
lgr = LogisticRegression(penalty="l1")
lgr.fit(x_train,y_train)
y_predict = lgr.predict(x_test)
print(lgr.coef_)
print("准确率:", lgr.score(x_test, y_test))
print("召回率:", classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "恶性"]))
[[1.56413702 0.03144891 0.68358982 1.06153649 0.11143349 2.28123219
1.11208516 0.74018562 0.61786565]]
准确率: 0.9473684210526315
召回率: precision recall f1-score support良性 0.98 0.94 0.96 111
恶性 0.89 0.97 0.93 60accuracy 0.95 171
macro avg 0.94 0.95 0.94 171
weighted avg 0.95 0.95 0.95 171
LogisticRegression总结
- 应用:广告点击率预测、电商购物搭配推荐
- 优点:适合需要得到一个分类概率的场景
- 缺点:当特征空间很大时,逻辑回归的性能不是很好(看硬件能力)
非监督学习
k-mean(聚类 做在分类之前)
k-means步骤
1、随机设置K个特征空间内的点作为初始的聚类中心
2、对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类
中心点作为标记类别
3、接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平
均值)
4、如果计算得出的新中心点与原中心点一样,那么结束,否则重新进行
第二步过程
k-means API:sklearn.cluster.KMeans
- sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)
- k-means聚类
- n_clusters:开始的聚类中心数量
- init:初始化方法,默认为’k-means ++’
- labels_:默认标记的类型,可以和真实值比较(不是值比较)
Kmeans性能评估指标API:sklearn.metrics.silhouette_score(一般不会超过0.7)
Kmeans总结
- 优点
- 采用迭代式算法,直观易懂并且非常实用
- 缺点:
- 容易收敛到局部最优解(多次聚类)
- 需要预先设定簇的数量(k-means++解决)