Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Статистический анализ.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
828.93 Кб
Скачать

Приложение. Исходный код.

import time

from math import pi, exp, log10, log

start_time = time.time()

default_categories = {

1: "frontpage",

2: "news",

3: "tech",

4: "local",

5: "opinion",

6: "on-air",

7: "misc",

8: "weather",

9: "health",

10: "living",

11: "business",

12: "sports",

13: "summary",

14: "bulletin board service",

15: "travel",

16: "msn-news",

17: "msn-sports"

}

class Data(object):

def __init__(self, file_name):

with open(file_name, "r") as f:

self.visitors = [Visitor(string) for string in f.readlines()[7:]]

self.visitors_amount = len(self.visitors)

self.deep = [v.deep for v in self.visitors]

self.deep_by_categories = {}

for i in range(1,18):

self.deep_by_categories[i] = [v.pages.count(i) for v in self.visitors

if i in v.categories]

def make_pages_flat(self):

pages_flat = [item for visitor in self.visitors for item in visitor.pages]

pages_flat_amount = len(pages_flat)

for e in range(1,18):

num = pages_flat.count(e)

per = num * 100 / pages_flat_amount

print("%2d.\t %-6d (%2.2f%%)\t %s." % (e, num, per, default_categories[e]))

print("%s - всего просмотров" % pages_flat_amount)

def save_result(self, result, file_name):

with open("results/"+file_name + ".txt", "w", encoding='utf-8') as f:

f.write(result)

class Visitor(object):

def __init__(self, string):

self.pages = [int(e) for e in string.strip().split(' ')]

self.deep = len(self.pages)

self.categories = set(self.pages)

self.categories_amount = len(self.categories)

def __str__(self):

visitor_string = ('%s elements: ' % (self.deep)) + ' '.join(str(e) for e in self.pages)

return visitor_string

### Выборочное среднее.

# get_mean([1, 1, 7], 3) -> 3

def get_mean(massive, length):

return sum(massive) / length

### Несмещённая выборочная дисперсия.

# get_unbiased_variance([1, 5], 3, 2) -> 8

def get_unbiased_variance(massive, mean, length):

return sum([(i-mean)**2 for i in massive]) / (length-1)

### Стандартный коэффициент асимметрии

def get_std_skewness(X, m, s, n):

return (sum([(x-m)**3 for x in X]) / (n * s**3)) / (6/n)**0.5

### Стандартный кксцесса

def get_std_kurtosis(X, m, s, n):

return (sum([(x-m)**4 for x in X]) / (n * s**4) - 3) / (24/n)**0.5

### Коэффициент асимметрии

def get_skewness(X, m, s, n):

return sum([(x-m)**3 for x in X])

### Коэффициент эксцесса

def get_kurtosis(X, m, s, n):

return sum([(x-m)**4 for x in X]) / (n * s**4) - 3

### Мода.

# get_mode([1, 4, 6, 6, 8]) -> 6

def get_mode(massive):

return max(set(massive), key=massive.count)

### Диапазон значений.

# На входе выборка, на выходе массив из минимального и максимального значений.

# get_range([4, 0, 19, 10]) -> [0, 19]

def get_range(massive):

return [min(massive), max(massive)]

### Медиана.

# get_median([5, 8, 35, 14]) -> 11

def get_quantile(massive, n, level):

l = 1/level

massive = sorted(massive)

if n % 2 == 1:

return massive[int(n//l) - 1] # целочисленное деление, округление в меньшую сторону

else:

return (massive[int(n//l)] + massive[int(n//l) - 1]) / 2

### Создание частотного распределения.

# На входе массив, на выходе словарь количества вхождений каждого из элементов.

# [1,1,2,3,4,2,1] -> {1: 3, 2: 2, 3: 1, 4: 1}

def frequency_distribution(massive):

return {i: massive.count(i) for i in sorted(set(massive))}

# Вычисление среднего выборочного, несмещённой выборочной дисперсии, моды, медианы

def get_main_characteristics(massive):

n = len(massive)

m = get_mean(massive, n)

variance = get_unbiased_variance(massive, m, n)

s = variance ** 0.5

mode = get_mode(massive)

median = get_quantile(massive, n, 0.5)

skewness = get_skewness(massive, m, s, n)

kurtosis = get_kurtosis(massive, m, s, n)

q075 = get_quantile(massive, n, 0.75)

massive_range = get_range(massive)

result_string = "\n{0} values in range: [{4[0]}; {4[1]}] \n"\

"mean = {1:0.3f} \n"\

"variance = {2:0.3f} \n"\

"deviation = {3:0.3f} \n" \

"skewness = {8:0.3f} \n"\

"kurtosis = {9:0.3f} \n"\

"mode = {5} \n" \

"median = {6} \n"\

"q(3/4) = {7}"\

.format(n, m, variance, s, massive_range, mode, median, q075, skewness, kurtosis)

return result_string

### Критерий нормальности Хи-квадрат

def test_normal_Hi_squared(massive):

result_string ="\n- - - - - - - \n ПРОВЕРКА НОРМАЛЬНОСТИ РАСПРЕДЕЛЕНИЯ (модифицированный критерий χ^2)\n\n"

n = len(massive)

m = get_mean(massive, n)

s = (sum([(i-m)**2 for i in massive]) / n) ** 0.5

c_coefficients = [-100000, -1.4652, -1.0676, -0.7916, -0.5660, -0.3661, -0.18,

0, 0.18, 0.3661, 0.5660, 0.7916, 1.0676, 1.4652, 100000]

intervals = [m + c*s for c in c_coefficients]

mi = 0

for i in range(1, len(intervals)):

hits = sum(1 for e in massive if (intervals[i-1]<e) & (e<intervals[i]))

mi += hits ** 2

result_string += '[{0:6.2f}; {1:6.2f}] - {2} values \n'.format(intervals[i-1], intervals[i], hits)

hi_squared = (14 * mi / n) - n

threshold = 19.937 # из таблицы (стр. 231)

if hi_squared > threshold:

result_string += "ВЫВОД\n" \

"{0:0.3f} > {1:0.3f} \n" \

"Значение критерия больше критического для k = 14 и α = 0.05 \n"\

"Гипотеза нормальности распределения отклоняется.\n"\

.format(hi_squared, threshold)

else:

result_string += "ВЫВОД\n" \

"{0:0.3f} ≤ {1:0.3f} \n" \

"Значение критерия не больше критического для k = 14 и α = 0.05 \n"\

"Гипотеза нормальности распределения не отклоняется.\n"\

.format(hi_squared, threshold)

return result_string

### Критерий экспоненциальности распределения Колмогорова-Смирнова

def test_exponence_Kolmogorov(massive):

result_string = "\n- - - - - - - \n ПРОВЕРКА ЭКСПОНЕНЦИАЛЬНОСТИ РАСПРЕДЕЛЕНИЯ (критерий Колмогорова-Смирнова) \n\n"

massive = sorted(massive)

n = len(massive)

m = get_mean(massive, n)

nu = n * (m-massive[0]) / (n-1)

mu = massive[0] - nu / n

z_minus, z_plus = [], []

for i, x in enumerate(massive):

z = 1 - exp(-(x - mu) / nu)

z_plus.append(i/n - z)

z_minus.append(z - (i-1)/n)

dn_plus, dn_minus = max(z_plus), max(z_minus)

result_string += "ν = {0:0.3f}, \t μ = {1:0.3f} \nDn+ = {2:0.3f}, \t Dn- = {3:0.3f} \n".\

format(nu, mu, dn_plus, dn_minus)

result = max(dn_plus, dn_minus) * (n**0.5)

threshold = 1.094 # из таблицы (стр. 283)

if result > threshold:

result_string += "ВЫВОД\n" \

"{0:0.3f} > {1:0.3f} \n" \

"Значение критерия больше критического для n -> ∞ и α = 0.05 \n"\

"Гипотеза экспоненциальности распределения отклоняется.\n"\

.format(result, threshold)

else:

result_string += "ВЫВОД\n" \

"{0:0.3f} ≤ {1:0.3f} \n" \

"Значение критерия не больше критического для n -> ∞ и α = 0.05 \n"\

"Гипотеза экспоненциальности распределения не отклоняется.\n"\

.format(result, threshold)

return result_string

### Быстрый критерий симметрии Кенуя

def test_symmetry_Quenouille(massive):

result_string = "\n- - - - - \n ПРОВЕРКА СИММЕТРИИ РАСПРЕДЕЛЕНИЯ (быстрый критерий Кенуя) \n"

massive = sorted(massive)

n = len(massive)

x1 = massive[n//16]

x2 = massive[n//2]

x3 = massive[(15*n)//16]

result_string += "Квантили уровня n/16, n/2, 15n/16: {0} - {1} - {2} \n".format(x1, x2, x3)

result = (n**0.5) * (x3 - 2*x2 + x1) / (x3 - x1)

threshold = 1.96 # квантиль стандартного нормального распределения u0.975

if result > threshold:

result_string += "{0:0.3f} > {1:0.3f} \n" \

"Значение критерия больше критического для α = 0.95 \n"\

"Гипотеза симметрии распределения отклоняется.\n"\

.format(result, threshold)

else:

result_string += "{0:0.3f} ≤ {1:0.3f} \n" \

"Значение критерия не больше критического для α = 0.95 \n"\

"Гипотеза симметрии распределения не отклоняется.\n"\

.format(result, threshold)

return result_string

def Johnson_curves(massive, ext):

result_string = "\n- - - - - - - \n ПОДБОР КРИВЫХ ДЖОНСОНА \n\n"

massive = sorted(massive)

n = len(massive)

m = get_mean(massive, n)

s = get_unbiased_variance(massive, m, n) ** 0.5

a3 = sum([(x-m)**3 for x in massive]) / (n*s**3)

a4 = sum([(x-m)**4 for x in massive]) / (n*s**4)

aa3 = 3 * (1 + 0.641 * (a3**2))

if a4 < 1+a3:

result_string += "Кривые Джонсона неприменимы"

return result_string

result_string += "Кривые Джонсона применимы, так как a4 > 1 + a3 \n" \

"a3 = {0:0.2f} \n" \

"a4 = {1:0.2f} \n" \

"aa3 = 3*(1+0.641*(a3^2)) = {2:0.2f} \n"\

.format(a3, a4, aa3)

if a4 < aa3:

quan1 = massive[n // 100 - 1]

quan2 = massive[99*n // 100 - 1]

med = get_quantile(massive, n, 0.5)

lamb = (med - ext) * (

(med-ext) * (quan1-ext) +

(med-ext) * (quan2-ext) -

2 * (quan1 - ext) * (quan2 - ext)) \

/((med - ext)**2 - (quan1 - ext) * (quan2 - ext) + 0.00001)

result_string += "\nСемейство кривых Джонсона - Sb \n" \

"Уровень доверия α = 0.01 \n" \

"Квантиль x(α) = {0} \n" \

"Квантиль x(1-α) = {1} \n" \

"Медиана x(0.5) = {2} \n"\

"e = {4:0.3f} \n" \

"λ = {3:0.3f} \n" \

.format(quan1, quan2, med, lamb, ext)

try:

eta = (3.090 + 3.090) / log(

((quan2 - ext) * (ext + lamb - quan1 + 0.00001)) /

((quan1 - ext) * (ext + lamb - quan2 + 0.00001)))

gamma = 3.090 - eta * log((quan2 - ext)/(ext + lamb - quan2 + 0.00001))

result_string += "\nВЫВОДЫ - Sb \n" \

"η = {1:0.3f} \n" \

"γ = {2:0.3f} \n"\

.format(lamb, eta, gamma)

result_string += "ПЛОТНОСТЬ РАСПРЕДЕЛЕНИЯ: \n" \

"f(x) = {4:0.3f} / ((x-{3}) * ({5:0.3f}-x)) * " \

"exp(-0.5 * [{2:0.3f} + {1:0.3f} * ln((x-{3}) / ({5:0.3f}-x))] ^ 2)"\

.format(lamb, eta, gamma, ext, eta*lamb/((2*pi)**0.5), lamb-ext)

except:

result_string += "Необходима кривая Джонсона другого вида \n"

else:

result_string += "Необходима кривая Джонсона другого вида \n"

return result_string

### Построение линейной регрессионной модели.

# На входе словарь {x[i]: y[i]}

# На выходе модель в виде формулы "y = a + b*x" со всеми промежуточными вычислениями.

def linear_regression(dictionary, type = "linear"):

n = len(dictionary)

x = list(dictionary.keys())

y = list(dictionary.values())

xx = [x[i]*x[i] for i in range(len(x))]

xy = [x[i]*y[i] for i in range(len(x))]

x_sum = sum(x)

y_sum = sum(y)

xx_sum = sum(xx)

xy_sum = sum(xy)

b = (n*xy_sum - x_sum*y_sum) / (n*xx_sum - x_sum**2)

a = (y_sum - b * x_sum) / n

if type == "multiplicative":

result_string = "%7d / X^%0.3f \t" % (exp(a), -b)

elif type == "reciprocal":

result_string = "%7d + %7d / X \n" % (a, b)

else:

result_string = "%7d + %0.3f * X \t" % (a, b)

return result_string

### Корреляционный анализ с помощью коэффициента контингенции.

def correlation_analysis(massive, x, y):

n = len(massive)

a, b, c, d = 0, 0, 0, 0

for element in massive:

if x in element and y in element:

a += 1

elif x in element and y not in element:

b += 1

elif x not in element and y in element:

c += 1

elif x not in element and y not in element:

d += 1

cont_table = [[a, b], [c, d]]

Hi = n*((abs(a*d-b*c) - n/2)**2) / ((a+b)*(a+c)*(b+d)*(c+d))

Hi = "%5d" % Hi if Hi >= 99 else "%.2f" % Hi

threshold = 3.85

print(n)

print(cont_table)

return Hi

def analyze_sample(sample):

result = "= = = = = = = = = АНАЛИЗ ВЫБОРКИ = = = = = = = = = \n"

result += get_main_characteristics(sample)

result += "\nГистограмма: \n"

frequency = frequency_distribution(sample)

for i in sorted(frequency):

result += "%s \t %7d \t %0.6f \n" % (i, frequency[i], frequency[i]/len(sample))

result += test_normal_Hi_squared(sample)

result += test_exponence_Kolmogorov(sample)

result += test_symmetry_Quenouille(sample)

result += Johnson_curves(sample, 1)

multiplicative = {log(i): log(frequency[i]) for i in frequency}

reciprocal = {1/i: frequency[i] for i in frequency}

result += linear_regression(frequency, 'linear')

result += linear_regression(multiplicative, "multiplicative")

result += linear_regression(reciprocal, "reciprocal")

return result

d = Data("msnbc990928.seq")

for i in d.deep_by_categories:

result = "\t \t %s (%s) \n \n" % (default_categories[i].upper(), i)

result += analyze_sample(d.deep_by_categories[i])

d.save_result(result, "deep%s" % i)

print("--- %s seconds ---" % (time.time() - start_time))