機器學習十講第六講

降維

數學知識

  • 特徵向量: 設A是n階方陣,如果有常數λ和n維非零列向量α的關係式Aα=λα成立,則稱λ爲方陣A的特徵值,非零向量α稱爲方陣A的對應於特徵值λ的特徵向量
  • 特徵值分解
1624607209155

降維

1624607321840

主成分分析

1624627077737

模型求解

1624627188634

  • 方差最大化

1624627287511

  • 算法流程

1624627434346

自編碼器

1624627389973

深層自編碼器

1624627565554

python實現PCA算法

import numpy as np
#PCA算法
def principal_component_analysis(X, l):
    X = X - np.mean(X, axis=0)#對原始數據進行中心化處理
    sigma = X.T.dot(X)/(len(X)-1) # 計算協方差矩陣
    a,w = np.linalg.eig(sigma) # 計算協方差矩陣的特徵值和特徵向量
    sorted_indx = np.argsort(-a) # 將特徵向量按照特徵值進行排序
    X_new = X.dot(w[:,sorted_indx[0:l]])#對數據進行降維****Y=XW
    return X_new,w[:,sorted_indx[0:l]],a[sorted_indx[0:l]] #返回降維後的數據、主成分、對應特徵值

from sklearn import datasets
import matplotlib.pyplot as plt
%matplotlib inline
#使用make_regression生成用於線性迴歸的數據集
x, y = datasets.make_regression(n_samples=200,n_features=1,noise=10,bias=20,random_state=111)
##將自變量和標籤進行合併,組成一份二維數據集。同時對兩個維度均進行歸一化。
x = (x - x.mean())/(x.max()-x.min())
y = (y - y.mean())/(y.max()-y.min())
###可視化展示
fig, ax = plt.subplots(figsize=(6, 6)) #設置圖片大小
ax.scatter(x,y,color="#E4007F",s=50,alpha=0.4)
plt.xlabel("$x_1$")
plt.ylabel("$x_2$")
1624627692149
#調用剛纔寫好的PCA算法對數據進行降維
import pandas as pd
X = pd.DataFrame(x,columns=["x1"])
X["x2"] = y
X_new,w,a = principal_component_analysis(X,1)
#直線的斜率爲w[1,0]/w[0,0]。將主成分方向在散點圖中繪製出來
import numpy as np
x1 = np.linspace(-.5, .5, 50)
x2 = (w[1,0]/w[0,0])*x1 
fig, ax = plt.subplots(figsize=(6, 6)) #設置圖片大小
X = pd.DataFrame(x,columns=["x1"])
X["x2"] = y
ax.scatter(X["x1"],X["x2"],color="#E4007F",s=50,alpha=0.4)
ax.plot(x1,x2,c="gray") # 畫出第一主成分直線
plt.xlabel("$x_1$")
plt.ylabel("$x_2$")


#使用散點圖繪製降維後的數據集
import numpy as np
fig, ax = plt.subplots(figsize=(6, 2)) #設置圖片大小
ax.scatter(X_new,np.zeros_like(X_new),color="#E4007F",s=50,alpha=0.4)
plt.xlabel("First principal component")


#導入olivettifaces人臉數據集
from sklearn.datasets import fetch_olivetti_faces
faces = fetch_olivetti_faces()
faces.data.shape

#隨機排列
rndperm = np.random.permutation(len(faces.data))
plt.gray()
fig = plt.figure(figsize=(9,4) )
#取18個
for i in range(0,18):
    ax = fig.add_subplot(3,6,i+1 )
    ax.matshow(faces.data[rndperm[i],:].reshape((64,64)))
    plt.box(False) #去掉邊框
    plt.axis("off")#不顯示座標軸
plt.show()

1624627811681

#將人臉數據從之前的4096維降低到20維
%time faces_reduced,W,lambdas = principal_component_analysis(faces.data,20)

#將降維後得到的20個特徵向量表示出來
fig = plt.figure( figsize=(18,4))
plt.gray()
for i in range(0,20):
    ax = fig.add_subplot(2,10,i+1 )
    #將降維後的W每一列都提出,從4096長度向量變成64×64的圖像
    ax.matshow(W[:,i].reshape((64,64)))
    plt.title("Face(" + str(i) + ")")
    plt.box(False) #去掉邊框
    plt.axis("off")#不顯示座標軸
plt.show()

1624627860656

使用PCA對新聞進行降維和可視化

#引入數據,因爲是中文所以要設置encoding參數爲utf8,sep參數爲\t
import pandas as pd
news = pd.read_csv("./input/chinese_news_cutted_train_utf8.csv",sep="\t",encoding="utf8")
#加載停用詞
stop_words = []
file = open("./input/stopwords.txt") 
for line in file:
    stop_words.append(line.strip())
file.close()

from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(stop_words=stop_words,min_df=0.01,max_df=0.5,max_features=500)
news_vectors = vectorizer.fit_transform(news["分詞文章"])
news_df = pd.DataFrame(news_vectors.todense())
#使用PCA將數據降維至二維
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
news_pca = pca.fit_transform(news_df)
#可視化
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(10,10))
sns.scatterplot(news_pca[:,0], news_pca[:,1],hue = news["分類"].values,alpha=0.5)
1624628130377
#採用t-SNE降維方法
from sklearn.manifold import TSNE
#先降到20維
pca10 = PCA(n_components=20)
news_pca10 = pca10.fit_transform(news_df)
#再降到2維
tsne_news = TSNE(n_components=2, verbose=1)
#輸出運行時間
%time tsne_news_results = tsne_news.fit_transform(news_pca10)
#可視化
plt.figure(figsize=(10,10))
sns.scatterplot(tsne_news_results[:,0], tsne_news_results[:,1],hue = news["分類"].values,alpha=0.5)
1624628207512

由上面結果得出,t-SNE降維方法效果更好些

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章