机器学习
一、概述
1.机器学习
机器学习是从数据中自动发热能系获得模型,并利用模型对未知数据进行预测
2.数据集的构成
- 特征值+目标值
例:
- 每一行是一个样本
- 有些数据可以没有目标值
3.机器学习算法分类
- 监督学习
目标值是类别时-分类问题 (k-近邻算法,贝叶斯算法,决策树与随机森林,逻辑回归)
目标值是连续性的数据时-回归问题(线性回归,岭回归)
- 无监督学习-无目标值(k-means 聚类)
ex
预测明天的气温? 回归问题
预测明天晴天雨天?分类问题
人脸识别?分类问题
4.开发流程
1)获取数据
2)数据处理
3)特征工程
4)机器学习算法训练-模型
5)模型评估
6)应用
二、特征工程
2.1 数据集
1.可用数据集
- sklearn
- kaggle
- UCI
2.安装sklearn
安装nmpy方法
3.scikit-learn数据集API的使用
- sklearn.datasets
__加载获取流行数据 - datasets.load_*() 获取小规模数据集,数据包含在datasets里
- datasets.fetch_*(data_home=None)获取大规模数据集,需要从网络上下载,函数的第一个参数时data_home,表示数据集下载的目录
- 返回值
datasets.base.Bunch(继承自字典)
dict[“key”]=values
bunch.key=values
返回值类型:
data:特征数据数组
target:标签数组
DESCR:数据描述
feature_names:特征名
target_names:标签名
例子
from sklearn.datasets import load_iris
def datasets_demo():
'''sklearn数据集使用'''
# 获取数据集
iris=load_iris()
print("鸢尾花数据集:\n",iris)
print("鸢尾花描述:\n",iris["DESCR"])
print("查看特征值的名字:\n",iris.feature_names)
print("查看特征值:\n",iris.data,iris.data.shape)
# 数据集划分
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.25,random_state=22)
print("训练集的特征值:\n",x_train,x_train.shape)
if __name__=="__main__":
# 代码1:sklearn数据集使用
datasets_demo()
4.数据集的划分
训练数据:用于训练,构建模型
测试数据:在模型检验时使用,用于评估模型是否有效
测试集:20~~30%,训练集:70~80%
- sklearn.model_selection.train_test_split(arrays,*options)
__x数据集的特征值
__y数据集的标签值
__test_size测试集的大小,一般为float
__random_state随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
__return训练集特征值(x_train),测试集特征值(x_test),训练集目标值(y_train),测试集目标值(y_test)
2.2 特征工程
理解:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
2.2.0 概述
1.用具:
sklearn
pandas数据清洗和数据处理
2.特征工程内容
- 特征抽取
- 特征预处理
- 特征降维
3.什么是特征抽取
-
机器学习算法-统计方法-数学公式
-
将任意数据(如文本或图像)转换为可用于机器学习的数字特征
-
特征提取API
sklearn.feature_extraction
2.2.1 字典特征提取——对字典数据进行特征值化
类别——>one-hot编码
sklearn.feature_extraction.Dicvectorizer(sparse=True....)
Dicvectorizer.fit_transform(X)
# X:字典或者包含字典的迭代器返回值:返回sparse矩阵
Dicvectorizer.inverse_transform(X)
# X:array数组或者sparse矩阵, 返回值:转换之前数据格式
Dicvectorizer.get_feature_names()
# 返回类别名称
例子:
from sklearn.feature_extraction import DictVectorizer
dict_demo():
# 字典特征提取
data=[{'city':'北京','temperature':100}, {'city':'上海','temperature':60}, {'city':'深圳','temperature':30}]
# 1.实例化一个转换器类
# 2.调用fit_transform{}
# sparse是稀疏矩阵的意思
transfer=DictVectorizer(sparse=False)
data_new=transfer.fit_transform(data)
print("data_new:\n",data_new)
print("特征名字:",transfer.get_feature_names())
return None
if __name__=="__main__":
dict_demo()
结果
其中前三列代表不通过的地方,北京,上海,广州
注意:返回sparse矩阵(稀疏)将非零值按位置表示出来可以节省内存,,提高加载效率
应用场景:
pclass,sex等,像这种数据集中类别特征比较多的情况下,组要数据集特征转变为字典类型,DictVectorizer转换
2.2.2 文本特征抽取——对文本数据进行特征值化
方法一:
特征:特征词
# 返回词频矩阵
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
# X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵
CountVectorizer.fit_transform(X)
# X:array数组或者sparse矩阵 返回值:转换之前数据格
CountVectorizer.inverse_transform(X)
# 返回值:单词列表
CountVectorizer.get_feature_names()
sklearn.feature_extraction.text.TfidfVectorizer
英文例子:
from sklearn.feature_extraction.text import CountVectorizer
def count_demo():
'''文本特征抽取'''
data=["life is short,i like python","life is too long,i dislike python"]
# 1.实例化一个转换器类
# 2.调用fit_transform
transfer=CountVectorizer()
data_new=transfer.fit_transform(data)
# 统计每一个样本出现特征词的个数
print("data_new\n",data_new.toarray())
print("特征名字:\n",transfer.get_feature_names())
结果
中文例子1:
def count_chinese_demo():
'''中文文本特征抽取'''
data=["我爱北京天安门","天安门上太阳升"]
# 1.实例化一个转换器类
# 2.调用fit_transform
transfer=CountVectorizer()
data_new=transfer.fit_transform(data)
# 统计每一个样本出现特征词的个数
print("data_new\n",data_new.toarray())
print("特征名字:\n",transfer.get_feature_names())
结果——因为没有空格,所以把短语作为特征词了
改进——只能把短语隔开
方法二:stop_words=[]停用词
def count_chinese_demo():
'''中文文本特征抽取'''
data=["life is short,i love python","life is too long,i dislike python"]
# 1.实例化一个转换器类,加上停用词is,too以后,is,too就不在停用词列表当中了
# 2.调用fit_transform
===================================================
transfer=CountVectorizer(stop_words=["is","too"]
====================================================
data_new=transfer.fit_transform(data)
# 统计每一个样本出现特征词的个数
print("data_new\n",data_new.toarray())
print("特征名字:\n",transfer.get_feature_names())
结果:
中文例子二:
将文字具体按照词组划分,因为没有空格,需要用到jieba数据库
from sklearn.feature_extraction.text import CountVectorizer
import jieba
def cut_word(text):
# 进行中文分词:科技是第一生产力——》科技 是 第一 生产力
a=" ".join(list(jieba.cut(text)))
return a
def count_chinese_demo():
'''中文文本特征抽取'''
data=["科技是第一生产力,十八世纪的工业革命拉动了英国的经济贸易大繁荣",
"美国作为二十一世纪的科技大国,积极地投入科技发展"]
# 将中文文本进行分词
data_new=[]
for sent in data:
data_new.append(cut_word(sent))
print(data_new)
# 实例化一个转换器类
# 调用fit_transform
transfer=CountVectorizer(stop_words=["的","地","积极"]) # 不显示的,地,积极特征词
data_final=transfer.fit_transform(data_new)
print("data_final:\n",data_final.toarray())
print("特征名字:\n",transfer.get_feature_names())
结果:
**关键词——TfidfVectorizer
关键词:在某一个类别的文章中,出现的次数很多,但是在其他类型的文章中出现极少
Tf-idf文本特征提取
主要思想:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此短语具有很好的类别区分能力
- 词频(term frequency):一个词语在文章中出现的频率
- 逆向文档频率(inverse document frequency):
tfidf(i,j)=tf(i,j)*idf(i,j)
log10(总文件数目/包含该词语之文件的数目)
例子:
1000篇文章-语料库 100篇文章-“非常” 10篇文章-“经济” 两篇文章:
文章A(100词):10次“经济”
TF-IDF:
-Tf 10/100=0.1
-IDF:LOG10(1000/10)=2
文章B(100词):10次“非常”
TF-IDF:
-Tf 10/100=0.1
-IDF:LOG10(1000/100)=1
API
sklearn.feature_extraction.text.TfidfVectorizer(stop_words=None...)
# X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵
TfidfVectorizer.fit_transform(X)
# X:array数组或者sparse矩阵 返回值:转换之前数据格
TfidfVectorizer.inverse_transform(X)
# 返回值:单词列表
TfidfVectorizer.get_feature_names()
例子:
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
def cut_word(text):
# 进行中文分词:科技是第一生产力——》科技 是 第一 生产力
a=" ".join(list(jieba.cut(text)))
return a
def Tfidf_demo():
# 用tfidf的方法发进行文本特征抽取
data = ["科技是第一生产力,十八世纪的工业革命拉动了英国的经济贸易大繁荣",
"美国作为二十一世纪的科技大国,积极地投入科技发展"]
# 将中文文本进行分词
data_new = []
for sent in data:
data_new.append(cut_word(sent))
print(data_new)
# 实例化一个转换器类
# 调用fit_transform
transfer = TfidfVectorizer(stop_words=["的", "地", "积极"]) # 不显示的,地,积极特征词
data_final = transfer.fit_transform(data_new)
print("data_final:\n", data_final.toarray())
print("特征名字:\n", transfer.get_feature_names())
结果:
2.2.3 特征预处理
1.通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程
数值型数据的无量纲化(不同规格的数据转换为同一规格):
- 归一化
- 标准化
2.特征预处理API
sklearn.preprocessing
3.归一化
- 通过对原始数据进行变换把数据映射到默认为[0,1]之间
- 公式:
- 理解
- API
sklearn.preprocessing.MinMaxScaler(feature_range=(0,1)...)
MinMaxScalar.fit_transform(X)
# X:numpy array格式的数据[in_samples,n_features]
# 返回值:转换后的形状相同的array
缺点:如果异常值过多,结果就会有很大影响,只适合传统精确小数据场景
例子:
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
def minmax_demo():
# 1.获取数据
# 数据文件要放在同一个目录下!!
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
print("data:\n", data)
# 2.实例化一个转换器类
transfer=MinMaxScaler()
# 3.调用fit_transform进行转化
data_new=transfer.fit_transform(data)
print("data_new:\n",data_new)
if __name__=="__main__":
minmax_demo()
结果
原数据集通过归一化都变成了0-1之间的数
4.标准化
-
定义:通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内
-
公式:
对于标准化:如果出现异常点,由于具有一定的数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小
API
sklearn.preprocessing.StandardScaler()
# 处理之后,每列数据都聚集在均值为0附近
StandardScaler.fit_transform(X)
# X:numpy array格式的数据[in_samples,n_features]
# 返回值:转换后的形状相同的array
例子:
from sklearn.preprocessing import StandardScaler
def stand_demo():
# 1.获取数据
# 数据文件要放在同一个目录下!!
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
print("data:\n", data)
# 2.实例化一个转换器类
transfer =StandardScaler()
# 3.调用fit_transform进行转化
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
if __name__=="__main__":
stand_demo()
结果
2.2.4 特征降维
降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程
相关特征
比如降雨量和空气湿度相关,所以对结果会产生影响
降维的两种方式:
- 特征选择
- 主成分分析
2.2.4.1 特征选择
1.Filter 过滤式
- 方差选择法:低方差特征过滤
- 相关系数:特征与特征之间的相关程度
2.Embedded 嵌入式
- 决策树:
- 正则化
- 深度学习
3.方差选择法
a. API
sklearn.feature_selection.VarianceThreshold(threshold=0.0)
删除所有方差特征
Variance.fit_transform(X)
# X:numpy array格式的数据[n_samples,n_features]
# 返回值:训练集差异低于threshold的特征将被删除,默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征
b.例子
from sklearn.feature_selection import VarianceThreshold
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=10)
# 3.调用fit_transform进行转化
data_new=transfer.fit_transform(data)
print("data_new:\n",data_new)
print("data_new_shape:\n",data_new.shape)
结果
特征向量变为由9个变为7个
4.相关系数
-
公式:
-
特点
a.
介于-1~1之间
b.
r>0正相关,r<0负相关
|r|=1,完全相关,r=0完全不相关
|r|月接近于1越相关,越接近于0越不相关
c.
三级划分:|r|<0.4低度相关,0.4<=|r|<0.7显著性相关,0.7<=|r|<1为高度线性相关 -
API
from scipy.stats import pearson
x:(N,) array_like
y:(N,) array_like Returns:(Pearson's correlation coefficient,p-value)
例子:
from scipy.stats import pearsonr
def correlation_demo():
# 过滤低方差特征
# 1.获取数据
data = pd.read_csv("factor_returns.csv")
data = data.iloc[:, 1:-2]
print("data:\n", data)
# 计算两个变量之间的相关系数
r = pearsonr(data["pe_ratio"], data["pb_ratio"])
r1 = pearsonr(data["revenue"], data["total_expense"])
print("相关系数:\n", r)
print("相关系数:\n", r1)
结果
可以看出revenue和total expense有很强的相关性,而pe ratio 与pb ratio没有很强的相关性
2.2.4.2 主成分分析(PCA)
- 定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量
- API
sklearn.decomposition.PCA(n_components=None)
# 将数据分解为较低维数空间
# n_components
# -小数:保留百分之多少的信息
# -整数:减少到多少特征
PCA.fit_transform(X)
# X:numpy array格式的数据[n_samples,n_features]
#返回值:转换后指定维度的array
from sklearn.decomposition import PCA
def PCA_demo():
data=[[2,8,4,5],[6,3,0,8],[5,4,9,1]]
# 1.实例化一个转换器类
transfer=PCA(n_components=2)
# 2.调用fit_transform
data_new=transfer.fit_transform(data)
print("data_new:\n",data_new)
结果
案例——未完成:(用到jupyter notebook,遇到问题)
探索用户对物品类别喜好的细分,数据如下:
1)需要将user_id和aisle(物品类别)放在同一个表当中
2)特征过多,降维
三、分类算法
3.1sklearn转换器与预估器
3.1.1 转换器_特征工程的父类
1.实例化
2.调用fit_transform
标准化:
(x-mean)/ std
fit_transform()
fit()
transform()
3.1.2 估计器 estimator
1.实例化一个estimator类
2.estimator.fit(x_train,y_train) 计算
——调用完毕,模型生成
3.模型评估
1)直接比对真实值和预测值
y_predict=estimator.predict(x_test)
y_test==y_estimator
2)计算准确率
accuracy=estimator.score(x_test,y_test)
- 估计器训练流程
3.2 K-近邻算法
1.KNN算法原理
核心思想:根据您的邻居推断你的类别
定义:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别
k=1 取得过小,说明容易受到异常点的影响
k值取得过大,容易受到样本不均衡的影响
2.距离公式
两个样本之间的距离公式又叫做欧式距离
曼哈顿距离、明可夫斯基距离
3.无量纲化:使用标准化,因为标准化不容易受异常值影响
4.API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
# n_neighbors:int,可选(默认=5),k_neighbors查询默认使用的邻居数
# algorithm:'auto','ball_tree','kd_tree','brute'}
- 案例
1)获取数据
2)数据集划分
3)特征工程
标准化
4)KNN预估器流程
5)模型评估
from sklearn.neighbors import KNeighborsClassifier
def knn_iris():
# 1)获取数据
iris=load_iris()
# 2)数据集划分
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=6)
# 3)特征工程:标准化
transfer = StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.transform(x_test)
# 4)KNN预估器流程
estimator=KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 5)模型评估:
# 方法一:直接比对的真实值和预测值:
y_predict=estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对的真实值和预测值:\n",y_test==y_predict)
# 方法二:计算准确率
score=estimator.score(x_test,y_test)
print("准确率为:\n",score)
结果
优点:
1)简单,易于理解
缺点:
1)懒惰算法,对测试样本分类的计算量大,内存开销大
2)必须指定K值,K值选择不当则分类精度不能保证
适用:小数据场景
3.3 模型选择与调优
1.交叉验证
- 训练集:训练集+验证集
- 测试集:测试集
2.超参数搜索——网格搜索
通常情况下,有很多参数需要手工指定的(如K-近邻算法中的K值),这种叫超参数。但是手动过程复杂,所以需要对模型预测几种超参数组合,每组超参数都采用交叉验证来进行评估,最后选出最优参数组合建立模型
3.API
# 对估计器的指定参数值进行详尽搜索
sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)
# estimator:估计器对象
# param_grid:估计器参数(dict){"n_neighbors":[1,3,5]}
# cv:指定几折交叉验证
# fit():输入训练参数
# score:准确率
# 结果分析:
最佳参数:best_param_
最佳结果:best_score_
最佳估计器:best_estimator_
交叉验证结果:cv_results_
例子
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
def knn_iris_gridscv():
# 用knn算法对鸢尾花进行分类,添加网格搜索和交叉验证
# 获取数据
iris=load_iris()
# 划分数据集
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=6)
# 特征工程:标准化
transfer=StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.fit_transform(x_test)
# KNN算法预估器
estimator=KNeighborsClassifier()
# 加入网络搜索与交叉验证
# 参数准备
param_dict={"n_neighbors":[1,3,5,7,9,11]}
estimator=GridSearchCV(estimator,param_grid=param_dict,cv=10)
estimator.fit(x_train,y_train)
# 模型评估
# 方法一:直接比对真实值和预测值
y_predict=estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n",y_test==y_predict)
# 方法二:计算准确率
score=estimator.score(x_test,y_test)
print("准确率为:\n",score)
# 最佳参数:best _params_
print("最佳参数:\n",estimator.best_params_)
# 最佳结果:best _scores_
print("最佳结果:\n",estimator.best_score_)
# 最佳估计器: best estimator
print("最佳估计器:\n",estimator.best_estimator_)
# 交叉验证结果: cv_results
print("交叉验证结果:\n",estimator.cv_results_)