|
| 1 | +import csv |
| 2 | + |
| 3 | +filename = 'henkiloautot-sahko-merkit.csv' |
| 4 | + |
| 5 | +all_rows = [] |
| 6 | + |
| 7 | +csv_file = open(filename, encoding='iso-8859-1') |
| 8 | +reader = csv.reader(csv_file) |
| 9 | +headers = next(reader) |
| 10 | +for row in reader: |
| 11 | + if row[0] in ['M1', 'M1G']: |
| 12 | + all_rows.append(row) |
| 13 | +csv_file.close() |
| 14 | + |
| 15 | +print(len(all_rows)) |
| 16 | + |
| 17 | +years = range(2016, 2024) # nyt on 2023 mukana |
| 18 | +counts = {} |
| 19 | +for row in all_rows: |
| 20 | + if row[1] == '': |
| 21 | + continue |
| 22 | + year = int(row[1][:4]) |
| 23 | + if year < years.start: |
| 24 | + continue |
| 25 | + if year not in counts: |
| 26 | + counts[year] = [0] * 12 |
| 27 | + month = int(row[1][5:7]) - 1 |
| 28 | + counts[year][month] += 1 |
| 29 | + |
| 30 | +# Lisää tyhjä lista myös vuodelle 2023: |
| 31 | +counts[years.stop - 1] = [0] * 12 |
| 32 | + |
| 33 | +print(f'Sähköautojen ensirekisteröinnit {years.start} - {years.stop - 1}') |
| 34 | +for year in years: |
| 35 | + print(f'{year}: {sum(counts[year]):>5}') |
| 36 | + for month in range(12): |
| 37 | + print(f'\t{month+1:>2}: {counts[year][month]}') |
| 38 | +print(f'Yhteensä: {len(all_rows)}') |
| 39 | + |
| 40 | +# Regressiomallia varten muista ensin aktivoida |
| 41 | +# virtuaaliympäristö, sitten asenna Scikit-Learn: |
| 42 | +# `pip install scikit-learn` |
| 43 | +# Matplotlibin asennus on jo vetänyt mukaan NumPy-kirjaston. |
| 44 | + |
| 45 | +import numpy as np |
| 46 | +from sklearn.linear_model import LinearRegression |
| 47 | + |
| 48 | +x_arr = [] |
| 49 | +x_val = 0 |
| 50 | +y_arr = [] |
| 51 | +leftover_count = 0 # montako kuukautta on vailla dataa |
| 52 | +for year in years: |
| 53 | + # Data puuttuu viimeiseltä vuodelta. |
| 54 | + # Se täydennetään ennusteen tuottamalla datalla. |
| 55 | + if year == 2023: |
| 56 | + leftover_count += 12 |
| 57 | + continue |
| 58 | + for month in range(12): |
| 59 | + # Data puuttuu myös v. 2022 lopulta |
| 60 | + if year == 2022 and month >= 6: |
| 61 | + leftover_count += 1 |
| 62 | + continue |
| 63 | + x_arr.append(x_val) |
| 64 | + x_val += 1 |
| 65 | + y_arr.append(counts[year][month]) |
| 66 | + |
| 67 | +# Nyt x_arr sisältää arvot 0...77, missä 0 = tammikuu 2016, |
| 68 | +# 1 = helmikuu 2016 jne., ja 77 = kesäkuu 2022. |
| 69 | +# Yhteensä siis 6 * 12 + 6 = 78 kuukautta. |
| 70 | + |
| 71 | +# y_arr sisältää rekisteröintimäärät 1/2016 ... 6/2022. |
| 72 | +#print(len(y_arr)) |
| 73 | +#print(y_arr) |
| 74 | + |
| 75 | +# NumPy-taulukot ovat hieman erilaisia kuin Pythonin listat, |
| 76 | +# joten täytyy tehdä pieni muunnos: |
| 77 | +x = np.array(x_arr).reshape((-1, 1)) |
| 78 | +y = np.array(y_arr) |
| 79 | + |
| 80 | +#print(x) |
| 81 | +#print(y) |
| 82 | + |
| 83 | +# Seuraava perustuu artikkeliin |
| 84 | +# https://realpython.com/linear-regression-in-python/ |
| 85 | + |
| 86 | +# Tehdään lineaarinen regressiomalli ja sovitetaan siihen x ja y: |
| 87 | +model = LinearRegression() |
| 88 | +model.fit(x, y) |
| 89 | + |
| 90 | +r_sq = model.score(x, y) |
| 91 | +print(f"coefficient of determination: {r_sq}") |
| 92 | +print(f"intercept: {model.intercept_}") |
| 93 | +print(f"slope: {model.coef_}") |
| 94 | + |
| 95 | +# Ennustetaan x:n perusteella y:n arvot |
| 96 | +y_pred = model.predict(x) |
| 97 | +#print(f"predicted response:\n{y_pred}") |
| 98 | + |
| 99 | +print(f'Ennustetaan {leftover_count} kuukautta...') |
| 100 | +future_x = list(range(x_val, x_val + leftover_count)) |
| 101 | +x_new = np.array(future_x).reshape((-1, 1)) |
| 102 | +#print(x_new) |
| 103 | +y_new = model.predict(x_new) |
| 104 | +print(y_new) |
| 105 | +print(type(y_new)) |
| 106 | + |
| 107 | +# Keräillään valmiit arvot ja niiden otsakkeet kuviota varten |
| 108 | +labels = [] |
| 109 | +year = years.start |
| 110 | +month = 0 |
| 111 | +values = y_arr |
| 112 | +for x in x_arr: |
| 113 | + labels.append(f'{year}-{month+1:>02}') |
| 114 | + month += 1 |
| 115 | + if month == 12: |
| 116 | + month = 0 |
| 117 | + year += 1 |
| 118 | + |
| 119 | +total_count = 0 |
| 120 | +count_2022 = 0 |
| 121 | +count_2023 = 0 |
| 122 | +year = 2022 |
| 123 | +month = 6 |
| 124 | +#print(future_x) |
| 125 | +for fx in future_x: |
| 126 | + count = int(y_new[fx - len(x_arr)]) |
| 127 | + total_count += count |
| 128 | + label = f'{year}-{month+1:>02}' |
| 129 | + labels.append(label) |
| 130 | + values.append(count) # lisätään ennustettu arvo |
| 131 | + print(f'{label}: {count} *') |
| 132 | + if year == 2022: |
| 133 | + count_2022 += count |
| 134 | + if year == 2023: |
| 135 | + count_2023 += count |
| 136 | + month += 1 |
| 137 | + if month == 12: |
| 138 | + month = 0 |
| 139 | + year += 1 |
| 140 | +print(f'Ennuste ajalle 2022-07 - 2023-12: {total_count}') |
| 141 | +print(f'Ennuste loppuvuodelle 2022: {count_2022}') |
| 142 | +print(f'Ennuste vuodelle 2023: {count_2023}') |
| 143 | + |
| 144 | +import matplotlib.pyplot as plt |
| 145 | +print(labels) |
| 146 | +print(values) |
| 147 | +plt.bar(labels, values, tick_label=labels) |
| 148 | +plt.show() |
0 commit comments