파이톤으로 처음부터 집계
63879 단어 machinelearningdatasciencepython
개술
이 글은 나Data Science from Scratch by Joel Grus가 보도한 다섯 번째 장이다.
주의해야 할 것은 본고에서 언급한 모든 내용은 NumPy와 statistics module in Python 같은 라이브러리에서 더욱 편리하고 효율적으로 완성할 수 있다는 것이다.
내가 보기에 이 책과 이 글의 주요 가치는 파이톤 원어를 어떻게 사용하는지 배우는 것을 강조하여 처음부터 도구를 구축하는 데 있다.다음은 시각 미리보기입니다.
구체적으로 말하면, 우리는 파이톤 언어의 특정한 기능을 어떻게 사용하는지, 그리고 우리가 이전 글에서 구축한 함수를 이용하여 데이터와 데이터의 내관계 (통계) 를 설명하는 도구를 구축하는지 연구할 것이다.
나는 이것이 매우 멋있다고 생각한다.허락해주셨으면 좋겠습니다.
샘플 데이터
이 장에서는 데이터 과학자인 소셜네트워크서비스인 DataScienster의 새로운 데이터 과학자에 대한 이야기를 이어가며 이 소셜네트워크서비스에 친구가 얼마나 있는지 묘사하는 일을 한다.우리는 두 개
lists
가 합작해야 한다.우리는 먼저 float
를 사용한 다음에 다시 사용할 것이다num_friends
.나는 이 문장이 독립적이기를 바란다. 이를 위해 우리는 평균 수준
daily_minutes
보다 높은 문장list
을 읽어야 한다.또 다른 방법은 책에서github repo (statistics.py)에서 데이터를 직접 얻는 것이다.num_friends = [100.0,49,41,40,25,21,21,19,19,18,18,16,15,15,15,15,14,14,13,13,13,13,12,12,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
daily_minutes = [1,68.77,51.25,52.08,38.36,44.54,57.13,51.4,41.42,31.22,34.76,54.01,38.79,47.59,49.1,27.66,41.03,36.73,48.65,28.12,46.62,35.57,32.98,35,26.07,23.77,39.73,40.57,31.65,31.21,36.32,20.45,21.93,26.02,27.34,23.49,46.94,30.5,33.8,24.23,21.4,27.94,32.24,40.57,25.07,19.42,22.39,18.42,46.96,23.72,26.41,26.97,36.76,40.32,35.02,29.47,30.2,31,38.11,38.18,36.31,21.03,30.86,36.07,28.66,29.08,37.28,15.28,24.17,22.31,30.17,25.53,19.85,35.37,44.6,17.23,13.47,26.33,35.02,32.09,24.81,19.33,28.77,24.26,31.98,25.73,24.86,16.28,34.51,15.23,39.72,40.8,26.06,35.76,34.76,16.13,44.04,18.03,19.65,32.62,35.59,39.43,14.18,35.24,40.13,41.82,35.45,36.07,43.67,24.61,20.9,21.9,18.79,27.61,27.21,26.61,29.77,20.59,27.53,13.82,33.2,25,33.1,36.65,18.63,14.87,22.2,36.81,25.53,24.62,26.25,18.21,28.08,19.42,29.79,32.8,35.99,28.32,27.79,35.88,29.06,36.28,14.1,36.63,37.49,26.9,18.58,38.48,24.48,18.95,33.55,14.24,29.04,32.51,25.63,22.22,19,32.73,15.16,13.9,27.2,32.01,29.27,33,13.74,20.42,27.32,18.23,35.35,28.48,9.08,24.62,20.12,35.26,19.92,31.02,16.49,12.16,30.7,31.22,34.65,13.13,27.51,33.2,31.57,14.1,33.42,17.44,10.12,24.42,9.82,23.39,30.93,15.03,21.67,31.09,33.29,22.61,26.89,23.48,8.38,27.81,32.35,23.84]
daily_hours = [dm / 60 for dm in daily_minutes]
묘사
floats
목록은 한 사람의'친구 수'를 대표하는 숫자 목록이다. 예를 들어 한 사람이 100명의 친구가 있다.우리가 데이터를 묘사하는 첫 번째 일은 100명의 친구, 49명의 친구, 41명의 친구를 그려내는 조형도를 만드는 것이다.우리는
num_friends
에서 Counter
를 가져오고 collections
를 가져올 것이다.우리는
matplotlib.pyplot
를 사용하여 Counter
목록을 유사num_friends
의 대상 맵키로 계수로 변환할 것이다.더 많은 정보를 알고 싶으면 카운터의 이 항목을 참조하세요.일단 우리가
defaultdict(int)
집합high-performance container datatype을 사용한다면 우리는 Counter
과 같은 방법으로 가장 흔히 볼 수 있는 값을 가진 키를 찾을 수 있다.여기서 우리가 가장 흔히 볼 수 있는 다섯 명의 친구는 각각 6, 1, 4, 3, 9이다.from collections import Counter
import matplotlib.pyplot as plt
friend_counts = Counter(num_friends)
# the five most common values are: 6, 1, 4, 3 and 9 friends
# [(6, 22), (1, 22), (4, 20), (3, 20), (9, 18)]
friend_counts.most_common(5)
인쇄를 계속하려면 most_common
을 사용하여 friend_counts
을 만들 것입니다. list comprehension
와 0-101 (xs) 사이의 모든 키를 순환시키고 해당하는 값을 출력합니다. (만약 존재한다면)이것은 Y축에서 friends_count
까지, 즉 x축이 됩니다.xs = range(101) # x-axis: largest num_friend value is 100
ys = [friend_counts[x] for x in xs] # y-axis
plt.bar(xs, ys)
plt.axis([0, 101, 0, 25])
plt.title("Histogram of Friend Counts")
plt.xlabel("# of friends")
plt.ylabel("# of people")
plt.show()
다음은 줄거리.너는 한 사람이 100명의 친구가 있는 것을 볼 수 있다.데이터의 시각화에 관한 더 많은 내용을 읽을 수 있습니다.
또는 우리는 내장된 파이톤 방법으로 간단한 통계 데이터를 생성하여
num_friends
,len
,min
,max
와sorted
를 설명할 수 있다.num_points = len(num_friends) # number of data points in num_friends: 204
largest_value = max(num_friends) # largest value in num_friends: 100
smallest_value = min(num_friends) # smallest value in num_friends: 1
sorted_values = sorted(num_friends) # sort the values in ascending order
second_largest_value = sorted_values[-2] # second largest value from the back: 49
중심 경향
한 그룹의 데이터를 설명하는 가장 자주 사용하는 방법은 그 평균값, 즉 모든 값의 합을 값의 개수로 나누는 것이다.참고: 유형 주석은 계속 사용됩니다.내가 보기에, 이것은 네가 더욱 심사숙고한 파이톤 프로그래머가 되는 데 도움이 될 것이다.
from typing import List
def mean(xs: List[float]) -> float:
return sum(xs) / len(xs)
assert 7.3333 < mean(num_friends) < 7.3334
그러나 균일치가 이상치에 대한 민감성은 유명하기 때문에 통계학자들은 보통 중위수 등 중심 추세의 다른 도량으로 보충한다.중위수는 가장 중간값이기 때문에 데이터 점의 수량이 짝수인지 홀수인지 매우 중요하다.여기서, 우리는 이 두 가지 상황을 위해 두 개의 사유 함수인 짝수와 홀수 데이터 포인트를 만들어서 중치를 계산할 것이다.우선, 우리는 데이터 값에 대해 정렬을 진행할 것이다.그리고 짝수 값에 대해 우리는 두 개의 중간 값을 찾아서 그것을 분리할 것이다.홀수 개의 값에 대해 우리는 데이터 집합의 길이를 2(즉 50)로 나눈다.
우리의 중치 함수는 사유 함수
_median_even
또는 _median_odd
를 조건부로 되돌려줍니다. 이것은 숫자 목록의 길이가 2로 정제될 수 있는지 여부에 달려 있습니다. (% 2=0)def _median_even(xs: List[float]) -> float:
"""If len(xs) is even, it's the average of the middle two elements"""
sorted_xs = sorted(xs)
hi_midpoint = len(xs) // 2 # e.g. length 4 => hi_midpoint 2
return (sorted_xs[hi_midpoint - 1] + sorted_xs[hi_midpoint]) / 2
def _median_odd(xs: List[float]) -> float:
"""If len(xs) is odd, its the middle element"""
return sorted(xs)[len(xs) // 2]
def median(v: List[float]) -> float:
"""Finds the 'middle-most' value of v"""
return _median_even(v) if len(v) % 2 == 0 else _median_odd(v)
assert median([1,10,2,9,5]) == 5
assert median([1, 9, 2, 10]) == (2 + 9) / 2
중위수는 가장 중간값이기 때문에 데이터의 모든 값에 완전히 의존하지 않는다.예를 들어 우리가 다른 명단num_friends2
을 가지고 있는데 그 중 한 명이 10000명의 친구가 있다고 가정하면 이런 변화에 대한 민감성은 중위수보다 평균적으로 훨씬 민감하다.num_friends2 = [10000.0,49,41,40,25,21,21,19,19,18,18,16,15,15,15,15,14,14
,13,13,13,13,12,12,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,9,9,9
,9,9,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7
,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5
,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3
,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1
,1,1,1,1,1,1,1,1,1,1,1,1]
mean(num_friends2) # more sensitive to outliers: 7.333 => 55.86274509803921
median(num_friends2) # less sensitive to outliers: 6.0 => 6.0
quantiles
를 사용하여 데이터를 설명할 수도 있습니다."X퍼센트 숫자"를 들을 때마다 100퍼센트에 대한 설명이다.사실상 중위수는 50번째 백분위(그중 50%의 데이터는 이 점 이하, 50%는 이 점 이상)이다.quantile
는 0-100 사이의 위치이기 때문에 두 번째 파라미터는 0.0에서 1.0 사이의 부동점이다.우리는 이 부동점수를 목록의 길이에 곱할 것이다.그리고, 우리는 int
을 사용하여 정수 인덱스를 만들 것입니다. 이 인덱스를 사용하여 정렬된 xs의 분위수를 찾을 것입니다.def quantile(xs: List[float], p: float) -> float:
"""Returns the pth-percentile value in x"""
p_index = int(p * len(xs))
return sorted(xs)[p_index]
assert quantile(num_friends, 0.10) == 1
assert quantile(num_friends, 0.25) == 3
assert quantile(num_friends, 0.75) == 9
assert quantile(num_friends, 0.90) == 13
마지막으로 모드입니다. 가장 흔히 볼 수 있는 값을 볼 수 있습니다.우선, 우리는 목록 매개 변수에 Counter
방법을 사용합니다. 계수기는 dict
의 하위 클래스이기 때문에 우리는 values()
등 방법으로 모든 값을 찾을 수 있고 items()
키 값 쌍을 찾을 수 있습니다.최대 값 (22) 을 찾기 위해
max_count
을 정의한 다음, 함수는 목록 이해를 되돌려줍니다. 최대 계수 (22) 와 관련된 키를 찾기 위해 순환 counts.items()
을 반복합니다.이것은 1과 6으로 22명(모드)에 한 명 또는 여섯 명의 친구가 있다는 것을 의미한다.def mode(x: List[float]) -> List[float]:
"""Returns a list, since there might be more than one mode"""
counts = Counter(x)
max_count = max(counts.values())
return [x_i for x_i, count in counts.items() if count == max_count]
assert set(mode(num_friends)) == {1, 6}
우리는 이미 num_friends
에서 Counter를 사용했기 때문에 friend_counts
방법을 사용해서 같은 결과를 얻을 수 있다.mode(num_friends) # [6, 1]
friend_counts.most_common(2) # [(6, 22), (1, 22)]
흩어지다
우리 데이터의 중심 추세를 제외하고는 그 전파나 분산도 알고 싶다.이 작업을 수행하는 도구는
most_common(2)
, data_range
, variance
및 standard deviation
입니다.범위는 간단한 최대치에서 최소치를 빼는 것이다.
방차는 aset of numbers is from their average value의 거리를 측정한다.우리에게는 더 흥미로운 것은 이전에 게시물과 구축된 함수를 빌려 방차 함수를 만드는 방법이 필요하다는 것이다.
만약 위키백과 페이지를 본다면, 방차는 변수와 그 평균치의 제곱 편차이다.
우선, 우리는
interquartile range
함수를 만들어야 한다. 이 함수는 숫자 목록을 가져오고, 목록의 모든 숫자에서 평균 값을 빼야 한다. (이것은 우리에게 평균 값과의 편차를 준다.)그리고 우리는
de_mean
이 모든 편차를 가질 것이다. 이것은 우리가 모든 값을 취하여 그것들을 자신과 곱하기 (제곱하기) 한 다음에 이 값을 더하고 (목록의 길이를 1로 나누기) 방차를 얻는 것을 의미한다.돌이켜보면
sum_of_squares
는 sum_of_squares
제품 기능의 특례이다.# variance
from typing import List
Vector = List[float]
# see vectors.py in chapter 4 for dot and sum_of_squares
def dot(v: Vector, w: Vector) -> float:
"""Computes v_1 * w_1 + ... + v_n * w_n"""
assert len(v) == len(w), "vectors must be the same length"
return sum(v_i * w_i for v_i, w_i in zip(v,w))
def sum_of_squares(v: Vector) -> float:
"""Returns v_1 * v_1 + ... + v_n * v_n"""
return dot(v,v)
def de_mean(xs: List[float]) -> List[float]:
"""Translate xs by subtracting its mean (so the result has mean 0)"""
x_bar = mean(xs)
return [x - x_bar for x in xs]
def variance(xs: List[float]) -> float:
"""Almost the average squared deviation from the mean"""
assert len(xs) >= 2, "variance requires at least two elements"
n = len(xs)
deviations = de_mean(xs)
return sum_of_squares(deviations) / (n - 1)
assert 81.54 < variance(num_friends) < 81.55
방차는 dot
개의 편차로 해석하기 어려울 수 있다.예를 들어 우리는 0에서 100 사이의 값을 가지고 있다sum_of_squares
.What does a variance of 81.54 mean?
더 흔히 볼 수 있는 대체 방법은 표준차이다.여기에서, 우리는 파이톤의
num_friends
모듈을 사용하여 방차의 제곱근을 얻는다.표준 편차는 9.03이고
math
의 평균치는 7.3이며 7+9=16 또는 7-9(친구 0명)보다 낮은 친구는 여전히 평균치의 표준 편차 범위 내에 있다는 것을 우리는 알고 있다.우리는 운행num_friends
을 통해 대다수의 사람들이 평균치의 표준 편차 범위 내에 있는지 검사할 수 있다.다른 한편, 우리는 20명의 친구가 있는 사람이 평균치에서 한 명 이상 차이가 있다는 것을 안다.
import math
def standard_deviation(xs: List[float]) -> float:
"""The standard deviation is the square root of the variance"""
return math.sqrt(variance(xs))
assert 9.02 < standard_deviation(num_friends) < 9.04
그러나 표준차는 방차의 기초 위에서 방차는 균일치에 의존하기 때문에 우리는 균일치처럼 이상치에 민감할 수 있다는 것을 알고 있다. 우리는 4분위 구간이라고 불리는 다른 방법을 사용할 수 있다. 이것은 중위수를 바탕으로 이상치에 민감하지 않다는 것을 안다.구체적으로 4분위 범위는 25위와 75위 사이의 차이
friend_counts
를 검사하는 데 쓰일 수 있다.대부분의 사람들은 대략 여섯 명의 친구가 있을 것이다.def interquartile_range(xs: List[float]) -> float:
"""Returns the difference between the 75%-ile and the 25%-ile"""
return quantile(xs, 0.75) - quantile(xs, 0.25)
assert interquartile_range(num_friends) == 6
기왕 우리가 하나의 데이터 목록만 묘사한 이상, 우리는 두 데이터 원본 간의 잠재적인 관계를 보고 싶다.예를 들어 DataScienster 소셜네트워크서비스(SNS)에 걸리는 시간이 한 사람이 가진 친구 수와 관련이 있다는 가설이 있을 수 있다.이어서 우리는 협방차와 관련성을 검사할 것이다.
상관성
만약에 방차가 한 조의 숫자가 그 평균치에서 벗어난 정도(즉, 윗글
num_friends
참조)이라면 협방차 도량은 두 조의 숫자가 그 평균치에서 벗어난 정도이다.그들의 생각은 공통된 변화량이 같으면 관련이 있을 수도 있다는 것이다.여기서 우리는 게시물에서 개발한
de_mean
생산 함수를 빌려 쓸 것이다.그 밖에 우리는
dot
와 num_friends
그리고 daily_minutes
사이에 관계가 있는지 검사할 것이다(상기 참조).def covariance(xs: List[float], ys: List[float]) -> float:
assert len(xs) == len(ys), "xs and ys must have same number of elements"
return dot(de_mean(xs), de_mean(ys)) / (len(xs) - 1)
assert 22.42 < covariance(num_friends, daily_minutes) < 22.43
assert 22.42 / 60 < covariance(num_friends, daily_hours) < 22.43 / 60
방차와 마찬가지로 협방차에 대해서도 비슷한 비판을 할 수 있으니, 너는 반드시 추가 절차를 취해 그것을 해석해야 한다.예를 들어 daily_hours
와 num_friends
의 합방차는 22.43이다.What does that mean? Is that considered a strong relationship?
보다 직관적인 평가 기준은 관련성이다.
def correlation(xs: List[float], ys: List[float]) -> float:
"""Measures how much xs and ys vary in tandem about their means"""
stdev_x = standard_deviation(xs)
stdev_y = standard_deviation(ys)
if stdev_x > 0 and stdev_y > 0:
return covariance(xs,ys) / stdev_x / stdev_y
else:
return 0 # if no variation, correlation is zero
assert 0.24 < correlation(num_friends, daily_minutes) < 0.25
assert 0.24 < correlation(num_friends, daily_hours) < 0.25
두 입력 변수의 표준 편차를 구분함으로써 관련성은 항상 -1(완벽(반)관련성)과 1(완벽관련성) 사이에 있다.0.24의 관련성은 상대적으로 약한 관련성이다(약, 중, 강한 관련성은 데이터의 상하문에 달려 있지만).기억해야 할 것은 샘슨 패러다임이나 세 번째 혼동 변수를 고려할 때 두 변수 간의 관계가 변화하는 것이다.그 밖에 우리는 이 케케묵은 말(이것은 원인이 있는 케케묵은 말)을 기억해야 한다. 관련성은 인과관계를 의미하지 않는다.
요약
우리는 지금 5장만 이야기했다. 우리는 우리가 현재 어떻게 도구를 구축하는지 이해하기 시작할 수 있다. 이따가 우리는 이 도구들을 사용할 것이다.다음은 우리가 이 글에서 토론한 내용의 시각적 정리와 그 내용이 이전의 글과 어떻게 연결되는지, 즉python 속성 과정: 참조, 등등이다.
이 게시물은 나의 이 책에 대한 보도를 계속한다.
데이터 과학, 머신러닝, R, 파이톤, SQL 등에 관한 더 많은 내용.
Reference
이 문제에 관하여(파이톤으로 처음부터 집계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/paulapivat/statistics-from-scratch-with-python-18fa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)