2024 مرسيدس بنز A-Class 200 AMG - سيدان فاخرة ذات مسافة قليلة!# -*- coding: utf-8 -*- [ Code 5-12 : K-Means Clustering + Scree Plot ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# ~ K-Means Clustering ~ (5) Scree Plot ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# Scree Plot (Elbow plot) - for finding the optimial number of clusters (k) in k-means clustering. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# 5.12 K-Means Clustering + Scree Plot (Elbow plot) from sklearn.cluster import KMeansimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdfrom sklearn.decomposition import PCA# read data from final_data.csv file into a DataFrame df = pd.read_csv('./datasets/final_data.csv')# convert the DataFrame to a numpy array data = df.values# standardize the data sc = StandardScaler()data = sc.fit_transform(data)# perform PCA to reduce the data dimensionality for visualization pca = PCA(n_components=2)data_pca = pca.fit_transform(data)# initialize lists to store the number of clusters and within-cluster sum of squares (WCSS) clusters_range = range(1, 11)wcss = []# perform k-means clustering for k in clusters_range and store the WCSS values for k in clusters_range: kmeans = KMeans(n_clusters=k, init='k-means++', random_state=0) kmeans.fit(data) wcss.append(kmeans.inertia_)# plot the Elbow plot (Scree plot) plt.figure(figsize=(8, 6))plt.plot(clusters_range, wcss, marker='o', linestyle='-', color='b')plt.title('Elbow plot (Scree plot) for K-Means Clustering', fontsize=14)plt.xlabel('Number of clusters (k)', fontsize=12)plt.ylabel('Within-Cluster Sum of Squares (WCSS)', fontsize=12)plt.xticks(clusters_range)plt.grid(True)plt.show()# perform k-means clustering with the optimal k value (here, k=3 based on the Elbow plot) kmeans = KMeans(n_clusters=3, init='k-means++', random_state=0)# fit the model to the data and predict the cluster labels kmeans.fit(data)labels = kmeans.predict(data)# visualize the clusters in 2D using PCA plt.figure(figsize=(8, 6))for i in range(3): plt.scatter(data_pca[labels == i, 0], data_pca[labels == i, 1], s=50, label=f'Cluster {i+1}')# plot the centroids in the reduced 2D space centroids = kmeans.cluster_centers_centroids_pca = pca.transform(centroids)plt.scatter(centroids_pca[:, 0], centroids_pca[:, 1], s=200, c='black', marker='X', label='Centroids')plt.title('K-Means Clustering of Final Data (3 clusters)', fontsize=14)plt.xlabel('Principal Component 1', fontsize=12)plt.ylabel('Principal Component 2', fontsize=12)plt.grid(True)plt.legend()plt.show()from selenium import webdriver as wd # 웹 브라우저 원격 조작에 사용하는 라이브러리입니다. # webdriver를 wd란 별칭으로 사용하겠다는 뜻입니다. # webdriver는 원격으로 브라우저를 조작할 때 사용하는 라이브러리입니다. # 별칭(alias)은 라이브러리 이름이 길 때 짧게 써서 편리하게 하려고 사용하는 것입니다. # 원래대로 한다면 webdriver.Chrome()이라고 써야 하는데, wd.Chrome()이라고 쓸 수 있습니다. # 이는 가독성을 높이고 타이핑을 줄이기 위함입니다. # 별칭은 개발자 마음대로 정할 수 있습니다. # 예를 들어, webdriver를 browser란 별칭으로 정하고 싶으면, # from selenium import webdriver as browser 라고 쓸 수 있습니다. # 그리고 이후 코드에서는 browser.Chrome() 이라고 사용하면 됩니다. # 하지만 일반적으로 webdriver는 wd나 driver라고 많이 사용합니다. # 이는 관례적인 것이니 따라주는 것이 좋습니다. # 관례는 개발자들 사이에 불문율처럼 지켜지는 규칙입니다. # 관례를 지키면 다른 개발자들이 코드를 보았을 때 이해하기 쉽습니다. # 예를 들어, 반복문에서 인덱스 변수로 i, j, k를 사용하는 것이 관례입니다. # 만약 다른 변수명을 사용하면 코드를 읽는 사람이 헷갈릴 수 있습니다. # 따라서 웬만하면 관례를 따라주는 것이 좋습니다. # 또한, 별칭은 너무 짧게 하면 오히려 가독성을 해칠 수 있습니다. # 예를 들어, webdriver를 w라고만 한다면, w.Chrome()이 webdriver.Chrome()인지 알기 어렵습니다. # 따라서 적당한 길이의 별칭을 사용하는 것이 중요합니다. # selenium 라이브러리는 주로 웹 자동화 테스트에 사용되지만, 웹 크롤링에도 사용됩니다. # selenium을 사용하면 JavaScript로 동적으로 생성되는 컨텐츠도 크롤링할 수 있습니다. # requests와 bs4만으로는 JavaScript로 렌더링되는 컨텐츠를 크롤링할 수 없습니다. # requests는 단순히 HTTP 요청을 보내고 응답을 받는 것만 가능합니다. # 즉, 서버에서 주는 HTML만 받을 수 있습니다. # 하지만 현대 웹 사이트들은 JavaScript를 이용해 브라우저에서 추가적으로 HTML을 생성하는 경우가 많습니다. # 이런 경우 requests로는 원하는 데이터를 가져올 수 없습니다. # selenium은 실제 브라우저를 동작시키기 때문에 JavaScript 실행 결과까지 모두 가져올 수 있습니다. # 따라서 JavaScript로 동적 생성되는 컨텐츠가 있는 웹 사이트는 selenium을 사용해야 합니다. # 물론 selenium은 브라우저를 띄우기 때문에 requests보다 느리고 리소스를 많이 사용합니다. # 따라서 정적 컨텐츠만 있는 사이트라면 requests를 사용하는 것이 좋습니다. # selenium을 사용할 때는 chromedriver라는 것이 필요합니다. # chromedriver는 Chrome 브라우저를 원격 조작할 수 있게 해주는 별도의 프로그램입니다. # selenium은 이 chromedriver를 통해 Chrome 브라우저를 조작합니다. # chromedriver는 Chrome 브라우저 버전과 호환되는 버전을 사용해야 합니다. # Chrome 브라우저 버전과 chromedriver 버전이 맞지 않으면 오류가 발생합니다. # 따라서 chromedriver는 자신의 Chrome 브라우저 버전에 맞는 것을 다운로드 받아야 합니다. # Chrome 브라우저 버전은 Chrome 메뉴 > 도움말 > Chrome 정보 에서 확인할 수 있습니다. # chromedriver는 https://chromedriver.chromium.org/downloads 에서 다운로드 받을 수 있습니다. # 다운로드 받은 chromedriver.exe 파일은 파이썬 스크립트가 있는 폴더에 넣거나, # 시스템 PATH에 등록해줘야 합니다. # 또는 코드에서 chromedriver.exe 파일의 경로를 직접 지정해줄 수도 있습니다. # 예를 들어, webdriver.Chrome('C:/chromedriver.exe') 이런 식으로요. # PATH는 운영체제가 실행 파일을 찾는 경로를 말합니다. # PATH에 등록되어 있으면 실행 파일 이름만으로도 실행할 수 있습니다. # selenium 4.0 이상 버전에서는 WebDriver Manager를 사용하면 편리합니다. # WebDriver Manager는 chromedriver를 자동으로 다운로드하고 관리해주는 도구입니다. # 사용법은 간단합니다. # 먼저, pip install webdriver-manager 로 설치한 후, # 아래 코드처럼 사용하면 됩니다. # from selenium.webdriver.chrome.service import Service # from webdriver_manager.chrome import ChromeDriverManager # driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) # 이렇게 하면 chromedriver를 직접 다운로드 받을 필요 없이 자동으로 처리됩니다. # 또한 Chrome 브라우저 버전에 맞는 chromedriver를 자동으로 설치해줍니다. # 이 예제에서는 간단함을 위해 chromedriver.exe를 스크립트 폴더에 넣었다고 가정합니다. # 따라서 webdriver.Chrome()만으로도 chromedriver를 사용할 수 있습니다. # 만약 chromedriver.exe가 다른 폴더에 있다면, # webdriver.Chrome('C:/path/to/chromedriver.exe') 이런 식으로 경로를 지정해줘야 합니다. # selenium을 이용한 웹 크롤링 기본 흐름은 다음과 같습니다. # 1. 웹 드라이버 생성 (이 코드에서는 Chrome 사용) # 2. 원하는 웹 페이지 접속 # 3. 페이지의 HTML 요소 찾기 (find_element, find_elements 메서드 사용) # 4. 요소에서 필요한 데이터 추출 # 5. 적절히 가공 및 저장 # 6. 웹 드라이버 종료 # selenium에서 요소를 찾는 주요 메서드는 다음과 같습니다. # - find_element(By.ID, 'id') : ID로 요소 찾기 # - find_element(By.NAME, 'name') : name 속성으로 요소 찾기 # - find_element(By.CSS_SELECTOR, 'css selector') : CSS 선택자로 요소 찾기 # - find_element(By.XPATH, 'xpath') : XPATH로 요소 찾기 # - find_element(By.CLASS_NAME, 'class') : class 이름으로 요소 찾기 # - find_element(By.TAG_NAME, 'tag') : 태그 이름으로 요소 찾기 # - find_element(By.LINK_TEXT, 'link text') : 링크 텍스트로 요소 찾기 # - find_element(By.PARTIAL_LINK_TEXT, 'partial link text') : 링크 텍스트 일부로 요소 찾기 # find_element는 첫 번째로 일치하는 요소 하나를 반환하고, # find_elements는 일치하는 모든 요소를 리스트로 반환합니다. # 요소를 찾을 때 가장 많이 사용하는 것은 CSS_SELECTOR와 XPATH입니다. # CSS_SELECTOR는 CSS 선택자 문법을 사용합니다. # 예를 들어, 'div.content > p.description' 이런 식으로 사용합니다. # XPATH는 XML 경로 언어를 사용합니다. # 예를 들어, '//div[@class=