一、机器学习概述
1.数据集构成
特征值 + 目标值(标签名)
2.算法分类
(1)监督学习
①分类问题---目标值:类别
②回归问题---目标值:连续型的数据
(2)无监督学习
无目标值
3.机器学习开发流程
(1)获取数据(2)数据处理(3)特征工程
(4)算法训练 - 模型(5)模型评估(6)应用
二、特征工程
1.sklearn数据集
#(1)获取小规模数据集:
sklearn.datasets.load_iris()
#(2)获取大规模数据集:
sklearn.datasets.fetch_20newsgroups(data_home=None,subset='train')
# subset:train--训练集,test--测试集,all--全部(默认)
#(3)sklearn数据集的返回值继承了字典
# 数据类型:datasets.base.Bunch
# 下面为属性
①data:特征数据数组值(numpy.ndarray)
②target:标签数组值
③DESCR:数据描述
④feature_names:特征名
⑤target_names:标签名
from sklearn.datasets import load_iris
# iris便是字典
iris=load_iris()
2.数据集的划分
(1)训练数据:用于训练,构建模型
(2)测试数据:在模型检验时使用,用于评估模型是否有效 20%~30%
sklearn.model_selection.train_test_split(arrays, *options)
# 属性
①x:数据集的特征值
②y:数据集的标签值
③test_size:测试集的大小,一般为float--%20用0.2表示
④random_state:随机数种子
⑤return:训练集特征值,测试集特征值,训练集目标值,测试集目标值
x_train, x_test, y_train, y_test
3.特征工程:处理数据,使得特征能在机器学习算法上发挥更好的作用的过程
(1)sklearn:特征工程
(2)pandas:数据清洗、数据处理
4.特征提取:①文本类型==>数值②类型==>数值
(1)字典特征提取:不同类别==>one-hot编码
from sklearn.feature_extraction import DictVectorizer
# 1.实例化一个转换器类
# sparse稀疏 ①将非零值-按位置表示出来 ②节省内存-提高加载效率
transfer=DictVectorizer(sparse=False)
data=[{"city":"北京","temperature":100},{"city":"上海","temperature":60},{"city":"深圳","temperature":30}]
# 2.调用fit_transform(data)
data_new=transfer.fit_transform(data)
(2)文本特征提取(中英文一样:①以空格分开②单个字母/汉字不统计)
# 1.CountVectorizer统计每个样本特征词出现的个数
from sklearn.feature_extraction.text import CountVectorizer
data=["life is short,i like like python","life is too long , i dislike python"]
# 2.实例化一个转换器类 # stop_words停用的那些单词
transfer=CountVectorizer(stop_words=["is","too"])
# 3.调用fit_transform
data_new=transfer.fit_transform(data)
# 4.多维数组
data_new.toarray()
# 5.特征名字
transfer.get_feature_names()
(3) 进行中文分词
# jieba是中文分词的库
import jieba
def cut_word(text):
# jieba.cut是分开语句 # 返回值需要强转 # " ".join:进行连接,以空格分开
text=" ".join(list(jieba.cut(text)))
return text
print(cut_word("我爱北京天安门"))
(4)中文文本特征抽取(自动分词)(CountVectorizer)
def count_chinese_demo2():
# 将中文文本进行分词
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# print(data_new)
# 1、实例化一个转换器类
transfer = CountVectorizer(stop_words=["一种", "所以"])
# 2、调用fit_transform
data_final = transfer.fit_transform(data_new)
print("data_new:\n", data_final.toarray())
print("特征名字:\n", transfer.get_feature_names())
return None
(5)Tf-idf文本特征提取(TfidfVectorizer)
关键词:在一个类别的文章中,出现的次数很多,但在别的类别文章中出现很少
①TF-IDF - 重要程度 文章A(100词) : 10次“经济” TF-IDF:0.2(tf*idf)
②TF - 词频 tf: 10/100 = 0.1 (关键词‘经济’/总词数)
③IDF - 逆向文档频率 idf: lg 1000/10 = 2(1000是所有文章,10是有关键词‘经济’的文章)
5.特征预处理
(1)归一化:原始数据变换到[0,1]之间(默认0-1)
form sklearn.preprocessing import MinMaxScaler
# 实例化一个转换器类
# feature_range:把默认值0-1变成2-3
transfer = MinMaxScaler(feature_range=[2, 3])
(2)标准化:(x - mean) / std
from sklearn.preprocessing import StandardScaler
# 1、获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
# 2、实例化一个转换器类
transfer = StandardScaler()
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
6.特征降维
(1)降维:降低特征的个数--得到特征与特征之间不相关
①特征选择:筛选掉冗余特征
特征选择的方法:
a.Filter(过滤式)
Ⅰ.方差选择法:低方差特征过滤
Ⅱ. 相关系数 - 特征与特征之间的相关程度
如果 特征与特征 之间相关性很高:
1)选取其中一个
2)加权求和
3)主成分分析
from sklearn.feature_selection import VarianceThreshold
# pearsonr是相关系数:如果皮尔逊相关系数为 1,表示两个变量完全正相关。
# 如果皮尔逊相关系数为 -1,表示两个变量完全负相关。
# 如果皮尔逊相关系数为 0,表示两个变量没有线性关系。
from scipy.stats import pearsonr
def variance_demo():
# 1.获取数据
data=pd.read_csv('factor_returns.csv')
data = data.iloc[:, 1:-2]
print("data:\n", data)
# 2、实例化一个转换器类
# threshold:阈值:低于此值的全部删除,为了筛选得到关联程度不高的
# 阈值越大,筛选程度越厉害
transfer = VarianceThreshold(threshold=20)
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new, data_new.shape)
# # 计算某两列之间的相关系数
# r1 = pearsonr(data["pe_ratio"], data["pb_ratio"])
# print("相关系数:\n", r1)
# r2 = pearsonr(data['revenue'], data['total_expense'])
# print("revenue与total_expense之间的相关性:\n", r2)
return None
b.Embedded(嵌入式)
Ⅰ.决策树
Ⅱ.正则化
Ⅲ.深度学习
(2)主成分分析(PCA)
PCA是一种数据降维的技术,它并不是将数据拟合到一个模型中,而是通过线性变换将原始的高维数据投影到一个低维的子空间中,使得投影后的数据仍然尽可能地保留原始数据的信息,同时减少了特征的数量和减少了冗余信
①定义:高维数据转化为低维数据的过程,可能会舍弃原有数据、创造新的变量
②作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息
③简单计算过成:找到一个合适的直线,把所有数据都贴到直线上,通过一个矩阵运算得出主成分分析的结果
from sklearn.decomposition import PCA
def pca_demo():
data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]]
# 1、实例化一个转换器类
# (1)传整数:把n个特征==>2个特征
# transfer = PCA(n_components=2)
# (2)传浮点数:保留95%的信息,并减少特征数
transfer = PCA(n_components=0.95)
# 2、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
三、分类算法
1 、sklearn转换器和预估器
(1)转换器 - 特征工程的父类
①实例化
②调用fit_transform(对于文档建立分类词频矩阵,不能同时调用)
# 进行标准化:(x - mean) / std
# 计算 每一列的平均值、标准差
fit()
# (x - mean) / std进行最终的转换
transform()
(2)估计器(sklearn机器学习算法的实现)
①实例化一个estimator
②estimator.fit(x_train, y_train):计算调用完毕,模型生成
③模型评估:
1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
y_test == y_predict
2)计算准确率
accuracy = estimator.score(x_test, y_test)
2、K-近邻算法
(1)KNN核心思想:
你的“邻居”来推断出你的类别
(2)k:想要分得(距离近的)类别的数量
(3)如果取的最近的电影数量不一样?会是什么结果?
①k值过小,容错率低
②k值过大,准确率低
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def knn_iris():
"""
用KNN算法对鸢尾花进行分类
:return:
"""
# 1)获取数据
iris = load_iris()
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 3)特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
# ***为什么x_test不用fit()
# 因为我们想要,训练集和测试集的mean和std一样对这俩集进行同样操作
# 如果x_test进行fit(),这个mean和std是根据自己计算出来的,不是train的mean和std
x_test = transfer.transform(x_test)
# 4)KNN算法预估器
# n_neighbors:k值
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
return None
(4)K-近邻缺点:
①必须指定K值,K值选择不当则分类精度不能保证
②懒惰算法,对测试样本分类时的计算量大,内存开销大
使用场景:小数据场景,几千~几万样本
3、模型选择与调优
(1)交叉验证:
①将训练数据,分为训练和验证集。
②四份数据,一份作为验证集,经过4组测试,取平均值作为最终结果。
③为了让训练得到模型结果更加准确。
a.验证集:优化模型的性能
B.测试集:评估模型
比如,验证集是公司测试外包方进行的标注成果是否正确,测试集是甲方的数据
(2)超参数搜索-网格搜索(Grid Search)
一般,很多算法中的参数需要手动指定(比如k-近邻算法中的K值),这种叫超参数。对模型预设不同的超参数组合,之后每组都采用交叉验证来进行评估。最后选出最优模型
from sklearn.model_selection import GridSearchCV
# 4)KNN算法预估器
estimator = KNeighborsClassifier()
# 加入网格搜索与交叉验证
# 估计器参数
param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
# cv:指定几折交叉数据
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率------------训练集
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
# 最佳参数:best_params_
print("最佳参数:\n", estimator.best_params_)
# 最佳结果:best_score_---------验证集
print("最佳结果:\n", estimator.best_score_)
# 最佳估计器:best_estimator_
print("最佳估计器:\n", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:\n", estimator.cv_results_)
4、朴素贝叶斯算法
(1)朴素:特征与特征之间是相互独立
朴素贝叶斯算法:朴素 + 贝叶斯
(2)如果有P(W1 | C),P(W5 | C)......在C的条件下,没有W1,W5的值。但是实际情况是大数量的,不可能没有,所以引入了alpha:拉普拉斯平滑系数。
(3)朴素贝叶斯算法总结
①优点:
对缺失数据不太敏感,算法也比较简单,常用于文本分类。
分类准确度高,速度快
②缺点:
由于使用了样本属性独立性的假设,所以如果特征属性有关联时其效果不好
比如:我爱北京天安门
5、决策树
(1)如何高效的进行决策?
答:特征的先后顺序
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
def decision_iris():
"""
用决策树对鸢尾花进行分类
:return:
"""
# 1)获取数据集
iris = load_iris()
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 3)决策树预估器
# entropy:信息增益的熵
estimator = DecisionTreeClassifier(criterion="entropy")
estimator.fit(x_train, y_train)
# 4)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
# 可视化决策树
export_graphviz(estimator, out_file="iris_tree.dot", feature_names=iris.feature_names)
return None
(2)优点:
可视化 - 可解释能力强
(3)缺点:
容易产生过拟合
6、集成学习方法之随机森林
(1)森林:包含多个决策树的分类器(判断结果:少数服从多数)
(2)两个随机
①训练集随机 - N个样本中随机有放回的抽样N个
②特征随机 - 从M个特征中随机抽取m个特征(降维)
(3)总结
①能够有效地运行在大数据集上
②处理具有高维特征的输入样本,而且不需要降维
四、回归算法
1、线性回归(一般不用)
(1)回归问题:
目标值 - 连续型的数据
(2)损失函数
①目标:怎么使模型参数能够预测准确
②a.真实关系:真实房子价格 = 0.02×中心区域的距离 + 0.04×城市一氧化氮浓度 + (-0.12×自住房平均房价) + 0.254×城镇犯罪率
b.随意假定:预测房子价格 = 0.25×中心区域的距离 + 0.14×城市一氧化氮浓度 + 0.42×自住房平均房价 + 0.34×城镇犯罪率
③损失函数:最小二乘法
④怎么优化损失:a.正规方程 b.梯度下降
Ⅰ.正规方程(不推荐):
Ⅱ.梯度下降(第二个公式的分母应该是w0)
from sklearn.linear_model import LinearRegression,SGDRegressor
1.# 正规方程的优化方法
# 4)预估器
estimator=LinearRegression()
estimator.fit(x_train,y_train)
# 梯度下降的优化方法
# 4)预估器
estimator = SGDRegressor()
estimator.fit(x_train, y_train)
2.# 模型评估
y_predict = estimator.predict(x_test)
print("预测房价:\n", y_predict)
# mean_squared_error()均方误差
error = mean_squared_error(y_test, y_predict)
print("均方误差为:\n", error)
2、欠拟合与过拟合
(1)过拟合:训练集上表现得好,测试集上不好
①原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点
②解决:正则化
Ⅰ.L1正则化:使一些W直接为0
Ⅱ.L2正则化(更常用):使一些W的值接近于0
(2)欠拟合:学习到数据的特征过少
3、线性回归的改进-- 岭回归
(1)带有L2正则化的线性回归-岭回归
①alpha 正则化力度=惩罚项系数
②alpha越大,惩罚力度越大,导致回归系数即权重w越小
from sklearn.linear_model import Ridge
# 4)预估器
estimator = Ridge(alpha=0.5, max_iter=10000)
estimator.fit(x_train, y_train)
4、分类算法 --- 逻辑回归与二分类
(1)逻辑回归的应用场景
广告点击率 是否会被点击
是否为垃圾邮件
是否患病
是否为金融诈骗
是否为虚假账号
正例 / 反例
(2)逻辑回归的原理
线型回归的输出 就是 逻辑回归 的 输入
①输入是连续的数值:
②激活函数:1/(1 + e^(-x))
sigmoid函数 [0, 1]:将某个函数映射到 0-1 的区间之间。设定一个阈值,大于阈值的为一类,小于阈值的为一类(二类)。
③实例:假设函数/线性模型:1/(1 + e^(-x)) ==>
1/(1 + e^(-(w1x1 + w2x2 + w3x3 + …… + wnxn + b)))
④损失函数
Ⅰ.以前是,具体的数值:(y_predict - y_true)平方和/总数
Ⅱ.现在是,是否属于某个类别
Ⅲ.所以现在使用:对数似然损失
⑤优化损失:梯度下降
# 1、读取数据
path = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
column_name = ['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(path, names=column_name)
# 2、缺失值处理
# 1)替换-》np.nan
data = data.replace(to_replace="?", value=np.nan)
# 2)删除缺失样本
data.dropna(inplace=True)
data.isnull().any() # 不存在缺失值
# 3、划分数据集
from sklearn.model_selection import train_test_split
# 筛选特征值和目标值
x = data.iloc[:, 1:-1]
y = data["Class"]
x_train, x_test, y_train, y_test = train_test_split(x, y)
# 4、标准化
from sklearn.preprocessing import StandardScaler
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 5、预估器流程
from sklearn.linear_model import LogisticRegression
estimator = LogisticRegression()
estimator.fit(x_train, y_train)
# 逻辑回归的模型参数:回归系数和偏置
estimator.coef_
estimator.intercept_
# 6、模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
5、分类的评估方法
(1)精确率与召回率
Ⅰ 精确率:查准率
Ⅱ 召回率:查全率
(2)F1-score:评估模型的稳健型
总共有100个人,如果99个样本癌症,1个样本非癌症 - 样本不均衡
不管怎样我全都预测正例(默认癌症为正例) - 不负责任的模型
①准确率:99%
②召回率:99/99 = 100%
③精确率:99%
④F1-score: 2*99%/ 199% = 99.497%
# 查看精确率、召回率、F1-score
from sklearn.metrics import classification_report
report = classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "恶性"])
# y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
# 将y_test 转换成 0 1
y_true = np.where(y_test > 3, 1, 0)
(3)ROC曲线与AUC指标
①TPR = TP / (TP + FN) - 召回率
所有真实类别为1的样本中,预测类别为1的比例
②FPR = FP / (FP + TN)
所有真实类别为0的样本中,预测类别为1的比例
from sklearn.metrics import roc_auc_score
roc_auc_score(y_true, y_predict)
6、模型保存和加载
import joblib
# 保存模型
joblib.dump(estimator, "my_ridge.pkl")
# 加载模型
estimator = joblib.load("my_ridge.pkl")
五、聚类算法
1、无监督学习算法
(1)聚类:K-means(K均值聚类)
(2)降维:PCA
2、K-means原理
(1)K - 超参数 :得人工手动指定的参数
(2)过程:选择合适的K个样本。计算n-K的样本到这个K个样本的距离,近的就归那类。如果计算得出的新中心点与原中心点一样,则结束;不一样,进行第二句话。
# 预估器流程
from sklearn.cluster import KMeans
# n_clusters:k值
estimator = KMeans(n_clusters=3)
estimator.fit(data_new)
y_predict = estimator.predict(data_new)
y_predict[:300]
3、Kmeans性能评估指标
(1)轮廓系数
①如果b_i>>a_i:趋近于1效果越好,
b_i<<a_i:趋近于-1,效果不好。
②轮廓系数的值是介于 [-1,1] ,
越趋近于1代表内聚度和分离度都相对较优。
# 模型评估-轮廓系数
from sklearn.metrics import silhouette_score
# 用户聚类结果评估
silhouette_score(data_new, y_predict)
4、K-means总结
(1)应用场景:没有目标值的分类
注:一般做在分类之前