PCA、LDA后SVM分类案例

高光谱数据SVM分类

  • PCA降维
    • sklearn.decomposition.PCA介绍
    • PCA对象方法
    • 导入库(后面使用到了的先全部导入了)
    • PCA使用简单案例
    • PCA.fit() 结果:前n个波段包含的主成分信息
  • SVM分类代码

PCA降维

都知道PCA是用来对数据进行降维的,就不多说明了,高光谱数据维度高,降维后可减少运算,要想下一步分类,往往都先做降维处理

sklearn.decomposition.PCA介绍

函数定义:

class sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False, svd_solver=‘auto’, tol=0.0, iterated_power=‘auto’, random_state=None)

·n-components:int, float, None or str

  1. 若为大于1的整数(int)时,表示希望保留的降维后的维数;
  2. 若为取值为(0,1)的float型时,表示自动根据样本特征方差来决定降维到的维度数,这里n_components表示主成分的方差和所占的最小比例阈值。

·copy:copybool, default=True

表示是否在运行算法时,将原始训练数据复制一份。若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为False,则运行PCA算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。

PCA对象方法

·fit(X,y=None)
fit()可以说是scikit-learn中通用的方法,每个需要训练的算法都会有fit()方法,它其实就是算法中的“训练”这一步骤。因为PCA是无监督学习算法,此处y自然等于None。
fit(X),表示用数据X来训练PCA模型。
函数返回值:调用fit方法的对象本身。比如pca.fit(X),表示用X对pca这个对象进行训练。
·explained_variance_
代表降维后的各主成分的方差值。方差值越大,则说明越是重要的主成分。·explained_variance_ratio_
代表降维后的各主成分的方差值占总方差值的比例,这个比例越大,则越是重要的主成分。

导入库(后面使用到了的先全部导入了)

import matplotlib.pyplot as plt
import joblib
from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split
import numpy as np
from sklearn.svm import SVC
from sklearn import metrics
from sklearn import preprocessing
from sklearn.decomposition import PCA
import pandas as pd
#from sklearn.grid_search import GridSearchCV
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from time import time
from sklearn import preprocessing
from scipy.io import loadmat
import spectral
from functools import reduce
import sklearn
from sklearn.preprocessing import StandardScaler

PCA使用简单案例

X = loadmat(r'E:\Indian_pines.mat')['indian_pines']
print ('x.shape: ',X.shape)
newX = np.reshape(X,(-1,X.shape[2]))
print ('newX.shape: ',newX.shape)
y = loadmat(r'E:\Indian_pines_gt.mat')['indian_pines_gt']
#pca=PCA( )
pca=PCA(n_components=0.9999)  # n_components可以写数字或小数,此处表示保留99.99%的原始信息
pca.fit(newX,y)
ratio=pca.explained_variance_ratio_
print("pca.components_。shape: ",pca.components_.shape)
print("pca_var_ratio.shape:",pca.explained_variance_ratio_.shape)
#绘制图形
for i in range(X.shape[2]):
    total = np.sum(ratio[0:i+1])
    if total >= 0.999:
        print('只需要前%d个主成分即可达到99.9%%'%i)
        break
plt.plot([i for i in range(X.shape[2])],
         [np.sum(ratio[:i+1]) for i in range(X.shape[2])])
plt.xticks(np.arange(X.shape[2],step=20))
plt.yticks(np.arange(0,1.01,0.10))
plt.grid()
plt.show()

PCA.fit() 结果:前n个波段包含的主成分信息

PCA、LDA后SVM分类案例_第1张图片
由图可得,仅使用前69个波段便可以包含99.9%的主成分信息

SVM分类代码

注释都写的很明确了

# 获取mat格式的数据,loadmat输出的是dict,需要进行定位
#原始数据
#数据是字典类型,键值对都不一样,打印一下loadmat后的数据的键,根据实际修改以下三个键的值
input_image = loadmat(r'E:\Indian_pines.mat')['indian_pines']
#标签数据
output_image = loadmat(r'E:\Indian_pines_gt.mat')['indian_pines_gt']
#分类结果数据
corrected_image = loadmat(r'E:\Indian_pines_corrected.mat')['indian_pines_corrected']
print(len(list(input_image[3][6])))
# plt.imshow(output_image,'gray')
# plt.show()
#看看打印的字典键
#前面input和output要去掉取键里的值才能进行下面两句的键打印
# print(input_image.keys())
# print(output_image.keys())
print('input size : ',input_image.shape)
print('input type : ',type(input_image))
print('output size: ',output_image.shape)
label = np.unique(output_image)
row,col = output_image.shape
labelNum = {}
for i in range(row):
    for j in range(col):
        if output_image[i][j] in labelNum:
            labelNum[output_image[i][j]] += 1
        else:
            labelNum[output_image[i][j]] = 0
#print(labelNum)
# total = lambda x,y:x+y,labelNum.values()
# #view = spectral.imshow(corrected_image,classes = output_image,bands=(1,2,3))
# ground_truth = spectral.imshow(input_image,classes = output_image.astype(int))
# plt.show()
need_label = np.zeros([output_image.shape[0],output_image.shape[1]])   
for i in range(output_image.shape[0]):
    for j in range(output_image.shape[1]):
        if output_image[i][j] != 0:
            need_label[i][j] = output_image[i][j]
# plt.imshow(need_label,'gray')
# plt.show()
new_datawithlabel_list = []
for i in range(output_image.shape[0]):
    for j in range(output_image.shape[1]):
        if need_label[i][j] != 0:
            c2l = list(input_image[i][j])
            c2l.append(need_label[i][j])
            new_datawithlabel_list.append(c2l)

new_datawithlabel_array = np.array(new_datawithlabel_list)
print('new_datawithlabel_array 的shape为: ',new_datawithlabel_array.shape)
#标准化

data_D = preprocessing.StandardScaler().fit_transform(new_datawithlabel_array[:,:-1])  #(arry[:, :-1])按逆序展示,去掉了最后一列
print('data_D.shape:',data_D.shape)
#data_D = preprocessing.MinMaxScaler().fit_transform(new_datawithlabel_array[:,:-1])


#data_L为label值的元组
data_L = new_datawithlabel_array[:,-1]
print(type(data_L.shape))

# 将结果存档后续处理

#new为标准化后加上label列表
new = np.column_stack((data_D,data_L))
new_ = pd.DataFrame(new)
new_.to_csv('E:/Indian_pine.csv',header=False,index=False)
# 生成csv文件后,就可以直接对该文件进行操作
print('Done')

#读取前面保存的csv文件数据进行使用
data = pd.read_csv('E:/Indian_pine.csv',header=None)
data = data.values
#取最后一列以前的所有列
data_D = data[:,:-1]
#取最后一列
data_L = data[:,-1]
#将原始数据分成训练集和测试集两部分
data_train, data_test, label_train, label_test = train_test_split(data_D,data_L,test_size=0.5)


# 模型训练与拟合linear  rbf  poly
t0 = time()
#训练模型
pca = PCA(n_components = 70, whiten=True).fit(data_D)
#使用训练的模型进行姜维
X_train_pca = pca.transform(data_train)
X_test_pca = pca.transform(data_test)


lda = LinearDiscriminantAnalysis(n_components = 14).fit(X_train_pca,label_train)
X_train_ida = lda.transform(X_train_pca)
X_test_ida = lda.transform(X_test_pca)

print('OK')

# param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],
#               'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
# param_grid = {'C': [10, 20, 100, 500, 1e3],
#               'gamma': [0.001, 0.005, 0.01, 0.05, 0.1, 0.125], }
# clf = GridSearchCV(SVC(kernel='linear', class_weight='balanced'), param_grid)

clf = SVC(kernel = 'rbf',gamma=0.1,C=20)   
clf.fit(X_train_ida,label_train)            
# clf.fit(data_train,label_train)

#获得训练时的参数,即C,gamma,kernel,返回一个字典
k = clf.get_params()
print('clf.param: ', k)
pred = clf.predict(X_test_ida)
# print('pred.shape',label_test[0:10])

accuracy = metrics.accuracy_score(label_test, pred)*100
print('准确率为: ',accuracy)    # 95.60687234435618
# print(clf.best_estimator_)
print("done in %0.3fs" % (time() - t0))  # done in 13.843s
# 存储结果学习模型,方便之后的调用
joblib.dump(clf, "salinas_MODEL.m")

#调用刚刚保存的模型
#clf = joblib.load("salinas_MODEL.m")

可以看到,在调用SVM分类前,使用了PCA和LDA两种降维,将PCA结构作为输入传入LDA,最后将LDA结果进行分类

你可能感兴趣的:(python,机器学习,pca降维,svm,ldap)