ã¯ããã« æ¬èšäºã§ã¯ Python ã©ã€ãã©ãªãKerasããçšããã¬ãã¥ãŒããŒã¿ã®ïŒå€åé¡çšã® ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®äœæã«ã€ããŠãŸãšããŸããKerasã«ã€ããŠã¯ã€ã³ã¿ãŒãããäžã§å€ãã®æ
å ±ãæã«å
¥ããããŸãããæ¬èšäºã§ã¯Kerasã«ããã¢ãã«ã®äœæã«å ããŠããã©ã¡ãŒã¿æé©å ãã¬ãŒã ã¯ãŒã¯ ãOptunaããçšããäžéšãã©ã¡ãŒã¿ã®èªåæé©åã®è©Šã¿ã«ã€ããŠã玹ä»ããŸãã ã¯ããã« Kerasãšã¯ Optunaãšã¯ Kerasã«ãããã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®äœæã®æµã Pythonã®ããŒãžã§ã³ãšå©çšã©ã€ãã©ãª ããŒã¿ã®å
¥æ å®è¡ãã£ã¬ã¯ããªã®æŽå ããŒã¿ã®ååŠç æååã®æŽåœ¢ ããŒã¿ã®èªã¿èŸŒã¿ãšåå² æååã®ãã¯ãã«å Kerasã«ãããã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®å®çŸ© ã¢ãã«äœæã»èšç·Žã»è©äŸ¡å®è¡çšã¯ã©ã¹ã®å®çŸ© Optunaã«ããæé©ãªãã©ã¡ãŒã¿ã®æ¢çŽ¢ æé©ãªãã©ãŒã¡ãŒã¿ã®æ¢çŽ¢ãšãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®äœæã»èšç·Žã®å®æœ äœæãããã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®å©çš çµæãšèå¯ å
šäœã¹ã¯ãªãã Kerasãšã¯ Keras㯠ãªãŒãã³ãœãŒã¹ ã® ãã¥ãŒã©ã«ãããã¯ãŒã¯ /深局åŠç¿ã©ã€ãã©ãªã§ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ãäœæããããã®ã©ã€ãã©ãªã«ã¯Keras以å€ã«ããTensorFlowãPytorchãªã©ããã€ãçš®é¡ããããŸãããKerasã¯ç°¡æœãªèšè¿°ã§ ãã¥ãŒã©ã«ãããã¯ãŒã¯ ãäœæã§ãããšããããŠããŸããå®éã«Kerasã§ã¯åæ°è¡ã§ ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«åšãã® ã¹ã¯ãªãã ãèšè¿°ã§ããŸãã Keraså
¬åŒãµã€ã(æ¥æ¬èª) keras.io Optunaãšã¯ Outunaã¯ãã€ããŒãã©ã¡ãŒã¿èªåæé©å ãã¬ãŒã ã¯ãŒã¯ ã§ããå°éçšèªã䜿ããã«ç°¡åã«èª¬æãããšãOptunaã¯ã人ãèªã調æŽããå¿
èŠããã£ã æ©æ¢°åŠç¿ ã¢ãã«çã®ãã©ã¡ãŒã¿ã®æé©å€ãèªåçã«èŠã€ããŠãããããŒã«ãã§ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã§ã¯é ãå±€ã®ãŠãããæ°ãªã©äžéšã®ãã©ã¡ãŒã¿ã®æé©åã人ãè¡ãããšã«ãªããŸãããOptunaã䜿ããšãããã®ãã©ã¡ãŒã¿ã®æé©åãèªååã§ããŸãã www.preferred.jp ã Kerasã«ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®äœæã®æµã ä»åã¯ä»¥äžã®æµãã§ ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ãäœæããŸãã ãããã Python ã®ããŒãžã§ã³ãšå©çšã©ã€ãã©ãª å©çšãã Python ã®ããŒãžã§ã³ã¯ã Python 3.9.9 ãã§ãã ä»åã® ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«äœæã«éãã以äžã®å€éšã©ã€ãã©ãªãå©çšããŠããŸãã Kerasã¯Tensorflowã®tensorflow.kerasã¢ãžã¥ãŒã«ãéããŠå©çšããŸãã pandas cleantext scikit-learn tensorflow optuna ããŒã¿ã®å
¥æ ä»åã¯è±èªã®ã¬ãã¥ãŒæçš¿ã«å¯Ÿããå
容ãè¯å®çãåŠå®çããäºæž¬ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®äœæã詊ã¿ãŸãããã®ããã«å¿
èŠãªããŒã¿ãKaggleããå
¥æããããšã«ããŸãã Kaggleã«ã€ããŠè©³ããã¯å
¬åŒãµã€ãã玹ä»èšäºãåç
§ããŠäžããã www.kaggle.com ai-kenkyujo.com ä»åã¯ããã¡ãã®Trip Advisor Hotel Reviewsãšããè±èªã®ããã«ã®ã¬ãã¥ãŒæçš¿ã®ããŒã¿ã䜿ããŸãã www.kaggle.com ãã®ããŒã¿ã¯è¡æ¯ã«ã¬ãã¥ãŒæ¬æãšã¬ãŒãã£ã³ã°(è¯å®çãåŠå®çãã®ææšã«ãªããŸã)ãã»ããã«ãªã£ãŠãã圢åŒã®ãããã¢ãã«ã®èšç·ŽçšãšããŠäœ¿ãããããšæããŸãã ãããã *Alam, M. H., Ryu, W.-J., Lee, S., 2016. Joint multi-grain topic sentiment: modeling semantic aspects for online reviews. Information Sciences 339, 206â223. â»ãã¬ãã¥ãŒæ¬æãèŠãŠã¿ããšææ³çã«ïŒãªè±æãçµæ§ãããŸãããä»åã¯ãã®ãŸãŸäœ¿ãããšã«ããŸãã(å
¬éçšã«å¿åååŠçããã圱é¿ãªã®ãããããŸããã) å®è¡ ãã£ã¬ã¯ã ãªã®æŽå äºã以äžã®ãããªæ§é ã§å®è¡ ãã£ã¬ã¯ã ãªãæŽåããŠãããŸããå®è¡çšã®pyãã¡ã€ã«ãããŠã³ããŒãããã¬ãã¥ãŒã® csv ãã¡ã€ã«ãTensorboardã«è¡šç€ºããããŒã¿ã®ä¿åå
ãšãªããã©ã«ããé
眮ããŸãã ããã ããŒã¿ã®ååŠç ã¬ãã¥ãŒããŒã¿ã¯ãã®ãŸãŸäœ¿ãããæååã®æŽåœ¢ãããŒã¿ã®åå²ãæååã®ãã¯ãã«åãšãã£ãååŠçãè¡ããŸãããŸãã¯ãã®ããã®é¢æ°ãããã€ãå®çŸ©ããŸãã æååã®æŽåœ¢ ã¬ãã¥ãŒæ¬æã¯è±èªã®ãããããã»ã©è€éãªåŠçã¯å¿
èŠãªããšæããŸããä»åã¯ã Python ã®ååŠçã©ã€ãã©ãªã®clean-textãšçµã¿èŸŒã¿é¢æ°ã®ã¿ã§ååŠçã宿œããŸãã Clean-text pypi.org â» ã€ã³ã¹ããŒã«æã«ã¯ãã€ãã³ããã®ãã®ãæå®ããŠãã ããããcleantextããšããå¥ã®ã©ã€ãã©ãªãããã®ã§æ³šæããŠãã ããã ãã pip install clean-text â»ã Python ã® ã¹ã¯ãªãã ãæ²èŒããéã«ã¯ããªãã¹ã説æã®ã³ã¡ã³ããå
¥ãã颿°ã«ã¯ Google ã¹ã¿ã€ã«ã®docstringã©ã€ã¯ãªèª¬æãã€ããããã«ããŸãã def normalize_doc (text, no_digits= False , no_numbers= False , to_ascii= False ): """èšç·ŽããŒã¿æ£èŠå èšç·ŽçšããŒã¿(ããã¹ã)ãæ£èŠåããŸãã Args: text (str): æ£èŠåãããããã¹ã no_digits (bool, optional): æ¡æ°ãç¶æãããŸãŸå
šãŠã®æ°åã0ã«å€æãããã©ãã(123ã¯000ã«ã5678ã¯0000ã«å€æãããŸã) no_numbers (bool, optional): æ¡æ°ãæ®ããæ°åãå
šãŠæå®ããæåå(ä»åã¯0ã«èšå®ããŠããŸã)ã«å€æãããã©ãã(123ã¯0ã«5678ã0ã«å€æãããŸã) to_ascii (bool, optional): éã¢ã¹ããŒæåãã¢ã¹ããŒæåã«å€æãããã©ãã (æ¥æ¬èªã¯éã¢ã¹ããŒæåãªãããæ¥æ¬èªãå«ãããã¹ãã«ã¯Falseãèšå®) Returns: str: æ£èŠåæžããã¹ã """ # ããã¹ãã®æåãšæåŸã®äœåãªã¹ããŒã¹ãé€å»ããŸãã text = text.strip() # æ£èŠåçšã©ã€ãã©ãªã䜿ã£ãŠããŒã¿ãæ£èŠåããŸããããã§ã¯unicode errorã®é€å»ãšã¢ã«ãã¡ãããã®å°æååã®ã¿ãè¡ã£ãŠããŸãã text = cleantext.clean(text, no_digits=no_digits, to_ascii=to_ascii, no_numbers=no_numbers, replace_with_number= "0" ) return text ããŒã¿ã®èªã¿èŸŒã¿ãšåå² CSV ãã¡ã€ã«ãèªã¿èŸŒã¿ãã¬ãŒãã£ã³ã°ã®ã€ãçŽããšããŒã¿æ°ã®åŠç¿çšãšè©äŸ¡çšãžã®åå²ãè¡ããŸãã ã¬ãŒãã£ã³ã°ã®ã€ãçŽãã§ã¯ãä»åã®äºæž¬ããã¬ãã¥ãŒãããžãã£ãããã¬ãã£ãããã®2å€äºæž¬(2å€åé¡)ãšãããããã¬ãŒãã£ã³ã°1ãš2ãã0ã(ãã¬ãã£ã)ãã¬ãŒãã£ã³ã°ïŒãšïŒã¯ã1ã(ããžãã£ã)ã«ã€ãçŽããŸããã©ã¡ããšãåããããªã¬ãŒãã£ã³ã°ïŒã¯é€å€ããããšã«ããŸãã ãŸããããŒã¿ãåŠç¿çšãšã¢ãã«ã®è©äŸ¡çšã«åå²ããåŠçãè¡ããŸãããã®ãšããããžãã£ãã¬ãã¥ãŒãšãã¬ãã£ãã¬ãã¥ãŒããããã§åŠç¿çšãšè©äŸ¡çšã«åå²ãããã®åŸã«åŠç¿çšã®ããžãã£ãã¬ãã¥ãŒãšãã¬ãã£ãã¬ãã¥ãŒå士ãè©äŸ¡çšã®ããžãã£ãã¬ãã¥ãŒãšãã¬ãã£ãã¬ãã¥ãŒå士ãçµåããŸãã (å
šäœã®8å²ãåŠç¿çšãšããå Žåããã¹ãŠã®ãã¬ãã£ãã¬ãã¥ãŒãåŠç¿çšãšãªããè©äŸ¡çšã«ã¯ããžãã£ãã¬ãã¥ãŒããå«ãŸããªããªãããšãé²ãããã§ãã2çªç®ã®å³ã§ç€ºãåŠçãè¡ããŸãã) ãããã def load_data (path): """èšç·ŽããŒã¿ãæ£è§£ã©ãã«ã®å å·¥ãšèšç·Žçšãè©äŸ¡çšãžã®åå² CSVãã¡ã€ã«ããèšç·ŽããŒã¿ãšæ£è§£ã©ãã«ãåãåºããæ£è§£ã©ãã«ã®2å€ãžã®å€æãš ããŒã¿ã®åŠç¿çšãšè©äŸ¡çšãžã®åå²ãè¡ããŸãã èšç·ŽçšããŒã¿ã®ããŒã¿ãã¬ãŒã ãšè©äŸ¡çšããŒã¿ã®ããŒã¿ãã¬ãŒã ãè¿ããŸãã Args: path (str): ã¬ãã¥ãŒæ¬æãšã¬ãŒãã£ã³ã°ã®CSVãã¡ã€ã«ã®ãã¹ :Returns: pandas.DataFrame: åŠç¿ããŒã¿ã®ããŒã¿ãã¬ãŒã pandas.DataFrame: è©äŸ¡çšã©ãã«ã®ããŒã¿ãã¬ãŒã """ # ã¬ãã¥ãŒæ¬æãšã¬ãŒãã£ã³ã°ã®CSVãã¡ã€ã«ãããŒã¿ãã¬ãŒã 圢åŒã§èªã¿èŸŒã¿ãŸãã review_df = pd.read_csv(path, header= 0 ) # ããŒã¿ãã¬ãŒã ã®åãåç
§ãããšãã«äŸ¿å©ãªã®ã§åã©ãã«ãååŸããŠãããŸãã columns = review_df.columns # ã¬ãã¥ãŒããããžãã£ãããããã¬ãã£ããã®2å€ã§äºæž¬ãããããã¬ãŒãã£ã³ã°1-2ã¯0(ãã¬ãã£ã)ã«ã4-5ã¯1(ããžãã£ã)ã«å€æããŸãã # ä»åäžéã®3ã¯ç¡èŠããŸãã(3ã¯ããžãã£ããšããã¬ãã£ããšããšããå Žåããããããªãã) mapping = { 1 : 0 , 2 : 0 , 3 : 3 , 4 : 1 , 5 : 1 } review_df[columns[ 1 ]] = review_df[columns[ 1 ]].map(mapping) # ãã¬ãã£ãã¬ãã¥ãŒã®ã¿ã§ãã£ã«ã¿ãŒããããŸãã negative_review_df = review_df[review_df[columns[ 1 ]] == 0 ] # ããžãã£ãã¬ãã¥ãŒã®ã¿ã§ãã£ã«ã¿ãŒããããŸãã positive_review_df = review_df[review_df[columns[ 1 ]] == 1 ] # ãã¬ãã£ãã¬ãã¥ãŒãããžãã£ãã¬ãã¥ãŒãããããåŠç¿çšãšè©äŸ¡çšã«åå²ããŸããä»åã¯åŠç¿çš8å²ãè©äŸ¡çš2å²ã«åå²ããŸãã # åå²ã«ã¯sklearnã®train_test_splitãå©çšããŸãã # ã¬ãã¥ãŒæ¬æã®ååŠçãåæã«è¡ãããã«ãã£ããããŒã¿ããªã¹ã圢åŒã«å€ããŠããŸãã xn = [normalize_doc(review_body) for review_body in negative_review_df[columns[ 0 ]]] yn = list (negative_review_df[columns[ 1 ]]) xp = [normalize_doc(review_body) for review_body in positive_review_df[columns[ 0 ]]] yp = list (positive_review_df[columns[ 1 ]]) xn_train, xn_test, yn_train, yn_test = train_test_split( xn, yn, test_size= 0.2 , random_state= 42 , ) xp_train, xp_test, yp_train, yp_test = train_test_split( xp, yp, test_size= 0.2 , random_state= 42 , ) # ãã¬ãã£ãã¬ãã¥ãŒãšããžãã£ãã¬ãã¥ãŒããŒã¿ãçµåããåŠç¿çšããŒã¿ã®ããŒã¿ãã¬ãŒã ãšè©äŸ¡çšããŒã¿ã®ããŒã¿ãã¬ãŒã ãäœæããŸãã x_train = xn_train + xp_train x_test = xn_test + xp_test y_train = yn_train + yp_train y_test = yn_test + yp_test # åŠç¿çšããŒã¿ã®ããŒã¿ãã¬ãŒã train = list () for x, y in zip (x_train, y_train): train.append([x, y]) train_df = pd.DataFrame(train, columns=[ "Review" , "Rating" ]) # è©äŸ¡çšããŒã¿ã®ããŒã¿ãã¬ãŒã test = list () for x, y in zip (x_test, y_test): test.append([x, y]) test_df = pd.DataFrame(test, columns=[ "Review" , "Rating" ]) # 颿°ã®æ»ãå€ãšããŠããŒã¿ãã¬ãŒã ãã»ããããéã«ã.sample(frac =1).reset_index(drop=True)ãã§ããŒã¿ãã·ã£ããã«ãã€ã³ããã¯ã¹ããµãçŽããŸãã return train_df.sample(frac= 1 ).reset_index(drop= True ), test_df.sample(frac= 1 ).reset_index(drop= True ) æååã®ãã¯ãã«å ã¢ãã«ã®èšç·Žã®éãããã¹ãããŒã¿ããã®ãŸãŸå
¥åãšããããšãã§ããŸããã ãã¯ãã«åãšããããã¹ããæ°å€åã«å€æããäœæ¥ãå¿
èŠã«ãªããŸããããã§ä»åã¯ãTF-IDFããšããããã¹ãå
ã®åèªã®éèŠæ§ãåæ ããæ°å€åã«ãããã¯ãã«åãè¡ã£ãŠã¿ãŸãã ãŸããä»åã¯ã ã¹ãããã¯ãŒã ããšããé »åºŠåèªã®ãã£ã«ã¿ã䜿ããªã代ããã«ãSklearnã®TfidfVectorizerã®ãã©ã¡ãŒã¿ã®ãmax_dfããèšå®ããéèŠã§ã¯ãªãåèªã®é€å»ã詊ã¿ãŸãã Tf-idfã«ã€ã㊠atmarkit.itmedia.co.jp Sklearnã®å
¬åŒããã¥ã¡ã³ã scikit-learn.org def get_vectorizer (corpus_x_train, corpus_x_test): """ããã¹ãã®TF-IDFã«ãããã¯ãã«å ã¬ãã¥ãŒæ¬æããŒã¿ãtfidfã«ãã£ãŠãã¯ãã«åããŸãããã¯ãã©ã€ã¶ãŒ(ãã¯ãã«ãžã®å€æåš)ã¯ããŒã¿ã®ãã¡ ã¢ãã«ã®èšç·Žã«äœ¿ãããŒã¿ã®ã¿ã§èšç·ŽããŸããè©äŸ¡çšããŒã¿ã¯åŠç¿ããŒã¿ã§èšç·Žãããã¯ãã©ã€ã¶ãŒã䜿ããã¯ãã«åããŸãã Args: corpus_x_train (iterator): ããŒã¿ã®ãã¡èšç·Žçšã«åå²ããéšå corpus_x_test (iterator): ããŒã¿ã®ãã¡è©äŸ¡çšã«åå²ããéšå Returns: sklearn.feature_extraction.text.TfidfVectorizer: èšç·ŽåŸã®TF-IDFãã¯ãã©ã€ã¶ãŒ ndarray: ãã¯ãã«åã®å¯Ÿè±¡ãšãªã£ãèªåœã®ãªã¹ã (ndarray of str objects) ndarray: ãã¯ãã«åããèšç·ŽçšããŒã¿ ndarray: ãã¯ãã«åããè©äŸ¡çšããŒã¿ ãã¯ãã©ã€ã¶ãŒããã¯ãã«åã®å¯Ÿè±¡ãšãªã£ãèªåœã®ãªã¹ãããã¯ãã«åããèšç·ŽçšããŒã¿ããã¯ãã«åããè©äŸ¡çšããŒã¿ """ # ãã¯ãã©ã€ã¶ãŒãäœæããŸããmax_dfã®å€ãèšå®ãããšæå®ããå€ã®å²å以äžã®ææžã«å«ãŸããèªåœã¯ãã¯ãã«åã®å¯Ÿè±¡ãšãªããªããªããŸãã # max_dfã®å€ã0.3ã«èšå®ããŠããŸãããããŒã¿ã®å®æ
ã«åãããŠèª¿æŽãå¿
èŠã§ã vectorizer = TfidfVectorizer(max_df= 0.3 ) # èšç·ŽçšããŒã¿ã䜿ã£ãŠãã¯ãã©ã€ã¶ãŒãèšç·Žããåæã«èšç·ŽçšããŒã¿ã®ãã¯ãã«åãè¡ããŸãã vec_corpus_x_train = vectorizer.fit_transform(corpus_x_train) # èšç·Žãããã¯ãã©ã€ã¶ãŒã§è©äŸ¡çšããŒã¿ã®ãã¯ãã«åãè¡ããŸãã vec_corpus_x_test = vectorizer.transform(corpus_x_test) return vectorizer, vectorizer.get_feature_names_out(), vec_corpus_x_train.toarray(), vec_corpus_x_test.toarray() Kerasã«ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®å®çŸ© ããŒã¿ã®ååŠççšé¢æ°ã®å®çŸ©ãçµãã£ãã®ã§ãKerasã䜿ã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ãå®çŸ©ããŠãããŸãã ä»åã¯æ¬¡ã®ãã㪠ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ãå®çŸ©ããŠãããŸãã ããã â»ãäžéå±€ã2å±€ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã¯æ·±å±€åŠç¿ã¢ãã«ãšãã¿ãªããŸãããæ¬èšäºã§ã¯ã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ããšåŒã¶ããšã«ããŸãã ããã¹ã(ä»åã¯ã¬ãã¥ãŒæ¬æ)ã®ãã¯ãã«ããŒã¿ãå
¥åãšããå
¥åå±€âäžéå±€1âäžéå±€2âåºåå±€ãšåŠçãè¡ã£ãŠãããŸãã ä»åã¯Kerasã®Functionalã¢ãã«ã䜿ããã®ã¢ãã«ãå®çŸ©ããŸããKerasã§ã¯ãã¢ãã«ã®å®çŸ©ã«ãFunctional API ããšãSequentialã¢ãã«ãã䜿ããŸãããè€æ°å
¥åãè€æ°åºåããããããªè€æ°ãªã¢ãã«ãå®çŸ©ããéã«ã¯Funcitional API ã䜿ããŸãã(ä»åã¯ãã¯ãã«1ã€ãå
¥åãšããã®ã§è€æ°å
¥åã§ã¯ãããŸããããå°æ¥çãªçºå±ã®å¯èœæ§ãèããŠãFunctional API ãéžãã§ããŸãã) Kerasã¯Tensorflowã®tensorflow.kerasã¢ãžã¥ãŒã«ããã€ã³ããŒãããŠäœ¿ããŸãã keras.io keras.io Kerasã§ã¢ãã«ãå®çŸ©ããéã¯ãkeras.layers.Inputãkeras.layers.Denseã䜿ãåå±€ã®ãŠãããæ°ãæŽ»æ§å颿°ãå®çŸ©ããŠãããŸãã äžã®å³ã§ã¯çç¥ããŠããŸãããäžéå±€1ãšäžéå±€ïŒã®éãäžéå±€2ãšåºåå±€ã®éã«Dropoutå±€(keras.layers.Dropout)ã远å ã éåŠç¿ 察çãããŸãã(äžã®å³ã§ã¯çç¥) deepage.net æåŸã«keras.Modelã®compileã¡ãœããã䜿ããã¢ãã«ã®æå€±é¢æ°ã ãªããã£ã ã€ã¶ãæå®ããŸãã def create_model (n_vocab, unit): """Kerasã«ãããã¥ãŒã©ã«ãããã¯ãŒã¯ã®å®çŸ© Kerasã®Funcitional APIã䜿ããã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ãå®çŸ©ããŸãã Args: n_vocab (int): å
¥åãšããŠæž¡ãããŒã¿ã®æ¬¡å
æ°ã§ããå
¥åå±€ã®ãŠãããæ°ãšãªããŸãã(ãã¯ãã©ã€ã¶ãŒããååŸããèªåœã®ãªã¹ãå
ã®èŠçŽ æ°ãšããŸãã) unit (int): äžéå±€ã®ãŠãããæ°ã§ããä»»æã®æ°ãèšå®ã§ããŸãããä»åã¯Optunaã«ããæé©ãªå€(æŽæ°)ãèªåã§èšå®ããŸãã Returns: tensorflow.keras.Model: ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«(ãªããžã§ã¯ã) """ # å
¥åå±€ã远å ããŸãããŠãããæ°ã¯vocabãšåãã§ãã input_ = keras.layers.Input(shape=(n_vocab,)) # äžéå±€(å
šçµåå±€)ãšããããã¢ãŠãå±€ã远å ããŸãããŠãããæ°ã¯åŒæ°unitã§æå®ããŸãã x = keras.layers.Dense(unit, activation= "relu" )(input_) x = keras.layers.Dropout( 0.8 )(x) # 2å±€ç®ã®äžéå±€(å
šçµåå±€)ãšããããã¢ãŠãå±€ã远å ããŸãããŠãããæ°ã¯åŒæ°unitã§æå®ããŸãã x = keras.layers.Dense(unit, activation= "relu" )(x) x = keras.layers.Dropout( 0.5 )(x) # åºåå±€ã远å ããŸãã ãœããããã¯ã¹é¢æ°ã䜿ã2å€åé¡ã®ãããŠãããæ°ã¯2ã§ãã output = keras.layers.Dense( 2 , activation= "softmax" )(x) # ã¢ãã«(ãªããžã§ã¯ã)ãäœæããŸãã model = keras.Model(inputs= input , outputs=output) # ãã©ã¡ãŒã¿ã®æŽæ°ãæå€±é¢æ°ãè©äŸ¡é¢æ°ã«äœã䜿ãããèšå®ããŸãã倿Žããå¿
èŠã¯ãªãããšæããŸãã model.compile( optimizer= "adam" , loss= "sparse_categorical_crossentropy" , metrics=[ "accuracy" ] ) # ã¢ãã«ã®æŠèŠãåºåããŸãã print (model.summary()) return model ã¢ãã«äœæã»èšç·Žã»è©äŸ¡å®è¡çšã¯ã©ã¹ã®å®çŸ© Kerasã«ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®å®çŸ©ãã§ããã®ã§ã次ã«ãã¢ãã«(ã®ãªããžã§ã¯ã)ãäœæãããã®ã¢ãã«ã®èšç·Žãè¡ãã¯ã©ã¹ããäœæããŸãã ãããŸã§ã«äœæããååŠç颿°ã䜿ããåŠç¿ããŒã¿ãæŽãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ãã§ãã®äœæãèšç·Žããè©äŸ¡ãŸã§ãè¡ãã¯ã©ã¹ãšããŠã¿ãŸãã class NnModel : """ãã¥ãŒã©ã«ãããã¯ãŒã¯äœæã»èšç·Žã»è©äŸ¡çšã¯ã©ã¹ ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ãªããžã§ã¯ãã®äœæãèšç·Žãè©äŸ¡ãè¡ãããã®ã¯ã©ã¹ã§ãã Attributes: vec_x_train (ndarray): ãã¯ãã«åæžã®èšç·ŽçšããŒã¿ x_test (pandas.Series): ãã¯ãã«ååã®è©äŸ¡çšããŒã¿ vec_x_test (ndarray): ãã¯ãã«åæžã®è©äŸ¡çšããŒã¿ y_train (pandas.Series): ã¢ãã«ã®èšç·Žæã«äœ¿ãæ£è§£ã©ãã« y_test (pandas.Series): ã¢ãã«ã®è©äŸ¡æã«äœ¿ãæ£è§£ã©ãã« model (tensorflow.keras.Model): model_fitå®è¡æã«äœæããããã¥ãŒã©ã«ãããã¯ãŒã¯ãªããžã§ã¯ã """ def __init__ (self, path): # CSVãã¡ã€ã«ããèšç·ŽããŒã¿ãšæ£è§£ããŒã¿ãååŸããŸãã train_df, test_df = load_data(path) columns = train_df.columns x_train = train_df[columns[ 0 ]] self.x_test = test_df[columns[ 0 ]] self.y_train = train_df[columns[ 1 ]] self.y_test = test_df[columns[ 1 ]] # èšç·ŽããŒã¿ããã¯ãã«åããŸãã self.vectorizer, self.vocab, self.vec_x_train, self.vec_x_test = get_vectorizer(x_train, self.x_test) # åŸã§èšç·ŽåŸã®ã¢ãã«ãå©çšããéã«å¿
èŠã«ãªãã®ã§ããã¯ãã©ã€ã¶ãŒã®ãªããžã§ã¯ããpickleãã¡ã€ã«ã«ä¿åããŠãããŸãã with open ( "my_vectorizer.pickle" , "wb" ) as f: pickle.dump(self.vectorizer, f) def model_fit (self, unit, logdir, validation_split= 0.2 , epochs= 20 , batch_size= 32 ): """ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã« (tensorflow.keras.Model)ã®äœæãšçšæããèšç·ŽããŒã¿ã§ã®èšç·Ž ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ãªããžã§ã¯ããäœæããçšæããèšç·ŽããŒã¿ã§èšç·ŽããŸãã Optunaãšã®é£æºã®ããããã¥ãŒã©ã«ãããã¯ãŒã¯ãªããžã§ã¯ãã¯ãã®ã¡ãœããã§äœæããŸãã Args: unit (int): äžéå±€ã®ãŠãããæ°ã§ããä»åã¯optunaã«ãã£ãŠæé©ãªå€ãèšå®ããŸãã logdir (str): èšç·Žæã®åŠç¿ãã°ãä¿åãããã©ã«ããæå®ããŸãã(tensorboardã䜿ãå Žåã«ãã®ãã©ã«ãå
ã®ãã°ãåç
§ããŸãã) validation_split (float): èšç·Žæ(keras.Modelã®fitã¡ãœããå®è¡æ)ã®åãšããã¯ã§æ€èšŒçšã«äœ¿ãèšç·ŽããŒã¿ã®å²åãæå®ããŸãã epochs (int): èšç·ŽããŒã¿ãç¹°ãè¿ããŠåŠç¿ãããåæ°ãæå®ããŸãã batch_size (int): äœä»¶ã®èšç·ŽããŒã¿æ¯ã«ãã©ã¡ãŒã¿ã®æŽæ°ãè¡ãããæå®ããŸãã Returns: float: ã¢ãã«ã®è©äŸ¡çšããŒã¿ã§ã®æå€±å€ """ # ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«(ãªããžã§ã¯ã)ãäœæããŸãã self.model = create_model( len (self.vocab), unit) # åŠç¿ã®é²è¡ç¶æ³ã®å¯èŠåã粟床ãåäžããªããªã£ãéã®åŠç¿ã®æ©æçµäºãè¡ã颿°ãã³ãŒã«ããã¯ã«ãŸãšããŸãã tensorboard = keras.callbacks.TensorBoard(log_dir=logdir) early_stopping = keras.callbacks.EarlyStopping(monitor= 'val_loss' , patience= 3 ) model_name = "my_neural_model.h5" modelCheckpoint = keras.callbacks.ModelCheckpoint( filepath=model_name, monitor= 'val_loss' , verbose= 1 , save_best_only= True , save_weights_only= False , mode= 'min' , period= 1 ) callbacks = [tensorboard, early_stopping, modelCheckpoint] # ã¢ãã«ã®èšç·Žã宿œããŸãã self.model.fit( self.vec_x_train, self.y_train, validation_split=validation_split, epochs=epochs, batch_size=batch_size, callbacks=callbacks # äžã§å®çŸ©ããã³ãŒã«ããã¯é¢æ°ã®ãªã¹ããæå®ããŸãã ) # my_neural_model.h5ã«ä¿åãããŠãã(åãšããã¯ã®ãã¡æã粟床ã®è¯ãã£ã)ã¢ãã«ãèªã¿èŸŒãã§ãã¹ãçšããŒã¿ã§ç²ŸåºŠãç®åºããŸãã model = keras.models.load_model(model_name) pred = model.evaluate(self.vec_x_test, self.y_test) # ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®é ãå±€ã®æé©ãŠãããæ°ã®æšå®ã®ãããä»åã¯ãã¹ãããŒã¿ã§ã®æå€±å€ãåŠç¿ã¡ãœããã®æ»ãå€ãšããŠãããŸãã return pred[ 0 ] def model_predict (self): """ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®æ§èœè©äŸ¡ train_test_splitã§åå²ããããŒã¿ã®ãã¡è©äŸ¡çšã®ããŒã¿ã䜿ãã model_fitã§èšç·Žããã¢ãã«ã®æ§èœãè©äŸ¡ããŸãã Returns: list: ã¢ãã«ã®äºæž¬çµæã®ãªã¹ã(äºæž¬ã©ãã«ã®ãªã¹ã) """ # (keras.Modelã®)predictã¡ãœããã«è©äŸ¡çšã®ããŒã¿ãæž¡ããŸãã y_pred = self.model.predict(self.vec_x_test) # äºæž¬çµæã®ãã¡ãã1ã(ãã)ããïŒã(ãªã)ã®ãã¡äºæž¬æ°å€ãé«ãã£ãæ¹ããªã¹ãã«è¿œå ããŸãã y_pred = [p.argmax() for p in y_pred] # sklearnã®ã¹ã³ã¢ç®åºçšã®å颿°ã«äºæž¬ã©ãã«ãšæ£è§£ã©ãã«ãæž¡ãã¢ãã«ã®æ§èœãè©äŸ¡ããŸãã print ( "result" ,f "accuracy: {accuracy_score(self.y_test, y_pred)}" , f "precision: {precision_score(self.y_test, y_pred)}" , f "recall: {recall_score(self.y_test, y_pred)}" , sep= " \r\n " ) return y_pred Optunaã«ããæé©ãªãã©ã¡ãŒã¿ã®æ¢çŽ¢ Kerasã䜿ã£ã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®äœæããè©äŸ¡ãŸã§ãè¡ãã¯ã©ã¹ãå®çŸ©ã§ããã®ã§ãå®è¡ããŠçµæãåŸãããšãã§ããã®ã§ãããä»åã¯äžéå±€ã®æé©ãªãŠãããæ°ããOptunaãã䜿ã£ãŠèªåæé©åããŠã¿ãŸãã Optunaã䜿ãéã«ã¯ãæé©åããããã©ã¡ãŒã¿ãšãã®ããŒã¿åãããå€ãæé©ãã©ããã倿ããããã®ææšã«äœã䜿ãããæå®ããŸããä»åã¯: æé©åããããã©ã¡ãŒã¿ãšãã®ããŒã¿å: äžéå±€ã®ãŠãããæ°ãæŽæ°(int)å æé©ãã©ããã®ææš: æå®ãããã©ã¡ãŒã¿ã§ã®ã¢ãã«èšç·ŽåŸã®æå€±å€ ãšããæ¡ä»¶ã§ãã©ã¡ãŒã¿ã®èªåæé©åã宿œããŸãã keras.io keras.io def objective (trial): """Optunaã§ãã©ã¡ãŒã¿æšå®ãè¡ãéã®åŠçå
容 Optunaã§ãã©ã¡ãŒã¿æšå®ãè¡ãããã®é¢æ°ã§ãã ç®çã®ãã©ã¡ãŒã¿ã倿Žããéã®ç²ŸåºŠã®ææšãšãªãæ°å€ãæ»ãå€ãšãªãããã«ããŠããå¿
èŠããããŸãã (å€ãæ¹åããã°ããè¯ããã©ãŒã¡ãŒã¿å€ãšã¿ãªããŸãã) Args: trial: Optunaã®Studyãªããžã§ã¯ããèšå®ããŸãã :Returns: float: Optunaããã©ã¡ãŒã¿ãèšå®ããäœæããã¢ãã«ã®æå€±å€(ç²ŸåºŠææš) """ # ä»åã¯ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®äžéå±€ã®ãŠãããæ°ã®èªåæšå®ã詊ã¿ãŸãã # æå®ããæ°å€(ä»åã¯2-30)ã®éã§æã粟床ãé«ããªãæ°å€ãæé©ãªãŠãããæ°ãšã¿ãªããŸãã # æšå®ããæ°å€ã¯åŸã§åç
§ããããã«"unit"ãšæå®ããŠãããŸãã unit = trial.suggest_int( "unit" , 2 , 30 ) loss = nn_model.model_fit(unit, r"logs" , epochs= 100 ) return loss æé©ãªãã©ãŒã¡ãŒã¿ã®æ¢çŽ¢ãš ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®äœæã»èšç·Žã®å®æœ ãããŸã§å®çŸ©ããŠãã颿°ãšã¯ã©ã¹ãOptunaã䜿ããæé©ãªãŠãããæ°ã®æ¢çŽ¢ãšæé©ãªãŠãããæ°ãèšå®ããã¢ãã«ã®äœæãè¡ããŸãã åŠçã®æµãã¯æ¬¡ã®ããã«ãªããŸãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«äœæçšãªããžã§ã¯ãã®äœæ(åŠç¿/è©äŸ¡çšããŒã¿ã®ååŠç) Optunaã®Studyãªããžã§ã¯ããäœæãæé©ãªãŠãããæ°ãæ¢çŽ¢ æ¢çŽ¢å®äºåŸã«Studyãªããžã§ã¯ããããŠãããæ°ã®æ°å€ãååŸ ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«äœæçšãªããžã§ã¯ã(keras.Model)ã®ã¢ãã«äœæ/èšç·Žã¡ãœãã(fit)ã«æé©ãªãŠãããæ°ãæž¡ããŠã¢ãã«ãäœæ/èšç·Ž è©äŸ¡çšããŒã¿ã§ã¢ãã«ãè©äŸ¡ # ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«äœæçšãªããžã§ã¯ããäœæããŸãã target_data = r"tripadvisor_hotel_reviews.csv" nn_model = NnModel(target_data) def main (): """å®è¡çšé¢æ° ãããŸã§ã«äœæããŠãã颿°ãšã¯ã©ã¹ã䜿ãæé©ãªäžéå±€ãŠãããæ°ã®æšå®ãã ã¢ãã«ã®å®çŸ©ãèšç·Žãè©äŸ¡ãŸã§ãå®è¡ããŸãã Returns: None """ # oputunaã§æé©ãªãŠãããæ°ãèŠã€ããŸããæåŸã«Best unitãšããŠåºåãããŸãã # directionã¯æå€±é¢æ°ã®å Žåã¯minimizeãæå®ããŸãã(æ£è§£çãç²ŸåºŠææšãšããå Žåã«ã¯maxizeãæå®ããŸãã) study = optuna.create_study(direction= "minimize" ) # æé©ãªãŠãããæ°ãèŠã€ããããã«äœåºŠè©Šè¡ããããæå®ããèªåæšå®ãå®è¡ããŸãã study.optimize(objective, n_trials= 10 ) # æé©ãªãŠãããæ°ã¯ãã®å€æ°ãããbest_params["unit"]ããšãããšååŸã§ããŸãããã£ã¬ã¯ããªåã®åç
§ãšåãã§ãã best_params = study.best_params print (f "Best unit: {best_params}" ) # æé©ãªæ°å€ãäžéå±€ã®ãŠãããæ°ã«æå®ããã¢ãã«ã®å®çŸ©ãšèšç·Žãè©äŸ¡ãè¡ããŸãã nn_model = NnModel(target_data) nn_model.model_fit(best_params[ "unit" ], r"logs" , epochs= 100 ) nn_model.model_predict() if __name__ == "__main__" : main() ä»åäœæããã¢ãã«ã®è©äŸ¡çµæã¯ä»¥äžã®ããã«ãªããŸããã ãããã Accuracy: 0.9555 ãããã Precision: 0.9609 ãããã Recall: 0.9861 ããªãè¯ãæ°å€ã§ãããTensorboardã§ã¢ãã«æå€±ã®ã°ã©ãã確èªããŠã¿ããšã2ãšããã¯ä»¥éæžå°ãèŠãããŸããã察çã¯ããŠããŸããã éåŠç¿ ãããŠããŸã£ãããã§ãã (æ¿ãéã®ç·ãåŠç¿ããŒã¿ã§ã®æå€±å€ãæ°Žè²ã®ç·ãè©äŸ¡çšããŒã¿ã§ã®æå€±å€) ãããã (Tensorboardã§ã¯åŠç¿ããŒã¿ã§ã¢ãã«ãç¹°ãè¿ãèšç·Žããäžã§ãã©ã®ããã«æ§èœãå€åããŠãã£ããã確èªããããšãã§ããŸãã) (model_fitã¡ãœããã®tensorboard = keras.callbacks.TensorBoard(log_dir=logdir)ã®è¡ã§tensorboardã®èšå®ãè¡ã£ãŠããŸãã) www.tensorflow.org deepage.net äœæãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®å©çš æåŸã«äœæããã¢ãã«ã䜿ã£ãŠãæªç¥ã®ããŒã¿ã§ã®äºæž¬ãè¡ãããã®é¢æ°ãäœæããŠã¿ãŸãã ã¢ãã«äœææã«äœ¿ã£ã ãã¯ãã© ã€ã¶ãŒãšä¿åãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ãèªã¿èŸŒã¿ããããã«äºæž¬ãè¡ãããããŒã¿(ããã¹ã)ãæž¡ããŠäºæž¬çµæã®ç¢ºçãåºåããŸãã ä¿åããã¢ãã«ã¯ãtensorflow.keras.models.load_modelã§èªã¿èŸŒã¿ãŸãã def model_load_predict (x, model_h5, vec_pickle): """ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ãå©çšããæªç¥ããŒã¿ã«å¯Ÿããäºæž¬çšé¢æ° äœæã»ä¿åãããã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ãå©çšããŠãæªç¥ããŒã¿ã®äºæž¬ãè¡ããŸãã Args: x (str): ããã¹ãããŒã¿(ã¬ãã¥ãŒæ¬æãšåã圢åŒ) model_h5 (str): äœæãããã¥ãŒã©ã«ãããã¯ãŒã¯ã¢ãã«ã®h5ãã¡ã€ã«ã®ãã¹ vec_pickle (str): ä¿åãããã¯ãã©ã€ã¶ãŒã®pickleãã¡ã€ã«ã®ãã¹ Returns: int: äºæž¬ã©ãã«ã®æŽæ°å€(å
¥åããããã¹ãããã¬ãã£ããšäºæž¬ããå Žåã¯0,ãããžãã£ããšäºæž¬ããå Žåã¯1) """ # ã¢ãã«ãšãã¯ãã©ã€ã¶ãŒãèªã¿èŸŒã¿ãŸãã model = keras.models.load_model(model_h5) with open (vec_pickle, 'rb' ) as f: vectorizer = pickle.load(f) # å
¥åããŒã¿ã®æ£èŠåãšãã¯ãã«åãè¡ããŸãã x = normalize_doc(x) vec_x = vectorizer.transform([x]).toarray() # å
¥åããŒã¿ã«å¯ŸããŠäºæž¬ãè¡ããçµæãåºåããŸãã pred = model.predict(vec_x) print ( "== Result ==" ) print ( "Positive" ) if pred[ 0 ][ 1 ] > pred[ 0 ][ 0 ] else print ( "Negative" ) print (f "Positive: {pred[0][1]}, Negative: {pred[0][0]}" ) return pred.argmax() if __name__ == "__main__" : x = input ( ">>>" ) model_h5 = "my_neural_model.h5" vec_pickle = "my_vectorizer.pickle" res = model_load_predict(x, model_h5, vec_pickle) print ( "äºæž¬ã©ãã«: " , res) 颿°ãå®è¡ãã>>>ããšè¡šç€ºããããããã¬ãã£ããããžãã£ãããäºæž¬ãããããã¹ããå
¥åããŸããããã¹ãå
¥ååŸã«ãenterããæŒããšäºæž¬çµæãåºåãããŸãã(äºæž¬çµæã®åã«èŠåã衚瀺ãããããšããããŸãããä»åã¯ç¡èŠããŸãã) ãããã ãããã çµæãšèå¯ KerasãšOptunaã䜿ããå®éã«äºæž¬ãè¡ãããšãã§ãã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ãäœæããããšãã§ããŸããã ãã®ã¢ãã«ã¯è©äŸ¡çµæã®æ°å€ãèŠããšæªããªãããã«èŠããã®ã§ãããæªç¥ã®ã¬ãã¥ãŒããŒã¿ã«å¯Ÿããäºæž¬æ§èœãé«ããšã¯èšããŸãããäžç®ã§ããžãã£ããšãããå
容ã®ã¬ãã¥ãŒã«å¯ŸããŠã99ïŒ
ãã¬ãã£ããšããäºæž¬ãããããšããããŸããã ä»åã®åçç¹ãšããŠã¯ã ããŒã¿ã®è³ªãè¯ããªãã£ãã ããâãä»åã¯ææ³çã«æªããè±æããã®ãŸãŸäœ¿ããŸããããããè¯ããªãã£ãã®ãããããŸããã ããâãéåžžã«é·ãã¬ãã¥ãŒæ¬æãæã€ã¬ã³ãŒããå«ãŸããŠããŸãããããã®æã®ã¬ã³ãŒãã¯ãããç¹ããã£ãããããããâŠããšããæµãã§ããžãã£ããªåŽé¢ãšãã¬ãã£ããªåŽé¢ãæã£ãŠããå¯èœæ§ããããã©ã¡ããã«åé¡ããã«ã¯å®¹æã§ã¯ãªãã®ãããããŸããã ããŒã¿ãè¶³ããªãã£ãã ããâã2äžã¬ã³ãŒãã§ã¯è¶³ããªãã£ãã®ãããããŸããã ãã¯ãã«åã®æ¹æ³ãè¯ããªãã£ãã ããâ TF-IDFãããåèªã®æå³ãåæ ãããšãããåæ£è¡šçŸã®æ¹ãããã£ãã®ãããããŸããã å¥ã®ãã€ããŒãã©ã¡ãŒã¿ãOptunaã§æé©åãã¹ãã ã£ãã ããâ ãŠãããæ°ä»¥å€ã«ãåŠç¿çãããããµã€ãºãæé©ãªå€ãOptunaã§èšå®ãããšããã£ãã®ãããããŸããã ã¢ãã«ã® ã¢ãŒããã¯ã㣠ãé©åã§ãªãã£ãã ããâ ä»åã®ãã㪠ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ããããªã«ã¬ã³ã ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«ã®æ¹ãããã¹ãåé¡ã«ã¯é©ããŠããã®ããç¥ããŸããã ãšãã£ãããšãèããããŸãããã®ã¢ãã«ãæ¹åããéãæ°ããªã¢ãã«ãäœæããéã«ã¯ãäžèšã®åçç¹ãèžãŸããå¿
èŠããããšæããŠããŸãã ç¹ã«ããŒã¿ã«é¢ããŠã¯ã倧éã®ããŒã¿ãå¿
èŠã«ãªãããããã詊è¡ã§ããŸããããªãã£ãéã«ãç°¡åã«ä»£æ¿ã®ããŒã¿ãçšæã§ãããšã¯éããŸããã èªåã§ããŒã¿ãçšæããéã«ã¯ãæåãã質ã®é«ãããŒã¿ãæãããã«ããŒã¿åéäœæ¥ãè¡ãå¿
èŠããããšæããŸãã å
šäœ ã¹ã¯ãªãã æåŸã«ãä»åã® ãã¥ãŒã©ã«ãããã¯ãŒã¯ ã¢ãã«äœæã®è©Šã¿ã«é¢ãã ã¹ã¯ãªãã å
šäœããŸãšããŠãããŸãã ããã¹ãããŒã¿ã®åé¡ã§ããã°ãå°ãã®ç·šéã§ãããããªããŒã¿ãæ±ãããšæããŸãããã²ããèªèº«ã®ããŒã¿ã§äºæž¬ã¢ãã«ãäœæããŠã¿ãŠãã ããã # coding: utf-8 import pandas as pd import pickle import cleantext import optuna from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, precision_score, recall_score from tensorflow import keras def normalize_doc (text, no_digits= False , no_numbers= False , to_ascii= False ): text = text.strip() text = cleantext.clean(text, no_digits=no_digits, to_ascii=to_ascii, no_numbers=no_numbers, replace_with_number= "0" ) return text def load_data (path): review_df = pd.read_csv(path, header= 0 ) columns = review_df.columns mapping = { 1 : 0 , 2 : 0 , 3 : 3 , 4 : 1 , 5 : 1 } review_df[columns[ 1 ]] = review_df[columns[ 1 ]].map(mapping) negative_review_df = review_df[review_df[columns[ 1 ]] == 0 ] positive_review_df = review_df[review_df[columns[ 1 ]] == 1 ] xn = [normalize_doc(review_body) for review_body in negative_review_df[columns[ 0 ]]] yn = list (negative_review_df[columns[ 1 ]]) xp = [normalize_doc(review_body) for review_body in positive_review_df[columns[ 0 ]]] yp = list (positive_review_df[columns[ 1 ]]) xn_train, xn_test, yn_train, yn_test = train_test_split( xn, yn, test_size= 0.2 , random_state= 42 , ) xp_train, xp_test, yp_train, yp_test = train_test_split( xp, yp, test_size= 0.2 , random_state= 42 , ) x_train = xn_train + xp_train x_test = xn_test + xp_test y_train = yn_train + yp_train y_test = yn_test + yp_test train = list () for x, y in zip (x_train, y_train): train.append([x, y]) train_df = pd.DataFrame(train, columns=[ "Review" , "Rating" ]) test = list () for x, y in zip (x_test, y_test): test.append([x, y]) test_df = pd.DataFrame(test, columns=[ "Review" , "Rating" ]) return train_df.sample(frac= 1 ).reset_index(drop= True ), test_df.sample(frac= 1 ).reset_index(drop= True ) def get_vectorizer (corpus_x_train, corpus_x_test): vectorizer = TfidfVectorizer(max_df= 0.3 ) vec_corpus_x_train = vectorizer.fit_transform(corpus_x_train) vec_corpus_x_test = vectorizer.transform(corpus_x_test) return vectorizer, vectorizer.get_feature_names_out(), vec_corpus_x_train.toarray(), vec_corpus_x_test.toarray() def create_model (n_vocab, unit): input_ = keras.layers.Input(shape=(n_vocab,)) x = keras.layers.Dense(unit, activation= "relu" )(input_) x = keras.layers.Dropout( 0.8 )(x) x = keras.layers.Dense(unit, activation= "relu" )(x) x = keras.layers.Dropout( 0.5 )(x) output = keras.layers.Dense( 2 , activation= "softmax" )(x) model = keras.Model(inputs= input , outputs=output) model.compile( optimizer= "adam" , loss= "sparse_categorical_crossentropy" , metrics=[ "accuracy" ] ) print (model.summary()) return model class NnModel : def __init__ (self, path): train_df, test_df = load_data(path) columns = train_df.columns x_train = train_df[columns[ 0 ]] self.x_test = test_df[columns[ 0 ]] self.y_train = train_df[columns[ 1 ]] self.y_test = test_df[columns[ 1 ]] self.vectorizer, self.vocab, self.vec_x_train, self.vec_x_test = get_vectorizer(x_train, self.x_test) with open ( "my_vectorizer.pickle" , "wb" ) as f: pickle.dump(self.vectorizer, f) def model_fit (self, unit, logdir, validation_split= 0.2 , epochs= 20 , batch_size= 32 ): self.model = create_model( len (self.vocab), unit) tensorboard = keras.callbacks.TensorBoard(log_dir=logdir) early_stopping = keras.callbacks.EarlyStopping(monitor= 'val_loss' , patience= 3 ) model_name = "my_neural_model.h5" modelCheckpoint = keras.callbacks.ModelCheckpoint( filepath=model_name, monitor= 'val_loss' , verbose= 1 , save_best_only= True , save_weights_only= False , mode= 'min' , period= 1 ) callbacks = [tensorboard, early_stopping, modelCheckpoint] self.model.fit( self.vec_x_train, self.y_train, validation_split=validation_split, epochs=epochs, batch_size=batch_size, callbacks=callbacks ) model = keras.models.load_model(model_name) pred = model.evaluate(self.vec_x_test, self.y_test) return pred[ 0 ] def model_predict (self): y_pred = self.model.predict(self.vec_x_test) y_pred = [p.argmax() for p in y_pred] print ( "result" , f "accuracy: {accuracy_score(self.y_test, y_pred)}" , f "precision: {precision_score(self.y_test, y_pred)}" , f "recall: {recall_score(self.y_test, y_pred)}" , sep= " \r\n " ) def objective (trial): unit = trial.suggest_int( "unit" , 2 , 30 ) loss = nn_model.model_fit(unit, r"logs" , epochs= 100 ) return loss target_data = r"tripadvisor_hotel_reviews.csv" nn_model = NnModel(target_data) def main (): study = optuna.create_study(direction= "minimize" ) study.optimize(objective, n_trials= 10 ) best_params = study.best_params print (f "Best unit: {best_params}" ) nn_model = NnModel(target_data) nn_model.model_fit(best_params[ "unit" ], r"logs" , epochs= 100 ) nn_model.model_predict() def model_load_predict (x, model_h5, vec_pickle): model = keras.models.load_model(model_h5) with open (vec_pickle, 'rb' ) as f: vectorizer = pickle.load(f) x = normalize_doc(x) vec_x = vectorizer.transform([x]).toarray() pred = model.predict(vec_x) print ( "== Result ==" ) print ( "Positive" ) if pred[ 0 ][ 1 ] > pred[ 0 ][ 0 ] else print ( "Negative" ) print (f "Positive: {pred[0][1]}, Negative: {pred[0][0]}" ) return pred.argmax() if __name__ == "__main__" : main() x = input ( ">>>" ) model_h5 = "my_neural_model.h5" vec_pickle = "my_vectorizer.pickle" res = model_load_predict(x, model_h5, vec_pickle) print (res) ãšã³ãžã㢠äžéæ¡çš ãµã€ã ã©ã¯ ã¹ã§ã¯ããšã³ãžãã¢ã»ãã¶ã€ããŒã® äžéæ¡çš ãç©æ¥µçã«è¡ã£ãŠãããŸãïŒ ãèå³ãããŸãããæ¯éã確èªããé¡ãããŸãã https://career-recruit.rakus.co.jp/career_engineer/ ã«ãžã¥ã¢ã«é¢è«ãç³èŸŒã¿ãã©ãŒã ã©ã®è·çš®ã«å¿åããã°è¯ããããããªããšããæ¹ã¯ãã«ãžã¥ã¢ã«é¢è«ãéæè¡ã£ãŠãããŸãã 以äžãã©ãŒã ãããç³èŸŒã¿ãã ããã rakus.hubspotpagebuilder.com ã©ã¯ ã¹Developersç»é²ãã©ãŒã https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ ã€ãã³ãæ
å ± äŒç€Ÿã®é°å²æ°ãç¥ãããæ¹ã¯ãæ¯é±éå¬ããŠããã€ãã³ãã«ãåå ãã ããïŒ âTECH PLAY techplay.jp âconnpass rakus.connpass.com