{"id":959,"date":"2024-07-30T19:10:48","date_gmt":"2024-07-30T19:10:48","guid":{"rendered":"https:\/\/gatesboltonanalytics.com\/?page_id=959"},"modified":"2025-02-24T23:48:44","modified_gmt":"2025-02-24T23:48:44","slug":"simple-pca-using-python-sklearn","status":"publish","type":"page","link":"https:\/\/gatesboltonanalytics.com\/?page_id=959","title":{"rendered":"PCA Using Python\/Sklearn"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>####-----------------------------------------------------------\n#### PCA and Pairwise Correlation\n##   3D Scatterplot\n##   !! Dataset !!  (A sample of this data was used in this code)\n##   Link to Full Iris Dataset from Kaggle:\n##   https:\/\/www.kaggle.com\/datasets\/uciml\/iris?resource=download\n##\n## Gates, 2024\n####------------------------------------------------------------\n##\n## Imports\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.decomposition import PCA\nfrom IPython.display import clear_output\nfrom mpl_toolkits.mplot3d import Axes3D\nfrom sklearn.cluster import KMeans\nfrom sklearn import datasets\nfrom sklearn.preprocessing import StandardScaler\nimport seaborn as sns\n\n##This is a small sample of the Iris dataset (link above)\n## !!! This is MY path :)  YOU need to update this to be YOUR path !!!\n\npath=\"C:\/Users\/profa\/Desktop\/UCB\/Classes\/ML CSCI 5612\/Data\/Iris_Subset2.csv\"\nDF=pd.read_csv(path)\nprint(DF)\nOriginalDF=DF.copy()\nprint(OriginalDF)\n##--------------------------------\n## Remove and save the label\n## Next, update the label so that \n## rather than names like \"Iris-setosa\"\n## we use numbers instead. \n## This will be necessary when we \"color\"\n## the data in our plot\n##---------------------------------------\nDFLabel=DF&#91;\"Species\"]  ## Save the Label \nprint(DFLabel)  ## print the labels\nprint(type(DFLabel))  ## check the datatype you have\nDFLabel_string=DFLabel\n## Remap the label names from strongs to numbers\nMyDic={\"Iris-setosa\":0, \"Iris-versicolor\":1, \"Iris-virginica\":2}\nDFLabel = DFLabel.map(MyDic)  ## Update the label to your number remap values\nprint(DFLabel) ## Print the labels to confirm \n## Now, remove the label from the original dataframe\nDF=DF.drop(&#91;\"Species\"], axis=1)\nprint(DF) #Print the dataframe to confirm \n\n###-------------------------------------------\n### Standardize your dataset\n###-------------------------------------------\nscaler = StandardScaler() ##Instantiate\nDF=scaler.fit_transform(DF) ## Scale data\nprint(DF)\nprint(type(DF))\nprint(DF.shape)\n\n###############################################\n###--------------PERFORM PCA------------------\n###############################################\n## Instantiate PCA and choose how many components\nMyPCA=PCA(n_components=3)\n# Project the original data into the PCA space\nResult=MyPCA.fit_transform(DF)\n## Print the values of the first component \n#print(Result&#91;:,0]) \nprint(Result) ## Print the new (transformed) dataset\nprint(\"The eigenvalues:\", MyPCA.explained_variance_)\n## Proof\nMyCov=np.cov(Result.T)\nprint(\"Covar of the PC PCA Matrix: \\n\", MyCov) ## The variance here (on the diagonal) will match the eigenvalues\nprint(\"The relative eigenvalues are:\",MyPCA.explained_variance_ratio_)\nprint(\"The actual eigenvalues are:\", MyPCA.explained_variance_)\nEVects=MyPCA.components_\nprint(\"The eigenvectors are:\\n\",EVects)\nprint(type(EVects))\nprint(\"The shape of the eigenvector matrix is\\n\", EVects.shape)\nprint(DF.shape)\nprint(DF)\n## Proof to transform origial data to eigenbasis\n## using the eigenvectors matrix.\nprint(EVects.T)\n##  (15, 4) @ (4, 3)\nTransf=DF@EVects.T\nprint(\"Proof that the transformed data is the EVects @ Data\\n\",Transf)\n\n\n################################################\n# Extract loadings\n## Rerun PCA with all columns - no dim reduction\n############################################################\nMyPCA2=PCA(n_components=4)\n# Project the original data into the PCA space\nResult2=MyPCA2.fit_transform(DF)\nprint(MyPCA2.components_) \nprint(MyPCA2.components_.T) ## Makes the eigenvectors columnwise\nprint(MyPCA2.explained_variance_ratio_) \n\nprint(OriginalDF)\nprint(len(OriginalDF))\nprint(OriginalDF.columns&#91;0:4])\n\nfor i in range(1, len(OriginalDF&#91;0:4].columns)):\n               print(i)\n               \nloadings = pd.DataFrame(MyPCA2.components_.T, \n                        columns=&#91;f'PC{i}' for i in range(1, len(OriginalDF&#91;0:4].columns))], \n                        index=OriginalDF.columns&#91;0:4])\nprint(loadings)\n\n## Print the most important variables using a threshold\nthreshold = 0.4\n# Find features with loadings above the threshold for each principal component\nimportant_features = {}\nfor column in loadings.columns:\n    important_features&#91;column] = loadings.index&#91;loadings&#91;column].abs() > threshold].tolist()\n\n# Now 'important_features' dictionary contains the important features for each PC\nfor pc, features in important_features.items():\n    print(f\"{pc}: {', '.join(features)}\")\n\n# Plot heatmap of loadings\nplt.figure(figsize=(10, 8))\nsns.heatmap(loadings, annot=True, cmap='coolwarm')\nplt.title('Feature Importance in Principal Components')\nplt.show()\n#################################################\n## Visualize the transformed 3D dataset\n## we just created using PCA\n#################################################\n\nfig2 = plt.figure()\n    #figsize=(12, 12))\nax2 = fig2.add_subplot(projection='3d')\n#Axes3D(fig2, rect=&#91;0, 0, .90, 1], elev=48, azim=134)\n\nx=Result&#91;:,0]\ny=Result&#91;:,1] \nz=Result&#91;:,2]\nprint(y)\n\nax2.scatter(x,y,z, cmap=\"RdYlGn\", edgecolor='k', s=200, c=DFLabel)\n#surf2 = ax2.plot_surface(x, y, z, cmap='viridis')\nax2.set_xlabel('X')\nax2.set_ylabel('Y')\nax2.set_zlabel('Z')\nax2.set_title('3D PCA')\n#\nplt.show()\nplt.savefig(\"MyImage.jpeg\")\n\n############################################\n## Create Plot to Show Eigenvalues\n############################################\nfig3=plt.figure()\nACCUM_eigenvalues = np.cumsum(MyPCA.explained_variance_)\nprint(ACCUM_eigenvalues)\nprint(MyPCA.explained_variance_ratio_)\nplt.bar(range(0,len(MyPCA.explained_variance_ratio_)), MyPCA.explained_variance_ratio_, \n        alpha=0.5, align='center', label='Individual Explained Variances')\n#plt.step(range(0,len(ACCUM_eigenvalues)), ACCUM_eigenvalues, where='mid',label='Cumulative Explained Variances')\nplt.ylabel('Explained variance ratio')\nplt.xlabel('Principal component index')\nplt.title(\"Eigenvalues: Percentage of Variance\/Information\")\n#plt.legend(loc='best')\nplt.tight_layout()\nplt.show()\n\n###############################################\n## Create a DF of the most important features\n##################################################\nshape= MyPCA.components_.shape&#91;0]\n#print(shape)\nfeature_names=&#91;\"SepalWidthCm\", \"PetalLengthCm\", \"PetalWidthCm\", \"SepalLengthCm\"]\n\nmost_important = &#91;np.abs(MyPCA.components_&#91;i]).argmax() for i in range(shape)]\nmost_important_names = &#91;feature_names&#91;most_important&#91;i]] for i in range(shape)]\n\n# Build a doctionary of the imprtant features by PC\nMyDic = {'PC{}'.format(i): most_important_names&#91;i] for i in range(shape)}\n\n# build the dataframe\nImportant_DF = pd.DataFrame(MyDic.items())\nprint(Important_DF)\n\n###############################################\n## Create a biplot of the most important features\n##################################################\nPCA_dataset= Result ## recall that we ran PCA with 3 to get this above\nEVectors_as_columns=EVects.T\nprint(EVectors_as_columns)\n## PCA  dataset\nprint(PCA_dataset)\n\n\n\ndef biplot(PCA_dataset, EVectors_as_columns, labels=feature_names):\n    xs = PCA_dataset&#91;:, 0]\n    ys = PCA_dataset&#91;:, 1]\n    n = EVectors_as_columns.shape&#91;0]\n   \n    scalex = 1.0 \/ (xs.max() - xs.min())\n    scaley = 1.0 \/ (ys.max() - ys.min())\n    \n    plt.scatter(xs*scalex, ys*scaley, cmap=\"RdYlGn\", edgecolor='k', s=100, c=DFLabel)\n              \n    for i in range(n):\n        plt.arrow(0, 0, EVectors_as_columns&#91;i, 0], EVectors_as_columns&#91;i, 1], color='r', alpha=0.5)\n        if labels is None:\n            plt.text(EVectors_as_columns&#91;i, 0] * 1.07 , EVectors_as_columns&#91;i, 1] * 1.07, \n                     \"Var\" + str(i + 1), color='g', ha='center', va='center')\n        else:\n            plt.text(EVectors_as_columns&#91;i, 0] * 1.07, \n                     EVectors_as_columns&#91;i, 1] * 1.07, labels&#91;i], color='g', \n                     ha='center', va='center')\n\n# Plot biplot\nplt.figure(figsize=(10, 20))\n#figsize=(10, 16)\nbiplot(PCA_dataset, EVectors_as_columns, labels=feature_names)\nplt.xlabel('PC1')\nplt.ylabel('PC2')\nplt.title('Biplot of Principal Components')\nplt.show()<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"class_list":["post-959","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=\/wp\/v2\/pages\/959","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=959"}],"version-history":[{"count":5,"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=\/wp\/v2\/pages\/959\/revisions"}],"predecessor-version":[{"id":1102,"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=\/wp\/v2\/pages\/959\/revisions\/1102"}],"wp:attachment":[{"href":"https:\/\/gatesboltonanalytics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=959"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}