Сравнете изпълнението с PCA на Scikit-Learn

Тази статия е продължение на историята „Намаляване на променливи с анализ на главните компоненти“. В предишната публикация говорих за един от най-известните и широко използвани методи, наречен Анализ на главните компоненти. Той използва ефективна линейна трансформация, която намалява размерността на набор от данни с големи размери, като същевременно улавя максималното информационно съдържание. Той генерира основните компоненти, които са линейни комбинации от оригиналните характеристики в набора от данни. Освен това показах стъпка по стъпка как да приложа тази техника с Python. Първо си помислих, че публикацията е достатъчна, за да обясни PCA, но почувствах, че нещо липсва. Приложих PCA, използвайки отделни редове код, но те са неефективни, когато искате да ги извиквате всеки път за различен проблем. По-добър начин е да създадете клас, който е ефективен, когато искате да капсулирате структури от данни и процедури на едно място. Освен това е наистина по-лесно да се модифицира, тъй като имате целия код в този уникален клас.

Съдържание:

  1. Набор от данни
  2. „Прилагане на PCA“
  3. PCA без стандартизация
  4. PCA със стандартизация
  5. „PCA със Sklearn“

1. Набор от данни

Преди да внедрим алгоритъма PCA, ние ще импортираме набора от данни за рак на гърдата в Уисконсин, който съдържа данните относно
рака на гърдата, диагностициран при 569 пациенти [1].

import pandas as pd
import numpy as np
import random
from sklearn.datasets import load_breast_cancer
import plotly.express as px
data = load_breast_cancer(as_frame=True)
X,y,df_bre = data.data,data.target,data.frame
diz_target = {0:'malignant',1:'benign'}
y = np.array([diz_target[y1] for y1 in y])
df_bre['target'] = df_bre['target'].apply(lambda x: diz_target[x])
df_bre.head()

Можем да забележим, че има 30 числови характеристики и целева променлива, които определят дали туморът е доброкачествен (цел = 1) или злокачествен (цел = 0). Преобразувам целевата променлива в низ, тъй като тя не се използва от PCA и се нуждаем от нея само във визуализациите по-късно.

В този случай искаме да разберем разликата в променливостта на характеристиките, когато туморът е доброкачествен или злокачествен. Това наистина е трудно да се покаже с прост проучвателен анализ, тъй като имаме повече от две ковариати. Например, можем да се опитаме да визуализираме матрица на разсейване само с шест характеристики, оцветени от целевата променлива.

fig = px.scatter_matrix(df_bre,dimensions=list(df_bre.columns)[:5], color="target")
fig.show()

Разбира се, можем да наблюдаваме два различни клъстера във всички тези диаграми на разпръскване, но е объркано, ако начертаем всички характеристики едновременно. Следователно, ние се нуждаем от компактно представяне на този многовариантен набор от данни, който може да бъде предоставен от анализа на главните компоненти.

2. Изпълнение на PCA

Стъпките за получаване на основните компоненти (или k-мерни вектори на характеристики) са обобщени в илюстрацията по-горе. Същата логика ще бъде приложена за изграждане на класа.

Ние дефинираме класа PCA_impl, който има три атрибута, инициализирани в началото. Най-важният атрибут е броят на компонентите, които искаме да извлечем. Освен това можем да възпроизвеждаме едни и същи резултати всеки път, като зададем random_state равно на True и стандартизираме набора от данни само ако имаме нужда от него.

Този клас също включва два метода, fit и fit_transform, подобно на PCA на scikit-learn. Докато първият метод предоставя по-голямата част от процедурата за изчисляване на основните компоненти, методът fit_transform също прилага трансформацията върху оригиналната матрица на характеристиките X. В допълнение към тези два метода, исках също да визуализирам главните компоненти, без да уточнявам всеки път, когато функциите на Plotly Express. Може да бъде наистина полезно да се ускори анализът на латентните променливи, генерирани от PCA.

3. PCA без стандартизация

Накрая класът PCA_impl е дефиниран. Трябва само да извикаме класа и съответните методи без никакви усилия.

Имаме достъп до атрибутите var_explained и cum_var_explained, които са изчислени в рамките на методите fit и fit_transform. Струва си да се отбележи, че улавяме 98% само с един компонент. Нека също визуализираме 2D и 3D диаграмите на разсейване, като използваме дефинирания по-горе метод:

pca1.pca_plot2d()

От визуализацията можем да наблюдаваме, че се появяват два клъстера, единият маркиран в синьо, представляващ пациентите със злокачествен рак, а другият - доброкачествен рак. Освен това изглежда, че синият клъстер съдържа много повече променливост от другия клъстер. Освен това виждаме леко припокриване между двете групи.

pca1.pca_plot3d()

Сега разглеждаме 3D диаграмата на разсейване с първите три компонента. Това е по-малко ясно от предишната диаграма на разсейване, но подобно поведение се появява дори в тази диаграма. Със сигурност има две отделни групи въз основа на целевата променлива. Открива се нова информация, разглеждайки това триизмерно представяне: двама пациенти със злокачествен рак изглежда имат напълно различни стойности по отношение на всички останали пациенти. Този аспект може да бъде леко забелязан, като се погледне 2D диаграмата или в матрицата на разсейване, която показахме преди.

4. PCA със стандартизация

Нека повторим същата процедура от предишния раздел. Добавяме стандартизацията само в началото, за да проверим дали има разлики в резултатите.

За разлика от предишния случай, можем да забележим, че диапазонът от стойности по отношение на главните компоненти е по-ограничен и 80% от обяснената дисперсия се улавя с три компонента. По-специално, приносът на първия компонент премина от 0,99 на 0,44. Това може да се оправдае с факта, че всички променливи имат едни и същи мерни единици и следователно PCA е в състояние да придаде еднаква тежест на всяка характеристика.

pca1.pca_plot2d()

Тези наблюдения се потвърждават от разглеждането на диаграмата на разсейване с първите два компонента. Клъстерите са много по-различни и имат по-ниски стойности.

pca1.pca_plot3d()

3D представянето е по-лесно за четене и разбиране. И накрая, можем да заключим, че двете групи пациенти имат различна вариабилност на характеристиките. Освен това все още има две точки от данни, които се намират отделно от останалите данни.

5. PCA със Sklearn

На този етап можем да приложим PCA, внедрен от Sklearn, за да го сравним с моята реализация. Трябва да отбележа, че има някои разлики, които трябва да се вземат предвид при това сравнение. Докато моето внедряване на PCA се основава на ковариационната матрица, PCA на scikit-learn включва центриране на входните данни и използва Разлагане на сингулярна стойност, за да проектира данните в пространство с по-ниско измерение.

Преди видяхме, че стандартизацията е много важна стъпка преди прилагането на PCA. Тъй като средната стойност вече е извадена от колоната на всяка характеристика чрез алгоритъма на Sklearn, трябва само да разделим всяка числена променлива на нейното собствено стандартно отклонение.

X_copy = X.copy().astype('float32')
X_copy /= np.std(X_copy, axis=0)

Сега предаваме броя на компонентите и random_state на класа PCA и извикваме метода fit_transform, за да получим основните компоненти.

Същите резултати от внедрения PCA със стандартизация се постигат с PCA на sklearn.

fig = px.scatter(components, x=0, y=1, color=df.label,labels={'0': 'PC 1', '1': 'PC 2'})
fig.show()

fig = px.scatter_3d(components, x=0, y=1,z=2, color=df.label,labels={'0': 'PC 1', '1': 'PC 2','2':'PC 3'})
fig.show()

По същия начин диаграмите на разсейване повтарят това, което видяхме в предишния раздел.

Последни мисли:

Надявам се, че сте намерили тази публикация за полезна. Намерението на тази статия беше да предостави по-компактна реализация на анализа на основните компоненти. В този случай моето внедряване и PCA на Sklearn предоставиха едни и същи резултати, но може да се случи понякога те да са малко по-различни, ако използвате различен набор от данни. Кодът на GitHub е тук. Благодаря за четенето. Приятен ден!

Референции:

[1] Набор от данни за рак на гърдата Уисконсин (диагностика)

Хареса ли ви статията ми? Станете член и получете неограничен достъп до нови научни публикации за данни всеки ден! Това е косвен начин да ме подкрепите без никакви допълнителни разходи за вас. Ако вече сте член, абонирайте се, за да получавате имейли, когато публикувам нови ръководства за наука за данни и Python!