数据分析(十三)

练习:图片压缩

导入三剑客:

import numpy as np
import pandas as pd
from matplotlib.pyplot as plt

如果从 0-255这256(16x16)种颜色 中 抽取出 16种(4x4)

则在保存的时候 如果是保存成png格式的图片 图片的元数据中会自动建立颜色索引 从而压缩数据量

# 128*128个像素点
# 压缩前 r g b三种颜色 每种颜色256个色值
# 保存 256种色值 占用8bit(2**8)
2**8
128*128*3*8
#[8,8,8]  24
# 压缩
# 通过聚类 提取具有代表性的16种颜色
2**4  4
# 元数据(描述数据的数据)
# png是压缩格式 如果发现 一共只有16种颜色 就会建立颜色索引
# 之前 每个像素点的值 8bit+8bit+8bit
# 就变成了一个记录当前颜色编号的值
# 一共有16种颜色要编号
# 2**4
# 每个像素点现在只占用4个bit
2**4
128*128*4 # 
# 把所有的彩色的像素点当作一个一个的样本 对所有的样本 进行 聚类分析 分成16类
# 将来 还要 把类似的一组彩色点 变成同样的彩色点 进行替换
# 替换完成之后 整个图片 其实就只有这16种像素点了
# 获取样本 (加载图片 获取里面的数据)
img = plt.imread('./before.png')
# 最后一个维度 是alpha值 表示透明度
# 我们这里不需要考虑透明度的问题
# 所以把最后一列 去掉
img
img2 = img[:,:,:-1]  # 最外围(行)所有的都要 再往里一个维度(列)所有的都要 (所有的像素点都保留了) 最后一个维度 值切片前三列(r g b)
plt.imshow(img2)
img2.shape
img2.reshape(-1,3)  # 对原来的图片进行变形 把每一个像素点取出来作为样本
# 并且 样本是顺序没变 仍然是原来(从左到右从上到下)的排列顺序
# 对图片进行聚类(把每一个像素点作为一个样本 聚合成16类)
img2
# 获取模型
from sklearn.cluster import KMeans
# 分16类
kmeans = KMeans(n_clusters=16)
# 训练的时候 传入的 训练集 的 数据结构
# 是二维的结构 每一行代表一个样本 每一列是一个特征
kmeans.fit(img2.reshape(-1,3))
y_ = kmeans.predict(img2.reshape(-1,3))  # 做预测 返回的是 按照顺序的 各个样本(像素点) 的归类的编号
y_
# kmeans.fit_predict
np.sort(pd.Series(y_).unique())  # 0-15 一共有16种分类
y_  # 按照顺序的 各个 像素点的分类编号
# 看看聚类中心
centers = kmeans.cluster_centers_
centers
centers.shape
centers.reshape(4,4,3)
plt.imshow(centers.reshape(4,4,3))
y_  # 按照顺序的 各个 像素点的分类编号
centers
centers[[3,3,3,3,3,3,3]]
centers[y_]  # 按照编号从centers中把聚类中心取出来
result = centers[y_]
result.shape
img3 =  result.reshape(128,128,3)
plt.imshow(img3)
# 传入 路径 和 数据 即可
plt.imsave('./after',img3)
16*16*16

时间(训练时间、使用时间)

准确率

模型的保存(模型的大小)

每种机器学习模型都有其各自的时间

看看模型的运行情况和分类效果

对比knn和lgc

时间问题和降维

import numpy as np
import pandas as pd
from matplotlib.pyplot as plt

from sklearn.datasets import load_digits
digits=load_digits()
data=digits.data#特征值
target=digits.target#目标值

#对数据进行切分
from sklearn.model_selection import train_test_split
data.shape
X_train,X_test,y_train,y_test=train_test_split(data,target)#
#获取模型并训练
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
# %time 可以计算后面的代码执行的时间
# %timeit
# %%time
# %%timeit 
# %time knn.fit(X_train,y_train)  # 15ms knn训练的速度是非常快的 因为knn在训练的时候 只是记录了一下所有训练样本的位置
from sklearn.linear_model import LogisticRegression
lgc = LogisticRegression()
# %time lgc.fit(X_train,y_train)  # 629 ms lgc训练的速度很慢 因为要计算各个特征的权重 计算量很大
# 使用时候的时间对比
# %time knn.predict(X_test)  # 299ms knn在使用的时候 速度非常慢 因为每一个要预测的样本
# %time lgc.predict(X_test)  # 3ms lgc在使用的时候 速度非常快 因为只需要把测试样本的各个特征值 和 参数 进行计算 得到分类的概率即可
# 平时肯定不可能 每次使用模型之前都先训练一遍
# 所以 平时 是 训练好模型之后 需要 把 模型保存到本地
from sklearn.externals import joblib
knn
# value, filename
# value就是要保存的模型
# filename是要保存的地址
joblib.dump(knn,'./knn_digits.m')  # 1430KB  模型很大 因为里面保存了所有训练样本的位置
joblib.dump(lgc,'./lgc_digits.m')  # 6KB 模型比较小 因为里面只需要 保存 各个特征的系数
knn2 = joblib.load('./knn_digits.m')  # 导入进来数据之后 就直接是可以使用的模型对象
knn2.predict(X_test)
lgc2 = joblib.load('./lgc_digits.m')
lgc2.predict(X_test)
knn.score(X_test,y_test)
lgc.score(X_test,y_test)
# 如果 最关心的是 准确率 确实 knn得分更高
# 时间方面
#    训练耗时  knn训练是很快的 lgc反而慢
#    使用时的耗时 knn用起来很慢 lgc快
# 时间方面 最主要是看使用时候消耗的时间(如果让用户等待太久 用户体验不好) 
# 时间方面lgc完胜
# 模型大小 
df = pd.read_csv('./data/digits.csv')
df.shape
df.head()
784**0.5
# 先把整体的数据 分成特征值和目标值
target = df['label']  # 目标值
target
target.shape
# 特征值
data = df.values[:,1:]
data.shape
data
plt.imshow(data[10].reshape(28,28))
print(target[10])
# 把数据集分成 训练集 和 测试集
X_train,X_test,y_train,y_test = train_test_split(data,target)  # 样本量足够多 可以使用默认的切分比例0.25
knn = KNeighborsClassifier()
# %time knn.fit(X_train,y_train)  # 32.8 s 这个速度是比较快的
# %time knn.predict(X_test)  # 大约十分钟
lgc = LogisticRegression()
# %time lgc.fit(X_train,y_train)  # 非常耗时 大约需要三四十分钟
# %time lgc.predict(X_test)  # 和knn相比 特别快 一秒都不到
# 如果遇到 训练模型非常耗时的情况 
# pca和lda可以实现 降维
# 降维后 可以缩短训练时间 同时 不会对模型的准确率产生很大的不良影响

pca 主成分分析

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 用鸢尾花数据集 展示 降维的效果
from sklearn.datasets import load_iris
iris = load_iris()
data = iris.data  # 特征值
target = iris.target # 目标值
# 绘制平面散点图
plt.scatter(data[:,0],data[:,1],c=target)
# 如果要想分类准确 需要考虑所有特征
from sklearn.model_selection import train_test_split
data.shape
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.1)
from sklearn.neighbors import KNeighborsClassifier
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.1)
KNeighborsClassifier().fit(X_train,y_train).score(X_test,y_test)
# 如果只是打分一次 会有很多偶然因素
# 所以 应该 做交叉验证
150*0.11
np.arange(0.1,0.2,0.01)
# 定义一个函数 调用函数 传入 模型 数据集的特征值和目标值
# 函数内部会按照 多个比例 对数据集进行切分 然后获取平均分
def cross_verify(model,data,target):
    scores = []
    # 按照不同比例去切分 训练集 和 测试集
    for i in np.arange(0.1,0.2,0.01):
        X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=i)
        score = model.fit(X_train,y_train).score(X_test,y_test)
        # 把每次打分 加入到分数列表中
        scores.append(score)
    
    return np.array(scores).mean()
cross_verify(KNeighborsClassifier(),data,target)  # 94-97之间
# 使用PCA来对数据进行降维
# decomposition 分解
from sklearn.decomposition import PCA
# 获取
# n_components 用来控制保留多少个特征 可以传入整数表示保留特征的个数 还可以传入小数表示保留的特征的比例
pca = PCA(n_components=2)
# 训练模型
pca.fit(data)  # pca只是找当前数据自身内部的最大差异 不关心各种分类之间的差别 所以只传入data即可 target可以不传
data.shape  # 150个样本 4个特征
# 对高维度的数据 进行降维 转换
pca_data = pca.transform(data)
# pca.fit_transform
pca_data.shape  # 样本还是原来的样本 只是特征从4个压缩到了2个
pca_data
plt.scatter(data[:,0],data[:,1],c=target)
plt.scatter(pca_data[:,0],pca_data[:,1],c=target)
cross_verify(KNeighborsClassifier(),pca_data,target)  # 降低维度是否会影响准确率呢 95-97 大部分情况下降维并不会影响准确率 而且会提高速度
# discriminant_analysis判别分析
# 线性判别分析 LinearDiscriminantAnalysis
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis(n_components=2)
# pca.fit(data)
lda.fit(data,target)  # lda是要查看 各个分类之间的差异 所以需要传入各个样本的分类的目标值
lda_data = lda.transform(data)
# lda.fit_transform
plt.scatter(pca_data[:,0],pca_data[:,1],c=target)
plt.scatter(lda_data[:,0],lda_data[:,1],c=target)
cross_verify(KNeighborsClassifier(),lda_data,target)  # 使用lda进行降维 也不会对准确率产生很大影响

model_selection

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#演示完整流程
df = pd.read_table('./data/wheats.tsv',header=None)
#回顾之前的做法
# 特征值 目标值
target = df.iloc[:,7]
data = df.iloc[:,:-1]
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(data,target)
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train,y_train).score(X_test,y_test)
  1. 数据预处理

先以0.25的默认比例分割数据集 选择合适的数据处理方式

# sklearn官网
# MinMaxScaler 区间归一化 (当前值-最小值)/(最大值-最小值)  把数值的范围缩放到0-1之间
# StandardScaler 标准化 (当前值-平均值)/标准差   均值变成了0 标准差变成了1 把数据集变成标准正态分布
# Normalizer 归一化 (当前值-平均值)/(最大值-最小值)  对区间进行缩放 -1 1
# Binarizer 二值化 (这里就不尝试了 主要用来处理图片)
# from sklearn.preprocessing import MinMaxScaler,Normalizer,StandardScaler,Binarizer
# 二值化 其实就是把很多值变成两个值
# 0-255 阈值 120 
from sklearn.preprocessing import MinMaxScaler,StandardScaler,Normalizer
mms = MinMaxScaler()
data.shape
mms.fit(data)
# mms.fit_transform  如果训练和转换用的是同样的数据集 可以使用fit_transform
mms_data = mms.transform(data)
# 使用处理后的数据去训练模型
# 对处理后的数据集进行切分 分成 训练集 和测试集
X_train1,X_test1,y_train1,y_test1 = train_test_split(mms_data,target)
knn.fit(X_train1,y_train1).score(X_test1,y_test1)  # 数据量比较小 打分可能有偶然因素
data.shape
def cross_verify(model,data,target):
    scores = []
    # 按照不同比例去切分 训练集 和 测试集
    for i in np.arange(5,35,1):
        X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=i/100)
        score = model.fit(X_train,y_train).score(X_test,y_test)
        scores.append(score)
    return np.array(scores).mean()
# 多次打分求平均分
# 使用不同的数据预处理方式 对数据进行处理
# 看看不同模型的差异
# 传入指定的模型 和 没有处理之前的 数据的特征值和目标值(在函数中 我们会进行各种预处理)
def prepro(model,data,target):
    # 先做区间缩放MinMaxScaler
    mms_data = MinMaxScaler().fit_transform(data)
    # 打印输出平均分
    print('使用MinMaxScaler预处理得分是:',cross_verify(model,mms_data,target))
    # StandardScaler
    ss_data = StandardScaler().fit_transform(data)
    print('使用StandardScaler预处理得分是:',cross_verify(model,ss_data,target))
    # Normalizer
    n_data = Normalizer().fit_transform(data)
    print('使用Normalizer预处理得分是:',cross_verify(model,n_data,target))
    # 注意:没有做过数据预处理的 数据集 也打下分
    print('没有做数据预处理得分是:',cross_verify(model,data,target))
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
from sklearn.linear_model import LogisticRegression
lgc = LogisticRegression()
from sklearn.tree import DecisionTreeClassifier
dtree = DecisionTreeClassifier()
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB()
from sklearn.svm import SVC
svc = SVC()
prepro(knn,data,target)
#使用MinMaxScaler预处理得分是: 0.9197825531367171
#使用StandardScaler预处理得分是: 0.9277567339665294
#使用Normalizer预处理得分是: 0.9071806117960503
#没有做数据预处理得分是: 0.8910126439475422
prepro(lgc,data,target)
# 剩下的模型可以自己尝试 看看 得分
# 假设 数据 不需要预处理 先做要考虑的是选择哪种模型
# 除了平均分 比较 重要 得分的差异情况也需要参考一下
# 算法的稳定性
knn.__class__.__name__
def cross_verify(model,data,target):
    scores = []
    for i in np.arange(5,35,1):
        X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=i/100)
        score = model.fit(X_train,y_train).score(X_test,y_test)
        scores.append(score)
    # 除了要计算平均值 还要计算标准差 就不返回了 打印输出
    # return np.array(scores).mean()
    print('使用{}模型,平均分{},标准差是{}'.format(model.__class__.__name__,np.array(scores).mean(),np.array(scores).std()))
# 以列表的形式 传入多个备选模型 以及数据
def select_model(models,data,target):
    for model in models:
        cross_verify(model,data,target)
select_model([knn,lgc,dtree,gnb,svc],data,target)
# 选择完模型之后 还需要 看看 不同的参数 对分类的准确率 能否提高
# 实际选择的是 可能是选择几个相对不错的
# C=1.0
# C指的是 对 误差样本的容忍程度
# C越大表示 容忍度越低 容易过拟合
# C越小表示 容忍度越高 容易欠拟合
svc = SVC()
# svc.set_params 创建好模型之后 还可以重新对模型的参数进行设置
for i in [0.01,0.1,1.0,10,100,1000,10000]:
    # svc = SVC(C=i)
    svc.set_params(C=i)
    cross_verify(svc,data,target)

关掉警告:

import warnings
warnings.filterwarnings("ignore")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值