监督学习(英语:Supervised learning),可以由输入数据中学
到或建立一个模型,并依此模式推测新的结果。输入数据是由
输入特征值和目标值所组成。函数的输出可以是一个连续的值
(称为回归),或是输出是有限个离散值(称作分类)。
无监督学习(英语:Supervised learning),可以由输入数据中
学到或建立一个模型,并依此模式推测新的结果。输入数据是
由输入特征值所组成。
sklearn.datasets.load_*()
sklearn.datasets
# 加载获取流行数据集
datasets.load_*()
# 获取小规模数据集,数据包含在datasets里
datasets.fetch_*(data_home=None)
# 获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是 ~/scikit_learn_data/
sklearn.datasets.load_iris()
# 加载并返回鸢尾花数据集
sklearn.datasets.load_digits()
# 加载并返回数字数据集
举例:加载并返回数字数据集
from sklearn.datasets import load_digits
li = load_digits()
print("特征值",li.data)
print("目标值",li.target)
print("描述",li.DESCR)
sklearn.datasets.load_boston()
# 加载并返回波士顿房价数据集
sklearn.datasets.load_diabetes()
# 加载和返回糖尿病数据集
举例:加载并返回波士顿房价数据集
from sklearn.datasets import load_boston
li = load_boston()
print(li.data)
print(li.target)
sklearn.model_selection.train_test_split
sklearn.model_selection.train_test_split(x,y,test_size)
"""
x 数据集的特征值
y 数据集的标签值
test_size 测试集的大小,一般为float
random_state 随机数种子,不同的种子会造成不同的随机
采样结果。相同的种子采样结果相同。
return 训练集特征值,测试集特征值,训练标签,测试标签
(默认随机取)
"""
例:
from sklearn.datasets import load_iris,fetch_20newsgroups
from sklearn.model_selection import train_test_split
li = load_iris()
x_train,x_test,y_train,y_test = train_test_split(li.data,li.target,test_size=0.25)
print("训练集特征值目标值",x_train,y_train)
print("测试集特征值目标值",x_test,y_test)
sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
# subset: 'train'或者'test','all',可选,选择要加载的数据集.训练集的“训练”,测试集的“测试”,两者的“全部”
datasets.clear_data_home(data_home=None)
# 清除目录下的数据
例:
from sklearn.datasets import load_iris,fetch_20newsgroups
from sklearn.model_selection import train_test_split
li = load_iris()
news = fetch_20newsgroups(subset='all')
print(news.data)
print(news.target)
fit_transform() = fit() + transform()
# fit_transform()输入数据直接转换
# fit()输入数据,但不做事(计算平均值,方差等等)
# transform()进行数据转换
from sklearn.preprocessing import StandardScaler
s = StandardScaler()
s.fit([[1,2,3],[4,5,6]])
print(s.transform([[1,2,3],[4,5,6]]))
ss = StandardScaler()
print(s.fit_transform([[1,2,3],[4,5,6]]))
在sklearn中,估计器(estimator)是一个重要的角色,分类器和回归器都属于estimator,是一类实现了算法的API
用于分类的估计器:
k-近邻算法 sklearn.neighbors
贝叶斯 sklearn.naive_bayes
逻辑回归 sklearn.linear_model.LogisticRegression
决策树与随机森林sklearn.tree
用于回归的估计器:
线性回归 sklearn.linear_model.LinearRegression
岭回归 sklearn.linear_model.Ridge
具体步骤:
4. 调用fit():fit(x_train,y_train)
5. 输入测试集数据:(1)y_predict = predict(x_test),(2)预测的准确率:score(x_test,y_test)
sklearn.metrics.classification_report
sklearn.metrics.classification_report(y_true, y_pred, target_names=None)
# y_true:真实目标值
# y_pred:估计器预测目标值
# target_names:目标类别名称
# return:每个类别精确率与召回率
例:classification_report(y_test,y_predict,target_names=news.target_names)
from sklearn.metrics import classification_report
超参数搜索-网格搜索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:指定几折交叉验证
fit:输入训练数据
score:准确率
结果分析:
best_score_:在交叉验证中测试的最好结果
best_estimator_:最好的参数模型
cv_results_:每次交叉验证后的测试集准确率结果和训练集准确率结果
"""
举例:网格搜索对k近邻算法预测调优
from sklearn.model_selection import GridSear
# 进行算法流程 # 超参数
# 1.实例化
knn = KNeighborsClassifier() # 网格搜索时不加参数,否则会按照该参数来评估
# # 2.调用fit ,predict,score
# knn.fit(x_train,y_train)
#
# # 得出预测结果
# y_predict = knn.predict(x_test)
# print("预测的目标签到位置:",y_predict)
#
# # 得出准确率
# print("预测的准确率:", knn.score(x_test,y_test))
# 用网格搜索评估
# 构造一些参数的值进行搜索
param = {"n_neighbors":[3,5,10]}
# 进行网格搜索
gc = GridSearchCV(knn,param_grid=param,cv=2)
gc.fit(x_train,y_train)
# 预测准确率
print("在测试上的准确率:",gc.score(x_test,y_test))
print("在交叉验证中测试的最好结果:",gc.best_score_)
print("最好的参数模型:", gc.best_estimator_)
print("每次交叉验证后的测试集准确率结果和训练集准确率结果:", gc.cv_results_)
前提:需要做标准化处理
原理:你的“邻居”来推断出你的类别,比较样本特征(相似的样本,特征之间的值应该都是相近的)
定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
其中计算距离的公式:
算法类,语法:
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
# n_neighbors:int,可选(默认= 5),k_neig hbors查询默认使用的邻居数
# algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算
# 法:‘ball_tree’将会使用 BallTree,‘kd_tree’将使用 KDTree。‘auto’将尝试根据传递
# 给fit方法的值来决定最合适的算法。 (不同实现方式影响效率)
其中注意:
n_neighbors = k
k值取很小:容易受异常点影响
k值取很大:容易受最近数据太多导致比例变化
实例流程:
数据集的处理:
(1)缩小数据集范围DataFrame.query()
(2).处理日期数据pd.to_datetime ,pd.DatetimeIndex
(3).增加分割的日期数据
(4).删除没用的日期数据pd.drop()
(5).将签到位置少于n个用户的删除[pandas分组]
place_count =data.groupby('place_id').aggregate(np.count_nonzero) ; tf = place_count[place_count.row_id > 3].reset_index(); data = data[data['place_id'].isin(tf.place_id)]
分割数据集
# 取出数据当中的特征值和目标值
y = data['place_id'] # DataFrame类型不能用.data表示特征值,data['place_id']表示目标值
x = data.drop(['place_id'],axis=1) # 除data['place_id']外为特征值
# 进行数据的分割训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)
对数据集进行标准化(提升预测的准确率)
estimator流程进行分类预测
(1).实例化KNeighborsClassifier()
(2).调用 fit ()
(3).得出预测结果predict()
(4).得出准确率score()
综合举例:
# @XST1520203418
# 要天天开心呀
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import pandas as pd
def kng():
"""
:k近邻算法预测用户签到位置
:return:
"""
#读取数据
data = pd.read_csv("D:/ProgramData/机器学习/数据/k近邻算法预测用户签到位置/train.csv")
# print(data.head(10))
#处理数据
#1.缩小数据,查询数据筛选
data = data.query("x>1.0&x<1.25&y>2.5&y<2.75")
#处理时间的数据
time_value = pd.to_datetime(data['time'],unit='s')
# print(time_value)
# 把日期格式转换成 字典格式
time_value = pd.DatetimeIndex(time_value)
# 构造一些新的特征
data['day'] = time_value.day
data['hour'] = time_value.hour
#把时间戳特征删除按列
data = data.drop(['time'],axis=1)
data = data.drop(['row_id'],axis=1)
data = data.drop(['accuracy'],axis=1)
# print(data)
# 把签到数量小于n个目标位置删除[分组]
place_count = data.groupby('place_id').count() # 按place_id相同数量分组
# print(place_count)
tf = place_count[place_count.x > 3].reset_index() # reset_index()表示把索引重新变成数据的一列
data = data[data['place_id'].isin(tf.place_id)]
print(data)
# 取出数据当中的特征值和目标值
y = data['place_id'] # DataFrame类型不能用.data表示特征值
x = data.drop(['place_id'],axis=1)
# 进行数据的分割训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)
# 特征工程(标准化):提升预测的准确率
std = StandardScaler()
# 对测试集和训练集的特征值进行标准化
x_train = std.fit_transform(x_train)
x_test = std.fit_transform(x_test)
# 进行算法流程
# 1.实例化
knn = KNeighborsClassifier(n_neighbors=5)
# 2.调用fit ,predict,score
knn.fit(x_train,y_train)
# 得出预测结果
y_predict = knn.predict(x_test)
print("预测的目标签到位置:",y_predict)
# 得出准确率
print("预测的准确率:", knn.score(x_test,y_test))
if __name__ == '__main__':
kng()
(1)优点:简单,易于理解,易于实现,无需估计参数,无需训练
(2)缺点:懒惰算法,对测试样本分类时的计算量大,内存开销大。必须指定K值,K值选择不当则分类精度不能保证
(3)使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试
条件:任意两个特征之间是相互独立的
但是其中Ni可能为0,但概率不能为0,于是有了拉普拉斯平滑系数
算法类、语法:
sklearn.naive_bayes.MultinomialNB
sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
# 朴素贝叶斯分类
# alpha:拉普拉斯平滑系数
案例流程:
综合举例:
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
def navie():
"""
朴素贝叶斯进行文本分类
:return:
"""
# 获取数据
news = fetch_20newsgroups(subset='all')
# 进行数据分割
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25)
# 对数据集进行特征抽取
# 1.实例化TfidfVectorizer
tf = TfidfVectorizer()
# 2.以训练集当中的词的列表进行每篇文章重要性统计
x_train = tf.fit_transform(x_train)
x_test = tf.transform(x_test)
print(x_train)
# 进行朴素贝叶斯算法的预测
# 1.实例化
mtl = MultinomialNB(alpha=1.0)
# 2.fit()传入数据
mtl.fit(x_train,y_train)
# 3.预测predict
y_predict = mtl.predict(x_test)
print("预测的文章类别为:",y_predict)
# 4.得出准确率score
print("准确率为:",mtl.score(x_test,y_test))
if __name__ == '__main__':
navie()
(1)特点:训练集误差大,结果肯定不好,受训练集影响较大。不需要调参
(2)优点:朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。对缺失数据不太敏感,算法也比较简单,常用于文本分类。分类准确度高,速度快
(3)缺点:需要知道先验概率P(F1,F2,…|C),因此在某些时候会由于假设的先验
模型的原因导致预测效果不佳。
(4)用于文本类预测(该算法前提假设文章中特征词语之间相互独立)
认识决策树:程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法
认识信息熵:
32支球队,log32=5比特
注:信息和消除不确定性是相联系的
决策树的划分依据之:信息增益,基尼系数
注:信息增益表示得知特征X的信息而使得类Y的信息的不确定性减少的程度
API:class sklearn.tree.DecisionTreeClassifier
class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
# 决策树分类器
"""
criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’
max_depth:树的深度大小
random_state:随机数种子
method:
decision_path:返回决策树的路径
"""
决策树预测步骤:
x_train.to_dict(orient="records")
tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])
举例:对泰坦尼克号进行预测生死
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier,export_graphviz
def decision():
"""
决策树对泰坦尼克号进行预测生死
:return:
"""
# 获取数据
titan = pd.read_csv("D:\ProgramData\机器学习\数据\Titanictrain.csv")
# print(titan.head(10).T)
# 处理数据,找出特征值和目标值
x = titan[['Pclass','Age','Sex']] # 特征值
y = titan['Survived'] # 目标值
# 缺失值处理
x['Age'].fillna(x['Age'].mean(),inplace=True) # inplace=True填补回x
# 分割数据集到训练集和测试集
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_train.to_dict(orient="records")默认把一行转换成一个字典
print(dict.get_feature_names())
x_test = dict.transform(x_test.to_dict(orient="records")) # 字典的特征抽取,需要将数据转换成字典类型
# print(x_train)
# 用决策树进行预测
dec = DecisionTreeClassifier(max_depth=10) # max_depth=10可以改变决策树的深度,也会改变预测的准确率
dec.fit(x_train,y_train)
# 预测准确率
print("准确率:",dec.score(x_test,y_test))
# 导出决策树的结构
export_graphviz(dec,out_file="./tree.dot",feature_names=['Age', 'Pclass', 'Sex=female', 'Sex=male'])
if __name__ == '__main__':
decision()
(1)优点:简单的理解和解释,树木可视化。需要很少的数据准备,其他技术通常需要数据归一化。
(2)缺点:决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。决策树可能不稳定,因为数据的小变化可能会导致完全不同的树被生成。
(3)改进:1.减枝cart算法。2.随机森林。
集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测
定义:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
随机森林建立多个决策树的过程(随机又放回的抽样):{N个样本,M个特征}
随机森林API:sklearn.ensemble.RandomForestClassifier
sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’,max_depth=None, bootstrap=True, random_state=None)
# 随机森林分类器
"""
n_estimators:integer,optional(default = 10) 森林里的树木数量
criteria:string,可选(default =“gini”)分割特征的测量方法
max_depth:integer或None,可选(默认=无)树的最大深度
bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样
"""
举例:
from sklearn.ensemble import RandomForestClassifier
# 随机森林进行预测 (超参数调优)
rf = RandomForestClassifier()
param = {"n_estimators":[100,120,200,300],"max_depth":[3,5,8,15]}
# 网格搜索与交叉验证
gc = GridSearchCV(rf,param_grid=param,cv=2)
gc.fit(x_train,y_train)
print("准确率:",gc.score(x_test,y_test))
print("查看选择的参数模型:",gc.best_params_)
(2)无缺点。故使用较多
sklearn.linear_model.LinearRegression
(普通最小二乘线性回归)sklearn.linear_model.SGDRegressor
(通过使用SGD最小化线性模型)实例流程:
# @XST1520203418
# 要天天开心呀
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression,SGDRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
def myliner():
"""
线性回归直接预测房价
:return:
"""
# 获取数据
lb = load_boston()
# 分割数据集到训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(lb.data,lb.target,test_size=0.25)
# print(y_train,y_test)
# 进行标准化处理(为使误差减小,数据之间差距较小,目标值特征值都需要进行标准化处理)
# 实例化两个标准化API
# 特征值标准化
std_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)
# 目标值标准化
std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1,1))
y_test = std_y.transform(y_test.reshape(-1,1))
"""
由于版本问题,0.19版本的转换器、estimator,要求数据必须是二维的,而0.18的二维一维都可以
而y_train,y_test是一维的,所以需要将y_train,y_test转换成二维的:y_train.reshape(-1,1)
"""
# estimator预测
# 正规方程求解方程预测(数据简单使用)
lr = LinearRegression()
lr.fit(x_train,y_train)
print(lr.coef_) # 回归系数
# 预测测试集房价
y_lr_predict = lr.predict(x_test)
print("测试集中每个房子的预测价格(标准化时):",y_lr_predict)
y_lr_predict = std_y.inverse_transform(y_lr_predict)
print("测试集中每个房子的预测价格(无标准化时):", y_lr_predict)
# 梯度下降去预测房价(数据复杂多样使用)
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
print(sgd.coef_) # 回归系数
# 预测测试集房价
y_sgd_predict = sgd.predict(x_test)
print("测试集中每个房子的预测价格(标准化时):", y_sgd_predict)
y_sgd_predict = std_y.inverse_transform(y_sgd_predict)
print("测试集中每个房子的预测价格(无标准化时):", y_sgd_predict)
if __name__ == '__main__':
myliner()
回归评估API:sklearn.metrics.mean_squared_error
mean_squared_error(y_true, y_pred)
# 均方误差回归损失
"""
y_true:真实值,预测值为标准化之前的值
y_pred:预测值
return:浮点数结果
"""
过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合, 但是在训练数据外的数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)
欠拟合:一个假设在训练数据上不能获得更好的拟合, 但是在训练数据外的数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
判断欠拟合与过拟合:
(1)原因:学习到数据的特征过少
(2)解决办法:增加数据的特征数量
欠拟合原因及解决方法:
(1)原因:原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点
(2)解决办法:进行特征选择,消除关联性大的特征(很难做)。
交叉验证(让所有数据都有过训练)。
正则化(了解):
API:sklearn.linear_model.Ridge
sklearn.linear_model.Ridge(alpha=1.0)
# 具有l2正则化的线性最小二乘法
# alpha:正则化力度,默认1.0
# coef_:回归系数
rg = Ridge(alpha=1.0) # alpha=1.0是一个超参数,可以通过网格搜索找到合适数值
rg.fit(x_train, y_train)
print(rg.coef_) # 回归系数
API:sklearn.externals.joblib
可直接下载使用:
import joblib
保存:joblib.dump(rf,'test.pkl')
加载:estimator=joblib.load('test.pkl')
注:文件格式pkl
lr = LinearRegression()
lr.fit(x_train,y_train)
print(lr.coef_) # 回归系数
# 保存模型
joblib.dump(lr,"./test.pkl")
# 加载模型
model = joblib.load("./test.pkl")
# 通过模型预测
y_predict = std_y.inverse_transform(model.predict(x_test))
print("保存的模型预测的结果:",y_predict)
逻辑回归:线性回归的式子作为逻辑回归的输入
逻辑回归:
逻辑回归API:sklearn.linear_model.LogisticRegression
sklearn.linear_model.LogisticRegression(penalty=‘l2’, C = 1.0)
# Logistic回归分类器
# coef_:回归系数
实例流程:
举例:良/恶性乳腺癌肿分类
def logistic():
"""
逻辑回归做二分类进行癌症预测(根据)
:return:
"""
# 构造列表标签名字
names = ['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("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data",names=names)
# print(data)
# 缺失值处理
data = data.replace(to_replace='?',value=np.nan) # 先将数据中的"?"替换成np.nan
data = data.dropna() # 直接删除nan
# 进行数据分割
x = data.drop(["Class"],axis=1) # 特征值
y = data["Class"] # 目标值
# print(x)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)
# 特征工程标准化处理(只需要特征值处理)
std = StandardScaler()
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)
# 逻辑回归预测
lo = LogisticRegression()
lo.fit(x_train,y_train)
print(lo.coef_)
y_predict = lo.predict(x_test)
print("逻辑回归预测值:",y_predict)
print("准确率:",lo.score(x_test,y_test))
print("精确率与召回率:",classification_report(y_test,y_predict,labels=[2,4],target_names=["良性","恶性"]))
if __name__ == '__main__':
logistic()
(1)应用:广告点击率预测、电商购物搭配推荐
(softmax方法-逻辑回归在多分类问题上的推广)
(2)优点:适合需要得到一个分类概率的场景
(2)缺点:当特征空间很大时,逻辑回归的性能不是很好(看硬件能力)
非监督学习特点:物以类聚,人以群分
k-means步骤:
k-means API:sklearn.cluster.KMeans
sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)
# k-means聚类
"""
n_clusters:开始的聚类中心数量
init:初始化方法,默认为'k-means ++’
labels_:默认标记的类型,可以和真实值比较(不是值比较)
"""
实例流程:
降维之后的数据
k-means聚类
聚类结果显示
举例:
# 减少样本数量
x = data[:500]
# print(x)
# 假设k=4,用户分成4个类别
km = KMeans(n_clusters=4)
km.fit(x)
predict = km.predict(x)
# 显示聚类结果
plt.figure(figsize=(10,8),dpi=80)
# 建立四个颜色的列表
colored = ['orange','blue','purple','green']
color = [colored[i] for i in predict]
plt.scatter(x[:1],x[:20],color=color)
plt.show()
Kmeans性能评估指标API:sklearn.metrics.silhouette_score
sklearn.metrics.silhouette_score(X, labels)
# 计算所有样本的平均轮廓系数
"""
X:特征值
labels:被聚类标记的目标值
"""
如果〖〗_ 小于0,说明_ 的平均距离大于最近的其他簇。
聚类效果不好
如果〖〗_ 越大,说明_ 的平均距离小于最近的其他簇。
聚类效果好
轮廓系数的值是介于 [-1,1] ,越趋近于1代表内聚度和分离度都相对较优
总结:
(1)特点分析:采用迭代式算法,直观易懂并且非常实用
(2)缺点:容易收敛到局部最优解(多次聚类)。需要预先设定簇的数量(k-means++解决)