ããã¯ã BASE Advent Calendar 2018 ãã®20æ¥ç®ã®èšäºã§ãã devblog.thebase.in ããã«ã¡ã¯ãData Strategy Group ã®å²¡ã§ããè¶£å³ã¯çãããé
ã飲ãããšãå°æ¥ã®å€¢ã¯ãŠã€ã¹ããŒã®èžçæãæã€ããšã§ãã ç§ã¯æ©æ¢°åŠç¿ãšã³ãžãã¢ãšããŠãŸã ïŒå¹Žç®ãªã®ã§ãããããã®äºæž¬ææ³ãæ¬ãwebäžã§ã»ãšãã©èŠãããªããªãããšãã£ãšæ°ã«ãªã£ãŠããææ³ããããŸãããã£ãã説æãããšãæç³»åããŒã¿ãã¯ã©ã¹ã¿ãªã³ã°ããŠåã¯ã©ã¹ã¿å
ã®å¹³åãäºæž¬ã«äœ¿ãããšãããã®ã§ãç§ãã20ãããæ³äžã®åæå±ã«æããŠããããŸãããäžèšã®è«æãäžçªããã«è¿ããšæããŸãã ã Time Series Forecasting through Clustering - A Case Study ã ä»åã¯å®éšãå
ŒããŠãã®äºæž¬ææ³ãåçŸããããšæããŸãã 䜿çšããŒã¿ ããããã°ãæšæ¥ã¯ @Toshi_Day1 ã®Fintechã«ã€ããŠã®èšäºããããå
æ¥ã®æ²³è¶ã® 鶎岡ããèŠ³å¯æ¥èš ã§ã¯ãžã£ãã¯ã»ããŒã·ãŒæ°ã®è©±é¡ããã£ãã®ã§ããã®æµãã§ Twitterã®æ ªäŸ¡ ãäºæž¬ããŠã¿ãŸãããã ãã¹ãã㯠ã®ãµã€ãããïŒå¹Žåã®æ¥æ¬¡æ ªäŸ¡ããŒã¿ãããŠã³ããŒãããŸããã ããããçŽè¿30æ¥åãæ€èšŒããŒã¿ãšããŠåãåºãããã以åã®ããŒã¿ãåŠç¿ããŒã¿ãšããŠäœ¿ããŸãã #!/usr/bin/env python3 # ã¢ãžã¥ãŒã« import numpy as np import pandas as pd from sklearn.cluster import KMeans from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error from matplotlib import pylab as plt # èªã¿èŸŒã¿ & æ¥ä»ã§ãœãŒã twtr_stock = pd.read_csv( 'twtr_stock.csv' ).sort_values( 'date' ).reset_index(drop= True ) # æ«å°Ÿ30ä»¶ãæ€èšŒããŒã¿ãšããŠåå² train_df = twtr_stock[ 0 :- 30 ].reset_index(drop= True ) test_df = twtr_stock[- 30 :].reset_index(drop= True ) å
é æ°ä»¶ã¯äžèšã®ããã«ãªã£ãŠããŸãã ãã®äžã§ closeïŒçµå€ïŒ ã®å€ãäºæž¬ããŠãããŸãã äžã®ã°ã©ãã¯closeã®å€ãæç³»åã§ããããããçµæã§ãã plt.plot(twtr_stock[ 'close' ]) åå倧ããäžãåŸåããããåŸåããåŸã
ã«äžãã調åã«ãªã£ãŠããŸããããã®ããŒã¿ããåŸã«ç¶ã30æ¥åã®ããŒã¿ãäºæž¬ããããšãä»åã®ç®æšã§ãã äºæž¬ã®æé ãã®äºæž¬ææ³ãçŽæçã«èª¬æããŠããŸããšã 1. æç³»åããŒã¿ãçééã§ã¹ã©ã€ããããªããã«ãŒããåãåºã㊠2. ãããã圢ç¶ã®äŒŒãŠãããã®å士ã§ã°ã«ãŒãã³ã°ã 3. åãã°ã«ãŒãå
ã§æ«å°Ÿã®æ ªäŸ¡ã ãåãåºãããã®å¹³åãäºæž¬å€ãšããŠæ±ã ãšããæµãã«ãªããŸããããå°ã詳ãã説æãããš æç³»åããŒã¿ããå¹
(N + K)ã®ã¹ã©ã€ãçªã®äœæ ã¹ã©ã€ãçªããšã«å¹³å0ã忣1ã«æšæºå ã¹ã©ã€ãçªã®æåNåã PCA + k-means ã§ã¯ã©ã¹ã¿ãªã³ã° åã¯ã©ã¹ã¿å
ã§ãN+Kæç¹ã®ããŒã¿ã®å¹³åå€ãèšç® cosé¡äŒŒåºŠã§è¿åã¯ã©ã¹ã¿ãæ±ãããã®ã¯ã©ã¹ã¿ã®å¹³åå€ãäºæž¬ã«äœ¿ã ãšããæé ã«ãªããŸãã 1. æç³»åããŒã¿ããã¹ã©ã€ãçªã®äœæ ã¹ã©ã€ãçªãšã¯ãæç³»åããŒã¿ããäžå®ã®å¹
ã§1æç¹ãã€ã¹ã©ã€ããããªããåãåºããŠäœãã«ãŒãã®ããšã§ããäžå³ããã®ã€ã¡ãŒãžã«ãªããŸãã ã¹ã©ã€ãçªãã ãšãããã«ããã®ã§ä»åŸã¯ã«ãŒããšåŒãã§ããŸããŸãã ããã§äœãããè€æ°ã®ã«ãŒãã䌌ãŠãããã®å士ã§ãŸãšããæ«å°Ÿã®å€ã®å¹³åã§äºæž¬ãè¡ããŸãã ä»åã¯çŽè¿20æ¥ã®ããŒã¿ãã5æ¥å
ã®ããŒã¿ãäºæž¬ãããšããŸããïŒ20 + 5ïŒæ¥åã®ããŒã¿ã§åãåºãããã®ã§ãå¹
25ã§1æ¥ããšã«ã¹ã©ã€ããããããŒã¿ã»ãããäœæããŸãã TRAIN_SIZE = 20 TARGET_FUTURE = 5 WINDOW_SIZE = TRAIN_SIZE + TARGET_FUTURE def split_window_data (array, window_size): length = array.shape[ 0 ] roop_num = length - window_size + 1 window_data = np.stack([ np.hstack( np.array(array[i: i+window_size].astype( 'float64' )).reshape(window_size, 1 ) ) for i in range (roop_num) ]) return window_data train_close = np.array(train_df[ 'close' ]) window_data = split_window_data(train_close, WINDOW_SIZE) 2. ã«ãŒãããšã«æšæºå ã«ãŒãããšã«åãåºããããŒã¿ã¯ããããã®ã¯ïŒ20 30 35 25 30ïŒãå¥ã®ãã®ã¯ïŒ60 80 70 80 100ïŒã ã£ãããšã¹ã±ãŒã«ãç°ãªããŸãããã®çã®å€ã§ã¯ã©ã¹ã¿ãªã³ã°ãè¡ããšãã¹ã±ãŒã«ã®å€§ãããã®å士ã§ãŸãšãŸã£ãŠããŸããŸãããä»åã¯æç³»åã®åœ¢ç¶ãç¹åŸŽã䌌ãŠãããã®å士ã§ãŸãšããå¿
èŠããããŸãã ãã®ããã«ãŒãããšã«ãæšæºåããšããæäœãè¡ããå¹³å0ã忣1ã®ã¹ã±ãŒã«ãçµ±äžããŠããŸããŸãã # æšæºå sc = StandardScaler() window_sc = np.stack([ np.hstack(sc.fit_transform(vec.reshape(WINDOW_SIZE, 1 ))) for vec in window_data ]) æšæºåã«ã€ããŠã¯äžèšãåèã«ãªããŸãã ã çµ±èšã«ãããæšæºåã®æå³ãšç®ç ã 3. PCA + k-means ã§ã¯ã©ã¹ã¿ãªã³ã° ããããã®æé ãäžå³ã䜿ã£ãŠèª¬æããŸããåãå¹
ã®ã«ãŒããåé ã§äœæããŸããããä»åºŠã¯ãããã圢ã®äŒŒãŠãããã®å士ã§ãŸãšããŠãããŸãã k-meansãšã¯ã¯ã©ã¹ã¿ãªã³ã°ã®äžã€ã§ãæ°åŠçã«äŒŒãŠããïŒæ°åŠçã«è·é¢ãè¿ãããšèšã£ããããŸãïŒããŒã¿ãä»»æã®ã°ã«ãŒãã«åé¡ããŸããåé¡åŸã®ã°ã«ãŒãããã¯ã©ã¹ã¿ããåã¯ã©ã¹ã¿ã®éå¿ã«äœçœ®ããããŒã¿ãã代衚ãã¯ãã«ããšåŒã³ãŸãã代衚ãã¯ãã«ãåŸã®èšç®ã§äœ¿ããããããã§ç®åºããŠãããŸããã¯ã©ã¹ã¿ãªã³ã°ã®åŸãå顿ã«ã¯å€ããŠããæ«å°Ÿã®ããŒã¿ã®å¹³åå€ãèšç®ããŸããæ«å°Ÿãšããã®ã¯ãä»åã§ãããš25æ¥åã®ã«ãŒãã®ãã¡æ«å°ŸïŒæ¥åã®ããŒã¿ã®ããšã§ãã 现ãã話ã«ãªãã®ã§äžå³ã«ã¯èšèŒããªãã£ãã®ã§ãããä»åã®äºæž¬ã§ã¯PCAãšããåŠçãéããŠããk-meansãå®è¡ããŸãããªãPCAãå¿
èŠããã«ã€ããŠã¯èšäºæ«å°Ÿã®è£è¶³ã«ãŠèšèŒããŠãããŸãã ã¯ã©ã¹ã¿ãªã³ã°ã®å®è¡ ããã§ã¯ãPCA + k-means ã¯ã©ã¹ã¿ãªã³ã°ãè¡ããã¯ã©ã¹ã¿ããšã®å¹³åå€ãèšç®ããŠãããŸãã def curve_clustering (array, curve_len): train = np.stack([vec[ 0 :curve_len] for vec in array]) test = np.stack([vec[curve_len:] for vec in array]) test_len = test.shape[ 1 ] # PCA pca = PCA(n_components=curve_len) pca.fit(train) # å
±åæ£è¡åããåå cov_mtrx = pca.get_covariance() train_pca = np.dot(train, cov_mtrx) # ããšã§å
ã«æ»ããããå
±åæ£è¡åã®éè¡åãæ±ããŠãã cov_mtrx_inverse = np.linalg.inv(cov_mtrx) # k-meansã¯ã©ã¹ã¿ãªã³ã° curve_clst_size = int (np.sqrt(train_pca.shape[ 0 ]/ 2 )) cls = KMeans(n_clusters=curve_clst_size, random_state= 123 ) curve_clst = cls.fit_predict(train_pca) # ã¯ã©ã¹ã¿æ¯ã«ãã«ãŒãã®ãªã¹ããå¹³åã忣ã代衚ãã¯ãã«ãæ±ããŠãã curve_df = pd.DataFrame({ 'curve_clst' : curve_clst , 'train' : [vec for vec in train] , 'train_pca' : [vec for vec in train_pca] }) for i in range (test_len): curve_df[ 'test{}' . format (i)] = [vec[i] for vec in test] print ([col for col in curve_df.columns if 'test' in col]) curve_clst_dict = { cluster : { 'test_means' : [df[col].mean() for col in df.columns if 'test' in col] , 'test_medians' : [df[col].median() for col in df.columns if 'test' in col] , 'test_stds' : [df[col].std() for col in df.columns if 'test' in col] , 'train_cluster_center' : np.dot(cls.cluster_centers_[cluster].flatten(), cov_mtrx_inverse) , 'train_pca_cluster_center' : cls.cluster_centers_[cluster].flatten() , 'train_vectors' : [vec for vec in df[ 'train' ]] , 'train_pca_vectors' : [vec for vec in df[ 'train_pca' ]] } for cluster, df in curve_df.groupby( 'curve_clst' ) } return (curve_clst_dict, cls, pca) curve_clst_dict, cls, pca = curve_clustering(window_sc, TRAIN_SIZE) ããã§ã¯ã¯ã©ã¹ã¿æ°ã curve_clst_size = int (np.sqrt(train_pca.shape[ 0 ]/ 2 )) ãšæ±ºããŠããŸãããçç±ã¯èšäºæ«å°Ÿã®è£è¶³ã«å°ãã ãèšèŒããŠãããŸãã ã¯ã©ã¹ã¿ãªã³ã°ã®çµæã®å¯èŠå ãããããåé¡ã«ãªã£ãŠããããã¯ã©ã¹ã¿æ¯ã®ã«ãŒãããŸãšããŠããããããŠãããŸãã # ã°ã©ããè¡å圢åŒã§è¡šç€ºãã clst_size = len (curve_clst_dict) row_size = int (clst_size/ 3 ) if clst_size% 3 == 0 else int (clst_size/ 3 ) + 1 x_axis = [x for x in range (WINDOW_SIZE - 1 )] fig = plt.figure(figsize=( 19 , 30 )) for key in curve_clst_dict: # ã«ãŒãã®ãªã¹ããåãåºã clst_info = curve_clst_dict[key] raw_curves = clst_info[ 'train_vectors' ] # subplotãšè¡åçªå·ã®èšå® row_n = int (key/ 3 ) col_n = key% 3 ax = plt.subplot2grid((row_size, 3 ), (row_n, col_n)) # ã«ãŒãã®ãããã for raw_curve in raw_curves: ax.plot(raw_curve, color= 'steelblue' , alpha= 0.3 ) # åºéã®ãããã upper_95 = np.hstack([np.repeat(np.nan, TRAIN_SIZE- 1 ), np.array(clst_info[ 'test_means' ]) + 2 *np.array(clst_info[ 'test_stds' ])]) lower_95 = np.hstack([np.repeat(np.nan, TRAIN_SIZE- 1 ), np.array(clst_info[ 'test_means' ]) - 2 *np.array(clst_info[ 'test_stds' ])]) ax.fill_between(x_axis, upper_95, lower_95, facecolor= 'gray' , alpha= 0.4 ) # å¹³åå€ã®ãããã ax.plot( list (np.repeat(np.nan, TRAIN_SIZE- 1 )) + list (clst_info[ 'test_means' ]), color= 'coral' ) ax.set_title( 'curve cluster{}' . format (key)) plt.show() å®è¡çµæã¯äžèšãšãªããŸãã ïŒæ¬åœã¯ã¯ã©ã¹ã¿23ãŸã§ããã®ã§ãããé·ãäžã«çµè«ãå€ãããªãã®ã§ã¯ã©ã¹ã¿8ãŸã§èŒããŠããŸããïŒ éè²ã®ç·ãã«ãŒãã®éãŸãã§ããäžã€ã®ã¯ã©ã¹ã¿ã泚èŠãããšãå€åã®å€§ããã«ãŒããšå°ããã«ãŒããæ··åšãã€ã€ãã倧ãŸããªãã¬ã³ãã¯åäžã§ãããšåãããŸãã ãªã¬ã³ãžã®ç·ãã¯ã©ã¹ã¿ãªã³ã°ã«äœ¿ããªãã£ãããŒã¿ã®å¹³åå€ã§ããã°ã¬ãŒã¯ ïŒå¹³å ± 2 * æšæºåå·®ïŒã®ç¯å²ã衚ããŠããŸãããã忣ã®å€§ããã¯ã©ã¹ã¿ãå€ãå°è±¡ã§ãã 4. cosé¡äŒŒåºŠã§è¿åã¯ã©ã¹ã¿ãæ±ãã ããããã®æé ãäžå³ã䜿ã£ãŠèª¬æããŸããä»åºŠã¯ãæªç¥ããŒã¿ãã©ã®ã¯ã©ã¹ã¿ã«è¿ãããcosé¡äŒŒåºŠãçšããŠæ¢ããŸãã cosé¡äŒŒåºŠãšã¯ã2ã€ã®ãã¯ãã«ïŒããã§ã¯ã«ãŒãã®ããšïŒã®é¡äŒŒåºŠãæž¬ãææšã§ããäžã®å³äžã§ã¯æªç¥ããŒã¿ã®ã«ãŒããšãåã¯ã©ã¹ã¿ã®ä»£è¡šãã¯ãã«ïŒéè²ã®ç¹ç·ïŒãæ¯èŒãé¡äŒŒåºŠãèšç®ããŠããŸããã¯ã©ã¹ã¿1ãšã®é¡äŒŒåºŠãé«ããšå€å®ãããæªç¥ããŒã¿ã®ã«ãŒãã®å
ã«ãã¯ã©ã¹ã¿1ã®å¹³åå€ïŒãªã¬ã³ãžã®ç¹ç·ïŒãåœãŠã¯ããŠäºæž¬å€ãšããŠããŸãã ããã§ã¯å®éã®ããŒã¿ã§å®è¡ããŠãããŸãã æè¿åã®ã¯ã©ã¹ã¿ãèŠã€ãã äžèšã®ã³ãŒãã§ã¯ã2018幎11æä»¥åã®ããŒã¿ãåã³ã¹ã©ã€ãçªã«åå²ããæšæºåããŠããŸããåã¯ã©ã¹ã¿ã®ä»£è¡šãã¯ãã«ãšã®é¡äŒŒåºŠãæ±ãããããåãåºãå¹
ã TRAIN_SIZE ã«ãªã£ãŠããç¹ãåé ãšç°ãªããŸãã # TRAIN_SIZEã§åå² window_data_train = split_window_data(train_close, TRAIN_SIZE) # æšæºå sc = StandardScaler() window_sc_train = sc.fit_transform(window_data_train.T).T 次ã«åãåºããã«ãŒãã®ãã¯ãã«ãšãåã¯ã©ã¹ã¿ã®ä»£è¡šãã¯ãã«ã®é¡äŒŒåºŠãèšç®ãããã£ãšãé¡äŒŒåºŠãé«ãã¯ã©ã¹ã¿ã®çªå·ãè¿ã颿°ãäœããŸãã # cosé¡äŒŒåºŠãèšç®ãã颿° def cos_sim (v1, v2): return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)) # ãã£ãšãé¡äŒŒåºŠã®é«ãã¯ã©ã¹ã¿ã®çªå·ãè¿ã颿° def calculate_neighbor_clst (window_vec, curve_dict): cos_sim_vec = np.array([ cos_sim(window_vec, curve_clst_dict[clst][ 'train_cluster_center' ]) for clst in curve_clst_dict ]) return cos_sim_vec.argmax() æè¿åã¯ã©ã¹ã¿ããå¹³åå€ã®åãåºã ç¶ããŠãæè¿åã¯ã©ã¹ã¿ã®å¹³åå€ãåãåºããŸããåãåºãããã¹ã±ãŒã«ãæ»ããŠäºæž¬å€ãšããŸãã # ãã£ãšãè¿ãã¯ã©ã¹ã¿ã®å¹³åå€ãåãåºã scaled_means = [] for vec in window_sc_train: neighbor_clst = calculate_neighbor_clst(vec, curve_clst_dict) scaled_mean = np.array(curve_clst_dict[neighbor_clst][ 'test_means' ][TARGET_FUTURE - 1 ]) scaled_means.append(scaled_mean) # åãåºããå¹³åå€ãå
ã®ã¹ã±ãŒã«ã«æ»ã scaled_means = np.array(scaled_means) pred_means = sc.inverse_transform(scaled_means) 以äžã§äºæž¬å€ãç®åºãããšãããŸã§ã¯å®äºã§ããæ¬¡ã®ç¯ã§äºæž¬ãã©ããããåœãã£ãŠãã®ããæ€èšŒããŠãããŸãã 5. äºæž¬çµæã®è©äŸ¡ äºæž¬çµæãšå®éã®å€ãããããããŠã¿ãŸãããã act = train_close[WINDOW_SIZE:] pred = pred_means[ 0 :-TARGET_FUTURE- 1 ].flatten().tolist() plt.plot(act, label= 'act' ) plt.plot(pred, label= 'pred' ) plt.legend() éè²ã宿ž¬å€ããªã¬ã³ãžãäºæž¬å€ã§ãããããåœãã£ãŠããããã«èŠããŸãããå®ã¯æ°æ¥åã®ã©ã°ãåã£ããããªäºæž¬ã«ãªã£ãŠããŸããããã§ã¯äºæž¬ã§ãããšèšããŸããã æ ªäŸ¡ã®ãäžæãããããäžèœããããã®äºæž¬ ä»åã¯çŽè¿20æ¥ã®ããŒã¿ãã5æ¥å
ã®ããŒã¿ãäºæž¬ããããšããããŒãã ã£ãã®ã§ã20æ¥ç®ã®æ ªäŸ¡ããïŒæ¥å
ã®æ ªäŸ¡ãäžãã£ãŠããããäžãã£ãŠãããã®å€å®ãããŠã¿ãŸãããã # 20æ¥ç®ã®æ ªäŸ¡ãšïŒæ¥åŸã®å®éã®æ ªäŸ¡ãæ¯ã¹ãäžãã£ãŠãoräžãã£ãŠãã act_updown = [ train_close[i + WINDOW_SIZE] > train_close[i + TRAIN_SIZE] for i in range ( len (train_close) - WINDOW_SIZE) ] # 20æ¥ç®ã®æ ªäŸ¡ãšïŒæ¥åŸã®äºæž¬æ ªäŸ¡ãæ¯ã¹ãäžãã£ãŠãoräžãã£ãŠãã pred_updown = [ pred[i] > train_close[i + TARGET_FUTURE] for i in range ( len (train_close) - WINDOW_SIZE) ] æåã® act_updown ã«ã¯20æ¥ç®ãšæ¯èŒããŠïŒæ¥åŸã®å®éã®æ ªäŸ¡ãäžãã£ãããäžãã£ããã®çåœå€ãæ ŒçŽããŠããŸããæ¬¡ã® pred_updown ã«ã¯ïŒæ¥åŸã®äºæž¬ã®æ ªäŸ¡ãšæ¯èŒããçµæãå
¥ã£ãŠããŸãããã®äºæ³çµæã®æ£ççãèšç®ããŠãããŸãã TF = (np.array(act_updown) == np.array(pred_updown)) sum (TF)/ len (TF) çµæã¯ 51.8% ã§ããïŒã·ã³ãã«ã«æ ªäŸ¡ã®äžäžãäºæ³ããŠãã»ãšãã©åœãã£ãŠãªãã§ããç¬ æ€èšŒããŒã¿ãšäºæž¬å€ã®æ¯èŒ ä»åºŠã¯åé ã®ã»ãã§æ€èšŒçšã«æ®ããŠããã2018幎11æä»¥éã®30æ¥åã®æ ªäŸ¡ãäºæž¬ããŠã¿ãŸãããã 30æ¥åã®äºæž¬ãªã®ã§ãã²ãšã€ãã€äºæž¬å€ãã«ãŒãã«è¿œå ããŠãããªãããæçµçã«ã¯20åã®äºæž¬å€ã䜿ã£ãŠ30æ¥å
ã®æ ªäŸ¡ãäºæž¬ããããšã«ãªããŸãã # ã¹ã©ã€ãçªããäºæž¬å€ãç®åºãã颿° def predict_ (window_vec, target_future): test_sc = StandardScaler() vec_sc = test_sc.fit_transform(window_vec.reshape(TRAIN_SIZE, 1 )).T neighbor_clst = calculate_neighbor_clst(vec_sc, curve_clst_dict) scaled_mean = np.array(curve_clst_dict[neighbor_clst][ 'test_means' ][target_future]).reshape(- 1 , 1 ) return test_sc.inverse_transform(scaled_mean.reshape(- 1 , 1 )) # äºæž¬å€ã远å ããªãããæ¬¡ç¹ã®å€ãäºæž¬ def predict_forward (window_vec, n_forward, target_future): predictions = [] vec_len = window_vec.shape[ 0 ] train_vec = window_vec.copy() for _ in range (n_forward): pred = predict_(train_vec, target_future).flatten() predictions.append(pred[ 0 ]) train_vec = np.append(train_vec[-vec_len + 1 :], pred) return predictions # ãã¹ãããŒã¿ã®é·ãåã®äºæž¬å€ãç®åº test_len = len (test_df) last_window = window_data_train[- 1 ] predictions = predict_forward(last_window, test_len, TARGET_FUTURE- 1 ) ãã®äºæž¬ãéããçµæãšã30æ¥åã®å®æž¬å€ãããããããçµæãäžèšãšãªããŸãã plt.plot(test_df[ 'close' ], label= 'act' ) plt.plot(predictions, label= 'pred' ) plt.legend() éè²ã宿ž¬å€ããªã¬ã³ãžã®ç·ãäºæž¬å€ã§ãã宿ž¬å€ããäºæž¬å€ã¯ãªã ãããªç·ã«ãªã£ãŠããŸãããã¯ãäºæž¬å€ãå¹³åã§ä»£çšããŠããã®ã§ãå€åã®å€§ããæç³»åãæããã®ã¯äžåŸæããã§ããã ãŸãšã æ ªäŸ¡ã䜿ãæç¹ã§äºæ³ããŠã¯ããŸãããããã£ã±ãããŸããããŸããã§ããããã®ææ³ãæããŠããã人ã¯ãããã§çºæ¿ã¬ãŒãã®äºæž¬ãããŸããã£ãïŒããšèšã£ãŠããã®ã§ãäžã«äžã€ã®å¯èœæ§ããã£ãŠæ ªã®äºæ³ãã§ãããããããšæããŸãããçŸå®ã¯å³ããã§ããã ããã®äœ¿ãã©ãããšããŠã¯ãã¯ã©ã¹ã¿æ¯ã«ãŸãšããå¹³åå€ãã€ãŸããã€ãºãçãããã¬ã³ããæ€åºã§ããã®ã§ãäžèšã®ã±ãŒã¹ãªãæå¹ãããããŸããã å±é¢å€åã®æ€ç¥ é·æã§ã¯ãªãçæã®äºæž¬ ä»¶æ°ã®å°ãªãæç³»åããŒã¿ã«å¯ŸããåŸåã®äŒŒãŠããå¥ã®æç³»åããŒã¿ããäºæž¬å€ãç®åº 以äžããç§ã®èšæ¶ãšæ°å°ãªãè³æãé Œãã«åçŸããäºæ³ææ³ã§ããããããèªãŸããã©ãªããããããã®åæç¥ã£ãŠããã©äœ¿ãæ¹éããïŒããªã©ãææãã ããã°äœããã§ãã ææ¥ã¯ãã¶ã€ããŒã®å°å±±ããã§ãïŒã楜ãã¿ã«ïŒ è£è¶³ PCAãšk-meansã®çµã¿åãã PCAãšk-meansãçµã¿åãããããšã§ãã綺éºã«ã¯ã©ã¹ã¿ãªã³ã°ã§ãããšãããã€ã±ãŠãåæå±ã®éã§ã¯ãã䜿ããããã¯ããã¯ã ããã§ãã ç§ã¯æè¿ãŸã§ç¥ããŸããã§ããã PCAãšk-meansã®é¢ä¿ã«ã€ããŠã¯ãäžèšã®è³æãåèã«ãªãããšæããŸãã ã K-means Clustering via Principal Component Analysis ã ã¯ã©ã¹ã¿æ°ã«ã€ã㊠äžèšã¯k-meansãå®è¡ããéšåã®ã³ãŒãã§ãã def curve_clustering (array, curve_len): ~~~ # k-meansã¯ã©ã¹ã¿ãªã³ã° curve_clst_size = int (np.sqrt(train_pca.shape[ 0 ]/ 2 )) ~~~ ããã§ããã£ãšã¯ã©ã¹ã¿æ°ã ïŒãµã³ãã«ãµã€ãº/2ïŒã®å¹³æ¹æ ¹ã§èšå®ããŠããŸãããé©åãªã¯ã©ã¹ã¿æ°ãäžæãªãšãã¯ããã§è¯ãããããšããå
人ã®ç¥æµãªãã ããã§ãã以äžã®ãããšãããæç®ã«ãã©ãçããã®ã§ãããããçè§£ãæ·±ããŠããããšæããŸãã ã How can we choose a "good" K for K-means clustering? ã