Advertisement
Guest User

Untitled

a guest
Dec 15th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.66 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # coding: utf-8
  3.  
  4. # # Задача 1
  5. # ## Условие
  6. # Загрузите данные из набора Forest Fires (файл forestfires.csv) о лесных пожарах в Португалии. Задача состоит в том, чтобы с помощью линейной регрессии научиться предсказывать координату area (площадь пожара) в виде линейной комбинации других данных.
  7. #
  8. # Чтобы работать с числовыми координатами, нечисловые координаты (month, day) нужно перевести в числовые. Для простоты можно заменить координату month на индикатор летнего сезона, а координату day не использовать вообще. По желанию можно сделать преобразование другим способом. Также добавьте координату, тождественно равную единице (вес при этой координате интерпретируется как сдвиг).
  9. #
  10. # Разбейте выборку на две части в соотношении 7:3 (перемешав её с помощью random.shuffle). По первой части постройте регрессионную модель. Примените модель ко второй части выборки и посчитайте по ней среднеквадратичную ошибку.
  11. #
  12. # Для переменной area выполните преобразование $f(x) = ln(x+c)$ и постройте для нее новую регрессионную модель. Посчитайте среднеквадратичную ошибку для преобразованных значений. При каком $c$ предсказания получаются лучше всего?
  13. #
  14. # При выбранном $c$ сделайте разбиение выборки в соотношении 7:3 разными способами (перемешивая каждый раз). Найдите способ оценить разброс качества от разбиения. Сильно ли меняется качество? Сделайте выводы.
  15.  
  16. # In[7]:
  17.  
  18.  
  19. import scipy.stats as sps
  20. import matplotlib.pyplot as plt
  21. import numpy as np
  22. from sortedcontainers import SortedList
  23. from IPython.display import display, Markdown
  24. import pandas as pd
  25. params = {'legend.fontsize': 15,
  26. 'legend.handlelength': 2,
  27. 'figure.figsize': (15, 10)}
  28. plt.rcParams.update(params)
  29.  
  30.  
  31. # In[71]:
  32.  
  33.  
  34. df = pd.read_csv('./forestfires.csv')
  35.  
  36.  
  37. # In[72]:
  38.  
  39.  
  40. df = df[df['area'] < df['area'].quantile(0.9)]
  41. summer_season = ['jun', 'jul', 'aug']
  42. conditions = [(df['month'] == 'jun') | (df['month'] == 'jul') | (df['month'] == 'aug')]
  43. choices = [1]
  44. df['month'] = np.select(conditions, choices)
  45. df['shift'] = 1
  46. del df['day']
  47.  
  48.  
  49. # In[73]:
  50.  
  51.  
  52. df = df.sample(frac=1)
  53. quant = int(.7*len(df))
  54. training_df, testing_df = df[:quant], df[quant:]
  55.  
  56.  
  57. # In[74]:
  58.  
  59.  
  60. def linear_regression(X, Z):
  61. Zt = np.transpose(Z)
  62. theta = np.dot(np.dot(np.linalg.inv(np.dot(Zt, Z)), Zt), X)
  63. est = X - np.dot(Z, theta)
  64. sigma = np.dot(est, est)/(len(Z) - len(Z[0]))
  65. return theta, sigma
  66.  
  67. def getXZ(df):
  68. return df['area'].to_numpy(), df.loc[:, df.columns != 'area'].to_numpy()
  69.  
  70. def compute_estimation(training_df):
  71. theta, sigma = linear_regression(*getXZ(training_df))
  72. return theta, sigma
  73.  
  74. def apply_regression(training_df, testing_df):
  75. theta, sigma = compute_estimation(training_df)
  76. X, Z = getXZ(testing_df)
  77. mse = ((np.dot(Z, theta) - X)**2).mean()
  78. return mse
  79.  
  80.  
  81. # In[75]:
  82.  
  83.  
  84. x_axis = np.arange(1, len(testing_df) + 1)
  85. plt.plot(x_axis, testing_df['area'], label='Area')
  86. _, Z = getXZ(testing_df)
  87. theta, _= linear_regression(*getXZ(training_df))
  88. plt.plot(x_axis, np.dot(Z, theta), label='Estimation of area')
  89. plt.xlabel('Number')
  90. plt.ylabel('Area')
  91. plt.title('Линейная регрессия для площади')
  92. plt.legend(loc='best')
  93. plt.show()
  94. mse = apply_regression(training_df, testing_df)
  95. print(mse)
  96.  
  97.  
  98. # In[80]:
  99.  
  100.  
  101. def get_log_mse(training_df, testing_df, c):
  102. _, Z_testing = getXZ(testing_df)
  103. _, Z_training = getXZ(training_df)
  104. testing_df_log_area = testing_df['area'].apply(lambda x: np.log(x + c))
  105. training_df_log_area = training_df['area'].apply(lambda x: np.log(x + c))
  106. theta, sigma = linear_regression(training_df_log_area, Z_training)
  107. X, _ = getXZ(testing_df)
  108. mse = ((np.exp(np.dot(Z_testing, theta)) - c - X)**2).mean()
  109. return mse
  110.  
  111.  
  112. # In[77]:
  113.  
  114.  
  115. min_mse = mse
  116. min_c = 0
  117. _, Z_testing = getXZ(testing_df)
  118. _, Z_training = getXZ(training_df)
  119. mse_list = np.array([])
  120. x_axis = np.arange(0, 100, 0.1)
  121. for c in x_axis:
  122. testing_df_log_area = testing_df['area'].apply(lambda x: np.log(x + c))
  123. training_df_log_area = training_df['area'].apply(lambda x: np.log(x + c))
  124. theta, sigma = linear_regression(training_df_log_area, Z_training)
  125. X, _ = getXZ(testing_df)
  126. mse = ((np.exp(np.dot(Z_testing, theta)) - c - X)**2).mean()
  127. mse_list = np.append(mse_list, mse)
  128. if mse < min_mse:
  129. min_mse = mse
  130. min_c = c
  131. theta_min = theta
  132. print(min_mse, min_c)
  133. plt.plot(x_axis, mse_list, label='MSE')
  134. plt.scatter(min_c, min_mse, color='red', label='minimum')
  135. plt.xlabel('c')
  136. plt.ylabel('MSE')
  137. plt.legend(loc='best')
  138. plt.title('Зависимость MSE от c')
  139. plt.show()
  140.  
  141.  
  142. # In[ ]:
  143.  
  144.  
  145.  
  146.  
  147.  
  148. # In[84]:
  149.  
  150.  
  151. x_axis = np.arange(1, len(testing_df) + 1)
  152. plt.plot(x_axis, testing_df['area'], label='Area')
  153. plt.plot(x_axis, np.exp(np.dot(Z_testing, theta_min)) - min_c, label='Estimation')
  154. plt.xlabel('Number')
  155. plt.ylabel('Area')
  156. plt.title('Линейная регрессия для площади. Экспонециальная зависимость')
  157. plt.legend(loc='best')
  158. plt.show()
  159.  
  160.  
  161. # In[82]:
  162.  
  163.  
  164. for tries in range(10):
  165. df = df.sample(frac=1)
  166. quant = int(.7*len(df))
  167. training_df, testing_df = df[:quant], df[quant:]
  168. print(get_log_mse(training_df, testing_df, min_c))
  169.  
  170.  
  171. # # Вывод
  172. # Мы получили оценку на величину, сначала в предположении ее линейной зависимости от остальных, а потом в предположении сдвинутой экспонециальной зависимости. Я убрал из рассмотрения очень сильно отклоняющиеся значения приближаемого поля(оставил квантиль 0.9), чтобы общий тренд увидеть более четче. Мы видим, что mse для второго предположения получается примерно такой же, и ошибка для оптимального c сильно зависит от разбиения. Из этого можно сделать вывод, что обе гипотезы не очень правдоподобны, то есть, вероятно, area не выражается подобным способом.
  173.  
  174. # # Задача 2
  175. # ## Условие
  176. # Пусть $$X_i = \beta_1+i\beta_2+\varepsilon_0+\ldots+\varepsilon_i,\, i= 0, 1, \ldots, n$$ --- расстояния, которое проехал трамвай за $i$ секунд по показанию датчика. Здесь $\beta_1$~--- начальное расстояние, $\beta_2$ --- скорость трамвая, $\varepsilon_0$ --- ошибка начального показания датчика. Трамвай едет с постоянной скоростью, и через каждую секунду датчик фиксирует расстояние, которое проехал трамвай. Отсчет времени идет от предыдущего замера, причем отсчет происходит с ошибкой. Для $i = 1, \ldots, n$ величина $\varepsilon_i$ есть ошибка приращения расстояния, то есть $\varepsilon_i = \varepsilon_i^t \beta_2,$ где $\varepsilon_i^t$ --- ошибка отсчета времени. Все ошибки $\varepsilon_i$ независимы и распределены по закону $N(0, \sigma^2)$.
  177. #
  178. # Сведите задачу к линейной модели и найдите оценки наименьших квадратов для начального расстояния $\beta_1$ и скорости $\beta_2,$ а также несмещенную оценку для $\sigma^2,$ из которой выразите оценку дисперсии отсчета времени.
  179. #
  180. # Данные возьмите из файла Regression.csv. Сделайте выводы.
  181. #
  182. # ## Решение
  183. # В домашнем задании мы показали, что при сведении к линейной регрессии($Y_0 = X_0$, $Y_i = X_i - X_{i-1}$), получаются оценки
  184. # * $\hat{\beta_1} = Y_0$
  185. # * $\hat{\beta_2} = \frac{\sum\limits_{i = 1}^{n}{Y_i}}{n}$
  186. # * $\hat{\sigma^2} = \frac{n}{n-1}s^2(Y_1, \ldots, Y_n)$
  187. #
  188. # Т.к. $\varepsilon_i \sim N(0, \sigma^2), \varepsilon_i^t = \frac{\varepsilon_i}{\beta_2}$, то
  189. # $\varepsilon_i^t \sim N(0, \frac{\sigma^2}{\beta_2^2})$.
  190. # Возьмем тогда $\hat{\varepsilon_i^t} = \frac{\hat{\sigma^2}}{\hat{\beta_2^2}}$
  191.  
  192. # In[89]:
  193.  
  194.  
  195. df = pd.read_csv('./regression.csv')
  196.  
  197.  
  198. # In[92]:
  199.  
  200.  
  201. def get_estimations(Xs):
  202. Ys = np.zeros(len(Xs))
  203. Ys[0] = Xs[0]
  204. for i in range(1, len(Xs)):
  205. Ys[i] = Xs[i] - Xs[i-1]
  206. beta_1 = Ys[0]
  207. beta_2 = Ys[1:].mean()
  208. n = len(Xs) - 1
  209. sigma = n/(n - 1)*np.var(Ys[1:])
  210. time_error = sigma / beta_2 ** 2
  211. return beta_1, beta_2, sigma, time_error
  212.  
  213.  
  214. # In[120]:
  215.  
  216.  
  217. Xs = df.to_numpy()
  218. beta_1, beta_2, sigma, time_error = get_estimations(Xs)
  219. print('beta_1: ', beta_1)
  220. print('beta_2: ', beta_2)
  221. print('sigma: ', sigma)
  222. print('time_error: ', time_error)
  223.  
  224.  
  225. # In[123]:
  226.  
  227.  
  228. estims = np.array([])
  229. Xs = Xs.reshape(1, len(Xs))[0]
  230. for i in range(3, len(Xs) + 1):
  231. estims = np.append(estims, get_estimations(Xs[:i])[3])
  232. plt.xlabel('Номер')
  233. plt.ylabel('Дисперсия ошибки отсчета времени')
  234. plt.title('Дисперсия ошибки отсчета времени')
  235. plt.plot(np.arange(1, len(estims) + 1), estims, label='Дисперсия ошибки отсчета времени')
  236. plt.legend(loc='best')
  237. plt.show()
  238.  
  239.  
  240. # # Вывод
  241. # Мы получили, что
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement