テキスト分類プロセス(一)テキスト分類の大まかな手順+データ抽出+データ前処理---卒業論文の記念


テキスト分類は大体私によって4種類に分けられ、リンクは以下の通りである:テキスト分類プロセス(一)テキスト分類の大まかな手順+データ前処理------卒業論文の記念テキスト分類(二)テキストデータ数値化、量子化、次元ダウンテキスト分類(三)–処理済みデータに対してKNN、Naive Bayes、SVM分類方法テキスト分類(四)–分類の良し悪しの評価
コードセクション:
Github
本文は主にテキスト分類の前のいくつかのステップを紹介し、データ取得+データ洗浄次のモジュールテキスト分類(二)テキストデータの数値化を行い、量子化会にテキストデータから数値データへの移行を説明し始め、テキストデータを数値データに変換し、変換後の特徴を抽出し、次元を下げ、テキスト分類器に入力して訓練、テスト、評価を行う.
テキスト分類の基本手順:
1.データ取得
方法:ウェブページの爬虫類、他の人のコードを使うか、自分でコードを書く(GitHubで必要なものがあるかどうかを探します)
2.データ洗浄
方法:
  • は、重複したコメントを削除します.データのキャプチャがよければ、このステップを実行しなくてもいいですが、コメントやコメントがないように、一般的にはやらなければなりません.
  • 上記で得られた空の文字列
  • を除去する.
  • 手動タグデータのカテゴリで、正クラスは1、負クラスは-1
  • である.
  • その他の表情記号(表情記号、いくつかの一般的な句読点、特殊な文字を含む)を除去し、正規表現を使用してWを一致させることができます(私は当初ネット上で一つ一つ探して、削除しました.
  • 前のステップで説明した記号が1つのコメントにしかない場合、それをすべて除去すると、空の文字列がいくつか得られ、2番目のステップのように、得られた空の文字列が除去されます.
  • 無効語を削除します(CSDNで無効語を検索し、テキストtxtドキュメントにコピーして貼り付けます).同様に、無効語のみの文字列が除去されると、空の文字列が除去されます.非アクティブ語を除去する文字列間にスペースを使用して接続し、counterVectorizerとTfidfVectorizerを使用してテキストデータを数値データに変換します.注意:初期のテキストデータをすべて1つのリストに入れ、タグテキストの正負クラスも対応するインデックスに従って1つのリストに対応して格納します.特殊文字や無効語を除去して空の文字列を得るたびに、テキストが保存されていたリストcommentsの関連要素も削除し、それに対応するclassも削除します.ここではどのindexの下のデータが削除されたのかを必ず覚えておき、このIndexに対応するclassも削除します.

  • 3.テキストデータ---->数値ベクトル
    4.分類分け方法を使用します.
    機械学習関連:KNN,Naive Bayes,SVM,AdaBoost,決定木,論理回帰,ニューラルネットワーク,深さ学習.私が主に使っているのは前の3つで、いろいろな方法の間で比較します.簡単に比較的に良いアルゴリズムの紹介の関連文章を貼ります:機械学習(二)分類アルゴリズムの詳細解分類アルゴリズムはクラスタリングアルゴリズムと分類アルゴリズムの総括を総括します
    5.評価
    方法:主にaccuracy,precision,recall,f 1-scoreを用いて評価した.
    各ステップの具体的な方法+コード:
    1.データ取得
    最初は自分で静探-Python 3ネット爬虫開発実戦教程というサイトについて、ホームページ爬虫類を勉強しました.ホームページの原理に触れたばかりなので、多くのパラメータが読めませんでした.ある種の強迫症の存在は、すべてのものをすべてマスターしたいと思って、彼の教程に従って一歩一歩コードをたたいて、メモを取って、このようにして私に進歩を感じさせないで、しかも勉強しなければならないものが多すぎて、時間が迫って、重点をつかむ感じがありません.このチュートリアルをしばらく置いて、大体何を話しているのかを理解してから、的確な勉強が必要です.最後にrequests,beautifulsoup,xpath,css,pymysql,jsonなどの関連知識を学び,これ以上見続けなかった.
    前のステップの途中でネットユーザーの提案を受けてscrapyのフレームワークとxpath、cssを学び、scrapyの中国語ネット実験サイトのすべての這い出すことができるものを這い出し、上で学んだ知識に基づいてscrapyを利用して豆弁の映画評論を這い出す.やっても1週間足らずで、京東の店のコメントを取りに行けるようになったような気がします(今考えてみると、当時はどうしてそんなに無理だったのでしょうか).はい、考えがあればやります.xpathで学んだ知識を使って京東のコメントを取りに行きます.F 12を利用して見た内容はソースコードを見て見た内容とは違います.前者からWebページに表示されるすべての要素を見ることができますが、後者では簡単なjavascript関数とjson文字列しか見えません.その時、私はとても悩んでいました.どうしてこんなことになったのですか.何度も试してみたが、やはりそうだったのか、人に闻いてもよく分からないので、简単に京东が取った反爬虫机构と見なした.
    时间が本当にきついため、データの取得の仕事はずっと进展していないで、そこでネットユーザーの提案を受け入れて直接GIthubの上で関连するコードを検索して、美団の評論を見つけてコードを登って、修正して、店の評論だけを取得して、その他はまったく気にしないで、このようにデータと相応のIndexをcsvファイルの中に保存します.データ取得の仕事は一時的にここまでで終わると思っていました.
    参考にして修正したコードは以下の通りです.
    parse_restaurant_id.py
    # -*- coding: utf-8 -*-
    # __author__ = "zok"  [email protected]
    # Date: 2019-04-17  Python: 3.7
    """
               ,        
      GitHub   :https://github.com/wkunzhi/SpiderCrackDemo/tree/master/MeiTuan
    -------
         ,    id  
            ,    ,  getId    Id
    """
    import requests
    import json
    import re
    import csv
    #   :     ,       ,     ,       id
    class ParseId(object):
        #      
        def __init__(self):
            headers = {
                'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
            }
            self.urls = self.getUrl()
            self.headers = headers
        #       
        def getUrl(self):
            urls = []
            for i in range(1,60):
                urls.append(('https://yt.meituan.com/meishi/c17/pn'+'%s'+"/")%(i))
            return urls    
        def getId(self):
            id_list = []
            k = 1
            for v in self.urls:
                html = requests.get(v,headers = self.headers)
                #       ,    id  
                re_info = re.compile(r'\"poiId\":(\d{4,})')
                id = re_info.findall(html.text)#                   
                #    writerows      csv   
                for v in id:
                    id_list.append((k,v))
                    k+=1
            #    ID   CSV   
            with open(r'D:\lagua\study\coding\pythonPractice\meituanComment\poId.csv','w+',newline="") as f:
                writer = csv.writer(f)          
                writer.writerows(id_list)        
            temp_id = []
            for il in id_list:
                temp_id.append(il[1])
            return temp_id
    

    parse_id_comments.py
    # -*- coding: utf-8 -*-
    # __author__ = "zok"  [email protected]
    # Date: 2019-04-17  Python: 3.7
    """
               ,        
      GitHub   :https://github.com/wkunzhi/SpiderCrackDemo/tree/master/MeiTuan
    -------
      :
            
       :        10   
    """
    import requests
    import json
    import time
    import csv
    import sys
    #                    ,           
    from urllib import parse
    
    sys.path.append(r'D:\lagua\study\coding\pythonPractice\meituanComment\meituanComment\spiders\parse_restaurant_id.py')
    from parse_restaurant_id import ParseId
    #      ,        
    class ParseComments(object):
        def __init__(self, shop_id):
            self.shop_id = shop_id#        ,        shop_id
            self.get_data()#         
            self.coms_ = self.get_data()
       
        #     ---        
        def get_data(self):
            url_code = self.get_originUrl() #      url
            #   ssl     ,  https     ,    http https,      http    
            url = 'http://www.meituan.com/meishi/api/poi/getMerchantComment?'
            params = {  #         
                'platform': '1',
                'partner': '126',
                'originUrl': url_code, #             url
                'riskLevel': '1',
                'optimusCode': '1',
                'id': self.shop_id,  #         id
                'offset': '0',
                'pageSize': '10',
                'sortType': '1',
            }
            #      ,     
            headers = {
                'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
            }
            response = requests.get(url=url, params=params, headers=headers) #   requests  ,      ,      
            data = response.text #           
            self.parse(data)  #      parse    
            return self.parse(data)
    
        ##          url
        def get_originUrl(self): #          url----          
            """    
            """
            needParse = ('http://www.meituan.com/meishi/' + '%s'+ '/')%self.shop_id
            return parse.quote_plus(needParse)
            # quote_plus         URL    -----       url
    
        #              ,           
        def parse(self, data):
            """    
            """
            data_dict = json.loads(data) # Json       json   --->json    
            print('parse is running....')   
            try:
                coms = [] #        ,       10  
                for item in data_dict.get('data').get('comments'): #         data  ,data    comments                
                    coms.append(item.get('comment'))                          
            except:
                print('Error!!!!!!!!!!!!!')
                print('%s'%self.shop_id)
            return coms #                ,                   
            
        @staticmethod # python         ,       
        #      ,        
        def parse_time(timeStamp): #      ,  ---
            """13      
            """
            time_stamp = float(int(timeStamp) / 1000)
            time_array = time.localtime(time_stamp)
            return time.strftime("%Y-%m-%d %H:%M:%S", time_array)
    
    #               ,         ,          
    #   ParseId    (),          ,       ,,           ,    
    ids = ParseId().getId()
    
    #     ---     csv   
    special_shops = []
    comments_ = []#        coms
    for shop_id in ids:
        pc = ParseComments(shop_id)
        special_shops.append(pc)
        for v in pc.coms_:# coms        ,   parse       ,              ,           
            comments_.append(v)
    
    """
           :
                           index,      comments   csv   
    """
    #          csv   ,    utf-8,       
    with open(r'D:\lagua\study\coding\pythonPractice\MT_test.csv', 'w+', encoding='utf-8',newline='') as f:
        writer = csv.writer(f)
        to_be_write = []
        index_= list(range(len(comments_))) #    
        for v1,v2 in zip(index_,comments_):#        
            to_be_write.append([v1,v2]) #       [[1,'a'],[2,'b'],[3,'c']]     ,   writerows  csv   
        writer.writerows(to_be_write)#####            ---       ,         
    
    

    2.データ洗浄
    私が最初に紹介したのとはあまり違いません.私がどんな試みをしたか話しましょう.私が始めたのは、ネット上でどのようにデータの前処理を行うかを探して、自分が取得したテキストと比較して、削除する必要があるものを見て、機械が認識できないものはすべて削除します.これでテキストは基本的にきれいになります.
    文字列を対応するテキストコメントに対応させるには、いくつかの方法を試みました.最初はjsonでデータを格納し,コメントのテキストをキーとし,1,−1をキー値valueとする.辞書をjson形式のデータに変換する方法を学習しました.最後に、いくつかの辞書とjsonに関する知識を勉強しました.この過程で、私は突然これらがそんなに複雑ではないことを思い出しました.リストを使って要素を対応すればいいと思っています.私はリストについてよく知っています.
    最初のデータは、処理するたびに対応するcsvファイルからデータを読み出し、処理が終わった後、csvファイルに戻します.効率については言及しないで、私も効率の高低を評価することができないため、コードが特に肥大化していると感じて、私はこの方法を1人のネットユーザーと交流した後にこのようによくないことを発見して、csvはただ1つのデータを格納する1つのファイルで、データは最初はcsvの中から取得することができて、最後に私たちが処理した最終的なデータをcsvファイルの中に格納して、このように比較的に良くて、さもなくば毎回アクセスが面倒です.
    へへへ、私は彼の言うとおりにして、データ処理の過程ですべてのデータをリストに保存します.ここで注意しなければならないのは、最初は私のデータ量が大きすぎて、数百kあって、リストは耐えられないと思っていましたが、実は全然心配しなくてもいいです.リストはいいですね.彼の腹量は大きくて、思う存分入れます.
    ここで私はまたいくつかのテキスト処理のいくつかのプログラミング技術を学びました:すべてのデータ処理の関数を1つのフィルタに包装して、処理するデータをプロセッサに入力して、処理したデータを出力して、それからこのデータを次のフィルタに入力します.石英砂フィルターのような感じがします.
    リスト1---->フィルタ1---->リスト2---->フィルタ2-------->リストn
    リスト1
    フィルタ1
    リスト2
    フィルタ2
    ...
    以上のフィルタを1つのチェーン({フィルタ1,フィルタ2,...フィルタn})にカプセル化し,初期データを入力し,最後に得られる出力を戻せばよい.これはいわゆる包装で、ははは、外は私の中で何をしたのか分からないで、特に神秘的で、このようにひそかにデータを処理して、私がどんなに神秘的で、どんなにすごいのはははは!
    その後、資料を見るとsklearnには、開始したテキストデータを前処理し、数値ベクトルに変換し、分類器に入れて訓練し、評価指標を得るモジュールがあることが分かった.これがsklearnの下のpipelineモジュールです.
    具体的には、sklearnのPipelineメカニズムsklearn学習ノート3——pipeline私も簡単に書きます:簡単な例を挙げて、KNNを使って分類します
    from sklearn.preprocessing import StandardScaler#      
    from sklearn.decomposition import PCA 
    from sklearn.pipeline import Pipeline#    
    from sklearn.neighbors import KNeighborsClassifier
    
    from last_process_2 import noStopWord_comments,noStopWord_class#                  
    import re
    from sklearn.feature_extraction.text import TfidfVectorizer,CountVectorizer#      
    from sklearn.model_selection import train_test_split#               
    from sklearn import preprocessing#       
    #             ---          ,          “         ”      ,    tfidfVectorizer          
    def get_split(x):
        temp = [v for v in re.split(' ',x) if v is not '']
        return temp
    def joinData(data_to_join):#          
        temp = [' '.join(x) for x in data_to_join]
        return temp    
    corpus = joinData([get_split(v) for v in noStopWord_comments]) #         
    tfidf = TfidfVectorizer()#     ,    
    retfidf = tfidf.fit_transform(corpus) #   +  
    input_data_matrix = retfidf.toarray()#     
    x_train,x_test,y_train,y_test=train_test_split(input_data_matrix,noStopWord_class,test_size=0.2,random_state=400)#       
    
    pipe_knn = Pipeline([('sc',StandardScaler()),('PCA',PCA(n_components=200)),('clf',KNeighborsClassifier())])
    pipe_knn.fit(x_train,y_train)#   +transform  
    
    print(pipe_knn.score(x_test,y_test))#         ,   
    # 0.8073770491803278
    

    ステップ1処理コード:final_process_1.py
    """
    1、  ,        
    2、  tag【】【】
    3、      ''
            ,      
    ————————————————————
    """
    import csv
    import re
    #               
    
    class InitialProcess(object):
        path_initial = r'D:\lagua\study\coding\pythonPractice\DataProcess\MT.csv' #            
        path_meituan = r'D:\lagua\study\coding\pythonPractice\DataProcess\MeiTuan.csv'#           index  
        #   
        def noRepeat(self,x):
            uni = []
            for v in x:
                if v not in uni:
                    uni.append(v)
            return uni
        #           
        def noTags(self,x):
            def f_replace(x):
                temp =  x.replace('【  】','').replace('【  】','').replace('【  】','').replace('【  】','').replace('
    '
    ,'').strip() return temp return [f_replace(v) for v in x] # def noVocant(self,x): temp = [v for v in x if v is not ''] return temp # def getData(self,path): seg_all = [] with open(path,'r',encoding='utf-8') as f: reader = csv.reader(f) for line in reader: seg_all.append(line[1]) print(" : csv ") return self.noRepeat(seg_all) def get_index(self,x): temp = [i for i,v in enumerate(x) if v==''] return temp # csv def writeCSV(self,path2,data): with open(path2,'w',encoding='utf-8',newline='') as f: writer = csv.writer(f) for k,v in enumerate(data): writer.writerow([k,v]) def do_thisMethod(self): data = self.getData(self.path_initial)# , data_noTag = self.noTags(data)# data_noVocant = self.noVocant(data_noTag) # self.writeCSV(self.path_meituan,data_noVocant) # , , IniPro = InitialProcess()# IniPro.do_thisMethod()#

    無効な単語を削除します.最初に、インターネットから取得したいくつかの無効語をtxtドキュメントに直接コピーして貼り付けました.無効語を除去するには,まず文書中の無効語を読み出し,これらの漢字語記号を削除する.ここでは、符号化に関する問題に直面します.私たちの一般的な漢字ストレージはASNIフォーマットです.pythonで読み取るには、データをunicodeフォーマットに変換する必要があります.
    具体的には、私たちが保存し始めたtxtテキストをtxtファイルとして保存します.この場合、関連ページに選択符号化されたフォーマットがあり、自分でunicodeフォーマットを選択すればいいので、このファイルの無効語を読み取ることができます.
    テキストを読み込むときにもう一つ注意しなければならないことがあります.
    def stopwordslist(): #     
        with open(path_stop,'r',encoding='utf-8', errors='ignore') as f:
            stopwords = [line.strip() for line in f.readlines()]
        return stopwords
    

    エラーを無視するためにerrors='ignore'パラメータを追加し、読み取り関数を続行します.ここで符号化の問題に遭遇した:Pythonでtxtテキストを読み取ると「『gbk』codec can』t decode byte 0 xbf in position 2:illegal multibyte sequence」という解決策が現れる
    ステップ2:無効な文字を除去+単語コードを無効にする:final_process_2.py
    """
      :       
    1、      +    ,      comments class_    
    2、             
    3、           ,     ,            ' '      
    4、                   ,              
    """
    import csv
    # import sys
    import jieba
    import re
    # import importlib
    path_meituan = r'D:\lagua\study\coding\pythonPractice\DataProcess\MeiTuan.csv'
    path_class = r'D:\lagua\study\coding\pythonPractice\DataProcess\class_.csv' #   
    path_stop = r'D:\lagua\study\coding\pythonPractice\DataProcess\stopWords_3.txt' #    
    path_neg = r'D:\lagua\study\coding\pythonPractice\DataProcess
    eg_newMeiTuan.txt'
    path_posi = r'D:\lagua\study\coding\pythonPractice\DataProcess\posi_newMeiTuan.txt' # def get_class(): class_ = [] with open(path_class,'r',encoding='utf-8',errors='ignore',newline='') as f: reader = csv.reader(f) for line in reader: temp = line[0].replace('
    '
    ,'').strip() class_.append(int(temp)) return class_ # -- def getData(path): # seg_all = [] with open(path,'r',encoding='utf-8') as f: reader = csv.reader(f) for line in reader: seg_all.append(line[1]) # csv index, return seg_all def get_index(x): # Index temp = [i for i,v in enumerate(x) if v==''] return temp # index --- comments def delete_comments_accord_index(x,index): # comments to_be_delete = [v for i,v in enumerate(x) if i in index] for i in to_be_delete: x.remove(i) return x # index , class # class 1,-1 comments def delete_class_accord_index(class_,index): # class temp = [] for i,v in enumerate(class_): if i not in index: temp.append(v) return temp # def splitOther(data_split): """ params: data_split: return: : index + index --- """ def re_split(desstr): temp = ''.join(re.split(r'\W',desstr)) return temp temp = [re_split(desstr) for desstr in data_split] # index index = get_index(temp) return (index,temp) # index def indexProcess(func,last_comments,last_class): """ params: func: last_comments: last_class: return: + class """ noFunc_index = func(last_comments)[0] noFunc_comments = func(last_comments)[1] final_noFunc = delete_comments_accord_index(noFunc_comments,noFunc_index) class_noFunc = delete_class_accord_index(last_class,noFunc_index) return (final_noFunc,class_noFunc) def splitStop(data_split): # # txt , def stopwordslist(): # with open(path_stop,'r',encoding='utf-8', errors='ignore') as f: stopwords = [line.strip() for line in f.readlines()] return stopwords stop_words_list = stopwordslist() stopwords = {}.fromkeys(stop_words_list) # def cutStopWords(word): segs = jieba.cut(word, cut_all=False) final = '' for seg in segs: if seg not in stopwords: final += seg final +=' ' return final splitStopData = [cutStopWords(v) for v in data_split] index = [i for i,v in enumerate(splitStopData) if v==''] return (index,splitStopData) # , def wirteClass(path_neg,path_posi,comments,class_): # file_neg = open(path_neg,'w',encoding = 'utf-8',errors='ignore') file_posi = open(path_posi,'w',encoding = 'utf-8',errors = 'ignore') for i,v in enumerate(noStopWord_comments): # try...except try: if noStopWord_class[i]==-1: file_neg.write(v+'
    '
    ) else: file_posi.write(v+'
    '
    ) except: print('Error') file_neg.close() file_posi.close() class_ = get_class() # comments = getData(path_meituan) # # #----------------------------------------------------------- noOtherWord_comments,noOtherWord_class= indexProcess(splitOther,comments,class_) # index comments class noStopWord_comments,noStopWord_class=indexProcess(splitStop,noOtherWord_comments,noOtherWord_class) #----------------------------------------------------------- wirteClass(path_neg,path_posi,noStopWord_comments,noStopWord_class)

    はい、前の2つのステップのすべてのものはここに記録されています.まだ多くのステップの詳細が表示されているので、ここで書くと多すぎます.次の章のテキスト分類(2)のテキストデータを数値化し、量子化して書きます.