#应用中,一般来说,收集到的数据集会非常混乱,不同于深度学习,把数据清洗等步骤也加入到神经网络模型的执行中,
#机器学习,数据往往不能直接用于模型的训练,需要对数据集进行数据预处理,数据清洗,填补缺失值,处理异常数据等
#在进行数据预处理之前,先导入我们的数据
#pickle是一个python中, 压缩/保存/提取数据的模块
import pickle #导入pickle模块
file = open('color.pickle', 'wb') #打开一个文件color.pickle,给予写权限,不存在文件时则新建
pickle.dump(list_, file) #把数据写入文件color.pickle,此处是把list数据写入到文件中
file.close() #关闭文件操作
with open('color.pickle', 'rb') as file: #用with的优点是可以不用执行关闭文件操作,打开文件color.pickle,给予读权限
list_ = pickle.load(file) #读取文件color.pickle内容,传给变量dict_get
#使用python的os模块创建与删除本地文件夹以及文件
import os #导入os模块
os.mkdir('D:\\xxx\\dir') #创建文件夹到本地目录下
os.makedirs('D:\\xxx\\dir\\dir\\dir') #创建多个文件夹到本地目录下
os.open('D:\\xxx\\txt') #创建文件到本地目录下
os.remove('D\\xxx\\txt') #删除本地目录下文件
path='C:\\Users\\WPJ\\Desktop\\huaweicloud-python-sdk-sis-1.0.0ICT' #指定路径
for a,b,c in os.walk(path): #查看指定目录下的文件夹路径,文件夹,文件等信息
print(a)
print(b)
print(c)
print('\n')
#使用python自带的read功能读取本地文件
path = 'C:\\Users\\WPJ\\Desktop\\huaweicloud-python-sdk-sis-1.0.0ICT\\机器学习.txt' #指定需要读取文件的本地路径
file = open(path,encoding='UTF-8') #获取文件,使用编码为UTF-8
data = file.read() #读取文件
print(data) #打印输出文件内容
file.close() #关闭文件操作
#使用download模块下载数据
from download import download #导入download模块
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" #指定要下载数据的url地址
"notebook/datasets/MNIST_Data.zip"
data = download(url, "./", kind="zip", replace=True) #下载数据,指定url,下载后存储的位置,解压,覆盖原文件
#使用pandas模块进行数据集类型的转换,更加方便对数据集进行信息查询等
import pandas as pd #导入pandas模块
data = pd.read_csv("./data.csv") #可以使用pandas直接读取数据集,会直接将数据集的类型转换为DtaeFream
data = pd.read_csv("data.csv") #如果是当前目录下,也可以直接写文件名,反斜杠得加r参数,或者双重反斜杠
data = pd.DateFream(data) #也可以使用datefream将数据转换为数据框类型
#机器学习中分监督学习、无监督学习、半监督学习和强化学习,使用监督学习时,需要标签,
#所以一般需要划分特征数据X和标签数据Y
#可以使用loc,iloc进行X,Y的提取
X = data.loc[:,:] #使用loc进行提取时,只能识别列名称,【行切片:列切片】
X = data.iloc[:,:] #使用iloc提取时,既可以识别列名称,也可以识别列级索引,【行切片:列切片】
X.describe([0.01,0.1,0.25,0.5,0.75,0.95,0.99]).T #对特征数据进行数据各分布下的描述性统计,然后进行转置
#结果返回个特征count,std等,可以根据经验来处理(删除)数据集异常的值
data.head() #查看数据框的前多少行信息,默认5
X.info() #查看数据框的所有列信息,即所有特征信息,有无缺失值,有多少缺失值等
#接下来可以根据查看到的特征信息,对有缺失值的数据进行处理
#由于某特征缺失的数据比较多时,或者该特征对于标签的贡献几乎没有时,可以直接将此特征进行删除,
#使用drop(),指定需要删除的特征的列级名称,inplace=True表示在原始数据集框上进行更改,axis=1指定删除列
data.drop(["Ticket"],inplace=True,axis=1)
#当某些特征的缺失值比较少时,且特征比较重要,往往需要对其进行缺失值填补操作,而不是删除
#将年龄的列的缺失值补上该列的均值,fillna()是填补缺失值的意思,括号里面可以输入自定义的数,
#也可以使用填补特征列的其它统计值来填补,例如最大值,最小值,众数,中位数等
data["Age"]=data["Age"].fillna(data["Age"].mean())
#当某些数据集只是缺少少量的数据而已,而且样本又比较庞大,也可以选择将所有缺失数据的行进行删除
#删除带用缺少数据的行,dropna与drop不一样,无需指定删除的数据,
#默认axis=0,删除行,inplace= False,需要指定新的变量存储返回的新特征矩阵
data = data.dropna()
data.index = range(data.shape[0]) #恢复索引,方便后续对数据框的其它操作
#由于机器学习模型只能识别数字类型的数据集,所以需要将其它的数据类型的数据转换成int类型的数据
#使用unique()可以将某特征中的所有数据进行无重复统计,tolist()将统计完的对象转换成列表
labels = data["Embarked"].unique().tolist()
#apply()对某列特征进行数据更新,labels.index()取出该列各数据在labels的索引值,并替换掉原来的数据,再替换原来特征列
data["Embarked"] = data["Embarked"].apply(lambda x: labels.index(x))
#当然,对于性别这种比较特殊的特征,由于只有俩种类别,所以可以使用bool值对应的int值更方便的将数据类型替换掉
#将性别数据类型改为int,‘==’可以返回bool系列,使用astype可以将数据类型转换成布尔值对应的int值,true=1,false=0
data.loc[:,"Sex"] = (data["Sex"] == "male").astype("int")
#当然,除了可以使用怕pandas自带的方法进行缺失值处理以及类型转换之外,还可以使用sklearn中的相关类来进行数据处理
from sklearn.impute import SimpleImputer #导入缺失值填补的类
data = df.loc[:,"score"] #提取需要进行缺失值填补的特征
import numpy as np #导入numpy模块
data = np.array(data) #使用array()将series转换成adarray类型
data = data.reshape(-1,1) #使用reshape(-1,1)对数据进行升维度,因为模型填补的是特征,所以需要二维及以上的数据
a = SimpleImputer() #实例化,默认填补该列特征数据的均值
b = SimpleImputer(strategy="median") #实例化,用中位数填补空值
c = SimpleImputer(strategy="constant", fill_value=0) #实例化,用0填补空值(strategy是策略的意思)
d = SimpleImputer(strategy="most_frequent") #实例化,用众数填补空值
a = a.fit_transform(data) #训练并返回结果
b = b.fit_transform(data) #训练并返回结果
c = c.fit_transform(data) #训练并返回结果
d = d.fit_transform(data) #训练并返回结果
df.loc[:,"score"] = b #根据所需,使用中位数填补完返回的结果替换掉原来的特征矩阵
#同样,可以使用sklearn中的类,将数据集的类型转换成数值类型(编码)
from sklearn.preprocessing import LabelEncoder #导入标签转换成数值类型编码的类
#通过1行代码将实例化与输出结果,并把结果传入原数据集一起实现,由于标签是1维矩阵,所以可以直接拿去训练,
#实现标签列编码,由于标签可以一维矩阵,所以不需要对数据进行升维度操作
da1.loc[:,"gender"] = LabelEncoder().fit_transform(da1.loc[:,"gender"])
from sklearn.preprocessing import OrdinalEncoder #导入特征编码的类
import numpy as np
data = np.array(df.loc[:,"gender"])
data = data.reshape(-1,1) #由于是对特征列进行训练,则需要二维以上矩阵,所以需要(-1,1)来升维度
df.loc[:,"gender"] = OrdinalEncoder().fit_transform(data) #使用编码,将特征进行0,1,2等格式编码
#性别男女是独立互不干扰的,所以之前的编码生成的数值型0和1等,存在大小以及数值运算等关系,
#对后面模型的算法运行以及训练存在干扰,所以更加适合使用哑变量来实现一列特征存在多个不同的类时,
#且它们之间不存在某种联系时使用,效果比较好
from sklearn.preprocessing import OneHotEncoder #导入独热编码的类
data=(np.array(df.loc[:,"gender"]).reshape(-1,1) #由于哑变量默认处理特征列的数值型转换,所以同样需要二维以上数据
#categories='auto',会根据特征下的类别自动的将数据划分为n类,独热编码表示为0,1,0类似格式,属于哪一类哪个位置置1
#生成的是稀疏矩阵,可以用toarray把它变成数组显示出来
s = OneHotEncoder(categories="auto").fit_transform(data).toarray()
s.get_feature_names_out() #输出分类后的各列代表的类别,0是该特征在原来数据集的索引,也就是数据框的列级索引
#当特征下的数据为数值类型时,且可以划分为俩个区间时,例如年龄,分数等,就可以使用二值化将数据缩减为俩类,
#有利于提高后续模型运行的效率
from sklearn.preprocecsing import Binarizer #导入二值化的类
#将分数以30分为界限分成两个区间,也就是两个类
#同样的,二值化也是对特征矩阵进行操作,所以需要进行升维度操作,使用values可以取出特征系列的所有值,
#再使用reshape(-1,1)对其进行数据升维
df.loc[:,"score"]=Binarizer(threshold=30).fit_transform(df.loc[:, "score"].values.reshape(-1,1))
#有时,需要把特征下的数据进行多区间分类操作,则需要使用分箱的类,原理跟二值化类似,只不过是将数据进行多值化而已
from sklearn.preprocessing import KBinsDiscretizer #导入特征数据分箱的类
data = df.loc[:,"score"].values.reshape(-1,1) #同样,需要对数据进行升维度操作
#使用等位分箱,采用编码,分成三份
s = KBinsDiscretizer(n_bins=3, encode="ordinal", strategy="quantile").fit_transform(data)
#使用等位分箱,采用独热编码,分成三份
ss = KBinsDiscretizer(n_bins=3,encode="onehot", strategy="quantile").fit_transform(data)
#使用等宽分箱,采用编码,分成三份
ssss = KBinsDiscretizer(n_bins=3,encode="ordinal", strategy="uniform").fit_transform(data)
#使用等宽分箱,采用独热编码,分成三份
sss = KBinsDiscretizer(n_bins=3,encode="onehot", strategy="uniform").fit_transform(data)
#以上输出结果都可以使用toarray()进行转换成数组显示
#后续对返回的新的特征列,可以与之前一样直接放入原来的数据集中或替换原来的数据集中的特征列
#为了方便观察特征数据的分布规律,以及加快模型的训练效率,可以考虑对数据进行归一化处理
from sklearn.preprocessing import MinMaxScaler #导入数据归一化的类
a = MinMaxScaler() #实例化,默认将数据归一到【0,1】之间
b = a.fit_transform(data) #归一化并导出数据
a.inverse_transform(b) # 将归一化后的结果逆转
c = MinMaxScaler(feature_range=(5,10)) #实例化,将数据归一到【0,1】以外的范围中
d = c.fit_transform(c) #归一化并导出数据
#同样可以逆转结果,前提是实例化与归一化训练分开执行,一起执行则返回最终结果,无法调用实例化后的模型来逆转结果
c.inverse_transform(d)
#也可以将数据标准化操作,可以让多个服从正态分布的特征缩小到统一范围内的正态分布中
#使得不同度量之间的特征具有可比性,同时不改变原始数据的分布特征
from sklearn.preprocessing import StandardScaler #导入标准化的类
a = StandardScaler() #实例化
b = a.fit_transform(data) #导出结果,是一个数组,服从正态分布
a.inverse_transform(b) #将标准化结果进行逆转
#往往在神经网络中数据标准化是比较好的选择
#另一种数据标准化方法
from sklearn.preprocessing import scale #导入标准化的类
x = scale(data) #axis默认为0,对每个特征进行标准化,新特征均值为0,方差为1
#不同点,scale不能将原数据集训练得到的均值和方差应用到新的数据集中,如果使用全局样本,标准化计算的结果是训练集和测试集
#共同的期望和方差;standardscaler可以将数据集的均值和方差应用到新的数据集,即假设训练集和测试集的期望是一样的,
#测试集的标准化用的是训练集的期望和方差
#虽然特征数据已经基本处理完,但是因为现实收集到的分类标签可能出现极度偏向某一类的结果,就需要对样本进行均衡处理
#下采样,对原始数据集进行随机采样,效果可能并不是很好
#使用sample(),指定随机采集样本个数250,并返回样本到sample,一般对全数据集(含标签)进行采样,再切分训练集和测试集
#后续不用再利用索引找数据,因为分开随机采样时训练集和测试集可能不是同一个样本,导致标签对不上
sample = df.sample(n=250)
#过采样,使用SMOTE对标签少的一类样本进行样本添加,使其与另一类样本数量一致,用于二分类
from imblearn.over_sampling import SMOTE #导入过采样的类SMOTE
smoke = SMOTE() #实例化
#训练,并返回特征样本和标签样本,需要输入X,Y,因为要利用标签和特征生成新的特征
X_oversample, Y_oversample = smoke.fit_resample(X, Y) #此时样本中类别数量一致
#一般使用过采样,可以处理样本间数据不平衡问题,如评分卡等
#日期转换问题
#将某一列的数据改为日期为年月日时分秒的格式
df["InvoiceDate"] = pd.to_datetime(df["InvoiceDate"])
#将原本2017年11月1日 12时24分转换成2017-11-01 12:24:00格式
df['B'] = pd.to_datetime(df['B'], format='%Y年%m月%d日 %H时%M分')
#获取年月数据并在原数据集上添加该列
df['Year_Month'] = df["InvoiceDate"].apply(lambda x: x.strftime('%Y-%m'))
#获取月数据并在原数据集上添加该列
df['Month'] = df["InvoiceDate"].apply(lambda x: x.strftime('%m'))
#获取星期几的数据并在原数据集上添加该列
df['Day'] = df["InvoiceDate"].apply(lambda x: x.weekday())
#获取小时数据并在原数据集上添加该列
df['Hour'] = df["InvoiceDate"].apply(lambda x: x.strftime('%H'))
#python也有datetime模块,有strftime和strptime
import datetime.datetime
'''
数据归一化和数据标准化都是对数据特征下的数据进行压缩处理,可以使在模型训练过程中,加快收敛,使不同特征之间的取值范
围差异不会过大,从而导致特征的权重调整过慢;
缺失值处理可以把特征列缺失的数据进行填补,后面才可以调用模型进行训练,而标签列是不会有空值的,因为决策树和随机森林
处理的是有监督学习,需要所有样本的标签才可以进行模型训练;
编码和独热编码都是对特征下的数据,一般是非数值数据进行数值的转换,例如,性别的特征,使用编码,就可以用1跟0替换,这
样子后续的模型才可以接受这些数据进行训练;但是些数据,例如不同的性别,车次,不同的地点,其内在是没有关系的,准确来
说,不像数值成绩一样,可以进行数值的加减乘除而改变结果,就像男生不可能说加1就可以变成女生一样,是女不是男是男不是
女,所有需要使用哑变量来进行数值替换会更加的靠谱,不容易对后续模型算法的运算造成干扰;
数据二值化则是将特征列的数值以某个界限分开,划分成俩类,用0和1表示,可以是特征里的数据,用于出现某种特征或没有出现
某种特征的场景,简化数据;
数据分箱与二值化原理一样,只是分箱可以将数据分成多个类,例如成绩的划分等,参数可以选择编码也可以选择独热编码,可以
指定按照等宽或等位来划分数据,等宽就是划分后的每组数据间的最大值间隔相等,等位则是将该特征的全部数据按照样本数量相
等的个数划分出来;
总之,上述操作都是对特征下的数据进行处理,就是数据预处理的操作,而对各个特征之间的操作才是特征工程,例如合并某些特征,删除,选择某些特征作为
模型训练的特征等;
样本过采样感觉应该执行于数据归一化、标准化之前,数据编码,处理缺失值之后
'''
#对数据进行预处理完后,如果数据集非常大,模型训练就会非常慢,而且有对模型毫无贡献的特征,就需要去把它删除掉,
#所以还需要特征选择,对特征进行一定的筛选
#Filter过滤法,有方差过滤,卡方过滤,F检验过滤,互信息法过滤,需要自己对模型进行评估
#方差过滤,如果一个特征本身的方差很小,甚至为0,就表明该特征下的数据几乎是一模一样的,对模型的训练根本起不了一点
#的作用,就需要把这类特征删除掉
from sklearn.feature_selection import VarianceThreshold #导入方差过滤的类
selector = VarianceThreshold() #实例化,不填参数默认方差为0,即选出特征下所有数据全部一样的特征进行删除
X_var0 = selector.fit_transform(X) #将特征矩阵放进去训练并返回新的特征矩阵,二维及以上
#也可以自定义方差训练,也可以统计样本所有特征方差的中位数进行训练,则会删除掉一半的特征
#使用X.var()计算所有特征的方差,再用values取出所有方差的值,进行求中位数
X_median = VarianceThreshold(np.median(X.var().values)).fit_transform(X)
#当特征是二分类时,也就是伯努利随机变量,这些变量的方差可以计算成P(1-P)
#假设P=0.8,则可以删除掉特征是二分类时,某种类的数量占比达到百分之80以上的特征
X_p = VarianceThreshold(.8*(1-.8)).fit_transform(X) #实例化并删除有些数据量占比达到80%以上的特征
#当方差设置的比较小时,对于模型的训练时间可能几乎没啥变化,对于模型的表现可能也变化不大,但当方差设置的比较大时,
#由于删除掉了大部分特征,所有模型的训练时间肯定会有所下降,但是如果删除了较多的噪音特征,则模型的表现能力会上升,
#如果删除掉的是有用的特征,则模型的表现能力可能会有所下降
#卡方过滤,专门处理分类模型
from sklearn.feature_selection import SelectKBest #导入选择最优特征分数的类
from sklearn.feature_selection import chi2 #导入卡方检验的类
#实例化并导出新的特征矩阵,之所以要导入y,是因为卡方校验需要用到标签来计算特征与标签的关系
X = SelectKBest(chi2, k=300).fit_transform(x,y)
#但是,可能后续对新的特征矩阵进行模型训练后,模型效果并不好,那就是因为K的取值不好,可以通过划学习曲线来找出K的最
#优取值,当然,还有另外一种方法,可以不画学习曲线,而是利用对卡方检验的结果P进行统计,可以知道最优的K的取值
#对卡方检验输出结果进行分析,如果P小于0.05或0.01,则该特征与标签有相关性,不删除,通过计算该总数可以确定k的取值
K,P = chi2(x,y)
K = len(P)-sum(P>=0.05)
X = SelectKBest(chi2, k=K).fit_transform(x,y)
#F检验,既可以用于分类,也可以用于回归,可以计算特征与标签之间的线性关系
from sklearn.feature_selection import f_classif #导入F检验分类的类
from sklearn.feature_selection import f_regression #导入F检验回归的类
#对F检验输出结果进行分析,同样,如果P小于0.05或0.01则该特征与标签具有线性相关,不删除,可以计算总数来确定k的取值
F, P = f_classif(x,y)
F,P = k_regression(x,y)
K = len(P)-sum(P>=0.05)
X = SelectKBest(f_classif, k=K).fit_transform(x,y)
#互信息法,用来捕捉每个特征与标签之间的任意关系的方法,包括线性与非线性关系,既可以用于分类也可以用于回归
from sklearn.feature_selection import mutual_info_classif #导入互信息法分类的类
from sklearn.feature_selection import mutual_info_regression #导入互信息法回归的类
#互信息法检验不返回K或F统计量,而是返回每个特征与目标之间的互信息量的估计,0表示独立,1表示完全相关,
#但要求特征数据取值均大于0,否则可以使用归一化来统一数据取值区间
result = mutual_info_classif(x,y)
K = result.shape[0]-sum(result<=0) #计算有用的特征数量取值
X = SelectKBest(mutual_info_classif,k=K).fit_transform(x,y) #实例化并导出新的特征矩阵
#一般建议先使用方差过滤掉方差为0的特征,再用互信息法过滤,因为互信息法捕捉任意相关性,包括线性相关
#嵌入法,让算法自己决定使用哪些特征的方法,即特征选择和算法训练同时进行,但需要具体到每个算法
from sklearn.feature_selection import SelectFromModel #导入嵌入法的类
from sklearn.ensemble import RandomForestClassifier as RFC #导入随机森林回归的类
RFC_ = RFC(n_estimators=10,random_state=0) #随机森林实例化
#嵌入法实例化,指定分类算法,设置特征重要性的阈值,低于该值的都将被删除,进行训练并返回结果
X_embedded = SelectFromModel(RFC_,threshold=0.005).fit_transform(x,y)
#逻辑回归中的特征工程,对于逻辑回归来说,嵌入法比较高效
from sklearn.linear_model import LogisticRegression #导入逻辑回归的类
LR = LogisticRegression(solver='liblinear',C=0.8,random_state=0) #实例化逻辑回归
#逻辑回归默认L2正则,嵌入法使用L1范式来选择特征,并返回筛选完的特征矩阵
X_embedded = SelectFromModel(LR,norm_order=1).fit_transform(x,y)
#逻辑回归也可以使用特征重要性阈值参数来筛选特征
X_embedded = SelectFromModel(LR,threshold=0.005).fit_transform(x,y)
#此时的判断指标不是L1范式,而是逻辑回归中的系数,可以通过画学习曲线来确定最优的阈值
#确定阈值取值范围
threshold=np.linspace(0,abs(LogisticRegression(solver='liblinear',C=0.8,random_state=0).fit(x,y).coef_).max(),20)
#嵌入法返回的是新的特征矩阵,也看不到模型效果,所以得利用学习曲线,把阈值用来循环遍历,
#从随机森林的feature_importances或逻辑回归的coef_来获取阈值的取值范围,
#最后把新特征矩阵与y拿去交叉验证,看哪个阈值最优
#嵌入法选择的特征效果很好,过滤法计算远远快于嵌入法,虽然过滤法要考虑很多统计量,但是大型数据中还是会考虑过滤法,
#因为嵌入法运行太慢了
#包装法,也是特征选择和算法训练同时的方法,与嵌入法十分相似,但是是依赖某个专业的数据挖掘算法,
#专门用来选取特征,而不是随机森林等算法
from sklearn.feature_selection import RFE #导入包装法的类
RFC_ = RFC(n_estimators=10,random_state=0) #随机森林实例化
#实例化包装法,保留340特征,每次迭代删除50个特征
selector = RFE(RFC_, n_features_to_select=340,step=50).fit(x,y)
selector.support_.sum() #返回所有的特征是否被选中的bool矩阵,计算被选中特征数量
selector.ranking_ #返回特征的按数次迭代中总合重要性排名
X_wrapper = selector.transform(x) #返回包装法选择过后的新的特征矩阵
'''
过滤法更加快速,但比较粗糙
包装法和嵌入法更加的精确,比较适合具体到算法去调整,但是计算量比较大,尤其是嵌入法
当数据量很大时,优先使用方差过滤和互信息法调整,使用逻辑回归时,优先使用嵌入法,使用支持向量机时,优先使用包装法
'''
#除了对数据集进行特征选择,还可以进行特征创造,
#特征选择是在原始数据集中选取并删除某些特征,而特征创造则是生成新的完全不一样的特征矩阵
#PCA,是将已存在的特征进行压缩,降维后的特征不是原本的特征矩阵中的任何一个特征,而是通过某些方式组合起来的新特征
#如扭转特征空间,但新特征矩阵不具有可读性
#PCA使用的信息量衡量指标就是样本方差,也称为可解释性方差,方差越大,特征所带的信息量就越多
from sklearn.decomposition import PCA #导入PCA的类
pca = PCA(n_components=2).fit_transform(X) #实例化并训练导出新的特征矩阵到变量pca,指定降维为2个特征
pca = PCA(n_components=2).fit(X) #实例化
pca.explained_variance_ #输出各列新特征的可解释性方差
pca.explained_variance_ratio_ #输出各列新特征信息量在原来数据集所有特征的占比
pca.explained_variance_ratio_.sum() #输出各列新特征信息量在原来数据集所有特征的占比总和
pca = PCA().fit(X) #实例化,不加参数默认生成与原来特征数量相同的新的特征矩阵
pca = PCA(n_components='mle').fit_transform(X) #指定mle最大似然估计法,模型自己选出最好的维度数
pca = PCA(n_components=0.97, svd_solver='full') #选出信息量大于0.97的特征维度构成新的特征矩阵,必须指定svd_solver
#降维常用于人脸识别,使模型只识别几个重要特征就可以实现准确高效的识别人脸
'''
数据集的预处理已经基本完成,后续只需对数据放进各类模型进行训练以及调参评估就可以应用
'''
#对模型进行训练前一般需要先拆分训练集和测试集
from sklearn.model_selection import train_test_split #导入拆分数据集的类
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3) #实例化,指定测试集的占比为30%,并返回结果
#当然,划分好训练集和测试集后,有时候还有必要进行交叉验证,来衡量我们拆分的数据集是否合理
from sklearn.model_selection import cross_val_score #导入交叉验证的类
#指定实例化好的模型,特征数据,标签,交叉验证次数10次,第一次第1份作为测试集,另外9份测试集,第二次第2份作为测试集,
#其它为训练集,如此往复,直到10次交叉验证完,输出结果
score = cross_val_score(clf,x,y,cv=10).mean()
#上面代码输出十次交叉验证的分数结果,求均值,如果发现输出的评估分数比模型本身评估分数低,证明拆分的数据集还行
#网格搜索可以用来搜索模型最优的超参数
from sklearn.model_selection import GridSeachCV #导入网格搜索的类
parameters = {"criterion":("gini","entropy") #定义网格搜索参数及取值范围,用字典以键值对形式定义
,"splitter":("best","random")
,"max_depth":[*range(1,10)]
,"min_samples_leaf":[*range(1,50,5)]
}
clf = DecisionTreeClassifier(random_state=0) #实例化决策树
gs = GridSearchCV(clf, parameters, cv=10) #实例化网格搜索,把实例化好的模型放进去,搜索参数,交叉迭代10次
gs = gs.fit(X,Y) #训练
gs.best_params_ #输出最优参数
gs.best_score_ #输出最优参数结合的模型评估结果
#K折交叉验证
from sklearn.model_selection import cross_val_score, KFold #导入K折交叉验证的类
KF = KFold(n_splits=5) #实例化,切分5块数据
#指定实例化好的模型,特征,标签,K折交叉,打分结果使用召回率
recall_ori = (cross_val_score(LG, X, Y, cv=KF, scoring='recall')).mean()
#输出结果是K折交叉验证后所有召回率的均值
'''
上面几个都是帮助选出好的模型参数或者模型
'''
#接下来,就是进行模型本身的训练,sklearn中有多种机器学习模型,用于处理分类和回归等任务
#决策树,分为分类树和回归树
from sklearn import tree #导入tree模块,里面包含分类和回归的类
clf = tree.DecisionTreeClassifier() #实例化,设置分类树训练的参数,默认是基尼系数(gini)
clf = clf.fit(Xtrain,Ytrain) #设置训练集的数据,通过训练得到模型返回给变量TC
score = clf.score(Xtest,Ytest) #设置测试集的数据,并将测试结果返回给变量score,一般返回准确率
TR = DecisionTreeRegressor(max_depth=2) #实例化,设置回归树的深度为2
TR = TR.fit(Xtrain,Ytrain) #设置训练集的数据,fit
score = TR.score(Xtest,Ytest) #输入测试集进行模型测试
score = TR.predict(Xtest) #输入测试集特征进行结果预测
feature_importances = TR.feature_importances_ #查看各特征重要性
#决策树实例化的参数有random_state(控制树的随机性)
#max_depth(树的深度)
#min_samples_leaf(叶子上面的最少数量有多少才能保留分支)
#min_samples_split(分叉最少要有多少个样本才能进行分支)
#max_features(限制最大用于模型的特征数量)
#criterion(gini,entropy)基尼系数和信息增益
#min_impurity_split(设置最低的不纯度,低于该值不再进行分支)
#max_leaf_nodes(设置最大叶子节点数量,高于该值删除叶子节点)
#使用集成学习(袋装法就是集成学习),利用多个模型共同预测结果,袋装法的典型代表是随机森林
#随机森林,可以提高模型预测的准确性
from sklearn.ensemble import RandomForestClassifier #导入随机森林分类的类
RC = RandomForestClassifier(random_state=0) #实例化
RC = RC.fit(Xtrain,Ytrain) #把测试集数据带入模型训练
source = rlf.score(Xtest,Ytest) #输入测试集数据进行模型打分
from sklearn.ensemble import RandomForestRegressor #导入随机森林回归器的类
rfr = RandomForestRegressor(n_estimators=100) #实例化,生成100棵树
rfr = rfr.fit(Xtrain, Ytrain) #把测试集数据带入模型训练
#随机森林实例化的参数有random_state(控制森林的随机性,同一片森林的树可以是不一样,但是森林一样)
#n_estimators(树的数量)
#max_depth(树的深度)
#min_samples_leaf(叶子上面的最少数量有多少才能保留分支)
#min_samples_split(分叉最少要有多少个样本才能进行分支)
#max_features(限制最大用于模型的特征数量)
#criterion(gini,entropy)基尼系数和信息增益
#bootstrap(随机放回抽样)
#oob_score(使用袋外数据作为测试集)
#Bagging(袋装法)
#使用随机抽样放回的参数训练模型,得划分训练集测试集,随机森林默认就是该参数(bootstrap=True)
rcf = RandomForestClassifier(bootstrap=True)
rcf.fit(Xtrain,Ytrain)
rcf.score(Xtest,Ytest)
#使用袋外数据进行模型测试,所以可以不用划分训练集与测试集,默认不使用袋外数据
rcf = RandomForestClassifier(random_state=1, oob_score=True)
rcf.fit(X, Y) #使用全部样本进行训练
rcf.oob_score_ #使用袋装法落到袋外的数据集进行模型测试
rcf.predict(Xtest) #预测数据
rcf.predict_proba(Xtest) #返回预测数据的各个类别的概率占比
#GBDT,也是属于集成学习的一种,下一个学习器利用上一个学习器的预测结果,尽可能拟合误差,如此类推,最后进行加和
from sklearn.ensemble import GradientBoostingRegressor #导入gbdt回归(梯度提升树)
from sklearn.ensemble import GradientBoostingClassifie #导入gbdt分类(梯度提升树)
gbdt = GradientBoostingRegressor(n_estimators=100) #实例化
gbdt = gbdt.fit(Xtrain,Ytrain) #训练
gbdt.predict(Xtest) #数据预测
#逻辑回归,分类,离散型数值
from sklearn.linear_model import LogisticRegression #导入逻辑回归的类
#使用L1正则化,稀疏特征
LR1= LogisticRegression(penalty='l1',solver='liblinear',C=0.5,max_iter=1000)
#使用L2正则化,C是正则化强度,默认1,越小惩罚力度越强
LR2= LogisticRegression(penalty='l2',solver='liblinear',C=0.5,max_iter=1000)
L1 = LR1.fit(Xtrain,Ytrain)
L2 = LR2.fit(Xtrain,Ytrain) #训练
L1.coef_ #查看特征系数,L1正则化的系数有的为0,可以实现特征选择的作用
L2.coef_ #查看特征系数,L2正则化的系数不为0,有正有负
L1.score(Xtest,Ytest) #模型评分
#线性回归,处理连续数值
from sklearn.linear_model import LinearRegression #导入线性回归的类
#实例化,fit_intercept=True指定需要计算线性回归中的截距,normalize=False训练样本会进行归一化处理,默认就是该值
LR = LinearRegression(fit_intercept=True,normalize=False)
LR.fit(Xtrain,Ytrain) #训练
LR.score(Xtest,Ytest) #模型评分
LR.predict(Xtest) #预测结果
LR.coef_ #权重向量
intercept_ #截距b值
#KNN,有监督学习,既可以分类,也可以回归,K个最近的邻居分类靠近哪一类归为哪一类
from sklearn.neighbors import KNeighborsClassifier as KNN #导入KNN的类
KN = KNN(n_neighbors=5) #实例化,n_neighbors,指定以多少个最近邻的属性来分类数据
KN.fit(Xtrain,Ytrain) #模型训练
KN.score(Xtest,Ytest) #模型打分
KN.predict(Xtest) #数据预测
KN.predict_proba(Xtest) #输出样本每种分类的概率值
#SVM,有监督学习,既可以分类,也可以回归,支持向量机
from sklearn.svc import SVC #导入svc分类的类
clf = SVC() #实例化
clf.fit(Xtrain,Ytrain) #训练
from sklearn.svc import SVR #导入svc回归的类
rlf = SVR() #实例化
rlf.fit(Xtrain,Ytrain) #训练
#朴素贝叶斯,分类
from sklearn.datasets import load_iris # 导入鸢尾花数据集
from sklearn.model_selection import train_test_split # 导入数据集划分函数
from sklearn.naive_bayes import GaussianNB # 导入高斯朴素贝叶斯分类器
from sklearn import metrics # 导入性能评估模块
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data # 特征数据
y = iris.target # 标签数据
# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建朴素贝叶斯分类器对象
model = GaussianNB()
# 在训练集上训练模型
model.fit(X_train, y_train)
# 在测试集上进行预测
y_pred = model.predict(X_test)
# 评估模型性能
accuracy = metrics.accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
# 输出混淆矩阵和分类报告
print("Confusion Matrix:")
print(metrics.confusion_matrix(y_test, y_pred))
print("Classification Report:")
print(metrics.classification_report(y_test, y_pred))
#Kmeans,无监督学习,聚类算法,根据数据内在相似性区分数据类别
from sklearn.cluster import KMeans #导入Kmeans的类
KM = KMeans(n_clusters=3, random_state=0).fit(data) #实例化,把数据聚成三类,fit返回结果
y_pred = KM.labels_ #查看数据集的聚类结果
from sklearn.metrics import silhouette_score #导入轮廓系数评价的类
score = silhouette_score(data,y_pred) #输入数据集,聚类结果,输出轮廓系数,越接近1越好,范围-1到1
'''metrics是sklearn中用来衡量模型指标的模块'''
#混淆矩阵可以用来对分类模型预测结果进行评估,结合画图可以更加明显显示预测结果好坏TP,TN,FP,FN等
from sklearn.metrics import confusion_matrix #导入混淆矩阵的类
matrix = confusion_matrix(y_true, y_pred) #输入真实结果和预测结果,输出混淆矩阵,行是真实值,列是预测值
#分类是机器学习中比较常见的任务,利用混淆矩阵,对于分类任务常见的评价指标有准确率(Accuracy)、
#精确率(Precision)、#召回率(Recall)
#准确率是分类正确的样本占总样本个数的比例,即TP+TN/TP+TN+FP+FN
#准确率是分类问题中最简单直观的评价指标,但存在明显的缺陷,比如如果样本中有99%的样本为正样本,那么分类器只需要
#一直预测为正,就可以得到99%的准确率,但其实际性能是非常低下的,也就是说,当不同类别样本的比例非常不均衡时,
#占比大的类别往往成为影响准确率的最主要因素,就需要进行过采样等
from sklearn.metrics import accuracy_score #导入准确性评估的类
print(accuracy_score(y_true, y_pred)) #输入真实的标签和预测的标签就可以输出准确率
#精确率指模型预测为正的样本中实际也为正的样本占被预测为正的样本的比例,即TP/TP+NP
from sklearn.metrics import precision_score #导入精确率评估的类
print(precision_score(y_true, y_pred, average='macro')) #先计算每个标签对应精确率,再求平均值
print(precision_score(y_true, y_pred, average='micro')) #先计算全局下的统计,再带入公式求精确率
print(precision_score(y_true, y_pred, average='weighted')) #给每个标签按照支持度赋予权重,再计算
print(precision_score(y_true, y_pred, average=None)) #输出多个类别下的精确率
#召回率指实际为正的样本中被预测为正的样本所占实际为正的样本的比例,即TP/TP+FN
from sklearn.metrics import recall_score #导入召回率评估的类
print(recall_score(y_true, y_pred, average='macro')) #先计算每个标签对应召回率,再求平均值
print(recall_score(y_true, y_pred, average='micro')) #先计算全局下的统计,再带入公式求召回率
print(recall_score(y_true, y_pred, average='weighted')) #给每个标签按照支持度赋予权重,再计算
print(recall_score(y_true, y_pred, average=None)) #输出多个类别下的召回率
#回归的评估指标有MAE,MSE,R*2,RMSE等
#MAE,平均绝对误差,Mean absolute error,预测值与真实值的绝对误差的平均值
from sklearn.metrics import mean_absolute_error #导入平均绝对误差的类
mean_absolute_erro(true, pred) #输出MAE
#MSE,均方误差,Mean squared error,预测值与真实值的绝对平方误差的平均值
from sklearn.metrics import mean_squared_error #导入均方误差的类
mean_squared_error(true, pred) #输出MSE
#ROC曲线
#TPR,真正率,预测正确的正样本占总正样本的比率,TP/TP+FN,和召回率(查全率)一样
#FPR,假正率,预测错误的负样本占总负样本的比率,FP/TN+FP
#ROC曲线的横坐标为FPR,纵坐标为TPR,AUC则是指ROC曲线下方的面积,越大模型性能越好
from sklearn.metrics import roc_curve, auc #导入绘制roc曲线相关的类
#参数y_true是标签,范围(0,1)或(-1,1),否则需要使用pos_label指定正样本
#y_score是模型预测的类别概率值
#pos_label是标签中被选中为正样本的标签,若标签为【0,1,2】且pos_label=1则1为正样本,其余为负样本
#则y_score也必须指定同一标签下的概率,具体实际情况用索引提取数据
fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob[:, 1], pos_label=1)
plt.plot(fpr, tpr, label='ROC curve area = {}'.format(auc(fpr, tpr)))
plt.plot([0, 1], [0, 1], 'k--') # 绘制对角线
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()
#机器学习常用到的一个第三方库是matplotlib,用来画图的,可以更加直观显示数据的信息
import matplotlib.pyplot as plt #导入画图模块
#折线图
plt.plot(X,Y,linestyle='-',linewidth=1,color='gray',alpha=0.5,label='hhh') #X是横坐标的值,Y是对应纵坐标的值,线形,线宽,颜色,透明度,图例
plt.legend()
#散点图
plt.scatter(X,Y,marker='o',s=60,color='red') #X是点的横坐标,Y是点的纵坐标,s是点的样式
#绘制多窗口
plt.figure(figsize=(4,3),facecolor='gray') #窗口大小,背景颜色
#设置坐标轴文本
plt.xlabel('text') #设置X轴文本标签
plt.ylabel('text') #设置Y轴文本标签
#设置坐标轴刻度
plt.xticks() #设置X轴刻度,([])时没有刻度
plt.yticks() #设置Y轴刻度
#文本
plt.text(X,Y,'text',size=33,ha='center',va='center') #在(X,Y)位置写文本text,居中
#柱状图
plt.bar(X,Y,0.8,color='limegreen') #宽度0.8
#填充图像
plt.imshow(data,cmap='gray') #传入数据矩阵,jet是热成像填充,gray是灰度填充
#子图
plt.figure()
plt.subplot(331)
plt.subplot(3,3,1) #操作3*3矩阵中第一张子图,后续对子图操作与之前画图操作一样
#一般画子图可以用for循环遍历
a, b = plt.subplots(237,10,figsize=(10,237),subplot_kw={'xticks':[], 'yticks':[]})
for i, j in enumerate(b.flat): #i是画布,j是子图
j.imshow(image[i]) #对空子图进行放入数据并显示图像,默认深蓝色到亮黄色渐变
AI-machine
最新推荐文章于 2024-05-03 23:37:05 发布