가장 영향력이 큰 특성:lat
DAY 34
공식문서
PDP 해석-사례
ICE 곡선(Individual Conditional Expectation Curves)
공식문서
PDP: 두 특성 간의 상호작용(2 특성)
PDP를 Plotly를 사용하여 3D로 출력 가능(N234)
PDP: 카테고리특성 사용
PDP: 카테고리특성 사용(1특성)
- male(x축0)에서 female(x축1)로 갈 때 0.3만큼 target이 1이 될 확률(생존할 확률)이 증가한다.
PDP: 카테고리특성 사용(2특성)
- 안에 있는 값 자체는 예측값이다!!
- 나이가 어리고 여자인 사람은 살 확률이 높고, 반면에 나이가 많고 남자인 사람은 살 확률이 적다
SHAP value
:특성들의 기여도(feature attribution)를 계산하기 위한 방법
force_plot
: 변수들의 영향력을 그래프로 표현하는 것
- 파란색(lower)은 안좋은 영향을 끼쳤음을 의미
- 빨간색(higher)은 좋은 영향을 끼쳤음을 의미
force_plot: 한 샘플(local)에 대한 shape_value
- 평균값이 기준값으로 정해져있고, 평균값보다 낮은 이유는 위치,룸이 영향을 끼쳤다
force_plot: X_testd의 Shap_value
summary_plot
- 특성 중요도(feature importance)와 특성 효과(feature effects)를 결합
- grade : 변수의 값이 높을수록, 예상 가격이 높은 경향성이 있다.
- yr_built : 변수의 값이 낮을수록, 예상 가격이 높은 경향성이 있다.( 옛날 집일수록 집값 높음)
- bathrooms : 변수의 값이 높을수록, 예상 가격이 높은 경향성이 있다.
- bedrooms : 변수의 값이 높을수록, 예상 가격이 높은 경향성이 있다.
- condition : 변수의 값이 높을수록, 예상 가격이 높은 경향성이 있다.
- waterfront : 변수의 값이 높을수록, 예상 가격이 높은 경향성이 있다.
- floors : 해석이 모호하다. (빨간색 값이 왼쪽,오른쪽 다있음)
- yr_renovated : 해석이 모호하다. (빨간색 값이 왼쪽,오른쪽 다있음)
영향력의 고저를 판단하는 기준
- 폭을 넓을수록 영향력이 높다
- 색의 농도가 영향력을 많이 준것
- shap value의 기준점인 0 위에가 positive effect이고 0아래가 negative로 주는 것이고 색은 그 영향을 주는 정도를 표시
가장 영향력이 큰 특성:lat
[Python] 파이썬 이미지 처리 pillow(PIL) 설치 및 사용 예제 총정리:드루와
이미지 분석 및 처리를 쉽게 할 수 있는 라이브러리(Python Imaging Library : PIL)가 있습니다. 바로 pillow모듈입니다. 다양한 이미지 파일 형식을 지원하며, 강력한 이미지 처리와 그래픽 기능을 제공하는 이미지프로세싱 라이브러리의 한 종류입니다.
PIL 이미지 작업을 위한 표준 절차를 제공하고 있으며, 다음과 같은 것이있다.(출처 :위키백과)
- 픽셀 단위의 조작
- 마스킹 및 투명도 제어
- 흐림, 윤곽 보정 다듬어 윤곽 검출 등의 이미지 필터
- 선명하게, 밝기 보정, 명암 보정, 색 보정 등의 화상 조정
- 이미지에 텍스트 추가
- 기타 여러가지
설치하는 방법
명령프롬프트(cmd)창을 열고 pip install pillow 명령어를 실행합니다. 파이참 IDE를 사용중이시면 툴 하단의 터미널(Terminal)창에서 명령어를 실행합니다.
다른 모듈들과 다르게 모듈 설치는 pillow로 하였지만, import 하는 방법은 상당히 다르네요.
이미지 처리를 하기 위해서는 from PIL import Image 와 같이 모듈을 임포트해야 사용가능합니다.
이미지 불러오기 (이미지 출력)
Image클래스의 Image.open()함수를 사용하여 이미지를 쉽게 불러올 수 있습니다. 이미지를 불러온 후 변수의 타입을 확인해보면 임을 알 수 있네요. bitmap 자료형을 예상했는데 아닙니다. show()함수를 사용하면 윈도우의 기본 이미지 보는 프로그램이 자동으로 실행되고 아래와 같이 볼 수 있네요.
PyCharm IDE
이미지 속성 확인 방법
이미지의 크기, 이름, 모드, 가로 세로 길이 등의 정보를 확인 할 수 있습니다.
실행결과 |
이미지 파일 이름 : C:/Users/ilike/Pictures/IU_400x400.jpg 이미지 파일형식(format) : JPEG 이미지 용량(size) : (400, 400) 이미지 색상모드 : RGB 이미지 width : 400 이미지 height : 400 |
이미지 크기 변경하기
이미지의 크기는 resize()함수를 사용하여 변경합니다. 인자값은 튜플자료형입니다.
원본이미지의 절반(50%) 사이즈로 변경
이미지 사이즈를 변경할때, 내부적으로 리샘플링을 합니다. 리샘플링 옵션으로 여러가지를 지원합니다.
필터 | 내용 |
PIL.Image.NEAREST | 입력 이미지에서 가장 가까운 픽셀 하나를 선택합니다. 다른 모든 입력 픽셀은 무시합니다. |
PIL.Image.BOX | 소스 이미지의 각 픽셀은 동일한 가중치를 가진 대상 이미지의 한 픽셀에 기여합니다. 업 스케일링의 경우 NEAREST. 이 필터는 resize() 및 thumbnail()메서드 에서만 사용할 수 있습니다 . |
PIL.Image.BILINEAR | 크기 조정을 위해 출력 값에 기여할 수있는 모든 픽셀에서 선형 보간법을 사용하여 출력 픽셀 값을 계산합니다. 다른 변환의 경우 입력 이미지의 2x2 환경에 대한 선형 보간이 사용됩니다. |
PIL.Image.HAMMING | BILINEAR보다 선명한 이미지를 생성합니다. BOX처럼 로컬 수준의 전위가 없습니다. 이 필터는 resize() 및 thumbnail()메서드 에서만 사용할 수 있습니다 . |
PIL.Image.BICUBI | 크기 조정을 위해 출력 값에 기여할 수 있는 모든 픽셀에서 삼차 보간법을 사용하여 출력 픽셀 값을 계산합니다. 다른 변환의 경우 입력 이미지의 4x4 환경에 대한 큐빅 보간이 사용됩니다. |
PIL.Image.LANCZOS | 핍 값 계산 방법출력 값에 기여할 수있는 모든 픽셀에서 고품질 Lanczos 필터 (잘린 sinc)를 사용하여 출력 픽셀 값을 계산합니다. 이 필터는 resize() 및 thumbnail()메서드 에서만 사용할 수 있습니다 . |
눈으로 식별은 잘 안되는 것 같습니다. 아래 필터 비교표를 참고하세요.
출처:pillow.readthedocs.io
이미지 자르기(Crop)
이미지를 crop하는 방법은 crop()함수를 사용합니다.
crop함수의 인자 값은 4개이며 왼쪽, 위, 오른쪽, 아래 순으로 값을 대입합니다. 튜플 자료형입니다.
crop((left, upper, right, lower))
이미지 회전
Image 클래스의 rotate()함수를 사용하면 이미지를 원하는 각도만 큼 회전 할 수 있습니다.
이미지 상하, 좌우 대칭(Flip)
transpose()함수를 사용하여 대칭 작업이 가능합니다. 2개의 옵션을 제공합니다.
Image.FLIP_LEFT_RIGHT 필터는 좌우 대칭처리를 할때 , Image.FLIP_TOP_BOTTOM 필터는 이미지를 뒤집을 때 (상하 대칭) 사용합니다.
왼쪽부터 원본이미지, 좌우대칭, 상하 반전(뒤집기) 이미지입니다.
transpose()함수를 사용하여 이미지 회전도 가능합니다. 단 3개의 고정된 각도만 제공합니다. Image.ROTATE_90 은 좌측으로 90도 회전시킵니다. Image.ROTATE_180은 좌측으로 180도 회전시키며, Image.ROTATE_270은 좌측으로 270도 회전 시킵니다. 이것이 의미하는 바는 이미지를 90도 단위로 뒤집기 또는 회전을 의미합니다.
왼쪽부터, 원본사진, 90도 회전, 180도 회전, 270도 회전된 이미지 입니다.
이미지 필터링
ImageFilter모듈에 정의된 필터를 사용하여 Image.filter()함수에서 사용하여 이미지에 필터를 적용할 수 있습니다. 제공되는 필터는 다음과 같습니다.
- BLUR
- CONTOUR
- DETAIL
- EDGE_ENHANCE
- EDGE_ENHANCE_MORE
- EMBOSS
- FIND_EDGES
- SHARPEN
- SMOOTH
- SMOOTH_MORE
필터를 사용하기 위해서는 ImageFilter모듈을 임포트합니다. 아래 스크립트는 이미지를 흐리게(Blur) 처리한 예제입니다. DSLR 카메라로 사진을 찍을 때 수동으로 초점을 흐려서 찍은 효과가 나타납니다. ImageFilter는 3개의 Blur함수를 제공합니다. 첫번째는 ImageFilter.BLUR입니다. 이 녀석은 고정된 값으로 Blur처리를 합니다. 개발자가 임의로 변경할 수 없어요. 하지만 ImageFiler.BoxBlur()함수와 ImageFilter.GaussianBlur()함수는 개발자가 임의의 값을 적용할 수 있습니다.
왼쪽부터 원본, BLUR, BoxBlur, GaussianBlur로 처리한 이미지 입니다.
하나씩 테스트 해보기에는 필터가 많아요. for문을 사용하여 모든 필터 효과를 살펴봅니다.
필터를 적용하여 새로운 이미지 파일로 모두 저장하였습니다.
이미지 합치기
여러개의 이미지를 불러와서 합치는 방법에 대해 알아봅니다. 여러개의 이미지를 합치기 위해서는 paste()함수를 사용합니다. 첫번째 이미지에 두번째 이미지를 붙이는 개념은 아닙니다. 3개의 이미지를 합쳐볼 건데요. 이미지를 합치기(붙이기)를 할 경우 new()함수를 사용하여 새로운 이미지를 생성해야합니다. 그리고 새로운 이미지에 여러개의 이미지를 붙여 넣을 수 있습니다. new()함수의 첫번째 인자는 mode입니다. 어떤 모드를 적용할지 설정하고, 두번째 인자는 이미지 사이즈입니다. 그리고 마지막으로 3번째 인자는 새로 만든 이미지의 백그라운드 색상을 지정합니다. 3번째 인자는 생략가능합니다.
이미지 저장
Image.save()함수를 사용하여 불러온 이미지를 저장할 수 있습니다. 45도 회전한 이미지를 png 확장자를 주고 저장하였습니다. 혹시나 저장하면서 이미지 정보를 new_img 변수에 담아주나 궁금하여 변수 타입을 찍어보았으나 NoneType이네요. 이미지를 저장할 경우 변수 없이 사용하시면 됩니다.
이미지 썸네일(thumbnail) 쉽게 만드는 방법(Create thumbnails)
thumbnail()함수를 사용하여 썸네일을 쉽게 만들 수 있습니다. 사이즈 인자 값으로 튜플(tuple) 자료형으로 받아서 처리합니다. img.thumbnail(40, 40) 처럼 정수(int)를 입력하면 TypeError:'int' object is not iterable오류가 발생됩니다.
현재 디렉토리의 모든 JPEG 이미지에 대해 썸네일 만드는 방법
glob모듈을 임포트한 후 for문을 사용하시면 간단하게 처리됩니다. 물론 파일에 접근해야하니 , os모듈도 필요합니다.
이미지를 바이트배열(bytearray)로 변환하는 방법
io.BytesIO()를 사용하여 save()함수에서 저장위치를 로컬이 아닌 io.BytesIO() 변수에 담은후 getvalue()함수를 사용하여 바이트 어레이 값을 가져올 수 있습니다.
함수로도 만들어서 상요하면 편리하겠죠?
이미지를 넘파이 배열로 변환하는 방법
numpy.array()함수를 사용하여 이미지를 배열 객체로 반환할 수 있습니다.
넘파이(numpy) 배열을 이미지로 변환하는 방법
이미지를 픽셀 값으로 변환하는 방법
이미지의 특정 픽셀의 RGB 색상 구하는 방법
convert()함수를 사용하여 RGB 데이터를 가져옵니다. 그런 다음, getpixel()함수를 사용하여 특정 픽셀의 x, y 좌표값을 지정하면 픽셀값을 튜플자료형으로 반환합니다.
Installation — Pillow (PIL Fork) 8.0.1 documentation
Build flags: --disable-zlib, --disable-jpeg, --disable-tiff, --disable-freetype, --disable-lcms, --disable-webp, --disable-webpmux, --disable-jpeg2000, --disable-imagequant, --disable-xcb. Disable building the corresponding feature even if the development
Image Module — Pillow (PIL Fork) 8.0.1 documentation
Attaches a palette to this image. The image must be a “P”, “PA”, “L” or “LA” image, and the palette sequence must contain 768 integer values, where each group of three values represent the red, green, and blue values for the corresponding p
Real Late Starter
데이터를 분석할 때, 데이터들이 표현하는 변수들을 수많은 값을 갖습니다. 데이터를 살펴보는 가장 기본적이고 기초적인 방법은 각 변수를 대표할 수 있는 값을 구하는 것 입니다. 이것을 '대푯값(typical value)'라고 합니다. 변수의 대부분의 값들이 어디쯤에 위치하는지를 핍 값 계산 방법 알아보는 중심경향성을 나타내는 추정값입니다.
중요 개념정리
- 평균(mean)
- 가중평균(weighted mean) : 가중치를 곱한 값의 총합을 가중치의 총합으로 나눈 값
- 중간값(median)
- 가중 중간값(weighted median) : 데이터를 정렬한 후, 각 가중치 값을 더할 때, 총합의 중간이 위치하는 데이터 값
- 절사평균(trimmed median) : 정해진 개수의 극단값(extreame value)을 제외한 나머지 값들의 평균
- 로버스트하다(robust) : 극단값들에 민감하지 않다는 것을 의미한다. 저항성이 있다.
- 특이값(outlier) : 대부분의 값과 매우 다른 데이터 값 (극단값)
1. 위치 추정
절사평균은 평균을 변형한 것 중에 하나이다. 값들을 크기 순으로 정렬한 후, 양 끝에서 일정 개수(p)의 값을 삭제한 뒤 남은 값들을 가지고 구한 평균을 말한다.
절사평균은 극단값들에 영향을 많이 받지 않는 추정치입니다. 예를 들면, 신입사원을 채용하는 면접자리에서 5명의 면접관이 면접자들의 점수를 기입한다고 할때, 가장 낮은 점수와 가장 큰 점수는 버리고 평균을 구하는 것입니다. 이렇게하면 부정채용이나 채용비리 등을 막을 수 있습니다.
가중평균은 각 데이터 값에 가중치(w)를 곱한 값들의 총합을 다시 가중치의 총합으로 나눈 것입니다.
가중치를 사용하는 이유에는 2가지가 있습니다.
- 어떤 값들이 본래 다른 값들에 비해 핍 값 계산 방법 큰 변화량을 갖을 때. 이러한 관측값에 대해 더 작은 가중치를 줄 수 있다. 예를 들어 여러 개의 센서로부터 평균을 구한다고 할 때, 일부 센서의 정확도가 떨어진다면 해당 센서에서 나온 값들에 대해 가중치를 적용하는 것이 바람직하다고 할 수 있습니다.
- 데이터를 수집할 때, 우리가 관심 있는 서로 다른 대조군에 대해서 항상 똑같은 수가 얻어지지는 않는다.
2. 중간값과 로버스트 추정
모든 관측치를 다 사용하는 평균과는 달리, 중간값은 정렬된 데이터의 가운데에 위치한 값들만으로 결정하는 추정치입니다. 데이터에 매우 민감한 평균과 달리 중간값이 많은 경우, 위치 추정에 더 유리합니다. 평균에 비해 Robust하다고 말할 수 있습니다.
중간값은 결과를 왜곡할 수도 있는 특이값(극단값)들의 영향을 받지 않으므로 robust한 위치 추정방법이라고 합니다. 특이값은 한 데이터 집합에서 다른 값들의 정상적인 분포와 달리 극단적으로 멀리 떨어져 있는 값들을 말합니다. 특이값은 데이터 값 자체가 유효하지 않다거나 잘못되었다는 것이 아닙니다.
절사평균에서는 가장 큰 5개 주의 인구와 가장 작은 5개 주의 인구를 제외하고 평균을 계산한다. trim_mean 에서
0.1은 각 끝에서 10%를 제외하라는 뜻이다.
python에서 가중 중위수를 구하기 위해서는 wquantiles 패키지를 사용하면된다. pip install을 통해 wquantiles을 설치하고 불러와 사용한다.
Tabpy (Tableau 핍 값 계산 방법 X Python) 활용하여 BTS 곡 분석해보기
안녕하세요. 태블로 위키에 콜라보레이터로 참여하게 된 이다희입니다. 어떤 컨텐츠를 공유드리면 좋을지 고민을 하다가 많은 분들이 궁금해하시는 것 중에 하나인 tabpy 활용에 관하여 공유 드릴까 합니다.
tableau를 활용 하다보면 현황을 차트로 표현하여 보여주는 것에서 나아가 예측, 클러스터링 등과 같이 머신러닝을 활용한 조금 더 심도 깊은 분석에 대해서도 시각화 해보고자 하는 욕심이 생기는 데요. python으로 코드를 돌려 그릴 수도 있지만 내가 원하는 형태와 디자인으로 차트를 빠르게 그리기 쉽지 않고 대시보드 내에서 사용자가 인터렉티브하게 분석 결과를 바로 바로 볼 수 없는 아쉬움이 있습니다.
이 부분을 가능하게 해주는 것이 바로 tabpy 인데요! tabpy를 활용하면 태블로에서 파이썬 코드가 실행되어 결과 값을 시각화된 형태로 바로 확인이 가능합니다. 생각보다 간단한 tabpy 활용법에 대해서 공유 드리겠습니다.
먼저 핍 값 계산 방법 각 사용자 PC환경에 Python이 설치되어 있다고 가정하겠습니다.
Tabpy 패키지 설치하기
먼저 패키지 설치 전에 pip를 업데이트합니다.
Tabpy 패키지를 설치합니다
설치된 Tabpy를 실행합니다.
실행이 잘 되고 있는지 확인하기 위해서는 브라우저에 http://localhost:9004/ 를 입력해서 아래와 같은 화면이 나오면 됩니다.
Tabpy 서버에 연결하기
Tabpy가 잘 실행되고 있다면 이제 Tableau Desktop에서 Tabpy 서버에 연결합니다.
Tableau Desktop > 도움말 > 설정 및 성능 > Analytics 확장 프로그램 연결 관리로 들어갑니다.
를 입력하고 연결 테스트를 누르면 팝업과 함께 연결이 됩니다.
(Tabpy가 설치된 서버 환경에 따라 SSL, 사용자 이름 및 비밀번호를 입력해야할 수도 있습니다)
이제 Tableau Desktop을 통해 Tabpy 서버에 잘 연결이 되었는데요.
분석 시작하기
이제부터는 평소에 진행 하고 싶었던 분석을 생각해 보면서 자유롭게 Python 코드를 Tableau에서 돌리며 결과값을 시각화해 볼 차례입니다.
Tableau는 사용자들의 수요가 높은 아래 4가지 모델에 대해서 제공해주고 있는데요.
- PCA (Principal Component Analysis)
- Sentiment Analysis
- T-Test
- ANOVA
이 중에서 PCA를 예시로 활용해 보도록 하겠습니다.
PCA 분석의 컨셉과 사용하는 예시
PCA란 Principal Component Analysis의 약자로 주성분 분석입니다. 고차원의 데이터를 저차원의 데이터로 축소시키는 차원 축소 방법 중 하나입니다. 차원 축소를 하는 이유는 차원 축소를 통해 2차원에 다양한 feature 변수를 시각화할 수 있고 시각화를 통해 데이터 패턴을 쉽게 인지할 수 있어서 많이 활용되고 있습니다.
개인적으로 흥미가 있는 BTS 데이터를 활용해 보겠습니다. 데이터는 각 곡의 날짜별 Streams수와 Audio Features 입니다. 아래 테이블에서 Acousticness부터 Tempo에 해당하는 8개의 변수가 각 곡의 특징을 보여주는 Audio Features에 해당합니다.
Streams 수와 Audio Features를 각각 x,y축으로 하여 scatter chart를 그려 보고자 하는데 Audio Features의 경우 2개 이상의 항목을 갖고 있어 한 축에 표현하기가 어려운 상황입니다.
이럴 때 차원을 축소하여 1개의 차원으로 만드는데 활용할 수 있는 것이 바로 PCA 입니다.
해당하는 모델을 이용하기 위해 먼저 PC에 해당 파일을 설치합니다.
PCA 패키지 설치
설치 후 다시 http://localhost:9004/ 열어보면 모델 4개가 잘 설치된 것을 확인할 수 핍 값 계산 방법 있습니다.
계산된 필드 만들기
이제 Tableau로 돌아가서 아래 식이 들어간 계산된 필드 만들면 끝입니다!
계산식을 만드는 방법은 아래와 같습니다.
- tabpy.query 안에는 deploy한 모델 이름인 ‘PCA’ 를 입력합니다.
- 매개 변수로 반환 받을 주성분 개수를 입력합니다. (여기서 입력하는 정수는 0보다 크고 인풋 하는 변수의 총 개수 보다 작아야 합니다. )
- 또 다른 매개변수인 인풋할 변수는 개수에 따라 _argN 형태로 입력합니다. 해당 매개 변수는 N 순서에 맞추어 집계된 값으로 나열해 줍니다.
- 반환하는 값의 형태에 따라 계산식 전체를 script_xxx로 감싸줍니다.
PCA x Streams로 스캐터차트 만들기
이제 PCA가 만들어 졌으니 8개의 변수 대신 PCA 필드를 활용하여 종합적인 값으로 이용할 수 있습니다.
x축은 곡의 특징인 pca, y축은 stream수로 하여 BTS의 각 track을 원으로 뿌린 scatter chart 입니다. streams수가 많은 곡들은 비슷한 범주의 pca 값을 갖고 있는 것을 확인할 수 있습니다.
이처럼 Tabpy서버에 Predeploy된 4가지 모델을 활용해서 이용해도 되고 필요에 따라 또 다른 분석 모델을 가져와 사용해도 됩니다.
현재 업무에서 데이터 전처리 작업을 위해 Tabpy를 활용하고 있는데요. 추후에는 Python에서 제공하는 다양한 분석 모델을 이용하여 더욱 다양한 분석을 진행해 볼 예정입니다.
OZ1NG의 뽀나블(Pwnable)
OZ1NG
- 분류 전체보기 (44)
- Pwn Study (2)
- CTF,Wargame Write-Up (4)
- Laboratory (6)
- Tips (32)
« 2022/08 »
일 월 화 수 목 금 토 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -
(7) (3) (2) (2)
OZ1NG의 뽀나블(Pwnable)
[Tips] Python float형(부동소수점) 계산 오차 발생 이유 및 해결법 본문
[Tips] Python float형(부동소수점) 계산 오차 발생 이유 및 해결법
파이썬3로 개발하다가 단순 float형끼리의 계산에서 오차가 발생한다는 것을 알았다.
[사진1] - Python3 float형 오차
분명 0.043-0.001의 값은 0.042가 나와야하는데 0.0419999. 가 나온다. (참고로 python2도 마찬가지다.)
이건 꼭 Python에서만 발생하는 문제가 아니라 모든 언어에서 거의 공통으로 발생하는 문제이고
그 이유는 컴퓨터는 숫자를 2진수로 받아들이기 때문에 생긴다는 것이다.
2진수의 정수부는 아래와 같이 표현할 수 있다.
1*2*2 = 2^2 = 100(2) = 4
2진수의 소수부는 아래와 같다.
1/2 = 2^-1 = 0.1(2) = 1/2 = 0.5
(1/2)/2 = 2^-2 = 0.01(2) = 1/4 = 0.25
((1/2)/2)/2 = 2^-3 = 0.001(2) = 1/8 = 0.125
그렇다면 0.75와 같은 수는 2진수로 0.11(2)와 같이 쉽게 떨어지지만 0.3과 같은 수는 어떨까?
0.3 = 0.01001100110011. (무한반복) (2) 이 된다.
컴퓨터의 메모리도 한계가 있으므로 결국 컴퓨터는 이 무한반복 되는 값에서 근사값을 저장하게 되고
바로 여기서 오차가 발생하게 되는 것이다.
이 근사값을 저장하는 방식은 고정소수점과 부동소수점 2가지가 있는데
고정소수점은 예를들어 한 실수를 32bit로 표현하기로 하였다면
부호로 사용할 부분 = 1bit, 정수를 저장할 부분 = 15bit, 소수를 표현할 부분 = 16bit와 같이
소수점의 위치를 고정 시켜 놓는 것이다.
0(부호 표현) 000 0000 0000 0000 (정수 표현) . 0000 0000 0000 0000 (소수 표현) (2)
이러면 소수를 표현 할 수 있는 부분은 16bit밖에 안되므로 소수 값이 0.3처럼 2진수로 변환하였을때 무한인 경우
좀더 정확한 표현이 불가능해진다.
고정소수점으로 표현한 경우 : 0.3 = 0.0100110011001100(2) ==> (10진수로 다시 변환) : 0.29998779296875
이런 단점을 조금더 보완한게 부동소수점이다.
부동소수점은 일반적으로 IEEE에서 표준으로 정한 방법(IEEE 754 32비트 단정밀도)을 따르므로 여기서도 IEEE표준에 따른 방법으로 정리 하겠다.
[사진2] - IEEE 754 부동 소수점 (출처 : https://ko.wikipedia.org/wiki/IEEE_754)
부동소수점은 부호부, 지수부, 가수부로 나누어진다.
부호부는 고정소수점과 마찬가지로 보통 최상위 bit를 사용하여 표현한다.
지수부와 가수부는 아래와 같이 구한다.
고정소수점 예시와 같이 0.3이라는 수를 변환한다고 가정해보면
1. 먼저 0.3의 절댓값을 2진수로 변환한다. 0.3 = 0.0100110011001100. (2)
2. 소수점을 이동시켜 왼쪽에는 1만 남도록 한다.
1 . 0011001100110011. *2^-2 : 지수 = -2
3. 소수점의 오른쪽 부분은 가수부로 만약 23bit보다 부족하면 0으로 채워 총 23bit를 만든다.
하지만 이 경우엔 부족하지 않으므로 그냥 냅둔다.
가수부 : 0011001100110011
4. 이제 Bias를 지수에 더하면 된다. 32비트 IEEE 754 형식에서의 Bias는 127 (== (2^8)-1) 이므로
127+(-2) = 125가 되고 이를 2진수로 변경하면 1111101(2)가 된다.
이제 결과를 부동 소수점으로 표현하면 아래와 같아진다.
0(부호 표현) 1111 1101 (지수부) 0011 0011 0011 0011 0011 001 (가수부)
이를 다시 한번 10진수로 변환해 보면
1. 0011 0011 0011 0011 0011001(2) * 2^-2 = 0.01 0011 0011 0011 0011 0011001(2) = 0.29999998211860657(10진수)
위와 같이 정확하지는 않지만 고정소수점을 사용했을 때보다 조금 더 정확하게 표현 할 수 있다.
뭔가 설명이 길었는데 아무튼 결과만 말하자면 컴퓨터는 이 부동소수점을 이용해서 핍 값 계산 방법 2진수로 근사값을 저장하고,
이 때문에 float형(C나 그런 언어에서는 double과 같이 소수를 저장 할 수 있는 타입도 포함) 끼리의 저장 또는 연산에서
정확한 계산이 일어나지 않는 다는 것이다.
그렇다면 이것을 어떻게 해결할 수 있을까?
Python의 decimal모듈 또는 fractions모듈을 사용하면 된다. (여기서는 decimal모듈만 설명하겠다.)
[사진3] - 계산 결과
Floating Point Math
Floating Point Math Your language isn’t broken, it’s doing floating point math. Computers can only natively store integers, so they need some way of representing decimal numbers. This representation is not perfectly accurate. This is why, more often th
0 개 댓글