일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 파이썬
- 마이온
- intern10
- Plotly
- DP
- GNN
- 마이온컴퍼니
- folium
- BFS
- 그리디
- parklab
- TiL
- 멋쟁이사자처럼멋쟁이사자처럼
- 멋재이사자처럼
- pyhton
- Python
- 멋사
- GIS
- ux·ui디자인
- 프로젝트
- likelion
- 멋쟁이사자처럼
- 인턴10
- 시각화
- seaborn
- Join
- DFS
- SQL
- likelionlikelion
- 알고리즘
- Today
- Total
지금은마라톤중
멋사 AI스쿨 TIL - (6) 본문
2023.01.05
7. class
- 변수, 함수를 묶어서 코드를 작성하는 방법
- 객체지향 구현하는 문법
- 객체지향 : 실제세계를 모델링하여 프로그램을 개발하는 개발 방법론 : 협업을 용이하게 하기 위한
- 함수 사용법 : 함수선언(코드작성) > 함수호출(코드실행)
- 클래스 사용법
- 클래스 선언(코드작성) > 객체생성(메모리사용) > 메서드실행(코드실행)
- 클래스 선언(설계도작성) > 객체생성(제품생산) > 메서드실행(기능사용)
-식별자 컨벤션
- 변수, 함수 : snake_case
- 클래스 : PascalCase, UpperCamelCase
- class, self, 사용자 정의 데이터 타입, special methods(__int__(), __add__()…)
- 상속, super, getter-setter, mangling, 메서드의 종류들(인스턴스, 클래스, 스태틱)
# 클래스선언 : 코드작성
# 계산기 설계 : Calculator : number1, number2, plus(), minus()
class Calculator:
number1, number2 = 1, 2
def plus(self):
return self.number1 + self.number2
def minus(self):
return self.number1 - self.number2
# 객체생성 : 메모리사용
calc1 = Calculator()
calc2 = Calculator()
calc1.number1, calc1.number2 # 출력 : 1, 2
# 메서드 실행 : 코드실행
calc1.plus(), calc1.minus() # 출력 : (3, -1)
# 객체의 변수 수정 : 데이터 선택 = 수정할 데이터
calc1.number1, calc1.number2, calc2.number1, calc2.number2 # 출력 : (1, 2, 1, 2)
calc1.number1 = 20 #객체의 변수 수정
calc1.number1, calc1.number2, calc2.number1, calc2.number2 # 출력 : (20, 2, 1, 2)
# self : 객체자신
# Calculator.plus() : self.number1 + self.number2
# calc1.plus() : self == calc1
# self.number1 + self.number2 > calc1.number1 + calc1.number2
1) 스페셜 메서드
- 특별한 기능을 하는 메서드 : 앞뒤로 __를 붙임
- 생성자 메서드 : __int__()
- 객체를 생성할 때 실행되는 메서드
- 변수의 초기값을 실행할 때 주로 사용
- 불량 객체(메서드 사용 X)가 만들어질 확률을 줄여줌
# 클래스생성 : 설계도작성
class Account:
def __init__(self, balance= 2000):
self.balance = balance
def insert(self, amount):
self.balance += amount
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
else:
print(f'잔액이 {amount - self.balance}원 부족합니다.')
# 객체생성 : 메모리 사용
account = Account()
# 메서드 실행 : 코드실행 : 기능사용
account.insert(200)
account.balance # 출력 : 2200
- 클래스는 사용자 정의 데이터 타입이다.
# account의 데이터 타입은 Account
# account 객체가 만들어진 클래스는 Account
# 데이터 타입 == 클래스 > 클래스는 데이터 타입이다.
# Account 클래스는 우리가 만듦 > 사용자 정의
# > 클래스는 사용자 정의 데이터 타입이다.
type(account) # 출력 : __main__.Account
# data의 데이터 타입은 list
# data 객체가 만들어진 클래스는 list
# list 클래스는 우리가 만들지 X
data = [1, 2, 3]
type(data) # list : 사용자 정의가 아닌 데이터 타입
# account의 메서드는 Account 클래스에서 정의
# data의 메서드는 list 클래스에서 정의
[var for var in dir(account) if var[0] != '_']
# 출력 : ['balance', 'insert', 'withdraw']
# account.insert(), data.sort(), data.append()
# 데이터 타입의의 메서드를 암기할 필요 X
print([var for var in dir(data) if var[0] != '_'])
# 출력 : ['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
# 객체의 데이터 타입에 따라서 사용할수 있는 변수, 메서드가 다르다.
# 숫자열과 튜퓰을 예시로 봤을 때 변수와 메서드가 다른 것을 확인 할 수 있다.
data1, data2 = 234, (1, 2, 3)
print(type(data1), type(data2))
print([var for var in dir(data1) if var[0] != '_'])
print([var for var in dir(data2) if var[0] != '_'])
# 출력 : <class 'int'> <class 'tuple'>
# ['as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
# ['count', 'index']
- 파이썬으로 만든 데이터 타입은 첫글자가 대문자이고, c언어로 만든 데이터 타입(ex. list, str)은 소문자로 표시된다.
- 추가적인 스페셜 메서드
- __add__() : + 연산자 정의
- 리스트 : +연산은 리스트를 붙여줌, numpy : +연산은 가은 인덱스끼리의 합을 보여줌.
- __str__() : print() 함수 실행 정의
# 기본 원리
# d1 + d2 : + 연산자 == d1.__add__() 실행
d1 + d2 == d1.__add__(d2)
d1, d2, d3, d4 = 1, 2, '3', '4'
# d1 + d2 : + 연산자 == d1.__add__() 실행
d1 + d2 == d1.__add__(d2)
# d1 + d2 : d1.__add__(d2) : d1.__add__() : int 클래스의 __add__() 메서드
# d3 + d4 : d3.__add__(d4) : d3.__add__() : str 클래스의 __add__() 메서드
# > 데이터 타입에 따라서 수행되는 __add__() 메서드가 다르다.
# 덧셈연산을 하지만 뺄셈연산이 수행되는 객체를 생성
class Number:
def __init__(self, data):
self.data = data
def __add__(self, obj):
return self.data - obj.data
def __str__(self):
return str(self.data)
def __repr__(self):
return str(self.data)
num1 = Number(10)
num2 = Number(3)
num1.data, num2.data # 출력 : (10 , 3)
num1 + num2 # 출력 : 7
2) 상속
- 다른 클래스의 변수(메서드)를 가져와서 사용하는 방법
- 특정 메서드와 제외하고 상속하는 것은 안됨.
- 중간에 상속받은 변수를 바꿀 수 있음.
# 상속
# iPhone1 : call
# iPhone2 : call, send_msg
# iPhone3 : call, send_msg, internet
class iPhone1:
def call(self):
print('calling!')
class iPhone2(iPhone1):
def send_msg(self):
print('send_msg!')
class iPhone3(iPhone2):
def internet(self):
print('internet!')
iphone1 = iPhone1()
iphone2 = iPhone2()
iphone3 = iPhone3()
def show_vars(obj) :
return [var for var in dir(obj) if var[0] != '_']
show_vars(iphone1), show_vars(iphone2), show_vars(iphone3)
# 출력 : (['call'], ['call', 'send_msg'], ['call', 'internet', 'send_msg'])
- 다중 상속
# 다중 상속은 python에서만
# 상속 순서 : Human > Korean > Jin
class Jin(Korean, Human):
def skill(self):
print('coding')
class Anchel(Indian, Human):
def skill(self):
print('speak english!')
jin = Jin()
show_vars(jin) # 출력 : ['eat', 'skill', 'walk']
anchel = Anchel()
jin.eat() # 출력 : eat kimchi!
anchel.eat() # 출력 : eat curry!
3) 데코레이터 : decoreator
-함수에서 중복되는 코드를 빼서 데코레이터 함수를 만들어 코드를 작성하는 방법
- 원래 있던 함수에 새로운 기능을 추가한 함수로 변경할 때 주로 사용
- 파이썬에만 있는 문법이다.
# code1, code3이 중복인 상태
def func1():
print('code1')
print('code2')
print('code3')
def func2():
print('code1')
print('code4')
print('code3')
def deco(func):
def wrapper(*args, **kwargs):
print('code1')
func()
print('code3')
return wrapper
# deco 함수의 파라미터 func에 func1이 들어감
# func1 함수는 deco 함수의 return 함수인 wrapper 함수로 변경
@deco
def func1():
print('code2')
@deco
def func2():
print('code4')
func1()
func2()
# 출력 :
# code1
# code2
# code3
# code1
# code4
# code3
# timer 데코레이터 함수 생성
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time() # 현재시간 저장
result = func(*args, **kwargs)
end = time.time() # 현재시간 저장
print(f'running time : {end - start} sec')
return result
return wrapper
@timer
def plus(n1, n2) :
return n1 + n2
def minus(n1, n2) :
return n1 - n2
plus(3,2)
# 출력 : running time : 1.1920928955078125e-06 sec
# 패스워드를 맞춰야 함수의 실행이 가능하도록 하는 데코레이터 작성
def admin(func):
def wrapper(*args, **kwargs):
pw = input('insert password : ')
if pw == 'python': # 패스워드 맞음
result = func(*args, **kwargs)
else: # 패스워드 맞지 않음
result = 'wrong password!'
return result
return wrapper
def plus(n1, n2) :
return n1 + n2
@timer # deco 2개 사용 가능
@admin
def minus(n1, n2) :
return n1 - n2
minus(1,2)
# 출력 :
# insert password : python
# running time : 4.556134223937988 sec
# -1
상관계수
1) 분산 (variance)
- 어떤 확률 변수의 분산(variance) 은 그 확률변수가 기댓값(expected value) 으로부터 얼마나 떨어진 곳에 분포하는지를 가늠하는 숫자
- 편차제곱의 평균
- 1개의 이산정도를 나타낸다.
import numpy as np
data1 = [80, 85, 100, 90, 95]
data2 = [70, 80, 100, 95, 95]
data3 = [100, 90, 70, 90, 80]
def variance(data):
var = 0
x_ = sum(data) / len(data)
for xi in data:
var += (xi - x_) ** 2
return var / len(data)
variance(data1), variance(data2), variance(data3) # 분산
# variance(data1) ** 0.5, variance(data2) ** 0.5, variance(data3) ** 0.5 # 표준편차
# np.var(data1), np.var(data2), np.var(data3)
# 출력 : (50.0, 126.0, 104.0)
2) 공분산 (covariance)
- 공분산 (Covariance, Cov)는 2개의 확률변수의 상관 정도를 나타내는 값
- x와 y의 단위의 크기에 영향을 받는다.
- 평균 편차곱
- 방향성은 보여줄수 있으나 강도를 나타내는데 한계가 있습니다.
- 표본데이터의 크기에 따라서 값의 차이가 큰 단점이 있습니다.
(a) : Cov(X, Y) > 0 X가 증가 할 때 Y도 증가한다. (b) : Cov(X, Y) < 0 X가 증가 할 때 Y는 감소한다. (c) : Cov(X, Y) = 0 공분산이 0이라면 두 변수간에는 아무런 선형관계가 없으며 두 변수는 서로 독립적인 관계에 있음을 알 수 있다. 그러나 두 변수가 독립적이라면 공분산은 0이 되지만, 공분산이 0이라고 해서 항상 독립적이라고 할 수 없다. |
def covariance(x, y):
cov = 0
x_ = sum(x) / len(x)
y_ = sum(y) / len(y)
for xi, yi in zip(x, y): # zip으로 같은 인덱스끼리 꺼내온다.
cov += (xi - x_) * (yi - y_)
return cov / (len(x) - 1) # - 1 : 자유도
covariance(data1, data2), covariance(data1, data3)
# 출력 : (93.75, -87.5)
# 공분산의 한계 : 방향성은 보여줄수 있으나, 강도는 보여줄수 없음
data4 = [data * 10 for data in data1]
data5 = [data * 10 for data in data3]
data1, data3, data4, data5
covariance(data1, data3), covariance(data4, data5)
# 출력 : (-87.5, -8750.0)
3) 상관계수(correlation coefficient)
* 피어슨 상관계수, 스피어만 상관계수, 켄달 상관계수가 있다.
- 공분산의 한계를 극복하기 위해서 만들어진다.
- -1 ~ 1까지의 수를 가지며 0과 가까울수록 상관도가 적음을 의미
- x의 분산과 y의 분산을 곱한 결과의 제곱근을 나눠주면 x나 y의 변화량이 클수록 0에 가까워진다.
# 상관계수 구하는 수식
def cc(x, y):
cov = covariance(x, y)
var = (variance(x) * variance(y)) ** 0.5
return cov / var
data1, data2, data3, data4, data5 # data4, data5 = data1*10, data3*10
# 1과 가까울수로 강한 양의 상관관계
# -1과 가까울수록 강한 음의 상관관계
# 0과 가까울수록 관계없음
cc(data1, data2), cc(data1, data3), cc(data4, data5)
# 출력 : (0.944911182523068, -0.970725343394151, -0.970725343394151)
4) 결정계수
- 일반적으로 선형회귀분석에서 많이 사용하는 용어
- x로부터 y를 예측할수 있는 정도
- 상관계수의 제곱 (상관계수를 양수화)
- 수치가 클수록 회기분석을 통해 예측할수 있는 수치의 정도가 더 정확
- 단순 회귀분석(독립변수가 하나)인 경우 상관계수의 제곱 = 결정계수의 제곱
- R^2으로 표기, 범위 0 ~ 1
- x와 y의 상관관계 클수록 R^2이 1에 가까워짐.
Quiz
- 어제 못 푼 퀴즈 풀이
# Quiz. map 함수 직접 구현
names1 = ['kim python(23)', 'lee notebook(32)', 'kim macbook(47)']
names2 = ['kim py(33)', 'lee note(52)', 'kim book(87)']
def ages1(data):
return data[:-3] + str(int(data[-3:-1]) // 10 * 10) + ')'
def ages2(*args):
return [data[:-3] + str(int(data[-3:-1]) // 10 * 10) + ')' for data in args]
# 1번째
def map_func(func, *args):
return [func(value) for value in args[0]]
map_func(ages1, names1) # 출력 : ['kim python(20)', 'lee notebook(30)', 'kim macbook(40)']
# 2번째
def map_func(func, *args):
# print(args)
result = []
for data in zip(*args): # zip(names1, names2)
# print(data)
result.append([func(value)[0] for value in data])
return result
print(map_func(ages2, names1, names2))
# 1,2번 합친 것
def map_func(func, *args):
if len(args) <= 1:
result = [func(value) for value in args[0]]
else:
result = []
for data in zip(*args):
result.append([func(value)[0] for value in data])
return result
- 오늘의 퀴즈
# 과제 : 미팅 수와 판매, 미팅 시간과 판매 상관관계 비교
import pickle
with open('sales.pkl', 'rb') as file :
data = pickle.load(file)
data.keys()
count = data['meeting_count']
time = data['meeting_time']
sales = data['sales']
# 분산
var_count, var_time, var_sales = variance(count), variance(time), variance(sales)
# 공분산
covar1 , covar2 = covariance(count, sales), covariance(time, sales)
# 상관계수
cc(count, sales), cc(time, sales)
# 출력 : (0.782224424861606, 0.22829902637616525)
# 미팅수와 판매의 상관계수가 더 크므로 미팅 수가 판매에 더 영향이 있다고 판단.
오늘 추가공부는 수업내용과는 조금 달라서 따로 포스팅하겠다.
출처:
- https://supermemi.tistory.com/71.
- https://supermemi.tistory.com/70.
- https://destrudo.tistory.com/15.
- https://m.blog.naver.com/istech7/50153288534.
- http://www.seoulpaper.com/seoul/board.php?bo_table=b05_02&wr_id=14&me_code=5020.
'멋쟁이사자처럼 > Python' 카테고리의 다른 글
멋사 AI스쿨 WIL - (8) (0) | 2023.01.12 |
---|---|
멋사 AI스쿨 TIL - (7) (0) | 2023.01.06 |
멋사 AI스쿨 TIL - (5) (0) | 2023.01.04 |
멋사 AI스쿨 TIL - (4) (1) | 2023.01.03 |
멋사 AI스쿨 TIL - (3) (0) | 2023.01.02 |