ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 55일차 - 파이썬 머신러닝
    AI 솔루션 개발자과정(Java, Python) 2022. 12. 23. 10:20

    머신러닝

    머신러닝의 개념은 다양하게 표현할 수 있으나, 일반적으로는 애플리케이션을 수정하지 않고도 데이터를 기반으로 패턴을 학습하고 결과를 예측하는 알고리즘 기법을 통칭한다.

     

    프로그램 로직을 통해 모든 조건과 다양한 환경 변수, 규칙을 반영해 사기 거래 적발의 정확성을 높일 수 있다면 이러한 시간과 비용의 희생을 감당할 수 있겠지만, 기대와는 다르게 소스가 복잡해지면서 예측의 정확성 향상이 이뤄지지 않는 경우가 현실이다.

     

    머신러닝은 이러한 문제를 데이터를 기반으로 숨겨진 패턴을 인지해 해결한다.

     

     

     

    머신러닝 분류

    - 지도 학습

    분류
    회귀
    추천 시스템
    시각 / 음성 인지
    텍스트 분석

    - 비지도 학습

    클러스터링 (군집화)
    차원 축소
    강화 학습

    머신러닝의 두 축, 데이터와 알고리즘

     

     

    머신러닝의 특징

    1. 데이터에 매우 의존적이다.
    2. 가비지 인, 가지비 아웃 특성을 가진다.
    3. 학습 데이터 기반의 로직은 현실에서는 좋지 않을 수 있다.
    4. 가령 학습시 90% 아웃풋이 나왔던 로직이 실제에서는 70% 아웃풋이 나올 수도 있다(과적합).

     

     

    파이썬 vs R

    R : 통계 전용 프로그래밍 언어

     

    개발 언어에 익숙하지 않지만, 통계 분석은 빠르게 해보고 싶다면 R이 적합할 수 있다.

    그러나 개발 언어에 익숙하고, 이제 막 머신러닝을 시작하려는 사람이라면 파이썬이 더 적합할 수 있다.

     

     

     

    넘파이

    머신러닝의 주요 알고리즘은 선형대수와 통계 등에 기반한다.

    넘파이(numpy)선형대수 관련 기능을 포함해 다양한 연산 기능을 제공한다.

    또한 c / c++과 같은 저수준 언어 기반의 호환 API를 제공한다.

    따라서 기존 프로그램과 데이터를 주고 받거나 API를 호출해 쉽게 통합할 수 있게 해준다.

     

    넘파이는 배열 기반의 연산은 물론이고 다양한 데이터 핸들링 기능도 제공한다. 그러나 비슷한 역할을 수행하는 판다스의 함수들이 좀 더 직관적이여서 판다스로 대체하는 경우가 대부분이다.

     

    numpy의 np.array를 이용해서 배열을 생성할 수 있다.

    numpy의 .shape변수를 이용해서 행렬 형태를 알 수 있다.

     

    numpy의 .ndim 변수를 이용해서 배열의 차원을 반환받을 수 있다.

     

     

     

    ndarray가 포함할 수 있는 데이터 타입은 다음과 같다.

    • 숫자형 int
    • 숫자형 unsigned int
    • 숫자형 float
    • 숫자형 complex
    • 문자열
    • 불리언


    넘파이 배열내 데이터 타입은 연산 특성상 같은 타입만 가능하다.

    배열 내 데이터 타입은 dtype 멤버 변수로 확인할 수 있다.

    정수는 int8, int16, int32 등으로 표현할 수 있다.

    만약 자료형이 섞인 리스트를 넘파이 배열로 변환하게 되면, 자동 형 변환이 일어나게 된다.

     

     

     

    넘파이 배열 내 타입 변경하기

    • astype() 메서드를 이용하면 타입 변경이 가능하다.
    • 이는 메모리를 절약해야 하는 상황에 주로 사용한다.
    • 단, 메모리 손실이 프로그램에 어떤 영향을 끼칠지 고려할 필요는 있다.

     

    ndarray 편리하게 생성하기

    • arange() : 범위를 정해 배열 생성하기
    • zeros() : 0으로 채워진 배열 생성하기
    • ones() : 1로 채워진 배열 생성하기

    .reshape 변수를 활용하여 배열을 재배열할 수 있다.

     

     

     

     

    배열에 대한 인덱싱과 슬라이싱 또한 가능하다.

     

    팬시 인덱싱리스트나 ndarray로 인덱스 집합을 지정하면 해당 위치의 인덱스에 해당하는 ndarray를 반환하는 인덱싱 방식이다.

     

     

     

     

     

     

     

    행렬의 정렬 - sort()와 argsort()

    numpy의 행렬 정렬은 np.sort()와 같이 넘파이에서 sort()를 호출하는 방식과, ndarray.sort()와 같이 행렬 자체에서 sort()를 호출하는 방식이 있다.

     

    두 방식의 차이는 np.sort()의 경우 원 행렬은 그대로 유지한 채 원 행렬의 정렬된 행렬을 반환하고

    ndarray.sort()는 원 행렬 자체를 정렬한 형태로 변환하며, 반환값은 None이다.

    np.sort()원본은 변경하지 않고, 정렬한 행렬을 반환한다.

    ndarray.sort()반환값이 없고, 원본을 정렬한다.

     

    sort()는 모두 기본적으로 오름차순으로 행렬 내 원소를 정렬한다.

    내림차순으로 정렬하기 위해서는 sort()[::-1]와 같이 사용하면 된다.

     

     

    행렬이 2차원 이상일 경우 axis축 값 설정을 통해 정렬할 수 있다.

     

     

    정렬된 행렬의 인덱스를 반환하기

    원본 행렬이 정렬되었을 때 기존 원본 행렬의 원소에 대한 인덱스를 필요로 할 때 np.argsort()를 이용한다.

    np.argsort()는 정렬 행렬의 원본 행렬 인덱스를 ndarray형으로 반환한다.

    argsort()는 넘파이에서 매우 활용도가 높다.

    넘파이의 ndarray는 RDBMS의 TABLE 칼럼이나 판다스 DataFrame 칼럼과 같은 메타 데이터를 가질 수 없다.

    따라서 실제 값과 그 값이 뜻하는 메타 데이터를 별도의 ndarray로 각각 가져야만 한다.

    np.argsort()로 원본 행렬의 인덱스를 반환받고, 이를 name_array에 팬시 인덱스로 적용하여 성적에 따른 학생의 이름을 추출할 수 있다.

     

    이러한 방식은 넘파이의 데이터 추출에서 많이 사용된다.

     

     

    선형대수 연산 - 행렬 내적과 전치 행렬 구하기

    행렬 내적(행렬 곱)

    행렬 내적행렬 곱이며, 두 행렬 A와 B의 내적은 np.dot()을 이용해 계산이 가능하다.

    두 행렬의 내적은 왼쪽 행렬의 로우(행)오른쪽 행렬의 칼럼(열)의 원소들을 순차적으로 곱한 뒤 그 결과를 모두 더한 값이다.

     

    이러한 행렬 내적의 특성으로는 왼쪽 행렬의 열 개수와 오른쪽 행렬의 행 개수가 동일해야 내적 연산이 가능하다.

     

     

    전치 행렬

    원 행렬에서 행과 열 위치를 교환한 원소로 구성한 행렬을 그 행렬의 전치 행렬이라고 한다.

    행렬 A가 있을 경우 A 행렬의 1행 2열의 원소2행 1열의 원소로, 2행 1열의 원소1행 2열의 원소로 교환하는 것이다.

     

    넘파이의 transpose()를 이용해 전치 행렬을 쉽게 구할 수 있다.

     

     

     

    데이터 핸들링 - 판다스

    일반적으로 대부분의 데이터 세트는 2차원 데이터이다.

    즉, 행과 열로 구성되어 있다. 행과 열의 2차원 데이터가 인기 있는 이유는 바로 인간이 가장 이해하기 쉬운 데이터 구조이면서 효과적으로 데이터를 담을 수 있는 구조이기 때문이다.

     

    판다스는 이러한 2차원 데이터를 효율적으로 가공/처리할 수 있는 다양하고 훌륭한 기능을 제공한다.

     

    판다스의 핵심 객체는 DataFrame이다.

    DataFrame는 여러 개의 행과 열로 이뤄진 2차원 데이터를 담는 데이터 구조체이다.

    판다스가 다루는 대부분의 영역은 이 DataFrame에 관련된 부분이다.

     

    DataFrame을 이해하기 전에 다른 중요 객체인 IndexSeries를 이해해야 한다.

    Index는 RDBMS의 PK처럼 개별 데이터를 고유하게 식별하는 Key 값이다.

    Series와 DataFrame은 모두 Indexkey 값으로 가지고 있다.

     

    Series와 DataFrame의 가장 큰 차이는 Series칼럼이 하나뿐인 데이터 구조체이고, DataFrame칼럼이 여러 개인 데이터 구조체라는 점이다.

    DataFrame은 여러 개의 Series로 이뤄졌다고 볼 수 있다.

     

     

     

    판다스는 다양한 포맷으로 된 파일을 DataFrame으로 로딩할 수 있는 편리한 API를 제공한다.

    read_csv(), read_table(), read_fwf()등이 있다.

     

    다음과 같이 read_csv를 입력해 데이터를 DataFrame으로 로딩할 수 있다.

    pd.read_csv()는 호출 시 파일명 인자로 들어온 파일을 로딩해 DataFrame 객체로 반환한다.

    read_csv()는 별다른 파라미터 지정이 없으면 맨 처음 로우를 칼럼명으로 인지하고 칼럼으로 변환한다.

    그리고 콤마로 분리된 데이터값들이 해당 칼럼에 맞게 할당한다.

    모든 DataFrame 내의 데이터는 생성되는 순간 고유의 Index값을 가지게 된다.

     

     

    로딩한 csv데이터를 titanic_df 변수에 저장하고, 호출하면 DataFrame의 모든 데이터를 출력한다.

     

     

    DataFrame과 리스트, 딕셔너리, 넘파이 ndarry 상호 변환

    기본적으로 DataFrame은 파이썬의 리스트, 딕셔너리 그리고 넘파이 ndarray 등 다양한 데이터로부터 생성될 수 있다.

    또한 반대로 변환될 수도 있다.

     

    다음과 같이 ndarray와 파이썬의 리스트를 생성하고 DataFrame으로 변환한다.

     

     

    딕셔너리를 DataFrame으로 변환하고, tolist()to_dict()로 이를 다시 리스트와 딕셔너리로 변환한다.

     

     

    DataFrame의 칼럼 데이터 세트 생성과 수정

    다음과 같이 DataFrame에 새로운 칼럼을 추가할 수 있다.

    SibSp칼럼과 Parch칼럼의 합을 새로 추가하는 Family_No칼럼에 적용된다.

     

     

    DataFrame 데이터 삭제

    DataFrame에서 데이터의 삭제는 drop() 메서드를 이용한다.

    drop() 메서드는 사용하는 데 혼동을 줄 만한 부분이 있어서 주의가 필요하다.

    drop() 메서드의 원형은 다음과 같다.

    DataFrame.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')

    이 중 가장 중요한 파라미터는 labels, axis, inplace이다.

    labels에 원하는 칼럼명을 입력하고, axis=1을 입력하면 지정된 칼럼을 드롭한다.

    axis=0을 입력하면 DataFrame은 자동으로 labels에 오는 값을 인덱스(행)로 간주한다.

     

    inplace=False인 상태로 위의 과정을 진행한다면 DataFrame의 데이터는 삭제하지 않고 삭제한 결과를 반환한다.

     

    inplace=True로 설정하면 자신의 DataFrame의 데이터를 삭제한다.

    또한 여러 개의 칼럼을 삭제하고 싶으면 리스트 형태로 삭제하고자 하는 칼럼명을 입력하면 된다.

     

     

     

    Index 객체

    판다스의 Index 객체는 RDBMS의 PK(Primary Key)와 유사하게 DataFrame, Series의 레코드를 고유하게 식별하는 객체이다.

    DataFrame, Series에서 Index 객체만 추출하려면 .index속성을 통해 가능하다.

     

     

    Index 객체는 식별성 데이터1차원 array로 가지고 있다.

    또한 ndarray와 유사하게 단일 값 반환 및 슬라이싱도 가능하다.

     

    하지만 한 번 만들어진 DataFrame 및 Series의 Index 객체는 함부로 변경할 수 없다.

     

     

     

    이 DataFrame에 reset_index() 메서드를 수행하면 새롭게 인덱스를 연속된 숫자형으로 할당하며 기존 인덱스는 'index'라는 새로운 칼럼명으로 DataFrame에 추가된다.

     

    이는 인덱스 번호가 정상적으로 순차 값을 가지지 않을 경우에는 사용할 만 하다.

    reset_index()의 파라미터로 drop=True를 설정하면 기존 인덱스는 칼럼으로 추가되지 않고 삭제된다.

     

     

     

     

     

     

    데이터 셀렉션 및 필터링

    판다스의 데이터 셀렉션과 필터링은 넘파이와 상당히 유사한 부분이 있다.

    DataFrame 바로 뒤에 있는 [ ] 안에 들어갈 수 있는 것은 칼럼명 문자, 또는 인덱스로 변환 가능한 표현식이다.

    현재는 칼럼만 지정할 수 있는 '칼럼 지정 연산자'로 이해하는 것이 혼돈을 막는 가장 좋은 방법이다.

     

    인덱스 표현식은 오류를 발생시킨다.

    하지만 슬라이싱과 칼럼명을 입력하는 것은 가능하다.

     

    이러한 이유로 칼럼 지정 연산자로 이해해야 한다.

     

     

     

    판다스는 DataFrame의 로우나 칼럼을 지정하여 데이터를 선택할 수 있는 인덱싱 방식으로 iloc[ ]loc[ ]를 제공한다.

    iloc[ ]는 위치 기반 인덱싱 방식으로 동작하며 loc[ ]는 명칭 기반 인덱싱 방식으로 동작한다.

     

    위치 기반 인덱싱은 행과 열 위치를, 0을 출발점으로 하는 세로축, 가로축 좌표 정숫값으로 지정한다.

     

    명칭 기반 인덱싱은 DataFrame의 인덱스 값으로 행 위치를, 칼럼의 명칭으로 열 위치를 지정하는 방식이다.

     

     

    불린 인덱싱은 매우 편리한 데이터 필터링 방식이다.

    오히려 iloc나 loc와 같이 명확히 인덱싱을 지정하는 방식보다는 불린 인덱싱에 의존해 데이터를 가져오는 경우가 더 많다.

     

    왜냐하면 명칭이나 위치 지정 인덱싱에서 가져올 값은 주로 로직이나 조건에 의해 계산한 뒤 행 위치, 열 위치 값으로 입력되는데, 그럴 필요 없이 처음부터 가져올 값을 조건으로 [ ] 내에 입력하면 자동으로 원하는 값을 필터링하기 때문이다.

    그리고 불린 인덱싱은 [ ] , loc[ ]에서 공통으로 지원한다.

     

    단지 iloc[ ]정숫값이 아닌 불린 값에 대해서는 지원하지 않는다.

Designed by Tistory.