class PCAProcess: def __init__(self): self.file_io = FileIO() self.pca = PrincipleComponentAnalysis() self.chart = DrawChart() def pca_process(self, file_path, dim_number): # ファイルオープン処理 org_df = self.file_io.open_file_as_pandas(file_path, "utf-8") # 不要な顧客IDを削除 Y = org_df['現金外支払合計'] + org_df['現金支払合計'] print("Y's shape is {}".format(Y.shape)) #df = org_df.drop(columns='顧客ID') X = org_df.drop(['顧客ID', '現金支払合計', '現金外支払合計'], axis=1) print("X's shape is {}".format(X.shape)) rd = self.pca.fit(X, dim_number) df_rd = self.pca.fit_transform(X, dim_number) # グラフ描画 self.chart.pca_scatter_plot(df_rd, Y) # 主成分の寄与率を出力する print('各次元の寄与率: {0}'.format(rd.explained_variance_ratio_)) print('累積寄与率: {0}'.format(sum(rd.explained_variance_ratio_))) return df_rd, Y
class SelectColumns: def __init__(self, con_path, char_type): # 初期化 self.file_io = FileIO() self.extract_col = ExtractColumns() self.con_path = con_path # ファイルオープン self.con = self.file_io.open_file_as_pandas(con_path, char_type) def select(self, **kwargs): # ターゲットリスト tg_list = kwargs['extract_col'] + ['現金外支払合計','現金支払合計'] # ターゲット列を抽出 target_col = self.extract_col.extract(self.con, self.con['顧客ID'], extract_col=tg_list) # ファイル書き込み self.file_io.export_csv_from_pandas(target_col, self.con_path)
class DecisionTree: def __init__(self, path, depth): self.clf = tree.DecisionTreeClassifier(max_depth=3) self.file_io = FileIO() #self.pca = PCAProcess() #self.chart = DrawChart() self.test = Test() self.file_path = path def analyze(self): # ファイルオープン処理 org_df = self.file_io.open_file_as_pandas(self.file_path, "utf-8") # 目的変数Xと説明変数Y Y = org_df['現金外支払合計'] + org_df['現金支払合計'] X = org_df.drop(['顧客ID', '現金支払合計', '現金外支払合計'], axis=1) # Xの各列を正規化 X_normal = X.apply(lambda x: (x - np.mean(x)) / (np.max(x) - np.min(x))) # トレーニングデータとテストデータに分割(30%) X_train, X_test, Y_train, Y_test = self.test.make_train_test_data( X_normal, Y, 0.3) print(X_train.head()) print("--- X_train's shape ---\n {}\n".format(X_train.shape)) print(X_test.head()) print("--- X_test's shape ---\n {}\n".format(X_test.shape)) print(Y_train.head()) print("--- Y_train's shape ---\n {}\n".format(Y.shape)) print(Y_test.head()) print("--- Y_test's shape ---\n {}\n".format(Y.shape)) # 分析を実施 predicted = self.clf.fit(X_train, Y_train) # 識別率を確認 ratio = sum(predicted == Y_train) / len(Y_train) # 精度を算出 # トレーニングデータ print(" --- train score ---\n {}\n".format( self.lr.score(X_train, Y_train))) # テストデータ print(" --- test score ---\n {}\n".format( self.lr.score(X_train, Y_train))) return self.lr.score(X_train, Y_train), self.lr.score(X_train, Y_train)
class LinRegression: def __init__(self): self.lr = LinearRegression() self.file_io = FileIO() #self.pca = PCAProcess() #self.chart = DrawChart() self.test = Test() self.individual = IndividualTest() self.sc = StandardScaler() self.ms = MinMaxScaler() self.drop_na = DropNaN() def regression(self, in_path, out_path): # ファイルオープン処理 org_df = self.file_io.open_file_as_pandas(in_path,"utf-8") feat_shop = self.file_io.open_file_as_pandas('./data/out/feat_shop.csv','utf-8') feat_pref = self.file_io.open_file_as_pandas('./data/out/feat_pref.csv','utf-8') ''' # 目的変数 org_df['支払合計'] = org_df['現金外支払合計'] + org_df['現金支払合計'] # 不要な説明変数削除 org_df = org_df.drop(['現金外支払合計', '現金支払合計'],axis=1) # 目的変数がゼロ以下の行を削除 org_df = org_df.drop(org_df[org_df['支払合計']==0].index) # 欠損値が多すぎる列を削除 #org_df = org_df.drop(['売上単価'],axis=1) # 目的変数が欠損値の行を削除 org_df = org_df.dropna(subset=['支払合計']) ''' # shop追加 #org_df = pd.merge(org_df, feat_shop, on='顧客ID',how='left') org_df = pd.merge(org_df, feat_pref, on='顧客ID',how='left') org_df = org_df.drop(['Unnamed: 0_x','Unnamed: 0_y'],axis=1) org_df = org_df[org_df.columns.drop(list(org_df.filter(regex='Unnamed:')))] # スコア=0を削除 org_df = org_df.drop(org_df[org_df['スコア']<=0].index) # 不要列削除 #org_df = org_df.drop(['Unnamed: 0', '顧客ID'], axis=1) org_df = org_df.drop(['顧客ID'],axis=1) #org_df = org_df[org_df.columns.drop(list(org_df.filter(regex='Unnamed:')))] #org_df = org_df.columns.drop(org_df.columns.str.contains('Unnamed:')) # 欠損値が70%以上の列を削除 #org_df = self.drop_na.drop_na_col(org_df, len(org_df), 0.7) #print('\n rows of org_df is:') #print(len(org_df)) #print(type(len(org_df))) # 欠損値をゼロうめ org_df = org_df.fillna(0) # 目的変数Xと説明変数Y #Y = org_df['売上'] Y = org_df['スコア'] #X = org_df.drop(['支払合計'],axis=1) X = org_df.drop(['商品コード','売上単価','数量','売上','明細ID','スコア'],axis=1) X = X.drop(['キャンセル回数','コンタクト回数','問い合わせ回数'],axis=1) X = X.drop(['治療送客回数_あり','治療送客回数_なし','院長挨拶回数_あり','院長挨拶回数_なし','紹介カード受渡回数_あり','紹介カード受渡回数_なし','携帯TEL_有','携帯メール_有','性別_女','性別_男','自宅TEL_有','PCメール_有'],axis=1) #X = X.drop(['職業_学生','職業_会社員','職業_主婦','職業_自営業','職業_その他','職業_パート・アルバイト'],axis=1) X = X.drop(['登録区分_HP','登録区分_店舗','登録区分_CC'],axis=1) #X = X.drop(['生年月日','滞在時間','閲覧ページ総数','閲覧ページ数/セッション'],axis=1) X = X[X.columns.drop(list(org_df.filter(regex='_nan')))] #X = X[X.columns.drop(list(org_df.filter(regex='_なし')))] X = X[X.columns.drop(list(org_df.filter(regex='_空欄')))] X = X[X.columns.drop(list(org_df.filter(regex='_無')))] X = X[X.columns.drop(list(org_df.filter(regex='_削除')))] X = X[X.columns.drop(list(org_df.filter(regex='施術時間')))] ''' X = X[X.columns.drop(list(org_df.filter(regex='キャンセル回数')))] X = X[X.columns.drop(list(org_df.filter(regex='コンタクト回数')))] X = X[X.columns.drop(list(org_df.filter(regex='問い合わせ回数')))] X = X[X.columns.drop(list(org_df.filter(regex='滞在時間')))] X = X[X.columns.drop(list(org_df.filter(regex='閲覧ページ総数')))] X = X[X.columns.drop(list(org_df.filter(regex='閲覧ページ数/セッション')))] ''' # 標準化 #std_Y = pd.DataFrame(self.sc.fit_transform(Y)) #std_Y.columns = Y.columns #std_X = pd.DataFrame(self.sc.fit_transform(X)) #std_X.columns = X.columns # 正規化 #norm_Y = pd.DataFrame(self.ms.fit_transform(Y)) #norm_Y.columns = Y.columns #norm_X = pd.DataFrame(self.ms.fit_transform(X)) #norm_X.columns = X.columns #self.file_io.export_csv_from_pandas(X, './data/out/X.csv') # トレーニングデータとテストデータに分割(30%) X_train, X_test, Y_train, Y_test = self.test.make_train_test_data(X, Y, 0.3) print(X_train.head()) print("--- X_train's shape ---\n {}\n".format(X_train.shape)) print(X_test.head()) print("--- X_test's shape ---\n {}\n".format(X_test.shape)) print(Y_train.head()) print("--- Y_train's shape ---\n {}\n".format(Y_train.shape)) print(Y_test.head()) print("--- Y_test's shape ---\n {}\n".format(Y_test.shape)) # 重回帰分析を実施 self.lr.fit(X_train, Y_train) # 偏回帰係数 print(pd.DataFrame({"Name":X.columns, "Coefficients":self.lr.coef_}).sort_values(by='Coefficients') ) # 切片 (誤差) print(self.lr.intercept_) # pandasファイル作成 org_pd = pd.DataFrame({"Name":X.columns, "Coefficients":self.lr.coef_}) # ファイルアウトプット self.file_io.export_csv_from_pandas(org_pd, "./data/out/linear_regression.csv") # 精度を算出 # トレーニングデータ print(" --- train score ---\n {}\n".format(self.lr.score(X_train,Y_train))) # テストデータ print(" --- test score ---\n {}\n".format(self.lr.score(X_test,Y_test))) return self.lr.score(X_train,Y_train), self.lr.score(X_test,Y_test)
class IndRegression: def __init__(self): #self.lr = LinearRegression() self.file_io = FileIO() #self.pca = PCAProcess() #self.chart = DrawChart() self.test = Test() self.individual = IndividualTest() self.sc = StandardScaler() self.ms = MinMaxScaler() self.drop_na = DropNaN() self.droplist = [] with open('droplist.txt') as f: self.droplist = [s.strip() for s in f.readlines()] def regression(self, in_path, out_path): # ファイルオープン処理 org_df = self.file_io.open_file_as_pandas(in_path, "utf-8") ''' # 目的変数 org_df['支払合計'] = org_df['現金外支払合計'] + org_df['現金支払合計'] # 不要な説明変数削除 org_df = org_df.drop(['現金外支払合計', '現金支払合計'],axis=1) # 売上関連説明変数削除 org_df = org_df.drop(self.droplist,axis=1) # 目的の下限を設定 org_df = org_df.drop(org_df[org_df['支払合計']<=0].index) # 目的変数の上限を設定 org_df = org_df.drop(org_df[org_df['支払合計']>=40000].index) ''' # 年齢の下限を設定 org_df = org_df.drop(org_df[org_df['生年月日'] <= 20].index) # 年齢の上限を設定 org_df = org_df.drop(org_df[org_df['生年月日'] >= 50].index) # 閲覧回数の下限を設定 org_df = org_df.drop(org_df[org_df['閲覧ページ総数'] <= 0].index) # 閲覧回数の上限を設定 org_df = org_df.drop(org_df[org_df['閲覧ページ総数'] >= 100].index) # スコア=0を削除 org_df = org_df.drop(org_df[org_df['スコア'] <= 0].index) ''' # 欠損値が多すぎる列を削除 #org_df = org_df.drop(['売上単価'],axis=1) # 目的変数が欠損値の行を削除 org_df = org_df.dropna(subset=['支払合計']) ''' # 不要列削除 #org_df = org_df.drop(['Unnamed: 0', '顧客ID'], axis=1) org_df = org_df.drop(['顧客ID'], axis=1) org_df = org_df[org_df.columns.drop( list(org_df.filter(regex='Unnamed:')))] # 欠損値が70%以上の列を削除 #org_df = self.drop_na.drop_na_col(org_df, len(org_df), 0.7) #print('\n rows of org_df is:') #print(len(org_df)) #print(type(len(org_df))) # 欠損値をゼロうめ #org_df = org_df.fillna(0) # 説明変数Y #Y = org_df['支払合計'] Y = org_df['スコア'] # 10等分 #bin_Y = pd.cut(org_Y, 2, labels=False) #print(bin_Y) # 目的変数X #X = org_df.drop(['支払合計'],axis=1) X = org_df.drop(['商品コード', '売上単価', '数量', '売上', '明細ID', 'スコア'], axis=1) # 属性情報削除 X = X.drop(['キャンセル回数', 'コンタクト回数', '問い合わせ回数'], axis=1) X = X[X.columns.drop(list(org_df.filter(regex='施術時間')))] X = X[X.columns.drop(list(org_df.filter(regex='指名回数')))] #X = X[X.columns.drop(list(org_df.filter(regex='コース受諾回数')))] X = X[X.columns.drop(list(org_df.filter(regex='紹介カード受渡回数')))] X = X[X.columns.drop(list(org_df.filter(regex='治療送客回数')))] X = X[X.columns.drop(list(org_df.filter(regex='院長挨拶回数')))] X = X[X.columns.drop(list(org_df.filter(regex='性別')))] X = X[X.columns.drop(list(org_df.filter(regex='携帯TEL')))] X = X[X.columns.drop(list(org_df.filter(regex='自宅TEL')))] X = X[X.columns.drop(list(org_df.filter(regex='携帯メール')))] X = X[X.columns.drop(list(org_df.filter(regex='PCメール')))] X = X[X.columns.drop(list(org_df.filter(regex='職業')))] X = X[X.columns.drop(list(org_df.filter(regex='登録区分')))] # 欠損値をゼロうめ Y = Y.fillna(0) X = X.fillna(0) # 個別テスト self.individual.lin_reg(X, Y, 0.3, X.columns, out_path)
"Random Forest", "AdaBoost", "Naive Bayes", "Linear Discriminant Analysis", "Quadratic Discriminant Analysis" ] classifiers = [ KNeighborsClassifier(3), SVC(kernel="linear", C=0.025), SVC(gamma=2, C=1), DecisionTreeClassifier(max_depth=5), RandomForestClassifier(max_depth=5, n_estimators=10, max_features=1), AdaBoostClassifier(), GaussianNB(), LinearDiscriminantAnalysis(), QuadraticDiscriminantAnalysis() ] datasets = file_io.open_file_as_pandas(inifile.get('classify', 'x_path'), "utf-8") X = datasets.drop(datasets[datasets['売上単価'] <= 0].index) #X = datasets['売上単価'].values.reshape(-1,1) y = ['売れ筋', '死に筋'] figure = plt.figure(figsize=(12, 12)) X = StandardScaler().fit_transform(X) # データを正規化 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4) h = .02 # step size in the mesh x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5 y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) # just plot the dataset first cm = plt.cm.RdBu
class ConcatCsvs: def __init__( self, id_path, cust_payment_path, cust_attr_path, product_attr_path, cust_path, cancel_path, contact_path, cti_path, register_type_path, status_path, stay_time_path, pv_sum_path, session_path, char_type): self.file_io = FileIO() self.encode = CategoryEncode() self.count_rec = CountRecord() self.extract_col = ExtractColumns() # ファイルオープン self.id = self.file_io.open_file_as_pandas(id_path,char_type) self.cust_payment = self.file_io.open_file_as_pandas(cust_payment_path, char_type) self.cust_attr = self.file_io.open_file_as_pandas(cust_attr_path, char_type) self.product_attr = self.file_io.open_file_as_pandas(product_attr_path, char_type) self.cust = self.file_io.open_file_as_pandas(cust_path, char_type) self.cancel = self.file_io.open_file_as_pandas(cancel_path, char_type) self.contact = self.file_io.open_file_as_pandas(contact_path, char_type) self.cti = self.file_io.open_file_as_pandas(cti_path, char_type) self.register_type = self.file_io.open_file_as_pandas(register_type_path, char_type) self.status = self.file_io.open_file_as_pandas(status_path, char_type) self.stay_time = self.file_io.open_file_as_pandas(stay_time_path, char_type) self.pv_sum = self.file_io.open_file_as_pandas(pv_sum_path, char_type) self.session = self.file_io.open_file_as_pandas(session_path, char_type) def concat(self, out_path, out_path2): # 特徴量抽出処理 # cust_payment # カテゴリーデータなし # --- check --- #print("--- cust_payment shape ---\n {}\n".format(self.cust_payment.shape)) #print(self.cust_payment.head()) # cust_attr cust_attr_col_list =[] cust_attr_tg_list = ['指名回数','コース受諾回数','紹介カード受渡回数','治療送客回数','院長挨拶回数'] # カテゴリ列を抽出 cust_attr_category_col = self.extract_col.extract(self.cust_attr, self.cust_attr['顧客ID'], extract_col=cust_attr_tg_list) # 非カテゴリ列を抽出 cust_attr_non_category_col = self.extract_col.exclude(self.cust_attr, exclude_col=cust_attr_tg_list) # 特徴量抽出 org_cust_attr = self.encode.transform_feature(cust_attr_category_col, aggregate_col=cust_attr_tg_list) org_cust_attr = org_cust_attr.fillna(0) #org_cust_attr = org_cust_attr.drop('Unnamed: 0', axis=1) # ラベル付与 for col in cust_attr_tg_list: cust_attr_col_list += self.encode.transform_label(self.cust_attr[col],col) else: cust_attr_col_list += ['顧客ID'] # ラベル設定 org_cust_attr.columns = cust_attr_col_list # 集計処理 feat_cust_attr = self.count_rec.group_sum(org_cust_attr, index_col='顧客ID', aggregate_col=cust_attr_col_list) # カテゴリ列と非カテゴリ列を結合 feat_cust_attr = pd.merge(feat_cust_attr, cust_attr_non_category_col, on='顧客ID',how='left') feat_cust_attr = feat_cust_attr.drop('Unnamed: 0', axis=1) # --- check --- #print("--- feat_cust_attr shape ---\n {}\n".format(feat_cust_attr.shape)) #print(feat_cust_attr.head()) #self.file_io.export_csv_from_pandas(feat_cust_attr, './data/out/mid_feat_cust_attr.csv') # product_attr product_attr_col_list = [] product_attr_tg_list = ['商品コード','売上区分','商品区分'] # カテゴリ列を抽出 product_attr_category_col = self.extract_col.extract(self.product_attr, self.product_attr['顧客ID'], extract_col=product_attr_tg_list) # 非カテゴリ列を抽出 product_attr_non_category_col = self.extract_col.exclude(self.product_attr, exclude_col=product_attr_tg_list) # 特徴量抽出 org_product_attr = self.encode.transform_feature(product_attr_category_col, aggregate_col=product_attr_tg_list) org_product_attr = org_product_attr.fillna(0) #org_product_attr = org_product_attr.drop('Unnamed: 0', axis=1) #print(org_product_attr) # ラベル付与 for col in product_attr_tg_list: product_attr_col_list += self.encode.transform_label(self.product_attr[col],col) else: product_attr_col_list += ['顧客ID'] # ラベル設定 org_product_attr.columns = product_attr_col_list # 集計処理 feat_product_attr = self.count_rec.group_sum(org_product_attr, index_col='顧客ID', aggregate_col=product_attr_col_list) # カテゴリ列と非カテゴリ列を結合 feat_product_attr = pd.merge(feat_product_attr, product_attr_non_category_col, on='顧客ID',how='left') feat_product_attr = feat_product_attr.drop('Unnamed: 0', axis=1) # --- check --- #print("--- feat_product_attr shape ---\n {}\n".format(feat_cust_attr.shape)) #print(feat_product_attr.head()) #self.file_io.export_csv_from_pandas(feat_product_attr, './data/out/mid_feat_product_attr.csv') # cust cust_col_list = [] cust_tg_list = ['性別','携帯TEL','自宅TEL','携帯メール','PCメール','職業'] # 外れ値を削除 new_cust = self.cust.drop(self.cust[self.cust['生年月日'].str.contains('\*', na=True)].index) today = int(pd.to_datetime('today').strftime('%Y%m%d')) new_cust['生年月日'] = pd.to_datetime(new_cust['生年月日']).dt.strftime('%Y%m%d').astype(np.int64) new_cust['生年月日'] = ((today - new_cust['生年月日'])/10000).astype(np.int64) # カテゴリ列を抽出 cust_category_col = self.extract_col.extract(new_cust, new_cust['顧客ID'], extract_col=cust_tg_list) # 非カテゴリ列を抽出 cust_non_category_col = self.extract_col.exclude(new_cust, exclude_col=cust_tg_list) # 特徴量抽出 feat_cust = self.encode.transform_feature(cust_category_col, aggregate_col=cust_tg_list) feat_cust = feat_cust.fillna(0) #feat_cust = feat_cust.drop('Unnamed: 0', axis=1) feat_cust = feat_cust[feat_cust.columns.drop(list(feat_cust.filter(regex='Unnamed:')))] # ラベル付与 for col in cust_tg_list: cust_col_list += self.encode.transform_label(new_cust[col],col) else: cust_col_list += ['顧客ID'] # ラベル設定 feat_cust.columns = cust_col_list # カテゴリ列と非カテゴリ列を結合 feat_cust = pd.merge(feat_cust, cust_non_category_col, on='顧客ID',how='left') #feat_cust = feat_cust.drop('Unnamed: 0', axis=1) # --- check --- #print("--- feat_cust shape ---\n {}\n".format(feat_cust.shape)) #print(feat_cust.head()) #self.file_io.export_csv_from_pandas(feat_cust, './data/out/mid_feat_cust.csv') # cancel # カテゴリーデータなし # --- check --- #print("--- cancel shape ---\n {}\n".format(cancel.shape)) #print(cancel.head()) # contact # カテゴリーデータなし # --- check --- #print("--- contact shape ---\n {}\n".format(contact.shape)) #print(contact.head()) # cti # カテゴリーデータなし # --- check --- #print("--- cti shape ---\n {}\n".format(cti.shape)) #print(cti.head()) # register_type reg_col_list = [] reg_tg_list = ['登録区分'] # カテゴリ列を抽出 reg_category_col = self.extract_col.extract(self.register_type, self.register_type['顧客ID'], extract_col=reg_tg_list) # 非カテゴリ列を抽出 reg_non_category_col = self.extract_col.exclude(self.register_type, exclude_col=reg_tg_list) # 特徴量抽出 feat_register_type = self.encode.transform_feature(reg_category_col, aggregate_col=reg_tg_list) feat_register_type = feat_register_type.fillna(0) #feat_register_type = feat_register_type.drop('Unnamed: 0', axis=1) # ラベル付与 for col in reg_tg_list: reg_col_list += self.encode.transform_label(self.register_type[col],col) else: reg_col_list += ['顧客ID'] # ラベル設定 feat_register_type.columns = reg_col_list # カテゴリ列と非カテゴリ列を結合 feat_register_type = pd.merge(feat_register_type, reg_non_category_col, on='顧客ID',how='left') feat_register_type = feat_register_type.drop('Unnamed: 0', axis=1) # --- check --- #print("--- feat_register_type shape ---\n {}\n".format(feat_register_type.shape)) #print(feat_register_type.head()) #self.file_io.export_csv_from_pandas(feat_register_type, './data/out/mid_feat_register_type.csv') # status stat_col_list = [] stat_tg_list = ['状況','指名区分'] # カテゴリ列を抽出 stat_category_col = self.extract_col.extract(self.status, self.status['顧客ID'], extract_col=stat_tg_list) # 非カテゴリ列を抽出 stat_non_category_col = self.extract_col.exclude(self.status, exclude_col=stat_tg_list) # 特徴量抽出 feat_status = self.encode.transform_feature(stat_category_col, aggregate_col=stat_tg_list) feat_status = feat_status.fillna(0) #feat_status = feat_status.drop('Unnamed: 0', axis=1) # ラベル付与 for col in stat_tg_list: stat_col_list += self.encode.transform_label(self.status[col],col) else: stat_col_list += ['顧客ID'] # ラベル設定 feat_status.columns = stat_col_list # カテゴリ列と非カテゴリ列を結合 feat_status = pd.merge(feat_status, stat_non_category_col, on='顧客ID',how='left') feat_status = feat_status.drop('Unnamed: 0', axis=1) #feat_status = feat_status.drop('Unnamed: 0', axis=1) # --- check --- #print("--- feat_status shape ---\n {}\n".format(feat_status.shape)) #print(feat_status.head()) #self.file_io.export_csv_from_pandas(feat_status, './data/out/mid_feat_status.csv') # 結合処理 con_file = pd.merge(self.id, self.cust_payment, on='顧客ID', how='left') #print("1.1: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, self.cancel, on='顧客ID',how='left') #print("1.2: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, self.contact, on='顧客ID',how='left') #print("1.3: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, self.cti, on='顧客ID',how='left') #print("1.4: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, self.stay_time, on='顧客ID',how='left') #print("1.5: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, self.pv_sum, on='顧客ID',how='left') #print("1.6: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, self.session, on='顧客ID',how='left') #print("1.7: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, feat_cust_attr, on='顧客ID',how='left') #print("1.8: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, feat_cust, on='顧客ID',how='left') #print("1.9: shape is {}".format(con_file.shape)) con_file = pd.merge(con_file, feat_register_type, on='顧客ID',how='left') #print("1.10: shape is {}".format(con_file.shape)) #con_file = pd.merge(con_file, feat_status, on='顧客ID',how='left') #print("1.11: shape is {}".format(con_file.shape)) '''con_file = pd.concat([ self.cust_payment, feat_cust_attr, feat_cust, self.cancel, self.contact, self.cti, feat_register_type, feat_status, self.stay_time, self.pv_sum, self.session], axis=1, join_axes=['顧客ID'])''' # --- check --- #print("--- con_file shape ---\n {}\n".format(con_file.shape)) #print(con_file.head()) # 結合処理 con_product_file = pd.merge(self.id, self.cust_payment, on='顧客ID', how='left') con_product_file = pd.merge(con_product_file, feat_product_attr, on='顧客ID', how='left') #print("2.1: shape is {}".format(con_file.shape)) # 重複がある場合、削除 con_file = con_file.drop_duplicates() con_product_file = con_product_file.drop_duplicates() con_product_file = con_product_file.drop(['施術時間','売上単価','数量'],axis=1) # 書き出し処理 self.file_io.export_csv_from_pandas(con_file, out_path) self.file_io.export_csv_from_pandas(con_product_file, out_path2)
class ExtractSales: def __init__(self, in_path, in_char, payment_path, out_char, cust_attr_path, target_attr_path, average_attr_path): self.count_rec = CountRecord() self.file_io = FileIO() self.in_path = in_path self.in_char = in_char self.payment_path = payment_path self.out_char = out_char self.cust_attr_path = cust_attr_path self.target_attr_path = target_attr_path self.average_attr_path = average_attr_path def extract(self): # ファイルオープン処理 file = self.file_io.open_file_as_pandas(self.in_path, self.in_char) # 顧客属性前処理:顧客属性取得のため、個別商品の行を売上の行に統合 sales_file = file.query('明細コード == 1') # 集計処理:顧客IDごとの支払情報を集計 cust_payment = self.count_rec.group_sum(sales_file, index_col='顧客ID', aggregate_col=['顧客ID', '施術時間']) # 顧客属性集計処理:顧客IDごとの属性情報を集計 ex_id = sales_file['顧客ID'] ex_nominate = sales_file['指名回数'] ex_course = sales_file['コース受諾回数'] ex_card = sales_file['紹介カード受渡回数'] ex_reception = sales_file['治療送客回数'] ex_director = sales_file['院長挨拶回数'] # 追加顧客属性 #ex_branch = sales_file['店舗'] #ex_accosiate = sales_file['担当者'] # マージ cust_attr = pd.concat([ex_id, ex_nominate], axis=1) cust_attr = pd.concat([cust_attr, ex_course], axis=1) cust_attr = pd.concat([cust_attr, ex_card], axis=1) cust_attr = pd.concat([cust_attr, ex_reception], axis=1) cust_attr = pd.concat([cust_attr, ex_director], axis=1) cust_attr = pd.concat([cust_attr, cust_payment], axis=1) #cust_attr = self.cont_rec.group_size(sales_file, index_col='顧客ID', keep_list=['顧客ID','指名回数','コース受託回数','紹介カード受渡回数','治療送客回数','院長挨拶回数']) # 集計処理2.2:顧客IDごとの個別商品属性情報を集計 ex_id_product = file['顧客ID'] ex_product_code = file['商品コード'] ex_price_product = file['売上単価'] ex_amount_product = file['数量'] # マージ product_attr = pd.concat([ex_id_product, ex_product_code], axis=1) product_attr = pd.concat([product_attr, ex_price_product], axis=1) product_attr = pd.concat([product_attr, ex_amount_product], axis=1) # 売上列追加 product_attr['売上'] = file['売上単価'] * file['数量'] # 個別商品IDに相当する列追加 product_attr['明細ID'] = file['伝票コード'] * 10 + file['明細コード'] # スコア列設定 product_attr['スコア'] = 0 # スコア設定 product_attr.loc[product_attr['商品コード'] == '1A1501', 'スコア'] = 5 product_attr.loc[product_attr['商品コード'] == '1B2201', 'スコア'] = 4 product_attr.loc[product_attr['商品コード'] == '1A1601', 'スコア'] = 3 product_attr.loc[product_attr['商品コード'] == '200071', 'スコア'] = 2 product_attr.loc[product_attr['商品コード'] == '200006', 'スコア'] = 1 product_attr['スコア'] = product_attr['スコア'] * product_attr['数量'] # 不要な列を削除 target_attr = product_attr[(product_attr['商品コード'] == '1A1501') | (product_attr['商品コード'] == '1B2201') | (product_attr['商品コード'] == '1A1601') | (product_attr['商品コード'] == '200071') | (product_attr['商品コード'] == '200006')] # 書き出し処理 self.file_io.export_csv_from_pandas(cust_payment, self.payment_path) self.file_io.export_csv_from_pandas(cust_attr, self.cust_attr_path) self.file_io.export_csv_from_pandas(target_attr, self.target_attr_path) self.file_io.export_csv_from_pandas(product_attr, self.average_attr_path)
class ExtractSales: def __init__(self, in_path, in_char, payment_path, out_char, cust_attr_path, product_attr_path): self.count_rec = CountRecord() self.file_io = FileIO() self.in_path = in_path self.in_char = in_char self.payment_path = payment_path self.out_char = out_char self.cust_attr_path = cust_attr_path self.product_attr_path = product_attr_path def extract(self): # ファイルオープン処理 file = self.file_io.open_file_as_pandas(self.in_path, self.in_char) # 前処理:個別商品の行を売上の行に統合 sales_file = file.query('明細コード == 1') # 集計処理1.1:顧客IDごとの支払情報を集計 cust_payment1 = self.count_rec.group_sum( sales_file, index_col='顧客ID', aggregate_col=['顧客ID', '施術時間', '現金支払合計', '現金外支払合計', '未収金前回残高']) # 集計処理1.2:顧客IDごとの個別商品情報を集計 cust_payment2 = self.count_rec.group_sum( file, index_col='顧客ID', aggregate_col=['顧客ID', '売上単価', '数量']) # 集計処理1.3:支払情報をマージ cust_payment = pd.merge(cust_payment1, cust_payment2, on='顧客ID', how='left') # 集計処理2.1:顧客IDごとの属性情報を集計 ex_id = sales_file['顧客ID'] ex_nominate = sales_file['指名回数'] ex_course = sales_file['コース受諾回数'] ex_card = sales_file['紹介カード受渡回数'] ex_reception = sales_file['治療送客回数'] ex_director = sales_file['院長挨拶回数'] # マージ cust_attr = pd.concat([ex_id, ex_nominate], axis=1) cust_attr = pd.concat([cust_attr, ex_course], axis=1) cust_attr = pd.concat([cust_attr, ex_card], axis=1) cust_attr = pd.concat([cust_attr, ex_reception], axis=1) cust_attr = pd.concat([cust_attr, ex_director], axis=1) #cust_attr = self.cont_rec.group_size(sales_file, index_col='顧客ID', keep_list=['顧客ID','指名回数','コース受託回数','紹介カード受渡回数','治療送客回数','院長挨拶回数']) # 集計処理2.2:顧客IDごとの個別商品属性情報を集計 ex_id_product = file['顧客ID'] ex_product_code = file['商品コード'] ex_sales_type = file['売上区分'] ex_product_type = file['商品区分'] # マージ product_attr = pd.concat([ex_id_product, ex_product_code], axis=1) product_attr = pd.concat([product_attr, ex_sales_type], axis=1) product_attr = pd.concat([product_attr, ex_product_type], axis=1) #product_attr = file['顧客ID','商品コード','売上区分','商品区分'] #product_attr = self.cont_rec.group_size(file, index_col='顧客ID', keep_list=['顧客ID','商品コード','売上区分','商品区分']) # 書き出し処理 self.file_io.export_csv_from_pandas(cust_payment, self.payment_path) self.file_io.export_csv_from_pandas(cust_attr, self.cust_attr_path) self.file_io.export_csv_from_pandas(product_attr, self.product_attr_path)
class LinRegression2: def __init__(self): self.lr = LinearRegression() self.file_io = FileIO() #self.pca = PCAProcess() #self.chart = DrawChart() self.test = Test() self.individual = IndividualTest() self.sc = StandardScaler() self.ms = MinMaxScaler() self.drop_na = DropNaN() def regression(self, in_path, out_path): # ファイルオープン処理 org_df = self.file_io.open_file_as_pandas(in_path, "utf-8") ''' # 目的変数 org_df['支払合計'] = org_df['現金外支払合計'] + org_df['現金支払合計'] # 不要な説明変数削除 org_df = org_df.drop(['現金外支払合計', '現金支払合計'],axis=1) # 目的変数がゼロ以下の行を削除 org_df = org_df.drop(org_df[org_df['支払合計']==0].index) # 欠損値が多すぎる列を削除 #org_df = org_df.drop(['売上単価'],axis=1) # 目的変数が欠損値の行を削除 org_df = org_df.dropna(subset=['支払合計']) ''' # スコア=0を削除 org_df = org_df.drop(org_df[org_df['スコア'] <= 0].index) # 不要列削除 #org_df = org_df.drop(['Unnamed: 0', '顧客ID'], axis=1) org_df = org_df.drop(['顧客ID'], axis=1) org_df = org_df[org_df.columns.drop( list(org_df.filter(regex='Unnamed:')))] # 欠損値が70%以上の列を削除 #org_df = self.drop_na.drop_na_col(org_df, len(org_df), 0.7) #print('\n rows of org_df is:') #print(len(org_df)) #print(type(len(org_df))) # 欠損値をゼロうめ org_df = org_df.fillna(0) # 目的変数Xと説明変数Y #Y = org_df['支払合計'] Y = org_df['スコア'] #X = org_df.drop(['支払合計'],axis=1) X = org_df.drop(['商品コード', '売上単価', '数量', '売上', '明細ID', 'スコア'], axis=1) # 属性情報削除 X = X.drop(['滞在時間'], axis=1) X = X.drop(['キャンセル回数', 'コンタクト回数', '問い合わせ回数'], axis=1) X = X[X.columns.drop(list(org_df.filter(regex='施術時間')))] X = X[X.columns.drop(list(org_df.filter(regex='指名回数')))] X = X[X.columns.drop(list(org_df.filter(regex='コース受諾回数')))] X = X[X.columns.drop(list(org_df.filter(regex='紹介カード受渡回数')))] X = X[X.columns.drop(list(org_df.filter(regex='治療送客回数')))] X = X[X.columns.drop(list(org_df.filter(regex='院長挨拶回数')))] X = X[X.columns.drop(list(org_df.filter(regex='性別')))] X = X[X.columns.drop(list(org_df.filter(regex='携帯TEL')))] X = X[X.columns.drop(list(org_df.filter(regex='自宅TEL')))] X = X[X.columns.drop(list(org_df.filter(regex='携帯メール')))] X = X[X.columns.drop(list(org_df.filter(regex='PCメール')))] X = X[X.columns.drop(list(org_df.filter(regex='職業')))] X = X[X.columns.drop(list(org_df.filter(regex='登録区分')))] # 標準化 #std_Y = pd.DataFrame(self.sc.fit_transform(Y)) #std_Y.columns = Y.columns #std_X = pd.DataFrame(self.sc.fit_transform(X)) #std_X.columns = X.columns # 正規化 #norm_Y = pd.DataFrame(self.ms.fit_transform(Y)) #norm_Y.columns = Y.columns #norm_X = pd.DataFrame(self.ms.fit_transform(X)) #norm_X.columns = X.columns #self.file_io.export_csv_from_pandas(X, './data/out/X.csv') # トレーニングデータとテストデータに分割(30%) X_train, X_test, Y_train, Y_test = self.test.make_train_test_data( X, Y, 0.3) print(X_train.head()) print("--- X_train's shape ---\n {}\n".format(X_train.shape)) print(X_test.head()) print("--- X_test's shape ---\n {}\n".format(X_test.shape)) print(Y_train.head()) print("--- Y_train's shape ---\n {}\n".format(Y_train.shape)) print(Y_test.head()) print("--- Y_test's shape ---\n {}\n".format(Y_test.shape)) # 重回帰分析を実施 self.lr.fit(X_train, Y_train) # 偏回帰係数 print( pd.DataFrame({ "Name": X.columns, "Coefficients": self.lr.coef_ }).sort_values(by='Coefficients')) # 切片 (誤差) print(self.lr.intercept_) # pandasファイル作成 org_pd = pd.DataFrame({ "Name": X.columns, "Coefficients": self.lr.coef_ }) # ファイルアウトプット self.file_io.export_csv_from_pandas( org_pd, "./data/out/linear_regression.csv") # 精度を算出 # トレーニングデータ print(" --- train score ---\n {}\n".format( self.lr.score(X_train, Y_train))) # テストデータ print(" --- test score ---\n {}\n".format(self.lr.score( X_test, Y_test))) return self.lr.score(X_train, Y_train), self.lr.score(X_test, Y_test)