Convert Plotly Jupyterlab to HTML

개요

  • jupyter notebook에서 plotly 기반의 시각화를 작성한다.
  • jupyter notebook에서 html로 변환 시, plotly로 작성된 코드는 나타나지 않았다.
  • 이 때 필수적으로 입력해야 할 코드를 작성한다.

필수 코드 적용 전 변환 시

  • 간단한 시각화 코드를 작성 후, html로 변환한다.
import plotly.express as px

fig = px.line(x=["a","b","c"], y=[1,3,2], title="sample figure")
fig.show()
  • 아래 그림은 일반적으로 JupyterLab 에디터에서 HTML로 변환하는 과정이다.
    • File - Save and Export Notebook As… - HTML 순차적으로 클릭한다.

Screen Shot 2022-04-11 at 10.56.22 PM.png

ElasticSearch & Kibana 설치 in WSL2

Step 1. 사전 필수 패키지 설치

  1. 우선 시스템 패키지를 업데이트 하고, HTTPS와 관련된 패키지를 설치한다.
$ sudo apt update
$ sudo apt install apt-transport-https
  1. 자바를 설치한다.
  • 이미 설치가 되어 있다면 버전만 확인한다.
$ sudo apt install openjdk-11-jdk
  • 설치한 버전을 확인한다.
$ java -version
openjdk version "11.0.14.1" 2022-02-08
OpenJDK Runtime Environment (build 11.0.14.1+1-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.14.1+1-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)
  1. 자바 환경 변수를 설정하기 위해 아래와 같이 에디터를 입력한다.
$ sudo vi /etc/environment
  • 그리고 아래와 같이 추가한다.
JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64"
  • 환경변수를 업데이트 한다.
$ source /etc/environment
  • 실제 경로가 나오는지 확인한다.
$ echo $JAVA_HOME
/usr/lib/jvm/java-11-openjdk-amd64

Step 2. ElasticSearch 설치

  • GPG Keys를 확인하여 설치를 진행한다.
$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
OK
  • 라이브러리를 아래와 같이 추가한다.
$ sudo sh -c 'echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" > /etc/apt/sources.list.d/elastic-7.x.list'
  • 이제 elasticsearch를 설치한다.
$ sudo apt-get update
Hit:1 https://artifacts.elastic.co/packages/7.x/apt stable InRelease
Hit:2 http://security.ubuntu.com/ubuntu focal-security InRelease
Hit:3 http://archive.ubuntu.com/ubuntu focal InRelease
Hit:4 http://archive.ubuntu.com/ubuntu focal-updates InRelease
Hit:5 http://archive.ubuntu.com/ubuntu focal-backports InRelease
Reading package lists... Done
$ sudo apt-get install elasticsearch
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  elasticsearch
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 312 MB of archives.
After this operation, 517 MB of additional disk space will be used.
Get:1 https://artifacts.elastic.co/packages/7.x/apt stable/main amd64 elasticsearch amd64 7.17.2 [312 MB]
Fetched 312 MB in 8s (40.9 MB/s)
Selecting previously unselected package elasticsearch.
(Reading database ... 32942 files and directories currently installed.)
Preparing to unpack .../elasticsearch_7.17.2_amd64.deb ...
Creating elasticsearch group... OK
Creating elasticsearch user... OK
Unpacking elasticsearch (7.17.2) ...
Setting up elasticsearch (7.17.2) ...
### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using systemd
 sudo systemctl daemon-reload
 sudo systemctl enable elasticsearch.service
### You can start elasticsearch service by executing
 sudo systemctl start elasticsearch.service
warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME
Created elasticsearch keystore in /etc/elasticsearch/elasticsearch.keystore
Processing triggers for systemd (245.4-4ubuntu3.15) ...

Step 3. Elasticsearch 서비스 시작

  • 이번에는 elasticsearch 서비스를 시작한다.
$ sudo systemctl start elasticsearch
System has not been booted with systemd as init system (PID 1). 
Can't operate. Failed to connect to bus: Host is down
  • 다음 명령어를 추가한다.
$ sudo -b unshare --pid --fork --mount-proc /lib/systemd/systemd --system-unit=basic.target
$ sudo -E nsenter --all -t $(pgrep -xo systemd) runuser -P -l $USER -c "exec $SHELL"
  • 서비스가 가능하도록 한다.
$ sudo systemctl enable elasticsearch
Synchronizing state of elasticsearch.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable elasticsearch
Created symlink /etc/systemd/system/multi-user.target.wants/elasticsearch.service → /lib/systemd/system/elasticsearch.service.
  • 서비스를 시작한다.
$ sudo systemctl start elasticsearch
  • 실제 서비스가 작동하는지 확인한다.
$ curl -X GET "localhost:9200/"
{
  "name" : "evan",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "vATWEOO1T9yOFGLc7G3L4w",
  "version" : {
    "number" : "7.17.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "de7261de50d90919ae53b0eff9413fd7e5307301",
    "build_date" : "2022-03-28T15:12:21.446567561Z",
    "build_snapshot" : false,
    "lucene_version" : "8.11.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
  • 만약 위와 같은 메시지가 뜨면, 윈도우 화면에서 재 확인해본다.

Untitled

PostgreSQL Installation on WSL2 and Windows

개요

  • WSL2에서 PostgreSQL을 설치한다.
  • pgAdmin은 Windows에 설치한다.

터미널 업그레이드

  • 먼저 WSL 터미널을 열고, Ubuntu 패키지를 모두 업데이트 및 업그레이드를 한다.
$ sudo apt update
[sudo] password for evan:
Hit:1 https://artifacts.elastic.co/packages/7.x/apt stable InRelease
Get:2 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Hit:3 http://archive.ubuntu.com/ubuntu focal InRelease
Get:4 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
Get:5 http://archive.ubuntu.com/ubuntu focal-backports InRelease [108 kB]
Get:6 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages [1712 kB]
Get:7 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages [916 kB]
Fetched 2963 kB in 5s (600 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
  • 이번에는 업그레이드를 해본다.
$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

PostgreSQL Installation in WSL2

  • 이번에는 WSL2에서 PostgreSQL을 설치한다. 설치가 종료되면, 반드시 버전을 확인한다.
$ sudo apt install postgresql postgresql-contrib
$ psql --version
psql (PostgreSQL) 12.9 (Ubuntu 12.9-0ubuntu0.20.04.1)
  • 설치 이후에는 Database를 접근가능하도록 활성화해야 한다.
    • 포트가 활성화 되어 있지 않다면 아래와 같은 메시지가 나타날 것이다.
$ sudo service postgresql status
12/main (port 5432): down
  • 이번에는 활성화를 해보도록 한다. 온라인이라는 메시지가 나타난다면 활성화가 되었다는 것을 의미한다.
$ sudo service postgresql start
 * Starting PostgreSQL 12 database server
$ sudo service postgresql status
12/main (port 5432): online
  • 이번에는 활성화된 데이터베이스를 종료시킨다.
$ sudo service postgresql stop
 * Stopping PostgreSQL 12 database server                                                                        [ OK ]
$ sudo service postgresql status
12/main (port 5432): down

사용자 계정 Password 설정

  • 기본적으로 admin 사용자로 등록이 되어 있다. 보통 DB 초기 세팅 시에는 패스워드를 입력받아야 한다. (예: evan)
$ sudo passwd postgres
New password:
Retype new password:
passwd: password updated successfully
  • 여기까지 했다면, WSL2에서 추가로 설정할 것은 더 없다.

pgAdmin Installation on Windows

Untitled

VSCode Remote WLS 연동

VSCode 설치

Untitled

  • 설치 시, 환경변수 체크란만 잘 확인한다.

Untitled

  • 설치가 다 끝난 후에는 재부팅을 실시한다.

Remote WSL 연동

  • Extension 버튼을 클릭한다.

Untitled

  • 검색창에서 Remote WSL을 검색 후, 설치를 진행한다.

Untitled

  • 모두 클릭 후, Mark Done을 선택한다.

Untitled

  • Open Folder를 클릭한다.

Untitled

  • WSL에서 설치했던 airflow-test 폴더를 선택한다.

Untitled

  • 해당 프로젝트를 열도록 한다.

Untitled

  • 메뉴바에 Terminal을 선택 후, 화면 하단에서 WSL이 있는지 확인한다.

Untitled

Setting up Apache-NiFi in Windows 10

개요

  • 윈도우에서 NiFi를 설치해본다.
  • NiFi를 설치하기 위해서는 자바 설치가 필요하다.

Step 01. NiFi 다운로드

/img/programming/2022/04/apache_nifi_installation_windows/apache_nifi_installation_windows

Untitled

Step 02. Java 환경 설정

Step 03. run-nifi 배치 파일 실행

  • run-nifi 배치파일을 관리자 권한으로 실행한다.

Untitled

  • 아래와 같은 메시지가 출력이 되면 성공한 것이다.

Untitled

Step 04. Web UI 확인

Untitled

Setting up Apache-Airflow in Windows using WSL2

개요

  • Windows WSL2에서 airflow를 설치한다.

Step 1. Install pip on WSL

  • airflow를 설치하기 위해 pip를 설치한다.
$ sudo apt install python3-pip
[sudo] password for username:

Step 2. Install virtualenv package

  • virtualenv 라이브러리를 설치한다.
$ sudo pip3 install virtualenv

Step 3. Create a virtual environment

  • C드라이브에 airflow-test 폴더를 생성한다.
    • 해당 디렉터리로 이동한다.
  • 이제 가상환경을 생성한다.
$ virtualenv venv
  • 가상환경에 접속을 한다.
$ source venv/bin/activate
  • 이번에는 .bashrc 파일을 수정한다.
$ vi ~/.bashrc
  • 파일을 연 후, 다음과 같은 코드를 추가한다.
export AIRFLOW_HOME=/mnt/c/airflow-test
  • 파일을 닫을 때는 ESC → :wq 순서대로 작성한다.
  • 수정된 코드를 업데이트 하기 위해서는 아래와 같이 반영한다.
$ source ~/.bashrc
  • 실제로 코드가 반영되었는지 확인하기 위해서는 다음과 같이 확인해본다.
echo $AIRFLOW_HOME
/mnt/c/airflow-test

Step 4. Apache Airflow 설치

  • PostgreSQL, Slack, Celery 패키지를 동시에 설치하는 코드를 작성한다.
$ pip3 install 'apache-airflow[postgres, slack, celery]'
  • 에어플로 실행 위해 DB 초기화를 해줘야 한다.
$ airflow db init
  • 실제로 잘 구현이 되었는지 확인하기 위해 webserver를 실행한다.
$ airflow webserver -p 8081
  • 다음으로 일정 주기로 데이터 흐름이 실행되게 하려면 Scheduler가 필요하다.
$ airflow scheduler

Untitled

Windows 10 도커 설치 과정 (2022 ver)

개요

Step 1. WSL2 설치 과정

  • Windows PowerShell 관리자로 실행 후 다음 명령어 입력
$ dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
$ dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
$ wsl --set-default-version 2
WSL 2와의 주요 차이점에 대한 자세한 내용은 https://aka.ms/wsl2를 참조하세요

Step 2l Docker Desktop 설치

  1. 다음 페이지로 이동해서 Docker Desktop for Windows를 다운로드 받습니다.

Untitled

Scikit-Learn OneHot Encoding 다양한 적용 방법

강의 홍보

개요

  • One-Hot Encoding 개념에 대해 이해한다.
  • One-Hot Encoder 사용법을 익힌다.

One-Hot Encoding

  • One-Hot Encoding은 문자를 숫자로 변환하는 것이다.
  • 먼저 그림을 보면서 이해하도록 한다.

  • 머신러닝 알고리즘은 데이터가 모두 숫자인 것으로 이해하기 때문에 모두 변환해주어야 한다.

OnetHotEncoder

  • OneHotEncoder는 Scikit-Learn 라이브러리에 있는 클래스이다.
    • 자세한 내용은 링크를 참조한다.
  • 먼저 예시를 참조한다.
import sklearn
print("sklearn ver.", sklearn.__version__)
sklearn ver. 1.0.2
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
X = [['Male', 1], ['Female', 3], ['Female', 2]]
enc.fit_transform(X).toarray()
array([[0., 1., 1., 0., 0.],
       [1., 0., 0., 0., 1.],
       [1., 0., 0., 1., 0.]])
  • 예시 코드를 보면 위 그림과 결괏값이 다르게 나오는 걸 확인할 수 있다.
  • 보통 우리가 다루는 데이터는 pandas 데이터프레임이기 때문에, 입문자분들에게는 거리감이 느껴질 수 있다.
  • 그래서 pandas 데이터프레임 데이터를 가져와서 테스트를 해보았다.
from sklearn.preprocessing import OneHotEncoder
from seaborn import load_dataset

penguins = load_dataset('penguins')
ohe = OneHotEncoder()
transformed = ohe.fit_transform(penguins[['island']])
print(transformed.toarray())
print(ohe.categories_)
print(penguins['island'].unique())
[[0. 0. 1.]
 [0. 0. 1.]
 [0. 0. 1.]
 ...
 [1. 0. 0.]
 [1. 0. 0.]
 [1. 0. 0.]]
[array(['Biscoe', 'Dream', 'Torgersen'], dtype=object)]
['Torgersen' 'Biscoe' 'Dream']
  • 이제 해당 코드를 기존 데이터프레임에 추가하도록 한다.
print(penguins.head())
  species     island  bill_length_mm  bill_depth_mm  flipper_length_mm  \
0  Adelie  Torgersen            39.1           18.7              181.0   
1  Adelie  Torgersen            39.5           17.4              186.0   
2  Adelie  Torgersen            40.3           18.0              195.0   
3  Adelie  Torgersen             NaN            NaN                NaN   
4  Adelie  Torgersen            36.7           19.3              193.0   

   body_mass_g     sex  
0       3750.0    Male  
1       3800.0  Female  
2       3250.0  Female  
3          NaN     NaN  
4       3450.0  Female  
penguins[ohe.categories_[0]] = transformed.toarray()
print(penguins.head())
  species     island  bill_length_mm  bill_depth_mm  flipper_length_mm  \
0  Adelie  Torgersen            39.1           18.7              181.0   
1  Adelie  Torgersen            39.5           17.4              186.0   
2  Adelie  Torgersen            40.3           18.0              195.0   
3  Adelie  Torgersen             NaN            NaN                NaN   
4  Adelie  Torgersen            36.7           19.3              193.0   

   body_mass_g     sex  Biscoe  Dream  Torgersen  
0       3750.0    Male     0.0    0.0        1.0  
1       3800.0  Female     0.0    0.0        1.0  
2       3250.0  Female     0.0    0.0        1.0  
3          NaN     NaN     0.0    0.0        1.0  
4       3450.0  Female     0.0    0.0        1.0  

만약 다중 문자열 컬럼을 한다면?

  • 위 예시는 변경하려는 컬럼이 1개일 때는 시의적절하게 사용할 수 있다.
  • 그러나, 보통 캐글이나 데이콘 같은 대회에서는 여러개의 문자열 컬럼을 변환시켜야 한다.
  • 물론, 프로그래밍 능력을 갖춘 분이라면, 반복문을 사용해서 처리할 수도 있다.
  • 그러나, sklearn.compose.make_column_transformer 클래스를 활용하면 보다 쉽게 처리할 수 있다.
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import LabelEncoder
from sklearn.compose import make_column_transformer
from seaborn import load_dataset
import pandas as pd

penguins = load_dataset('penguins')
sample_cols = ['island', 'sex', 'bill_length_mm', 'species']
penguins = penguins[sample_cols]

# 결측치 제거 
penguins = penguins.dropna()
print(penguins.head())
print(penguins.info())
      island     sex  bill_length_mm species
0  Torgersen    Male            39.1  Adelie
1  Torgersen  Female            39.5  Adelie
2  Torgersen  Female            40.3  Adelie
4  Torgersen  Female            36.7  Adelie
5  Torgersen    Male            39.3  Adelie
<class 'pandas.core.frame.DataFrame'>
Int64Index: 333 entries, 0 to 343
Data columns (total 4 columns):
 #   Column          Non-Null Count  Dtype  
---  ------          --------------  -----  
 0   island          333 non-null    object 
 1   sex             333 non-null    object 
 2   bill_length_mm  333 non-null    float64
 3   species         333 non-null    object 
dtypes: float64(1), object(3)
memory usage: 13.0+ KB
None
categorical_cols = ['island', 'sex']
label_cols = ['species']

transformer = make_column_transformer(
    (OneHotEncoder(), categorical_cols),
    remainder='passthrough', 
    verbose_feature_names_out = False)

transformed = transformer.fit_transform(penguins)
transformed_df = pd.DataFrame(transformed, columns=transformer.get_feature_names_out())
print(transformed_df.head())
  island_Biscoe island_Dream island_Torgersen sex_Female sex_Male  \
0           0.0          0.0              1.0        0.0      1.0   
1           0.0          0.0              1.0        1.0      0.0   
2           0.0          0.0              1.0        1.0      0.0   
3           0.0          0.0              1.0        1.0      0.0   
4           0.0          0.0              1.0        0.0      1.0   

  bill_length_mm species  
0           39.1  Adelie  
1           39.5  Adelie  
2           40.3  Adelie  
3           36.7  Adelie  
4           39.3  Adelie  

OrdinalEncoder 클래스와 같이 사용이 가능한가?

  • 이번에는 OrdinalEncoder 클래스와 같이 사용을 하도록 한다.
import pandas as pd
from seaborn import load_dataset

tips = load_dataset('tips')

# 결측치 제거 
tips = tips.dropna()
print(tips.info())
<class 'pandas.core.frame.DataFrame'>
Int64Index: 244 entries, 0 to 243
Data columns (total 7 columns):
 #   Column      Non-Null Count  Dtype   
---  ------      --------------  -----   
 0   total_bill  244 non-null    float64 
 1   tip         244 non-null    float64 
 2   sex         244 non-null    category
 3   smoker      244 non-null    category
 4   day         244 non-null    category
 5   time        244 non-null    category
 6   size        244 non-null    int64   
dtypes: category(4), float64(2), int64(1)
memory usage: 9.1 KB
None
  • 위 데이터에서 sex, day는 onehot encoding을 진행하고, smoker와 time은 ordinal encoding을 동시 진행해본다.
  • 또한, numeric features를 위해 스케일러도 진행했다.
  • 그 후, 새로운 데이터 프레임으로 변환하는 코드를 작성한다.
  • ColumnTransformer 메서드 적용 후, get_feature_names()를 얻기 위해서는 helper 함수가 필요하다.
    • 함수는 해당 링크에서 가져왔다.
import warnings
import sklearn
import pandas as pd
import numpy as np

def get_feature_names(column_transformer):
    """Get feature names from all transformers.
    Returns
    -------
    feature_names : list of strings
        Names of the features produced by transform.
    """
    # Remove the internal helper function
    #check_is_fitted(column_transformer)
    
    # Turn loopkup into function for better handling with pipeline later
    def get_names(trans):
        # >> Original get_feature_names() method
        if trans == 'drop' or (
                hasattr(column, '__len__') and not len(column)):
            return []
        if trans == 'passthrough':
            if hasattr(column_transformer, '_df_columns'):
                if ((not isinstance(column, slice))
                        and all(isinstance(col, str) for col in column)):
                    return column
                else:
                    return column_transformer._df_columns[column]
            else:
                indices = np.arange(column_transformer._n_features)
                return ['x%d' % i for i in indices[column]]
        if not hasattr(trans, 'get_feature_names'):
        # >>> Change: Return input column names if no method avaiable
            # Turn error into a warning
            warnings.warn("Transformer %s (type %s) does not "
                                 "provide get_feature_names. "
                                 "Will return input column names if available"
                                 % (str(name), type(trans).__name__))
            # For transformers without a get_features_names method, use the input
            # names to the column transformer
            if column is None:
                return []
            else:
                return [name + "__" + f for f in column]

        return [name + "__" + f for f in trans.get_feature_names()]
    
    ### Start of processing
    feature_names = []
    
    # Allow transformers to be pipelines. Pipeline steps are named differently, so preprocessing is needed
    if type(column_transformer) == sklearn.pipeline.Pipeline:
        l_transformers = [(name, trans, None, None) for step, name, trans in column_transformer._iter()]
    else:
        # For column transformers, follow the original method
        l_transformers = list(column_transformer._iter(fitted=True))
    
    
    for name, trans, column, _ in l_transformers: 
        if type(trans) == sklearn.pipeline.Pipeline:
            # Recursive call on pipeline
            _names = get_feature_names(trans)
            # if pipeline has no transformer that returns names
            if len(_names)==0:
                _names = [name + "__" + f for f in column]
            feature_names.extend(_names)
        else:
            feature_names.extend(get_names(trans))
    
    return feature_names
  • 이제 위 함수들을 적용해서 각 인코딩과 사용하지 않는 컬럼들을 하나로 합치는 코드를 작성해본다.
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import OrdinalEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

categorical_cols = ['sex', 'day']
ordinal_cols = ['smoker', 'time']
numeric_cols = ['total_bill']
keep_features = [x for x in tips.columns if x not in categorical_cols + ordinal_cols + numeric_cols]

tips2 = tips[categorical_cols + ordinal_cols + numeric_cols]

transformer = ColumnTransformer(
    [('StandardScaler', StandardScaler(), numeric_cols),
     ('OneHotEncoder', OneHotEncoder(), categorical_cols),
     ('OrdinalEncoder', OrdinalEncoder(), ordinal_cols)],
    remainder='passthrough', 
    verbose_feature_names_out = False)

transformed = transformer.fit_transform(tips2)
transformed_df = pd.DataFrame(transformed, columns=get_feature_names(transformer))
tip3 = pd.concat([tips[keep_features], transformed_df], axis = 1)
tip3.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 244 entries, 0 to 243
Data columns (total 11 columns):
 #   Column                      Non-Null Count  Dtype  
---  ------                      --------------  -----  
 0   tip                         244 non-null    float64
 1   size                        244 non-null    int64  
 2   StandardScaler__total_bill  244 non-null    float64
 3   OneHotEncoder__x0_Female    244 non-null    float64
 4   OneHotEncoder__x0_Male      244 non-null    float64
 5   OneHotEncoder__x1_Fri       244 non-null    float64
 6   OneHotEncoder__x1_Sat       244 non-null    float64
 7   OneHotEncoder__x1_Sun       244 non-null    float64
 8   OneHotEncoder__x1_Thur      244 non-null    float64
 9   OrdinalEncoder__smoker      244 non-null    float64
 10  OrdinalEncoder__time        244 non-null    float64
dtypes: float64(10), int64(1)
memory usage: 22.9 KB


/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:38: UserWarning: Transformer StandardScaler (type StandardScaler) does not provide get_feature_names. Will return input column names if available
/usr/local/lib/python3.7/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function get_feature_names is deprecated; get_feature_names is deprecated in 1.0 and will be removed in 1.2. Please use get_feature_names_out instead.
  warnings.warn(msg, category=FutureWarning)
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:38: UserWarning: Transformer OrdinalEncoder (type OrdinalEncoder) does not provide get_feature_names. Will return input column names if available
  • 일단 임시로 작업을 하기는 했으나, 뭔가 깔끔해보이지는 않는다.
  • 만약 작업을 한다면, 한꺼번에 하지 말고, 각 단계별로 pipeline을 구성 후, 순차적으로 하는 것이 현재로써는 좀 더 “정신건강상 좋아보인다!”

Plot Tree 색상 변경

개요

  • skleran.tree.plot_tree의 색상을 바꿔보도록 한다.
  • matplotlib 객체지향의 구조를 알면 어렵지(?) 않게 바꿀 수 있다.
  • 간단하게 plot_tree 시각화를 구현해본다.
    • 언제나 예제로 희생당하는 iris 데이터에게 애도를 표한다.
  • 구글코랩에서 실행 시, 다음 코드를 실행하여 최신 라이브러리로 업그레이드 한다.
!pip install -U matplotlib
Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (3.2.2)
Collecting matplotlib
  Downloading matplotlib-3.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (11.2 MB)
     |████████████████████████████████| 11.2 MB 27.0 MB/s 
[?25hRequirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib) (1.4.0)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.7/dist-packages (from matplotlib) (2.8.2)
Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.7/dist-packages (from matplotlib) (1.21.5)
Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.7/dist-packages (from matplotlib) (7.1.2)
Requirement already satisfied: pyparsing>=2.2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib) (3.0.7)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib) (0.11.0)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.7/dist-packages (from matplotlib) (21.3)
Collecting fonttools>=4.22.0
  Downloading fonttools-4.31.2-py3-none-any.whl (899 kB)
     |████████████████████████████████| 899 kB 50.5 MB/s 
[?25hRequirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from kiwisolver>=1.0.1->matplotlib) (3.10.0.2)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7->matplotlib) (1.15.0)
Installing collected packages: fonttools, matplotlib
  Attempting uninstall: matplotlib
    Found existing installation: matplotlib 3.2.2
    Uninstalling matplotlib-3.2.2:
      Successfully uninstalled matplotlib-3.2.2
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.2.9 which is incompatible.
Successfully installed fonttools-4.31.2 matplotlib-3.5.1
%matplotlib inline 

import sklearn
print(sklearn.__version__)
import matplotlib
print(matplotlib.__version__)

# 필수 라이브러리 불러오기
from sklearn.datasets import load_iris
from sklearn import tree 
import matplotlib.pyplot as plt

# 데이터 불러오기
iris = load_iris()
print(iris.data.shape, iris.target.shape)
print("feature names", iris.feature_names)
print("class names", iris.target_names)

# 모형 학습 및 plot_tree 그래프 구현
dt = tree.DecisionTreeClassifier(random_state=0)
dt.fit(iris.data, iris.target)

fig, ax = plt.subplots(figsize=(10, 6))
ax = tree.plot_tree(dt, max_depth = 2, filled=True, feature_names = iris.feature_names, class_names = iris.target_names)
plt.show()
1.0.2
3.5.1
(150, 4) (150,)
feature names ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
class names ['setosa' 'versicolor' 'virginica']

png

R 텍스트 마이닝 1일차 - 빅카인즈 데이터 수집

Step 01 - 빅카인즈 접속 후, 데이터 내려받기

  • 싸이트 : https://www.bigkinds.or.kr/v2/news/index.do
  • 해당 싸이트에서 키워드를 입력 한다.
    • 이 때, 기간, 신문사 등을 선택할 수 있다.
    • 필자는 키워드는 ‘사회적 경제’ 신문사는 국민일보, 조선일보, 중앙일보를 선택한다.
    • 하단으로 내려 적용하기 버튼을 클릭한다.

Screen Shot 2022-03-13 at 12.27.40 AM.png

  • Step 03 - 분석 결과 및 시각화 탭을 클릭한다.
    • 데이터 다운로드 탭 하단에 엑셀 다운로드 버튼을 클릭한다.

Screen Shot 2022-03-13 at 12.39.59 AM.png

  • 해당 파일에는 본문이 있지만, 보통 200자 내외로 짧게 요약이 되어 있다.

Step 02 - 웹 크롤링 소스 코드 작성을 위한 사전 준비

  • 먼저 기 다운로드 된 파일을 불러온다.
  • 전체 데이터에서 필요한 컬럼만 재추출한다.
> library(dplyr)
> library(readxl)
> raw_df = read_excel("data/NewsResult_20211213-20220313.xlsx", sheet = 1)
> raw_df2 = raw_df %>% select(일자, 언론사, 제목, URL)
> raw_df2 %>% group_by(언론사) %>% summarise(n = n())
# A tibble: 3 × 2  
언론사       n  
<chr>    <int>
1 국민일보   180
2 조선일보   115 
3 중앙일보   256
  • 각 신문사별로 나눠서 객체를 저장한다. 여기에서는 국민일보만 추출하는 코드를 예시로 하였다.
> kmib_df = raw_df2 %>% filter(언론사 == "국민일보")
> head(kmib_df, 3)
# A tibble: 3 × 4  일자     언론사   제목                                         URL                   
<chr>    <chr>    <chr>                                        <chr>               
1 20220312 국민일보 팬데믹의 비극 무너지는 가정, 스러지는 아이들 http://news.kmib.co…
2 20220312 국민일보 ‘장로’ 디딤돌인가 걸림돌인가                 http://news.kmib.co…
3 20220311 국민일보 [기고]대전은 우리가 지킨다                   http://news.kmib.co…
  • 이번에는 URL만 추출하여 특이점이 있는지 확인한다.
    • 전체적으로 주소는 비슷하다.
    • 몇몇 주소에서는 &cp=kd 같은 문자가 더 추가된 것을 확인할 수 있다.
    • 서로 다른 싸이트에서 본문의 위치 등이 동일한지 다른지 확인할 필요가 있다. (확인 결과, 차이는 없다!)
> kmib_df$URL[1:5]
[1] "http://news.kmib.co.kr/article/view.asp?arcid=0924235144&code=11131100"      
[2] "http://news.kmib.co.kr/article/view.asp?arcid=0924235120&code=23111111"      
[3] "http://news.kmib.co.kr/article/view.asp?arcid=0016856942&code=61221514&cp=kd"
[4] "http://news.kmib.co.kr/article/view.asp?arcid=0016853803&code=61111711&cp=kd"
[5] "http://news.kmib.co.kr/article/view.asp?arcid=0016847353&code=61131111&cp=kd"

Step 03 - 웹 크롤링 본문 내용 발췌

  • 이번에는 본문만 크롤링 하도록 한다.
    • 1개의 데이터만 가져와서 테스트를 해본다.
> url = kmib_df$URL[1]
> news = read_html(url, encoding = "EUC-KR")
> news
{html_document}<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko">
[1] <head>\n<title>팬데믹의 비극… 무너지는 가정, 스러지는 아이들-국민일보</title>\n<meta http-equiv="Cont ...
[2] <body>\r\n<div id="wrap">\r\n\r\n<!-- header -->\r\n\r\n<script src="http://ww ...
  • 여기에서 div 태그 안에 있는 class tx 하단에 텍스트가 있는 것을 확인할 수 있다.

Screen Shot 2022-03-13 at 4.36.47 PM.png