已经使用的软件
numpy
pandas
Matplotlib
tables
jutyper
sklearn
安装scikit-learn需要Numpy, Scipy等库
包含内容
分类、聚类、回归
特征工程
模型选择、调优
sklearn.datasets.load_iris()
归一化
注意最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景。
# coding:utf-8
from sklearn.preprocessing import MinMaxScaler, StandardScaler
import pandas as pd
data = pd.read_csv("./data/dating.txt")
print(data)
# # 1.归一化
# # 1.1 实例化一个转换器
transfer = MinMaxScaler(feature_range=(0, 10))
# # 1.2 调用fit_transfrom方法
minmax_data = transfer.fit_transform(data[['milage', 'Liters', 'Consumtime']])
print("经过归一化处理之后的数据为:\n", minmax_data)
# 2.标准化
# 2.1 实例化一个转换器
transfer = StandardScaler()
# 2.2 调用fit_transfrom方法
minmax_data = transfer.fit_transform(data[['milage', 'Liters', 'Consumtime']])
print("经过标准化处理之后的数据为:\n", minmax_data)
example:
# coding:utf-8
from sklearn.neighbors import KNeighborsClassifier
# 获取数据
x = [[1], [2], [0], [0]]
y = [1, 1, 0, 0]
# 机器学习
# 1.实例化一个训练模型
estimator = KNeighborsClassifier(n_neighbors=2)
# 2.调用fit方法进行训练
estimator.fit(x, y)
# 预测其他值
ret = estimator.predict([[24]])
print(f'输出结果是{ret}')
案例一鸢尾花种类预测–数据集介绍
# coding:utf-8
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.datasets import load_iris, fetch_20newsgroups
from sklearn.model_selection import train_test_split
# 1.数据集获取
# 1.1 小数据集获取
iris = load_iris()
# print(f'第一次展示数据{iris}');
# 1.2 大数据集获取
news = fetch_20newsgroups()
# print(news)
# 2.数据集属性描述
# print("数据集中特征值是:\n", iris.data)
# print("数据集中目标值是:\n", iris["target"])
# print("数据集中特征值名字是:\n", iris.feature_names)
# print("数据集中目标值名字是:\n", iris.target_names)
# print("数据集的描述:\n", iris.DESCR)
# 3.数据可视化
# 3.1 数据类型转换,把数据用DataFrame存储
iris_data = pd.DataFrame(data=iris.data, columns=['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width'])
iris_data["target"] = iris.target
# print(iris_data)
def iris_plot(data, col1, col2):
sns.lmplot(x=col1, y=col2, data=data, hue="target", fit_reg=False)
plt.title("鸢尾花数据展示")
plt.xlabel(col1)
plt.ylabel(col2)
plt.show()
# iris_plot(iris_data, "Sepal_Length", 'Petal_Width')
# iris_plot(iris_data, 'Sepal_Width', 'Petal_Length')
# 4.数据集的划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=2)
# print("训练集的特征值是:\n", x_train)
# print("训练集的目标值是:\n", y_train)
# print("测试集的特征值是:\n", x_test)
# print("测试集的目标值是:\n", y_test)
# print("训练集的目标值形状:\n", y_train.shape)
# print("测试集的目标值形状:\n", y_test.shape)
x_train1, x_test1, y_train1, y_test1 = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
x_train2, x_test2, y_train2, y_test2 = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
print("测试集的目标值是:\n", y_test1)
print("测试集的目标值是:\n", y_test2)
seaborn介绍
案例2-鸢尾花种类预测—流程实现
# coding:utf-8
"""
1.获取数据集
2.数据基本处理
3.特征工程
4.机器学习(模型训练)
5.模型评估
"""
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
# 1.获取数据集
iris = load_iris()
# 2.数据基本处理
# 2.1 数据分割
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22, test_size=0.2)
# 3.特征工程
# 3.1 实例化一个转换器
transfer = StandardScaler()
# 3.2 调用fit_transform方法
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习(模型训练)
# 4.1 实例化一个估计器
estimator = KNeighborsClassifier(n_neighbors=5)
# 4.2 模型训练
estimator.fit(x_train, y_train)
# 5.模型评估
# 5.1 输出预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
print("预测值和真实值对比:\n", y_pre == y_test)
# 5.2 输出准确率
ret = estimator.score(x_test, y_test)
print("准确率是:\n", ret)
(1)构造根结点,使根结点对应于K维空间中包含所有实例点的超矩形区域;
(2)通过递归的方法,不断地对k维空间进行切分,生成子结点。在超矩形区域上选择一个坐标轴和在此坐标轴上的一个切分点,确定一个超平面,这个超平面通过选定的切分点并垂直于选定的坐标轴,将当前超矩形区域切分为左右两个子区域(子结点);这时,实例被分到两个子区域。
(3)上述过程直到子区域内没有实例时终止(终止时的结点为叶结点)。在此过程中,将实例保存在相应的结点上。
(4)通常,循环的选择坐标轴对空间切分,选择训练实例点在坐标轴上的中位数为切分点,这样得到的kd树是平衡的(平衡二叉树:它是一棵空树,或其左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是平衡二叉树)。
KD树中每个节点是一个向量,和二叉树按照数的大小划分不同的是,KD树每层需要选定向量中的某一维,然后根据这一维按左小右大的方式划分数据。在构建KD树时,关键需要解决2个问题:
(1)选择向量的哪一维进行划分;
(2)如何划分数据;
第一个问题简单的解决方法可以是随机选择某一维或按顺序选择,但是更好的方法应该是在数据比较分散的那一维进行划分(分散的程度可以根据方差来衡量)。好的划分方法可以使构建的树比较平衡,可以每次选择中位数来进行划分,这样问题2也得到了解决。
首先通过二叉树搜索(比较待查询节点和分裂节点的分裂维的值,小于等于就进入左子树分支,大于就进入右子树分支直到叶子结点),顺着“搜索路径”很快能找到最近邻的近似点,也就是与待查询点处于同一个子空间的叶子结点;
然后再回溯搜索路径,并判断搜索路径上的结点的其他子结点空间中是否可能有距离查询点更近的数据点,如果有可能,则需要跳到其他子结点空间中去搜索(将其他子结点加入到搜索路径)。
重复这个过程直到搜索路径为空。
数据分训练集与测试集
交叉验证目的:为了让被评估的模型更加准确可信
并不一定可以提高模型准确率
通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
# coding:utf-8
"""
1.获取数据集
2.数据基本处理
3.特征工程
4.机器学习(模型训练)
5.模型评估
"""
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
# 1.获取数据集
iris = load_iris()
# 2.数据基本处理
# 2.1 数据分割
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)
# 3.特征工程
# 3.1 实例化一个转换器
transfer = StandardScaler()
# 3.2 调用fit_transform方法
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习(模型训练)
# 4.1 实例化一个估计器
estimator = KNeighborsClassifier()
# 4.2 调用交叉验证网格搜索模型
param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=10, n_jobs=-1)
# 4.3 模型训练
estimator.fit(x_train, y_train)
# 5.模型评估
# 5.1 输出预测值
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
print("预测值和真实值对比:\n", y_pre == y_test)
# 5.2 输出准确率
ret = estimator.score(x_test, y_test)
print("准确率是:\n", ret)
# 5.3 其他评价指标
print("最好的模型:\n", estimator.best_estimator_)
print("最好的结果:\n", estimator.best_score_)
print("整体模型结果:\n", estimator.cv_results_)
import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
# 1、获取数据集
facebook = pd.read_csv("./data/FBlocation/train.csv")
# 2.基本数据处理
# 2.1 缩小数据范围
facebook_data = facebook.query("x>2.0 & x<2.5 & y>2.0 & y<2.5")
# 2.2 选择时间特征
time = pd.to_datetime(facebook_data["time"], unit="s")
time = pd.DatetimeIndex(time)
facebook_data["day"] = time.day
facebook_data["hour"] = time.hour
facebook_data["weekday"] = time.weekday
# 2.3 去掉签到较少的地方
place_count = facebook_data.groupby("place_id").count()
place_count = place_count[place_count["row_id"]>3]
facebook_data = facebook_data[facebook_data["place_id"].isin(place_count.index)] # 表示包含在此集中
# 2.4 确定特征值和目标值
x = facebook_data[["x", "y", "accuracy", "day", "hour", "weekday"]]
y = facebook_data["place_id"]
# 2.5 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# 3.特征工程--特征预处理(标准化)
# 3.1 实例化一个转换器
transfer = StandardScaler()
# 3.2 调用fit_transform
x_train = transfer.fit_transform(x_train)
# x_test = transfer.transform(x_test) # 也可以直接调用训练好的转换器,因为差距不大,直接调用可以节省时间
x_test = transfer.fit_transform(x_test)
# 4.机器学习--knn+cv
# 4.1 实例化一个估计器
estimator = KNeighborsClassifier()
# 4.2 调用gridsearchCV
param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5)
# 4.3 模型训练
estimator.fit(x_train, y_train)
# 5.模型评估
# 5.1 基本评估方式
score = estimator.score(x_test, y_test)
print("最后预测的准确率为:\n", score)
y_predict = estimator.predict(x_test)
print("最后的预测值为:\n", y_predict)
print("预测值和真实值的对比情况:\n", y_predict == y_test)
# 5.2 使用交叉验证后的评估方式
print("在交叉验证中验证的最好结果:\n", estimator.best_score_)
print("最好的参数模型:\n", estimator.best_estimator_)
print("每次交叉验证后的验证集准确率结果和训练集准确率结果:\n",estimator.cv_results_)
定义
利用回归方程(Linear regression)(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式
特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归
表示方式:
h(w) = w1x1 + w2x2 + w3x3 + … + b
= W转置x + b
分类
线性关系
非线性关系 如果是非线性关系,那么回归方程可以理解为:w1x1+w2x22+w3x3^2
正规方程 与 梯度下降法
利用矩阵的逆,转置进行一步求解
只是适合样本和特征比较少的情况
理解:X为特征值矩阵,y为目标值矩阵。直接求到最好的结果
缺点:当特征过多过复杂时,求解速度太慢并且得不到结果
梯度下降法介绍
1 全梯度下降算法(FG):在进行计算的时候,计算所有样本的误差平均值,作为我的目标函数
2 随机梯度下降算法(SG):每次只选择一个样本进行考核
3 小批量梯度下降算法(mini-bantch):选择一部分样本进行考核 (用的最多)
4 随机平均梯度下降算法(SAG):会给每个样本都维持一个平均值,后期计算的时候,参考这个平均值
拓展(深度学习再学)
动量法、Nesterov加速梯度下降法、Adagrad、Adadelta、RMSProp、Adam
梯度下降法和正规方程对比:
梯度下降 | 正规方程 |
---|---|
需要选择学习率 | 不需要 |
需要迭代求解 | 一次运算得出 |
特征数量较大可以使用 | 需要计算方程,时间复杂度高O(n3) |
选择:
解决过拟合有很多方法,线性回归选择正则化。但是对于其他机器学习算法如分类算法来说也会出现这样的问题,除了一些算法本身作用之外(决策树、神经网络),我们更多的也是去自己做特征选择,包括之前说的删除、合并一些特征
正则化:在学习的时候,数据提供的特征有些影响模型复杂度或者这个特征的数据点异常较多,所以算法在学习的时候尽量减少这个特征的影响(甚至删除某个特征的影响)
注:调整时候,算法并不知道某个特征影响,而是去调整参数得出优化的结果
类别:
维数灾难与过拟合
维数灾难:随着维度(特征数量)的增加,分类器的性能却下降了
高维空间训练形成的线性分类器,相当于在低维空间的一个复杂的非线性分类器
训练集的维度越多,过度拟合的风险就越大。
所需的训练实例数量随着使用的维度数量呈指数增长。
α值越小,系数值越大,α越大,系数值越小
2. Lasso 回归
对系数值进行绝对值处理
由于绝对值在顶点处不可导,所以进行计算的过程中产生很多0,最后得到结果为:稀疏矩阵
3. Elastic Net 弹性网络
是前两个内容的综合
设置了一个r,如果r=0–岭回归;r=1–Lasso回归
选择:
均方误差(Mean Squared Error)MSE)评价机制:
注:yi为预测值,¯y为真实值
sklearn.linear_model.LinearRegression(fit_intercept=True)
sklearn.linear_model.SGDRegressor(loss=“squared_loss”, fit_intercept=True, learning_rate =‘invscaling’, eta0=0.01)
Ridge方法相当于SGDRegressor(penalty=‘l2’, loss=“squared_loss”),只不过SGDRegressor实现了一个普通的随机梯度下降学习,推荐使用Ridge(实现了SAG)
sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)
正则化力度越大,权重系数会越小
正则化力度越小,权重系数会越大
# coding:utf-8
"""
1.获取数据
2.数据基本处理
2.1 数据集划分
3.特征工程 --标准化
4.机器学习(线性回归)
5.模型评估
"""
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, RidgeCV
from sklearn.metrics import mean_squared_error
def linear_model1():
"""
正规方程
:return: None
"""
# 1.获取数据
boston = load_boston()
# 2.数据基本处理
# 2.1 数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程 --标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习(线性回归)
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n", estimator.intercept_)
# 5.模型评估
# 5.1 预测值和准确率
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
score = estimator.score(x_test, y_test)
print("准确率是:\n", score)
# 5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差是:\n", ret)
def linear_model2():
"""
梯度下降法
:return: None
"""
# 1.获取数据
boston = load_boston()
# 2.数据基本处理
# 2.1 数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程 --标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习(线性回归)
estimator = SGDRegressor(max_iter=1000, learning_rate="constant", eta0=0.001)
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n", estimator.intercept_)
# 5.模型评估
# 5.1 预测值和准确率
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
score = estimator.score(x_test, y_test)
print("准确率是:\n", score)
# 5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差是:\n", ret)
def linear_model3():
"""
岭回归
:return: None
"""
# 1.获取数据
boston = load_boston()
# 2.数据基本处理
# 2.1 数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程 --标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习(线性回归)
# estimator = Ridge()
estimator = RidgeCV(alphas=(0.001, 0.1, 1, 10, 100))
estimator.fit(x_train, y_train)
print("这个模型的偏置是:\n", estimator.intercept_)
# 5.模型评估
# 5.1 预测值和准确率
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
score = estimator.score(x_test, y_test)
print("准确率是:\n", score)
# 5.2 均方误差
ret = mean_squared_error(y_test, y_pre)
print("均方误差是:\n", ret)
if __name__ == '__main__':
linear_model1()
linear_model2()
linear_model3()
def load_dump_demo():
"""
线性回归:岭回归
:return:
"""
# 1.获取数据
data = load_boston()
# 2.数据集划分
x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, random_state=22)
# 3.特征工程-标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习-线性回归(岭回归)
# # 4.1 模型训练
# estimator = Ridge(alpha=1)
# estimator.fit(x_train, y_train)
#
# # 4.2 模型保存
# joblib.dump(estimator, "./data/test.pkl")
# 4.3 模型加载
estimator = joblib.load("./data/test.pkl")
# 5.模型评估
# 5.1 获取系数等值
y_predict = estimator.predict(x_test)
print("预测值为:\n", y_predict)
print("模型中的系数为:\n", estimator.coef_)
print("模型中的偏置为:\n", estimator.intercept_)
# 5.2 评价
# 均方误差
error = mean_squared_error(y_test, y_predict)
print("误差为:\n", error)
解决的是一个二分类问题
逻辑回归的输入是线性回归的输出
把整体的值映射到[0,1]
再设置一个阈值,进行分类判断
优化
提升原本属于1类别的概率,降低原本是0类别的概率。
默认将类别数量少的当做正例
LogisticRegression方法相当于 SGDClassifier(loss=“log”, penalty=" "),SGDClassifier实现了一个普通的随机梯度下降学习。而使用LogisticRegression(实现了SAG)
在很多分类场景当中我们不一定只关注预测的准确率。比如以这个癌症举例子!!!我们并不关注预测的准确率,而是关注在所有的样本当中,癌症患者有没有被全部预测(检测)出来。
在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适用于多分类)
ROC曲线
ROC曲线的横轴就是FPRate,纵轴就是TPRate,当二者相等时,表示的意义则是:对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的,此时AUC为0.5(可以理解为面积)
AUC指标
最终AUC的范围在[0.5, 1]之间,并且越接近1越好
AUC只能用来评价二分类
AUC非常适合评价样本不平衡中的分类器性能
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn.metrics import roc_auc_score
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# 1.获取数据
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)
data.head()
# 2.基本数据处理
# 2.1 缺失值处理
data = data.replace(to_replace="?", value=np.NaN)
data = data.dropna()
# 2.2 确定特征值,目标值
x = data.iloc[:, 1:10]
x.head()
y = data["Class"]
y.head()
# 2.3 分割数据
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# 3.特征工程(标准化)
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4.机器学习(逻辑回归)
estimator = LogisticRegression()
estimator.fit(x_train, y_train)
# 5.模型评估
# 5.1 基本评估
y_pre = estimator.predict(x_test)
print("预测值是:\n", y_pre)
score = estimator.score(x_test, y_test)
print("准确率是:\n", score)
# 5.2 其他评估
ret = classification_report(y_test, y_pre, labels=(2,4), target_names=("良性", "恶性"))
print(ret)
# 不平衡二分类问题评估方法
y_test = np.where(y_test>3, 1, 0)
roc_auc_score(y_true=y_test, y_score=y_pre)
决策树:是一种树形结构,其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出,最后每个叶节点代表一种分类结果,本质是一颗由多个判断节点组成的树。
1.熵
用于衡量一个对象的有序程度
系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
2.信息熵
1.从信息的完整性上进行的描述:
当系统的有序状态一致时,数据越集中的地方熵值越小,数据越分散的地方熵值越大。
2.从信息的有序性上进行的描述:
当数据量一致时,系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
3.把信息转换成熵值
-plogp
增益率:增益比率度量是用前面的增益度量Gain(S,A)和所分离信息度量SplitInformation(如上例的性别,活跃度等)的比值来共同定义的。
基尼值Gini(D):从数据集D中随机抽取两个样本,其类别标记不一致的概率。 故,Gini(D)值越小,数据集D的纯度越高。
基尼指数Gini_index(D):一般,选择使划分后基尼系数最小的属性作为最优化分属性。
(1) ID3算法在选择根节点和各内部节点中的分支属性时,采用信息增益作为评价标准。 信息增益的缺点是倾向于选择取值较多的属性,在有些情况下这类属性可能不会提供太多有价值的信息.
(2) ID3算法只能对描述属性为离散型属性的数据集构造决策树。
(1) 用信息增益率来选择属性
(2) 可以处理连续数值型属性
(3)采用了一种后剪枝方法
(4)对于缺失值的处理
C4.5算法的优缺点
优点:
产生的分类规则易于理解,准确率较高。
缺点:
在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。
此外,C4.5只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时程序无法运行。
同时,无论是ID3, C4.5还是CART,在做特征选择的时候都是选择最优的一个特征来做分类决策,但是大多数,分类决策不应该是由某一个特征决定的,而是应该由一组特征决定的。 这样决策得到的决策树更加准确。 这个决策树叫做多变量决策树(multi-variate decision tree)。 在选择最优特征的时候,多变量决策树不是选择某一个最优特征,而是选择最优的一个特征线性组合来做决策。 这个算法的代表是OC1,这里不多介绍。
如果样本发生一点点的改动,就会导致树结构的剧烈改变。 这个可以通过集成学习里面的随机森林之类的方法解决。
随着树的增长,在训练样集上的精度是单调上升的, 然而在独立的测试样例上测出的精度先上升后下降。
预剪枝
(1)每一个结点所包含的最小样本数目,例如10,则该结点总样本数小于10时,则不再分;
(2)指定树的高度或者深度,例如树的最大深度为4;
(3)指定结点的熵小于某个值,不再划分。随着树的增长, 在训练样集上的精度是单调上升的, 然而在独立的测试样例上测出的精度先上升后下降。
后剪枝:
后剪枝,在已生成过拟合决策树上进行剪枝,可以得到简化版的剪枝决策树。
定义:将任意数据(如文本或图像)转换为可用于机器学习的数字特征
对字典数据进行特征值化
转化为
对于特征当中存在类别信息的我们都会做one-hot编码处理
对文本数据进行特征值化
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率
逆向文档频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到
Tf-idf的重要性:分类机器学习算法进行文章分类中前期数据处理方式
# coding:utf-8
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
import jieba
def dict_demo():
"""
字典特征提取
:return:
"""
data = [{'city': '北京', 'temperature': 100},
{'city': '上海', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]
# 字典特征提取
# 1.实例化
transfer = DictVectorizer(sparse=False)
# 2.调用fit_transform
trans_data = transfer.fit_transform(data)
print("特征名字是:\n", transfer.get_feature_names())
print(trans_data)
def english_count_text_demo():
"""
文本特征提取 -- 英文
:return: NOne
"""
data = ["life is is short,i like python",
"life is too long,i dislike python"]
# 1.实例化
# transfer = CountVectorizer(sparse=False) # 注意,没有sparse
transfer = CountVectorizer(stop_words=["dislike"])
# 2.调用fit_transform
transfer_data = transfer.fit_transform(data)
print(transfer.get_feature_names())
print(transfer_data.toarray()) # 用于看到sparse矩阵
def chinese_count_text_demo1():
"""
文本特征提取 -- 中文
:return: NOne
"""
data = ["人生 苦短, 我 喜欢 Python",
"生活 太长久, 我 不 喜欢 Python"]
# 1.实例化
transfer = CountVectorizer()
# 2.调用fit_transform
transfer_data = transfer.fit_transform(data)
print(transfer.get_feature_names())
print(transfer_data.toarray())
def cut_word(sen):
"""
中文分词
:return: sen
"""
# print(" ".join(list(jieba.cut(sen))))
return " ".join(list(jieba.cut(sen)))
def chinese_count_text_demo2():
"""
文本特征提取 -- 中文
:return: NOne
"""
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
list = []
for temp in data:
# print(temp)
list.append(cut_word(temp))
print(list)
# 1.实例化
transfer = CountVectorizer(stop_words=["一种", "还是"])
# 2.调用fit_transform
transfer_data = transfer.fit_transform(list)
print(transfer.get_feature_names())
print(transfer_data.toarray())
def tfidf_text_demo():
"""
文本特征提取 -- 中文
:return: NOne
"""
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
list = []
for temp in data:
# print(temp)
list.append(cut_word(temp))
# print(list)
# 1.实例化
# transfer = CountVectorizer(stop_words=["一种", "还是"])
transfer = TfidfVectorizer()
# 2.调用fit_transform
transfer_data = transfer.fit_transform(list)
print(transfer.get_feature_names())
print(transfer_data.toarray())
if __name__ == '__main__':
# dict_demo()
# english_count_text_demo()
# chinese_count_text_demo1()
# cut_word("我喜欢你中国")
chinese_count_text_demo2()
# tfidf_text_demo()
乘坐班是指乘客班(1,2,3),是社会经济阶层的代表。
其中age数据存在缺失。
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
data = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
# 2.数据基本处理
# 2.1 确定特征值,目标值
x = data[["pclass", "age", "sex"]]
x.head()
y = data["survived"]
y.head()
# 2.2 缺失值处理
x["age"].fillna(value=data["age"].mean(), inplace=True)
# 2.3 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22, test_size=0.2)
# 3.特征工程(字典特征抽取)
x_train = x_train.to_dict(orient="records")
x_test = x_test.to_dict(orient="records")
"""
# 对于x转换成字典数据x.to_dict(orient="records")
# [{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]
transfer = DictVectorizer(sparse=False)
x_train = transfer.fit_transform(x_train.to_dict(orient="records"))
x_test = transfer.fit_transform(x_test.to_dict(orient="records"))
"""
# 4.机器学习(决策树)
estimator = DecisionTreeClassifier(criterion="entropy", max_depth=5)
estimator.fit(x_train, y_train)
# 5.模型评估
estimator.score(x_test, y_test)
estimator.predict(x_test)
# 可视化
export_graphviz(estimator, out_file="./data/tree.dot", feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
保存树的结构到dot文件
把文件内的内容复制到网站内生成图
http://webgraphviz.com/
注:企业重要决策,由于决策树很好的分析能力,在决策过程应用较多, 可以选择特征
集成学习通过建立几个模型来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测。
只要单分类器的表现不太差,集成学习的结果总是要好于单分类器的.
目标:将样本进行分类
实现过程
在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
随机森林 = Bagging + 决策树
思考 注意 Bagging + 决策树/线性回归/逻辑回归/深度学习… = bagging集成学习方法 经过上面方式组成的集成学习方法: 随着学习的积累从弱到强 简而言之:每新加入一个弱学习器,整体能力就会得到提升 代表算法:Adaboost,GBDT,XGBoost 实现过程: 关键点: api链接:https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html#sklearn.ensemble.AdaBoostClassifier 梯度提升决策树(GBDT Gradient Boosting Decision Tree) 是一种迭代的决策树算法,该算法由多棵决策树组成,所有树的结论累加起来做最终答案。它在被提出之初就被认为是泛化能力(generalization)较强的算法。近些年更因为被用于搜索排序的机器学习模型而引起大家关注。 例子: XGBoost= 二阶泰勒展开+boosting+决策树+正则化 面试题:了解XGBoost么,请详细说说它的原理 Boosting:XGBoost使用Boosting提升思想对多个弱学习器进行迭代式学习 二阶泰勒展开:每一轮学习中,XGBoost对损失函数进行二阶泰勒展开,使用一阶和二阶梯度进行优化。 决策树:在每一轮学习中,XGBoost使用决策树算法作为弱学习进行优化。 正则化:在优化过程中XGBoost为防止过拟合,在损失函数中加入惩罚项,限制决策树的叶子节点个数以及决策树叶子节点的值。 一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。 在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。 k-means其实包含两层内容: K : 初始中心点个数(计划聚类数) means:求中心点到其他数据点距离的平均值 流程: SC系数(轮廓系数法):取值为[-1, 1],其值越大越好 优点: 缺点: 降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组**“不相关”主变量**的过程 两种方式 数据中包含冗余或无关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征。 删除低方差的一些特征,前面讲过方差的意义。再结合方差的大小来考虑这个方式的角度。 主要实现方式: 相关系数的值介于–1与+1之间,即–1≤ r ≤+1。其性质如下: api: from scipy.stats import pearsonr 斯皮尔曼相关系数(Rank IC) 与之前的皮尔逊相关系数大小性质一样,取值 [-1, 1]之间 api from scipy.stats import spearmanr
随机森林够造过程中的关键步骤(用N来表示训练用例(样本)的个数,M表示特征数目):
1)一次随机选出一个样本,有放回的抽样,重复N次(有可能出现重复的样本)
2) 随机去选出m个特征, m <
1.为什么要随机抽样训练集?
如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的
2.为什么要有放回地抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。api
案例
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction import DictVectorizer
# from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.ensemble import RandomForestClassifier
# 1.获取数据
data = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
# 2.数据基本处理
# 2.1 确定特征值,目标值
x = data[["pclass", "age", "sex"]]
y = data["survived"]
# 2.2 缺失值处理
x["age"].fillna(value=data["age"].mean(), inplace=True)
# 2.3 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22, test_size=0.2)
# 3.特征工程(字典特征抽取)
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习(模型训练)
estimator = RandomForestClassifier()
param_grid = {"n_estimators": [120,200,300,500,800,1200], "max_depth": [5, 8, 15, 25, 30]}
# 超参数调优 网格搜索
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5)
estimator.fit(x_train, y_train)
estimator.score(x_test, y_test)
print("随机森林预测的准确率为:", estimator.score(x_test, y_test))
bagging集成优点
Boosting
boosting集成原理
AdaBoost的构造过程小结
api
from sklearn.ensemble import AdaBoostClassifierbagging集成与boosting集成的区别:
GBDT(了解)
如果上式中的hi(x)=决策树模型,则上式就变为:
GBDT = 梯度下降 + Boosting + 决策树
GBDT主要执行思想
1.使用梯度下降法优化代价函数;
2.使用一层决策树作为弱学习器,负梯度作为目标值;
3.利用boosting思想进行集成。XGBoost【了解】
回答要点:二阶泰勒展开,boosting,决策树,正则化6. 聚类
K-means聚类api
案例
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabaz_score
# 创建数据集
# X为样本特征,Y为样本簇类别, 共1000个样本,每个样本4个特征,共4个簇,
# 簇中心在[-1,-1], [0,0],[1,1], [2,2], 簇方差分别为[0.4, 0.2, 0.2, 0.2]
X, y = make_blobs(n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state=9)
# 数据集可视化
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show()
y_pred = KMeans(n_clusters=2, random_state=9).fit_predict(X)
# 分别尝试n_cluses=2\3\4,然后查看聚类效果
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
# 用Calinski-Harabasz Index评估的聚类分数
print(calinski_harabaz_score(X, y_pred))
k-means聚类算法实现流程
k-means模型评估
结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果:
每次聚类后,每个样本都会得到一个轮廓系数,当它为1时,说明这个点与周围簇距离较远,结果非常好,当它为0,说明这个点可能处在两个簇的边界上,当值为负时,暗含该点可能被误分了。k-means聚类算法优化
优化方法
思路
Canopy+kmeans
Canopy粗聚类配合kmeans
kmeans++
距离越远越容易成为新的质心
二分k-means
拆除SSE最大的簇
k-medoids
和kmeans选取中心点的方式不同
kernel kmeans
映射到高维空间
ISODATA
动态聚类
Mini-batch K-Means
大数据集分批聚类
特征工程-特征降维
特征选择
低方差特征过滤
api
# coding:utf-8
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
def var_thr():
"""
特征选择:低方差特征过滤
:return:
"""
data = pd.read_csv("./data/factor_returns.csv")
print(data)
transfer = VarianceThreshold(threshold=10)
trans_data = transfer.fit_transform(data.iloc[:, 1:10])
print("之前数据的形状:\n",data.iloc[:, 1:10].shape)
print("之后数据的形状:\n",trans_data.shape)
print(trans_data)
pass
if __name__ == '__main__':
var_thr()
相关系数
斯皮尔曼相关系数表明 X (自变量) 和 Y (因变量)的相关方向。 如果当X增加时, Y 趋向于增加, 斯皮尔曼相关系数则为正# coding:utf-8
from scipy.stats import pearsonr, spearmanr
# 皮尔逊演示
x1 = [12.5, 15.3, 23.2, 26.4, 33.5, 34.4, 39.4, 45.2, 55.4, 60.9]
x2 = [21.2, 23.9, 32.9, 34.1, 42.5, 43.2, 49.0, 52.8, 59.4, 63.5]
ret = pearsonr(x1, x2)
print("这两列数据的皮尔逊相关系数为:\n", ret)
ret = spearmanr(x1, x2)
print("这两列数据的斯皮尔曼相关系数为:\n", ret)
主成分分析(PCA)
api
案例
# coding:utf-8
from sklearn.decomposition import PCA
data = [[2, 8, 4, 5],
[6, 3, 0, 8],
[5, 4, 9, 1]]
# 1.保留到多少维度
# transfer = PCA(n_components=2)
# trans_data = transfer.fit_transform(data)
# print(trans_data)
# 2.保留信息的百分比
transfer = PCA(n_components=0.95)
transfer_data = transfer.fit_transform(data)
print(transfer_data)
k-means案例
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# 1.获取数据
order_product = pd.read_csv("./data/instacart/order_products__prior.csv")
products = pd.read_csv("./data/instacart/products.csv")
orders = pd.read_csv("./data/instacart/orders.csv")
aisles = pd.read_csv("./data/instacart/aisles.csv")
# 2.数据基本处理
# 2.1 合并表格
table1 = pd.merge(order_product, products, on=["product_id", "product_id"])
table2 = pd.merge(table1, orders, on=["order_id", "order_id"])
table = pd.merge(table2, aisles, on=["aisle_id", "aisle_id"])
# 2.2 交叉表合并
data = pd.crosstab(table["user_id"], table["aisle"])
# 2.3 数据截取
new_data = data[:1000]
# 3.特征工程 — pca
transfer = PCA(n_components=0.9)
trans_data = transfer.fit_transform(new_data)
# 4.机器学习(k-means)
estimator = KMeans(n_clusters=5)
y_pre = estimator.fit_predict(trans_data)
# 5.模型评估
silhouette_score(trans_data, y_pre)