• [其他] 《深度学习入门》笔记 - 05
    接下来就是讲线性模型了。线性模型相对比较简单,但是他是学习比较复杂的深度学习模型的一个基础,而且线性模型本身也具有广泛的用途。 这里讲了线性模型中的线性回归模型和logistic模型。线性回归模型用于处理`回归问题`。logistic模型用于处理`分类问题`。 线性回归模型可以写作如下的形式: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/28/1658967898278255086.png) 其中那`一系列的x`都是已知,而且比较容易测量到的向量。`一系列的w`是权重或者叫做系数。`b`是一个常数,叫做截距或偏差。$\boldsymbol\epsilon$ 是误差,代表了没有在x里体现但对y有影响的信息。 这其中一系列的w和b都是未知数,就是`模型参数`。
  • [新手课堂] 多元线性回归模型选股应用(α策略)
    内容介绍本文重点在于如何利用python收集各类型因子并进行预处理最终用于构建量化选股模型。工具介绍本代码所需要调用的包如下图所示:import pandas as pdimport tushare as tspro = ts.pro_api()import numpy as npimport timeimport mathimport statsmodels.api as smfrom sklearn import preprocessingfrom sklearn.decomposition import PCAimport os这里需要用到的是python中的pandas和statsmodels模块,分别用于数据处理和做多元回归。另外,还需要获取股票和指数的各项数据,这里所用到的是tushare,tushare拥有丰富的数据内容,如股票、基金等行情数据,公司财务理等基本面数据。通过tushare平台赚取一定的积分可以免费获取平台提供的数据。(个人ID:419382)数据获取本段代码展示了如何通过tushare获取相关数据并清洗成为所需因子,共展示了估值因子,成长因子,财务质量因子,杠杆因子,动量反转因子,波动率因子以及beta的构建。其中beta因子是取个股与指数收益率线性回归的回归系数。def get_all_factors(codes_list,date,start,end,one_m_start,beta_start,beta_end):    #获取估值因子    evaluate_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定交易日的指标        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,trade_date,pe_ttm,pb,ps_ttm,dv_ttm")        evaluate_factors = evaluate_factors.append(df1)        time.sleep(0.4)        print("第%d支股票估值因子获取成功"%i)    #根据指标计算因子    evaluate_factors["EP"] = 1/evaluate_factors["pe_ttm"]     evaluate_factors["BP"] = 1/evaluate_factors["pb"]    evaluate_factors["SP"] = 1/evaluate_factors["ps_ttm"]    evaluate_factors["DP"] = evaluate_factors["dv_ttm"]    evaluate_factors = evaluate_factors[["ts_code","trade_date","EP","BP","SP","DP"]]        #获取成长因子    growth_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.income(ts_code=codes_list[i],end_date=date,                          fields="ts_code,end_date,revenue,n_income")        df1 = df1.drop_duplicates(subset=["end_date"])    #根据财报计算因子        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[[0,4],:]        revenue = df1["revenue"].tolist()        n_income = df1["n_income"].tolist()        sales_G = revenue[0]/revenue[1] - 1        profit_G = n_income[0]/n_income[1] - 1        df2 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df2 = df2.drop_duplicates(subset=["end_date"])        df2["end_date"] = df2["end_date"].astype("int64")        df2 = df2.iloc[[0,4],:]        roe = df2["roe"].tolist()        ROE_G = roe[0]/roe[1] - 1        df3 = pd.DataFrame({"ts_code":codes_list[i],"sales_G":sales_G,"profit_G":profit_G,"ROE_G":ROE_G},index=[20201231])        growth_factors = growth_factors.append(df3)        time.sleep(1.2)        print("第%d支股票成长因子获取成功"%i)    all_factors = evaluate_factors.merge(growth_factors)        #获取财务质量因子    quality_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","roe","assets_turn"]]        quality_factors = quality_factors.append(df1)        time.sleep(1)        print("第%d支股票财务质量获取成功"%i)    all_factors = all_factors.merge(quality_factors)    #获取杠杆因子    leverage_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","debt_to_assets"]]        leverage_factors = leverage_factors.append(df1)        time.sleep(0.8)        print("第%d支股票杠杆因子获取成功"%i)    all_facotrs = all_factors.merge(leverage_factors)            #获取市值因子    capital_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,total_mv")        df1["total_mv"] = df1["total_mv"].apply(lambda x:math.log(x))        capital_factors = capital_factors.append(df1)        time.sleep(0.5)        print("第%d支股票市值因子获取成功"%i)    all_factors = all_facotrs.merge(capital_factors)            #获取动量反转因子    return_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], freq='M', adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        close = df1["close"].tolist()        return_1m = df1["pct_chg"].tolist()[0]        return_3m = close[0]/close[3] - 1        df2 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df2["trade_date"] = df2["trade_date"].astype("int64")        df3 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df3["trade_date"] = df3["trade_date"].astype("int64")        df2 = df2[df2["trade_date"]>=start]        w_return_3m = (df2["pct_chg"]*df3["turnover_rate"]).sum()/len(df2)        df_1m_return = df2[df2["trade_date"]>=one_m_start]        df_1m_turnover = df3[df3["trade_date"]>=one_m_start]        w_return_1m = (df_1m_return["pct_chg"]*df_1m_turnover["turnover_rate"]).sum()/len(df_1m_return)                df4 = pd.DataFrame({"ts_code":codes_list[i],                            "return_1m":return_1m,"return_3m":return_3m,"w_return_1m":w_return_1m,"w_return_3m":w_return_3m},index=[0])        return_factors = return_factors.append(df4)        print("第%d支股票动量反转因子获取成功"%i)    all_factors = all_factors.merge(return_factors)                    #获取波动率因子    vol_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        df2 = df1[df1["trade_date"]>=start]        std_1m = df2["pct_chg"].std()        df3 = df1[df1["trade_date"]>=one_m_start]        std_3m = df3["pct_chg"].std()        df4 = pd.DataFrame({"ts_code":codes_list[i],"std_1m":std_1m,"std_3m":std_3m},index=[0])        vol_factors = vol_factors.append(df4)        print("第%d支股票波动率因子获取成功"%i)    all_factors = all_factors.merge(vol_factors)    #获取beta    beta_factors = pd.DataFrame()    rf = 1.03**(1/360) - 1    hs300 = pro.index_daily(ts_code="399300.SZ",start_date=beta_start,end_date=beta_end)    hs300["rm"] = hs300["pct_chg"]/100 - rf    for i in range(len(codes_list)):        df1 = pro.daily(ts_code=codes_list[i],start_date=beta_start,end_date=beta_end)        df1["rp"] = df1["pct_chg"]/100 - rf        df_model = pd.merge(hs300[["trade_date","rm"]],df1[["trade_date","rp"]],on="trade_date")        df_model.index = pd.to_datetime(df1.trade_date)        df_model.sort_index(inplace=True)        model = sm.OLS(df_model["rp"],sm.add_constant(df_model["rm"]))        result = model.fit()        beta = result.params["rm"]        df2 = pd.DataFrame({"ts_code":codes_list[i],"beta":beta},index=[0])        beta_factors = beta_factors.append(df2)        print("第%d支股票beta因子获取成功"%i)    all_factors = all_factors.merge(beta_factors)    #获取换手率因子    turn_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df1["trade_date"] = df1["trade_date"].astype("int64")        turn_3m = df1["turnover_rate"].sum().mean()        df2 = df1[df1["trade_date"]>=one_m_start]        turn_1m = df2["turnover_rate"].sum().mean()        df3 = pd.DataFrame({"ts_code":codes_list[i],"turn_1m":turn_1m,"turn_3m":turn_3m},index=[0])        turn_factors = turn_factors.append(df3)        print("第%d支股票换手率因子获取成功"%i)        time.sleep(0.3)    all_factors = all_factors.merge(turn_factors)        return all_factors    数据预处理本段的数据预处理显示获取个股所属行业,这一部分需要先在网上下载一份上司公司所属中信一级行业的表格(即代码中的“ industry.xlsx ”)。之后再用merge函数合并进数据表中。之后可以利用所属行业进行行业市值中性化处理,其他预处理步骤包括中位数去极值,缺失值处理,标准化和PCA。这里的PCA主要是为了去除多重共线性的影响,不在于筛选因子。#获取标签def get_tag(data,date):    stocks = data["ts_code"].tolist()    rm = pro.index_monthly(ts_code="399300.SZ",trade_date=date).pct_chg.tolist()    return_list=[]    for i in range(len(stocks)):        r = pro.monthly(ts_code=stocks[i], trade_date=date).pct_chg.tolist()        return_list.append(r[0]-rm[0])        print("第%d支股票超额收益计算完成"%i)        time.sleep(0.5)    data["ex_return"] = return_list    return data#获取行业def get_industry(data):    df1 = pd.read_excel(r"industry.xlsx",dtype="object")    df1 = df1.rename(columns={"code":"ts_code"})    ts_codes = data["ts_code"].tolist()    data["ts_code"] = data["ts_code"].apply(lambda x:x[0:6])    data = data.merge(df1,on="ts_code")    data["ts_code"] = ts_codes    return data#数据预处理#中位数去极值def MAD(data,n):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        Dm = data[indexes[i]].quantile(0.5)        Dm1 = ((data[indexes[i]] - Dm).abs()).quantile(0.5)        max_range = Dm + n*Dm1        min_range = Dm - n*Dm1        data[indexes[i]] = np.clip(data[indexes[i]],min_range,max_range)    return data#缺失值处理def Miss_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        data[indexes[i]] = data.groupby("industry")[indexes[i]].transform(lambda x:x.fillna(x.mean()))    return data#市值行业中性化def Indifference(data):    data2 = data.drop_duplicates(subset=["industry"])    list1 = data2["industry"].tolist()    list2 = data["industry"].tolist()    industry_matrix = pd.DataFrame(columns=list1)    industry_names = industry_matrix.columns.values.tolist()    for each in range(len(industry_names)):        for i in range(len(list2)):            if list2[i] == list1[each]:                list2[i] = 1            else:                list2[i] = 0        industry_matrix[list1[each]] = list2        list2 = data["industry"].tolist()    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        model = sm.OLS(data[indexes[i]],sm.add_constant(industry_matrix))        result = model.fit()        data[indexes[i]] = result.resid    return data#标准化def Standardize(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    data[indexes] = preprocessing.scale(data[indexes])    return data        #主成分分析def PCA_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    pca = PCA(n_components=20)    new_data = pca.fit_transform(data[indexes])    new_data = pd.DataFrame(new_data)    data[indexes] = new_data    return data模型构建到这里之后用于回归模型的数据集就已经构建完成了,利用传统机器学习的步骤,将数据集分为训练集和测试集,训练集为T-2期至T-12期的数据,测试集为T-1期的数据,本模型最终目的是利用T-1期的数据预测T期个股的超额收益率。
  • [新手课堂] 机器学习之简单线性回归
    最广为人知的线性回归模型——将数据拟合成一条直线。直线拟合的模型方程为 y = ax + b,其中 a 是直线斜率,b 是直线截距。看看下面的数据,它们是从斜率为 2、截距为 -5 的直线中抽取的散点:rng = np.random.RandomState(1) x = 10 * rng.rand(50) y = 2 * x - 5 + rng.randn(50) plt.scatter(x, y);可以用 Scikit-Learn 的 LinearRegression 评估器来拟合数据,并获得最佳拟合直线:from sklearn.linear_model import LinearRegression model = LinearRegression(fit_intercept=True) model.fit(x[:, np.newaxis], y) xfit = np.linspace(0, 10, 1000) yfit = model.predict(xfit[:, np.newaxis]) plt.scatter(x, y) plt.plot(xfit, yfit);数据的斜率和截距都在模型的拟合参数中,Scikit-Learn 通常会在参数后面加一条下划线,即 coef_ 和 intercept_:print("Model slope: ", model.coef_[0]) print("Model intercept:", model.intercept_) 输出结果如下所示:Model slope: 2.02720881036 Model intercept: -4.99857708555可以看到,拟合结果与真实值非常接近,这正是我们想要的。然而,LinearRegression 评估器能做的可远不止这些——除了简单的直线拟合,它还可以处理多维度的线性回归模型:y = a 0 + a 1 x 1 + a 2 x 2 + … 里面有多个 x 变量。从几何学的角度看,这个模型是拟合三维空间中的一个平面,或者是为更高维度的数据点拟合一个超平面。虽然这类回归模型的多维特性使得它们很难可视化,但是我们可以用 NumPy 的矩阵乘法运算符创建一些数据,从而演示这类拟合过程:rng = np.random.RandomState(1) X = 10 * rng.rand(100, 3) y = 0.5 + np.dot(X, [1.5, -2., 1.]) model.fit(X, y) print(model.intercept_) print(model.coef_) 输出结果如下所示:0.5 [ 1.5 -2. 1.]
  • [新手课堂] 机器学习之简单线性回归
    最广为人知的线性回归模型——将数据拟合成一条直线。直线拟合的模型方程为 y = ax + b,其中 a 是直线斜率,b 是直线截距。看看下面的数据,它们是从斜率为 2、截距为 -5 的直线中抽取的散点:rng = np.random.RandomState(1) x = 10 * rng.rand(50) y = 2 * x - 5 + rng.randn(50) plt.scatter(x, y);可以用 Scikit-Learn 的 LinearRegression 评估器来拟合数据,并获得最佳拟合直线:from sklearn.linear_model import LinearRegression model = LinearRegression(fit_intercept=True) model.fit(x[:, np.newaxis], y) xfit = np.linspace(0, 10, 1000) yfit = model.predict(xfit[:, np.newaxis]) plt.scatter(x, y) plt.plot(xfit, yfit);数据的斜率和截距都在模型的拟合参数中,Scikit-Learn 通常会在参数后面加一条下划线,即 coef_ 和 intercept_:print("Model slope: ", model.coef_[0]) print("Model intercept:", model.intercept_) 输出结果如下所示:Model slope: 2.02720881036 Model intercept: -4.99857708555可以看到,拟合结果与真实值非常接近,这正是我们想要的。然而,LinearRegression 评估器能做的可远不止这些——除了简单的直线拟合,它还可以处理多维度的线性回归模型:y = a 0 + a 1 x 1 + a 2 x 2 + … 里面有多个 x 变量。从几何学的角度看,这个模型是拟合三维空间中的一个平面,或者是为更高维度的数据点拟合一个超平面。虽然这类回归模型的多维特性使得它们很难可视化,但是我们可以用 NumPy 的矩阵乘法运算符创建一些数据,从而演示这类拟合过程:rng = np.random.RandomState(1) X = 10 * rng.rand(100, 3) y = 0.5 + np.dot(X, [1.5, -2., 1.]) model.fit(X, y) print(model.intercept_) print(model.coef_) 输出结果如下所示:0.5 [ 1.5 -2. 1.]
  • [新手课堂] 机器学习之简单线性回归
    最广为人知的线性回归模型——将数据拟合成一条直线。直线拟合的模型方程为 y = ax + b,其中 a 是直线斜率,b 是直线截距。看看下面的数据,它们是从斜率为 2、截距为 -5 的直线中抽取的散点:rng = np.random.RandomState(1) x = 10 * rng.rand(50) y = 2 * x - 5 + rng.randn(50) plt.scatter(x, y);可以用 Scikit-Learn 的 LinearRegression 评估器来拟合数据,并获得最佳拟合直线:from sklearn.linear_model import LinearRegression model = LinearRegression(fit_intercept=True) model.fit(x[:, np.newaxis], y) xfit = np.linspace(0, 10, 1000) yfit = model.predict(xfit[:, np.newaxis]) plt.scatter(x, y) plt.plot(xfit, yfit);数据的斜率和截距都在模型的拟合参数中,Scikit-Learn 通常会在参数后面加一条下划线,即 coef_ 和 intercept_:print("Model slope: ", model.coef_[0]) print("Model intercept:", model.intercept_) 输出结果如下所示:Model slope: 2.02720881036 Model intercept: -4.99857708555可以看到,拟合结果与真实值非常接近,这正是我们想要的。然而,LinearRegression 评估器能做的可远不止这些——除了简单的直线拟合,它还可以处理多维度的线性回归模型:y = a 0 + a 1 x 1 + a 2 x 2 + … 里面有多个 x 变量。从几何学的角度看,这个模型是拟合三维空间中的一个平面,或者是为更高维度的数据点拟合一个超平面。虽然这类回归模型的多维特性使得它们很难可视化,但是我们可以用 NumPy 的矩阵乘法运算符创建一些数据,从而演示这类拟合过程:rng = np.random.RandomState(1) X = 10 * rng.rand(100, 3) y = 0.5 + np.dot(X, [1.5, -2., 1.]) model.fit(X, y) print(model.intercept_) print(model.coef_) 输出结果如下所示:0.5 [ 1.5 -2. 1.]
  • [新手课堂] 机器学习之简单线性回归
    最广为人知的线性回归模型——将数据拟合成一条直线。直线拟合的模型方程为 y = ax + b,其中 a 是直线斜率,b 是直线截距。看看下面的数据,它们是从斜率为 2、截距为 -5 的直线中抽取的散点:rng = np.random.RandomState(1) x = 10 * rng.rand(50) y = 2 * x - 5 + rng.randn(50) plt.scatter(x, y);可以用 Scikit-Learn 的 LinearRegression 评估器来拟合数据,并获得最佳拟合直线:from sklearn.linear_model import LinearRegression model = LinearRegression(fit_intercept=True) model.fit(x[:, np.newaxis], y) xfit = np.linspace(0, 10, 1000) yfit = model.predict(xfit[:, np.newaxis]) plt.scatter(x, y) plt.plot(xfit, yfit);数据的斜率和截距都在模型的拟合参数中,Scikit-Learn 通常会在参数后面加一条下划线,即 coef_ 和 intercept_:print("Model slope: ", model.coef_[0]) print("Model intercept:", model.intercept_) 输出结果如下所示:Model slope: 2.02720881036 Model intercept: -4.99857708555可以看到,拟合结果与真实值非常接近,这正是我们想要的。然而,LinearRegression 评估器能做的可远不止这些——除了简单的直线拟合,它还可以处理多维度的线性回归模型:y = a 0 + a 1 x 1 + a 2 x 2 + … 里面有多个 x 变量。从几何学的角度看,这个模型是拟合三维空间中的一个平面,或者是为更高维度的数据点拟合一个超平面。虽然这类回归模型的多维特性使得它们很难可视化,但是我们可以用 NumPy 的矩阵乘法运算符创建一些数据,从而演示这类拟合过程:rng = np.random.RandomState(1) X = 10 * rng.rand(100, 3) y = 0.5 + np.dot(X, [1.5, -2., 1.]) model.fit(X, y) print(model.intercept_) print(model.coef_) 输出结果如下所示:0.5 [ 1.5 -2. 1.]
  • [新手课堂] 多元线性回归模型选股应用(α策略)
    内容介绍本文重点在于如何利用python收集各类型因子并进行预处理最终用于构建量化选股模型。工具介绍本代码所需要调用的包如下图所示:import pandas as pdimport tushare as tspro = ts.pro_api()import numpy as npimport timeimport mathimport statsmodels.api as smfrom sklearn import preprocessingfrom sklearn.decomposition import PCAimport os这里需要用到的是python中的pandas和statsmodels模块,分别用于数据处理和做多元回归。另外,还需要获取股票和指数的各项数据,这里所用到的是tushare,tushare拥有丰富的数据内容,如股票、基金等行情数据,公司财务理等基本面数据。通过tushare平台赚取一定的积分可以免费获取平台提供的数据。(个人ID:419382)数据获取本段代码展示了如何通过tushare获取相关数据并清洗成为所需因子,共展示了估值因子,成长因子,财务质量因子,杠杆因子,动量反转因子,波动率因子以及beta的构建。其中beta因子是取个股与指数收益率线性回归的回归系数。def get_all_factors(codes_list,date,start,end,one_m_start,beta_start,beta_end):    #获取估值因子    evaluate_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定交易日的指标        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,trade_date,pe_ttm,pb,ps_ttm,dv_ttm")        evaluate_factors = evaluate_factors.append(df1)        time.sleep(0.4)        print("第%d支股票估值因子获取成功"%i)    #根据指标计算因子    evaluate_factors["EP"] = 1/evaluate_factors["pe_ttm"]     evaluate_factors["BP"] = 1/evaluate_factors["pb"]    evaluate_factors["SP"] = 1/evaluate_factors["ps_ttm"]    evaluate_factors["DP"] = evaluate_factors["dv_ttm"]    evaluate_factors = evaluate_factors[["ts_code","trade_date","EP","BP","SP","DP"]]        #获取成长因子    growth_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.income(ts_code=codes_list[i],end_date=date,                          fields="ts_code,end_date,revenue,n_income")        df1 = df1.drop_duplicates(subset=["end_date"])    #根据财报计算因子        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[[0,4],:]        revenue = df1["revenue"].tolist()        n_income = df1["n_income"].tolist()        sales_G = revenue[0]/revenue[1] - 1        profit_G = n_income[0]/n_income[1] - 1        df2 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df2 = df2.drop_duplicates(subset=["end_date"])        df2["end_date"] = df2["end_date"].astype("int64")        df2 = df2.iloc[[0,4],:]        roe = df2["roe"].tolist()        ROE_G = roe[0]/roe[1] - 1        df3 = pd.DataFrame({"ts_code":codes_list[i],"sales_G":sales_G,"profit_G":profit_G,"ROE_G":ROE_G},index=[20201231])        growth_factors = growth_factors.append(df3)        time.sleep(1.2)        print("第%d支股票成长因子获取成功"%i)    all_factors = evaluate_factors.merge(growth_factors)        #获取财务质量因子    quality_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","roe","assets_turn"]]        quality_factors = quality_factors.append(df1)        time.sleep(1)        print("第%d支股票财务质量获取成功"%i)    all_factors = all_factors.merge(quality_factors)    #获取杠杆因子    leverage_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","debt_to_assets"]]        leverage_factors = leverage_factors.append(df1)        time.sleep(0.8)        print("第%d支股票杠杆因子获取成功"%i)    all_facotrs = all_factors.merge(leverage_factors)            #获取市值因子    capital_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,total_mv")        df1["total_mv"] = df1["total_mv"].apply(lambda x:math.log(x))        capital_factors = capital_factors.append(df1)        time.sleep(0.5)        print("第%d支股票市值因子获取成功"%i)    all_factors = all_facotrs.merge(capital_factors)            #获取动量反转因子    return_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], freq='M', adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        close = df1["close"].tolist()        return_1m = df1["pct_chg"].tolist()[0]        return_3m = close[0]/close[3] - 1        df2 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df2["trade_date"] = df2["trade_date"].astype("int64")        df3 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df3["trade_date"] = df3["trade_date"].astype("int64")        df2 = df2[df2["trade_date"]>=start]        w_return_3m = (df2["pct_chg"]*df3["turnover_rate"]).sum()/len(df2)        df_1m_return = df2[df2["trade_date"]>=one_m_start]        df_1m_turnover = df3[df3["trade_date"]>=one_m_start]        w_return_1m = (df_1m_return["pct_chg"]*df_1m_turnover["turnover_rate"]).sum()/len(df_1m_return)                df4 = pd.DataFrame({"ts_code":codes_list[i],                            "return_1m":return_1m,"return_3m":return_3m,"w_return_1m":w_return_1m,"w_return_3m":w_return_3m},index=[0])        return_factors = return_factors.append(df4)        print("第%d支股票动量反转因子获取成功"%i)    all_factors = all_factors.merge(return_factors)                    #获取波动率因子    vol_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        df2 = df1[df1["trade_date"]>=start]        std_1m = df2["pct_chg"].std()        df3 = df1[df1["trade_date"]>=one_m_start]        std_3m = df3["pct_chg"].std()        df4 = pd.DataFrame({"ts_code":codes_list[i],"std_1m":std_1m,"std_3m":std_3m},index=[0])        vol_factors = vol_factors.append(df4)        print("第%d支股票波动率因子获取成功"%i)    all_factors = all_factors.merge(vol_factors)    #获取beta    beta_factors = pd.DataFrame()    rf = 1.03**(1/360) - 1    hs300 = pro.index_daily(ts_code="399300.SZ",start_date=beta_start,end_date=beta_end)    hs300["rm"] = hs300["pct_chg"]/100 - rf    for i in range(len(codes_list)):        df1 = pro.daily(ts_code=codes_list[i],start_date=beta_start,end_date=beta_end)        df1["rp"] = df1["pct_chg"]/100 - rf        df_model = pd.merge(hs300[["trade_date","rm"]],df1[["trade_date","rp"]],on="trade_date")        df_model.index = pd.to_datetime(df1.trade_date)        df_model.sort_index(inplace=True)        model = sm.OLS(df_model["rp"],sm.add_constant(df_model["rm"]))        result = model.fit()        beta = result.params["rm"]        df2 = pd.DataFrame({"ts_code":codes_list[i],"beta":beta},index=[0])        beta_factors = beta_factors.append(df2)        print("第%d支股票beta因子获取成功"%i)    all_factors = all_factors.merge(beta_factors)    #获取换手率因子    turn_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df1["trade_date"] = df1["trade_date"].astype("int64")        turn_3m = df1["turnover_rate"].sum().mean()        df2 = df1[df1["trade_date"]>=one_m_start]        turn_1m = df2["turnover_rate"].sum().mean()        df3 = pd.DataFrame({"ts_code":codes_list[i],"turn_1m":turn_1m,"turn_3m":turn_3m},index=[0])        turn_factors = turn_factors.append(df3)        print("第%d支股票换手率因子获取成功"%i)        time.sleep(0.3)    all_factors = all_factors.merge(turn_factors)        return all_factors    数据预处理本段的数据预处理显示获取个股所属行业,这一部分需要先在网上下载一份上司公司所属中信一级行业的表格(即代码中的“ industry.xlsx ”)。之后再用merge函数合并进数据表中。之后可以利用所属行业进行行业市值中性化处理,其他预处理步骤包括中位数去极值,缺失值处理,标准化和PCA。这里的PCA主要是为了去除多重共线性的影响,不在于筛选因子。#获取标签def get_tag(data,date):    stocks = data["ts_code"].tolist()    rm = pro.index_monthly(ts_code="399300.SZ",trade_date=date).pct_chg.tolist()    return_list=[]    for i in range(len(stocks)):        r = pro.monthly(ts_code=stocks[i], trade_date=date).pct_chg.tolist()        return_list.append(r[0]-rm[0])        print("第%d支股票超额收益计算完成"%i)        time.sleep(0.5)    data["ex_return"] = return_list    return data#获取行业def get_industry(data):    df1 = pd.read_excel(r"industry.xlsx",dtype="object")    df1 = df1.rename(columns={"code":"ts_code"})    ts_codes = data["ts_code"].tolist()    data["ts_code"] = data["ts_code"].apply(lambda x:x[0:6])    data = data.merge(df1,on="ts_code")    data["ts_code"] = ts_codes    return data#数据预处理#中位数去极值def MAD(data,n):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        Dm = data[indexes[i]].quantile(0.5)        Dm1 = ((data[indexes[i]] - Dm).abs()).quantile(0.5)        max_range = Dm + n*Dm1        min_range = Dm - n*Dm1        data[indexes[i]] = np.clip(data[indexes[i]],min_range,max_range)    return data#缺失值处理def Miss_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        data[indexes[i]] = data.groupby("industry")[indexes[i]].transform(lambda x:x.fillna(x.mean()))    return data#市值行业中性化def Indifference(data):    data2 = data.drop_duplicates(subset=["industry"])    list1 = data2["industry"].tolist()    list2 = data["industry"].tolist()    industry_matrix = pd.DataFrame(columns=list1)    industry_names = industry_matrix.columns.values.tolist()    for each in range(len(industry_names)):        for i in range(len(list2)):            if list2[i] == list1[each]:                list2[i] = 1            else:                list2[i] = 0        industry_matrix[list1[each]] = list2        list2 = data["industry"].tolist()    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        model = sm.OLS(data[indexes[i]],sm.add_constant(industry_matrix))        result = model.fit()        data[indexes[i]] = result.resid    return data#标准化def Standardize(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    data[indexes] = preprocessing.scale(data[indexes])    return data        #主成分分析def PCA_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    pca = PCA(n_components=20)    new_data = pca.fit_transform(data[indexes])    new_data = pd.DataFrame(new_data)    data[indexes] = new_data    return data模型构建到这里之后用于回归模型的数据集就已经构建完成了,利用传统机器学习的步骤,将数据集分为训练集和测试集,训练集为T-2期至T-12期的数据,测试集为T-1期的数据,本模型最终目的是利用T-1期的数据预测T期个股的超额收益率。
  • [新手课堂] 多元线性回归模型选股应用(α策略)
    内容介绍本文重点在于如何利用python收集各类型因子并进行预处理最终用于构建量化选股模型。工具介绍本代码所需要调用的包如下图所示:import pandas as pdimport tushare as tspro = ts.pro_api()import numpy as npimport timeimport mathimport statsmodels.api as smfrom sklearn import preprocessingfrom sklearn.decomposition import PCAimport os这里需要用到的是python中的pandas和statsmodels模块,分别用于数据处理和做多元回归。另外,还需要获取股票和指数的各项数据,这里所用到的是tushare,tushare拥有丰富的数据内容,如股票、基金等行情数据,公司财务理等基本面数据。通过tushare平台赚取一定的积分可以免费获取平台提供的数据。(个人ID:419382)数据获取本段代码展示了如何通过tushare获取相关数据并清洗成为所需因子,共展示了估值因子,成长因子,财务质量因子,杠杆因子,动量反转因子,波动率因子以及beta的构建。其中beta因子是取个股与指数收益率线性回归的回归系数。def get_all_factors(codes_list,date,start,end,one_m_start,beta_start,beta_end):    #获取估值因子    evaluate_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定交易日的指标        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,trade_date,pe_ttm,pb,ps_ttm,dv_ttm")        evaluate_factors = evaluate_factors.append(df1)        time.sleep(0.4)        print("第%d支股票估值因子获取成功"%i)    #根据指标计算因子    evaluate_factors["EP"] = 1/evaluate_factors["pe_ttm"]     evaluate_factors["BP"] = 1/evaluate_factors["pb"]    evaluate_factors["SP"] = 1/evaluate_factors["ps_ttm"]    evaluate_factors["DP"] = evaluate_factors["dv_ttm"]    evaluate_factors = evaluate_factors[["ts_code","trade_date","EP","BP","SP","DP"]]        #获取成长因子    growth_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.income(ts_code=codes_list[i],end_date=date,                          fields="ts_code,end_date,revenue,n_income")        df1 = df1.drop_duplicates(subset=["end_date"])    #根据财报计算因子        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[[0,4],:]        revenue = df1["revenue"].tolist()        n_income = df1["n_income"].tolist()        sales_G = revenue[0]/revenue[1] - 1        profit_G = n_income[0]/n_income[1] - 1        df2 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df2 = df2.drop_duplicates(subset=["end_date"])        df2["end_date"] = df2["end_date"].astype("int64")        df2 = df2.iloc[[0,4],:]        roe = df2["roe"].tolist()        ROE_G = roe[0]/roe[1] - 1        df3 = pd.DataFrame({"ts_code":codes_list[i],"sales_G":sales_G,"profit_G":profit_G,"ROE_G":ROE_G},index=[20201231])        growth_factors = growth_factors.append(df3)        time.sleep(1.2)        print("第%d支股票成长因子获取成功"%i)    all_factors = evaluate_factors.merge(growth_factors)        #获取财务质量因子    quality_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","roe","assets_turn"]]        quality_factors = quality_factors.append(df1)        time.sleep(1)        print("第%d支股票财务质量获取成功"%i)    all_factors = all_factors.merge(quality_factors)    #获取杠杆因子    leverage_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","debt_to_assets"]]        leverage_factors = leverage_factors.append(df1)        time.sleep(0.8)        print("第%d支股票杠杆因子获取成功"%i)    all_facotrs = all_factors.merge(leverage_factors)            #获取市值因子    capital_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,total_mv")        df1["total_mv"] = df1["total_mv"].apply(lambda x:math.log(x))        capital_factors = capital_factors.append(df1)        time.sleep(0.5)        print("第%d支股票市值因子获取成功"%i)    all_factors = all_facotrs.merge(capital_factors)            #获取动量反转因子    return_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], freq='M', adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        close = df1["close"].tolist()        return_1m = df1["pct_chg"].tolist()[0]        return_3m = close[0]/close[3] - 1        df2 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df2["trade_date"] = df2["trade_date"].astype("int64")        df3 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df3["trade_date"] = df3["trade_date"].astype("int64")        df2 = df2[df2["trade_date"]>=start]        w_return_3m = (df2["pct_chg"]*df3["turnover_rate"]).sum()/len(df2)        df_1m_return = df2[df2["trade_date"]>=one_m_start]        df_1m_turnover = df3[df3["trade_date"]>=one_m_start]        w_return_1m = (df_1m_return["pct_chg"]*df_1m_turnover["turnover_rate"]).sum()/len(df_1m_return)                df4 = pd.DataFrame({"ts_code":codes_list[i],                            "return_1m":return_1m,"return_3m":return_3m,"w_return_1m":w_return_1m,"w_return_3m":w_return_3m},index=[0])        return_factors = return_factors.append(df4)        print("第%d支股票动量反转因子获取成功"%i)    all_factors = all_factors.merge(return_factors)                    #获取波动率因子    vol_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        df2 = df1[df1["trade_date"]>=start]        std_1m = df2["pct_chg"].std()        df3 = df1[df1["trade_date"]>=one_m_start]        std_3m = df3["pct_chg"].std()        df4 = pd.DataFrame({"ts_code":codes_list[i],"std_1m":std_1m,"std_3m":std_3m},index=[0])        vol_factors = vol_factors.append(df4)        print("第%d支股票波动率因子获取成功"%i)    all_factors = all_factors.merge(vol_factors)    #获取beta    beta_factors = pd.DataFrame()    rf = 1.03**(1/360) - 1    hs300 = pro.index_daily(ts_code="399300.SZ",start_date=beta_start,end_date=beta_end)    hs300["rm"] = hs300["pct_chg"]/100 - rf    for i in range(len(codes_list)):        df1 = pro.daily(ts_code=codes_list[i],start_date=beta_start,end_date=beta_end)        df1["rp"] = df1["pct_chg"]/100 - rf        df_model = pd.merge(hs300[["trade_date","rm"]],df1[["trade_date","rp"]],on="trade_date")        df_model.index = pd.to_datetime(df1.trade_date)        df_model.sort_index(inplace=True)        model = sm.OLS(df_model["rp"],sm.add_constant(df_model["rm"]))        result = model.fit()        beta = result.params["rm"]        df2 = pd.DataFrame({"ts_code":codes_list[i],"beta":beta},index=[0])        beta_factors = beta_factors.append(df2)        print("第%d支股票beta因子获取成功"%i)    all_factors = all_factors.merge(beta_factors)    #获取换手率因子    turn_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df1["trade_date"] = df1["trade_date"].astype("int64")        turn_3m = df1["turnover_rate"].sum().mean()        df2 = df1[df1["trade_date"]>=one_m_start]        turn_1m = df2["turnover_rate"].sum().mean()        df3 = pd.DataFrame({"ts_code":codes_list[i],"turn_1m":turn_1m,"turn_3m":turn_3m},index=[0])        turn_factors = turn_factors.append(df3)        print("第%d支股票换手率因子获取成功"%i)        time.sleep(0.3)    all_factors = all_factors.merge(turn_factors)        return all_factors    数据预处理本段的数据预处理显示获取个股所属行业,这一部分需要先在网上下载一份上司公司所属中信一级行业的表格(即代码中的“ industry.xlsx ”)。之后再用merge函数合并进数据表中。之后可以利用所属行业进行行业市值中性化处理,其他预处理步骤包括中位数去极值,缺失值处理,标准化和PCA。这里的PCA主要是为了去除多重共线性的影响,不在于筛选因子。#获取标签def get_tag(data,date):    stocks = data["ts_code"].tolist()    rm = pro.index_monthly(ts_code="399300.SZ",trade_date=date).pct_chg.tolist()    return_list=[]    for i in range(len(stocks)):        r = pro.monthly(ts_code=stocks[i], trade_date=date).pct_chg.tolist()        return_list.append(r[0]-rm[0])        print("第%d支股票超额收益计算完成"%i)        time.sleep(0.5)    data["ex_return"] = return_list    return data#获取行业def get_industry(data):    df1 = pd.read_excel(r"industry.xlsx",dtype="object")    df1 = df1.rename(columns={"code":"ts_code"})    ts_codes = data["ts_code"].tolist()    data["ts_code"] = data["ts_code"].apply(lambda x:x[0:6])    data = data.merge(df1,on="ts_code")    data["ts_code"] = ts_codes    return data#数据预处理#中位数去极值def MAD(data,n):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        Dm = data[indexes[i]].quantile(0.5)        Dm1 = ((data[indexes[i]] - Dm).abs()).quantile(0.5)        max_range = Dm + n*Dm1        min_range = Dm - n*Dm1        data[indexes[i]] = np.clip(data[indexes[i]],min_range,max_range)    return data#缺失值处理def Miss_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        data[indexes[i]] = data.groupby("industry")[indexes[i]].transform(lambda x:x.fillna(x.mean()))    return data#市值行业中性化def Indifference(data):    data2 = data.drop_duplicates(subset=["industry"])    list1 = data2["industry"].tolist()    list2 = data["industry"].tolist()    industry_matrix = pd.DataFrame(columns=list1)    industry_names = industry_matrix.columns.values.tolist()    for each in range(len(industry_names)):        for i in range(len(list2)):            if list2[i] == list1[each]:                list2[i] = 1            else:                list2[i] = 0        industry_matrix[list1[each]] = list2        list2 = data["industry"].tolist()    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        model = sm.OLS(data[indexes[i]],sm.add_constant(industry_matrix))        result = model.fit()        data[indexes[i]] = result.resid    return data#标准化def Standardize(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    data[indexes] = preprocessing.scale(data[indexes])    return data        #主成分分析def PCA_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    pca = PCA(n_components=20)    new_data = pca.fit_transform(data[indexes])    new_data = pd.DataFrame(new_data)    data[indexes] = new_data    return data模型构建到这里之后用于回归模型的数据集就已经构建完成了,利用传统机器学习的步骤,将数据集分为训练集和测试集,训练集为T-2期至T-12期的数据,测试集为T-1期的数据,本模型最终目的是利用T-1期的数据预测T期个股的超额收益率。
  • [其他] 机器学习分类与回归
    1.机器学习的主要任务:一是将实例数据划分到合适的分类中,即分类问题。 而是是回归, 它主要用于预测数值型数据,典型的回归例子:数据拟合曲线。2.监督学习和无监督学习:分类和回归属于监督学习,之所以称之为监督学习,是因为这类算法必须直到预测什么,即目标变量的分类信息。对于无监督学习,此时数据没有类别信息,也不会给定目标值。在无监督学习中,将数据集合分成由类似的对象组成的多个类的过程被成为聚类;将寻找描述数据统计值的过程称之为密度估计。此外,无监督学习还可以减少数据特征的维度,以便我们可以使用二维或者三维图形更加直观地展示数据信息。3.线性回归和非线性回归  线性回归需要一个线性模型。一个线性的模型意味着模型的每一项要么是一个常数,要么是一个常数和一个预测变量的乘积。一个线性等式等于每一项相加的和。等式:Response = constant + parameter * predictor + ... + parameter * predictor  <=>  Y = b o + b1X1 + b2X2 + ... + bkXk在统计学中,如果一个回归方程是线性的,那么它的参数必须是线性的。但是可以转换预测变量加上平方,来使得模型产生曲线,比如 Y = b o + b1X1 + b2X12这时模型仍然是线性的,虽然预测变量带有平方。当然加上log或者反函数也可以。
  • [技术干货] 【MindSpore:跟着小Mi一起机器学习】单变量线性回归(二)
    小Mi学习,向上积极!在上一篇机器学习中,小Mi已经带大家认识了单变量线性回归的数学模型,以及对应代价函数的图形解释,小Mi也提及过,我们真正需要的是一种有效的算法,能够自动地找出这些使代价函数J取最小值的参数,来,因此它来了它来了!今天小Mi在此基础上,继续带大家一起学习梯度下降算法。3梯度下降梯度下降法是一个用来求函数最小值的算法,同理其他函数最小化问题也可以用此解决,因此适用于一般所有函数。梯度下降的原理就是:开始时我们随机选择一个参数的组合,计算代价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合,我们持续这么做直到达到一个局部最小值,因为我们并没有尝试完所有的参数组合,所以不能确定我们得到的局部最小值是否便是全局最小值,选择不同的初始参数组合,可能会找到不同的局部最小值;言简意赅点儿:梯度下降法就是给定,初始值,通常都为0或其他值;然后不停地一点点改变,来使得变小,直到我们找到J的最小值或局部最小值。3.1 背后思想假设的函数图形如上图所示,不管,取值为多少,假设一个情景,想象你正站立在某个公园的其中一座红色山上(起点为绿色爱心处),在梯度下降算法中,我们要做的就是旋转360度,看看周围,并决定从什么方向将会最快下山,然后迈进了一小步;接着到达另一点,你再看一下周围,你会发现最佳的下山方向,你再看看周围,然后再一次想想,我应该从什么方向迈着小碎步下山?然后你按照自己的判断又迈出一步,重复上面的步骤,并依次类推,直到你接近局部最低点的位置。而如果假设初始值在另一点,又会得到上图中另一个完全不同的局部最优解。背后的数学原理,批量梯度下降算法的公式为:在梯度下降算法中,还有一个更细节的问题,梯度下降中,我们要更新,当j=0,j=1时,会产生更新,所以你将更新。实现梯度下降算法的微妙之处是,在这个表达式中,计算上述公式右边的部分,通过那一部分计算出(赋值语句:a:=b,设定不管a的初始值是多少,都将b的值赋值给a;真假判断语句:a=b,表示做一个声明,断言a和b的值相同) 。是学习率,它决定了我们沿着能让代价函数下降程度最大的方向上迈出的步子有多大。如果比较大,梯度下降就很迅速,就会大步子下山;如果比较小,就会迈着小碎步下山。在批量梯度下降过程中,我们每一次都同时让所有的参数减去学习速率乘以代价函数的导数。3.2  梯度下降的直观理解而对于求导这部分我们可以结合图形来看,取这个红色爱心点的切线,就是这样一条红色的直线,刚好与函数相切于这一点,这条直线的斜率正好是这个三角形的高度除以水平长度,现在,这条有一个正斜率,也就是说它有正导数,同时,梯度下降法的更新规则表示为:太小了,即我的学习速率小,结果就是只能这样一点点地慢慢挪动,去努力接近最低点,这样就需要很多步才能到达全局最低点;如果太大,那么梯度下降法可能会越过最低点,甚至可能无法收敛,下一次迭代又移动了一大步,越过一次,又越过一次,一次次越过最低点,直到你发现实际上离最低点越来越远。所以,如果太大,它会导致无法收敛,甚至发散。小Mi带大家再来看个例子,上图是代价函数。我想找到它的最小值,首先初始化我的梯度下降法,在图像右侧红色点开始初始化,如果我更新一步梯度下降,也许它会带我到绿色的点,可以发现这个点的切线是相当陡的;然后沿着这个绿色的点,如果我再更新一步,你会发现我的切线没有那么陡了。所以,每梯度下降一步后,新的导数会变小一点点,最终导数项是越来越小,接近于零的,更新的幅度也会更小。因此,随着梯度下降法的运行,移动的幅度会自动变得越来越小,直到最终移动幅度非常小,这时我们就可以发现,已经收敛到局部极小值。小Mi还有一个问题,如果我们预先把放在一个局部的最低点,你认为下一步梯度下降会怎么样工作?假设将初始化在局部最低点,那么该点的导数为零。这就意味着你已经在局部最优点,它能使得不再改变,也就是新的等于原来的。因此,如果你的参数已经处于局部最低点,那么梯度下降法更新其实什么都没做,它不会改变参数的值。这也解释了为什么即使学习速率保持不变时,梯度下降也可以收敛到局部最低点。这就是梯度下降算法,你可以用它来最小化任何代价函数J,不只是线性回归中的代价函数J。3.3 梯度下降法的线性回归算法接着,我们要将梯度下降和代价函数结合,将其应用于具体的拟合直线的线性回归算法里。梯度下降算法和线性回归算法比较如图:对之前的线性回归问题运用梯度下降法,关键在于求出代价函数的导数项,即:通过图像我们可以发现线性回归的代价函数总是一个凸函数。这个函数没有局部最优解,只有一个全局最优解,不断改变,直至到了全局最小值,全局最小对应的假设曲线能很好地拟合数据,这就是梯度下降。这样的算法,有时也称为批量梯度下降。梯度下降法,指的是在梯度下降的每一步中,我们都用到了所有的训练样本,在梯度下降中,在计算微分求导项时,我们需要进行求和运算,所以,在每一个单独的梯度下降中,我们最终都要计算这样一个东西,这个项需要对所有m个训练样本求和。因此,批量梯度下降法这个名字说明了我们需要考虑所有这一“批”训练样本,而事实上,有时也有其他类型的梯度下降法,不是这种“批量”型的,不考虑整个的训练集,而是每次只关注训练集中年的一些小子集。在后面的学习中,小Mi也会陆续给大家介绍~当然啦,可能你会知道还有一种计算代价函数J最小值的数值解法,不需要梯度下降这种迭代算法。它可以在不需要多步梯度下降的情况下,也能解出代价函数J的最小值,这是另一种称为正规方程的方法,同样,在后面的课程中,小Mi也会带领大家一起学习啦。不过实际上在数据量较大的情况下,梯度下降法比正规方程更适用一些。今天小Mi带着大家一起学习了梯度下降法,以及线性回归算法,而代价函数J最小化的梯度下降法不仅仅用在线性回归上,还被用在机器学习的众多领域来最小化其他函数。所以,在这里小Mi先祝贺大家成功地学会第一个机器学习算法(撒花撒花~),我们下期再见~原文链接:https://blog.csdn.net/skytttttt9394/article/details/122244980?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164224086116780357283983%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164224086116780357283983&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-5-122244980.first_rank_v2_pc_rank_v29&utm_term=MindSpore&spm=1018.2226.3001.4187
  • [新手课堂] 多元线性回归模型选股应用(α策略)
    本文重点在于如何利用python收集各类型因子并进行预处理最终用于构建量化选股模型。工具介绍本代码所需要调用的包如下图所示:import pandas as pdimport tushare as tspro = ts.pro_api()import numpy as npimport timeimport mathimport statsmodels.api as smfrom sklearn import preprocessingfrom sklearn.decomposition import PCAimport os这里需要用到的是python中的pandas和statsmodels模块,分别用于数据处理和做多元回归。另外,还需要获取股票和指数的各项数据,这里所用到的是tushare,tushare拥有丰富的数据内容,如股票、基金等行情数据,公司财务理等基本面数据。通过tushare平台赚取一定的积分可以免费获取平台提供的数据。(个人ID:419382)数据获取本段代码展示了如何通过tushare获取相关数据并清洗成为所需因子,共展示了估值因子,成长因子,财务质量因子,杠杆因子,动量反转因子,波动率因子以及beta的构建。其中beta因子是取个股与指数收益率线性回归的回归系数。def get_all_factors(codes_list,date,start,end,one_m_start,beta_start,beta_end):    #获取估值因子    evaluate_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定交易日的指标        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,trade_date,pe_ttm,pb,ps_ttm,dv_ttm")        evaluate_factors = evaluate_factors.append(df1)        time.sleep(0.4)        print("第%d支股票估值因子获取成功"%i)    #根据指标计算因子    evaluate_factors["EP"] = 1/evaluate_factors["pe_ttm"]     evaluate_factors["BP"] = 1/evaluate_factors["pb"]    evaluate_factors["SP"] = 1/evaluate_factors["ps_ttm"]    evaluate_factors["DP"] = evaluate_factors["dv_ttm"]    evaluate_factors = evaluate_factors[["ts_code","trade_date","EP","BP","SP","DP"]]        #获取成长因子    growth_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.income(ts_code=codes_list[i],end_date=date,                          fields="ts_code,end_date,revenue,n_income")        df1 = df1.drop_duplicates(subset=["end_date"])    #根据财报计算因子        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[[0,4],:]        revenue = df1["revenue"].tolist()        n_income = df1["n_income"].tolist()        sales_G = revenue[0]/revenue[1] - 1        profit_G = n_income[0]/n_income[1] - 1        df2 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df2 = df2.drop_duplicates(subset=["end_date"])        df2["end_date"] = df2["end_date"].astype("int64")        df2 = df2.iloc[[0,4],:]        roe = df2["roe"].tolist()        ROE_G = roe[0]/roe[1] - 1        df3 = pd.DataFrame({"ts_code":codes_list[i],"sales_G":sales_G,"profit_G":profit_G,"ROE_G":ROE_G},index=[20201231])        growth_factors = growth_factors.append(df3)        time.sleep(1.2)        print("第%d支股票成长因子获取成功"%i)    all_factors = evaluate_factors.merge(growth_factors)        #获取财务质量因子    quality_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","roe","assets_turn"]]        quality_factors = quality_factors.append(df1)        time.sleep(1)        print("第%d支股票财务质量获取成功"%i)    all_factors = all_factors.merge(quality_factors)    #获取杠杆因子    leverage_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","debt_to_assets"]]        leverage_factors = leverage_factors.append(df1)        time.sleep(0.8)        print("第%d支股票杠杆因子获取成功"%i)    all_facotrs = all_factors.merge(leverage_factors)            #获取市值因子    capital_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,total_mv")        df1["total_mv"] = df1["total_mv"].apply(lambda x:math.log(x))        capital_factors = capital_factors.append(df1)        time.sleep(0.5)        print("第%d支股票市值因子获取成功"%i)    all_factors = all_facotrs.merge(capital_factors)            #获取动量反转因子    return_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], freq='M', adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        close = df1["close"].tolist()        return_1m = df1["pct_chg"].tolist()[0]        return_3m = close[0]/close[3] - 1        df2 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df2["trade_date"] = df2["trade_date"].astype("int64")        df3 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df3["trade_date"] = df3["trade_date"].astype("int64")        df2 = df2[df2["trade_date"]>=start]        w_return_3m = (df2["pct_chg"]*df3["turnover_rate"]).sum()/len(df2)        df_1m_return = df2[df2["trade_date"]>=one_m_start]        df_1m_turnover = df3[df3["trade_date"]>=one_m_start]        w_return_1m = (df_1m_return["pct_chg"]*df_1m_turnover["turnover_rate"]).sum()/len(df_1m_return)                df4 = pd.DataFrame({"ts_code":codes_list[i],                            "return_1m":return_1m,"return_3m":return_3m,"w_return_1m":w_return_1m,"w_return_3m":w_return_3m},index=[0])        return_factors = return_factors.append(df4)        print("第%d支股票动量反转因子获取成功"%i)    all_factors = all_factors.merge(return_factors)                    #获取波动率因子    vol_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        df2 = df1[df1["trade_date"]>=start]        std_1m = df2["pct_chg"].std()        df3 = df1[df1["trade_date"]>=one_m_start]        std_3m = df3["pct_chg"].std()        df4 = pd.DataFrame({"ts_code":codes_list[i],"std_1m":std_1m,"std_3m":std_3m},index=[0])        vol_factors = vol_factors.append(df4)        print("第%d支股票波动率因子获取成功"%i)    all_factors = all_factors.merge(vol_factors)    #获取beta    beta_factors = pd.DataFrame()    rf = 1.03**(1/360) - 1    hs300 = pro.index_daily(ts_code="399300.SZ",start_date=beta_start,end_date=beta_end)    hs300["rm"] = hs300["pct_chg"]/100 - rf    for i in range(len(codes_list)):        df1 = pro.daily(ts_code=codes_list[i],start_date=beta_start,end_date=beta_end)        df1["rp"] = df1["pct_chg"]/100 - rf        df_model = pd.merge(hs300[["trade_date","rm"]],df1[["trade_date","rp"]],on="trade_date")        df_model.index = pd.to_datetime(df1.trade_date)        df_model.sort_index(inplace=True)        model = sm.OLS(df_model["rp"],sm.add_constant(df_model["rm"]))        result = model.fit()        beta = result.params["rm"]        df2 = pd.DataFrame({"ts_code":codes_list[i],"beta":beta},index=[0])        beta_factors = beta_factors.append(df2)        print("第%d支股票beta因子获取成功"%i)    all_factors = all_factors.merge(beta_factors)    #获取换手率因子    turn_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df1["trade_date"] = df1["trade_date"].astype("int64")        turn_3m = df1["turnover_rate"].sum().mean()        df2 = df1[df1["trade_date"]>=one_m_start]        turn_1m = df2["turnover_rate"].sum().mean()        df3 = pd.DataFrame({"ts_code":codes_list[i],"turn_1m":turn_1m,"turn_3m":turn_3m},index=[0])        turn_factors = turn_factors.append(df3)        print("第%d支股票换手率因子获取成功"%i)        time.sleep(0.3)    all_factors = all_factors.merge(turn_factors)        return all_factors    数据预处理本段的数据预处理显示获取个股所属行业,这一部分需要先在网上下载一份上司公司所属中信一级行业的表格(即代码中的“ industry.xlsx ”)。之后再用merge函数合并进数据表中。之后可以利用所属行业进行行业市值中性化处理,其他预处理步骤包括中位数去极值,缺失值处理,标准化和PCA。这里的PCA主要是为了去除多重共线性的影响,不在于筛选因子。#获取标签def get_tag(data,date):    stocks = data["ts_code"].tolist()    rm = pro.index_monthly(ts_code="399300.SZ",trade_date=date).pct_chg.tolist()    return_list=[]    for i in range(len(stocks)):        r = pro.monthly(ts_code=stocks[i], trade_date=date).pct_chg.tolist()        return_list.append(r[0]-rm[0])        print("第%d支股票超额收益计算完成"%i)        time.sleep(0.5)    data["ex_return"] = return_list    return data#获取行业def get_industry(data):    df1 = pd.read_excel(r"industry.xlsx",dtype="object")    df1 = df1.rename(columns={"code":"ts_code"})    ts_codes = data["ts_code"].tolist()    data["ts_code"] = data["ts_code"].apply(lambda x:x[0:6])    data = data.merge(df1,on="ts_code")    data["ts_code"] = ts_codes    return data#数据预处理#中位数去极值def MAD(data,n):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        Dm = data[indexes[i]].quantile(0.5)        Dm1 = ((data[indexes[i]] - Dm).abs()).quantile(0.5)        max_range = Dm + n*Dm1        min_range = Dm - n*Dm1        data[indexes[i]] = np.clip(data[indexes[i]],min_range,max_range)    return data#缺失值处理def Miss_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        data[indexes[i]] = data.groupby("industry")[indexes[i]].transform(lambda x:x.fillna(x.mean()))    return data#市值行业中性化def Indifference(data):    data2 = data.drop_duplicates(subset=["industry"])    list1 = data2["industry"].tolist()    list2 = data["industry"].tolist()    industry_matrix = pd.DataFrame(columns=list1)    industry_names = industry_matrix.columns.values.tolist()    for each in range(len(industry_names)):        for i in range(len(list2)):            if list2[i] == list1[each]:                list2[i] = 1            else:                list2[i] = 0        industry_matrix[list1[each]] = list2        list2 = data["industry"].tolist()    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        model = sm.OLS(data[indexes[i]],sm.add_constant(industry_matrix))        result = model.fit()        data[indexes[i]] = result.resid    return data#标准化def Standardize(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    data[indexes] = preprocessing.scale(data[indexes])    return data        #主成分分析def PCA_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    pca = PCA(n_components=20)    new_data = pca.fit_transform(data[indexes])    new_data = pd.DataFrame(new_data)    data[indexes] = new_data    return data模型构建到这里之后用于回归模型的数据集就已经构建完成了,利用传统机器学习的步骤,将数据集分为训练集和测试集,训练集为T-2期至T-12期的数据,测试集为T-1期的数据,本模型最终目的是利用T-1期的数据预测T期个股的超额收益率。
  • [交流吐槽] 多元线性回归模型选股应用(α策略)
    内容介绍本文重点在于如何利用python收集各类型因子并进行预处理最终用于构建量化选股模型。工具介绍本代码所需要调用的包如下图所示:import pandas as pdimport tushare as tspro = ts.pro_api()import numpy as npimport timeimport mathimport statsmodels.api as smfrom sklearn import preprocessingfrom sklearn.decomposition import PCAimport os这里需要用到的是python中的pandas和statsmodels模块,分别用于数据处理和做多元回归。另外,还需要获取股票和指数的各项数据,这里所用到的是tushare,tushare拥有丰富的数据内容,如股票、基金等行情数据,公司财务理等基本面数据。通过tushare平台赚取一定的积分可以免费获取平台提供的数据。(个人ID:419382)数据获取本段代码展示了如何通过tushare获取相关数据并清洗成为所需因子,共展示了估值因子,成长因子,财务质量因子,杠杆因子,动量反转因子,波动率因子以及beta的构建。其中beta因子是取个股与指数收益率线性回归的回归系数。def get_all_factors(codes_list,date,start,end,one_m_start,beta_start,beta_end):    #获取估值因子    evaluate_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定交易日的指标        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,trade_date,pe_ttm,pb,ps_ttm,dv_ttm")        evaluate_factors = evaluate_factors.append(df1)        time.sleep(0.4)        print("第%d支股票估值因子获取成功"%i)    #根据指标计算因子    evaluate_factors["EP"] = 1/evaluate_factors["pe_ttm"]     evaluate_factors["BP"] = 1/evaluate_factors["pb"]    evaluate_factors["SP"] = 1/evaluate_factors["ps_ttm"]    evaluate_factors["DP"] = evaluate_factors["dv_ttm"]    evaluate_factors = evaluate_factors[["ts_code","trade_date","EP","BP","SP","DP"]]        #获取成长因子    growth_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.income(ts_code=codes_list[i],end_date=date,                          fields="ts_code,end_date,revenue,n_income")        df1 = df1.drop_duplicates(subset=["end_date"])    #根据财报计算因子        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[[0,4],:]        revenue = df1["revenue"].tolist()        n_income = df1["n_income"].tolist()        sales_G = revenue[0]/revenue[1] - 1        profit_G = n_income[0]/n_income[1] - 1        df2 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df2 = df2.drop_duplicates(subset=["end_date"])        df2["end_date"] = df2["end_date"].astype("int64")        df2 = df2.iloc[[0,4],:]        roe = df2["roe"].tolist()        ROE_G = roe[0]/roe[1] - 1        df3 = pd.DataFrame({"ts_code":codes_list[i],"sales_G":sales_G,"profit_G":profit_G,"ROE_G":ROE_G},index=[20201231])        growth_factors = growth_factors.append(df3)        time.sleep(1.2)        print("第%d支股票成长因子获取成功"%i)    all_factors = evaluate_factors.merge(growth_factors)        #获取财务质量因子    quality_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","roe","assets_turn"]]        quality_factors = quality_factors.append(df1)        time.sleep(1)        print("第%d支股票财务质量获取成功"%i)    all_factors = all_factors.merge(quality_factors)    #获取杠杆因子    leverage_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","debt_to_assets"]]        leverage_factors = leverage_factors.append(df1)        time.sleep(0.8)        print("第%d支股票杠杆因子获取成功"%i)    all_facotrs = all_factors.merge(leverage_factors)            #获取市值因子    capital_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,total_mv")        df1["total_mv"] = df1["total_mv"].apply(lambda x:math.log(x))        capital_factors = capital_factors.append(df1)        time.sleep(0.5)        print("第%d支股票市值因子获取成功"%i)    all_factors = all_facotrs.merge(capital_factors)            #获取动量反转因子    return_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], freq='M', adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        close = df1["close"].tolist()        return_1m = df1["pct_chg"].tolist()[0]        return_3m = close[0]/close[3] - 1        df2 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df2["trade_date"] = df2["trade_date"].astype("int64")        df3 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df3["trade_date"] = df3["trade_date"].astype("int64")        df2 = df2[df2["trade_date"]>=start]        w_return_3m = (df2["pct_chg"]*df3["turnover_rate"]).sum()/len(df2)        df_1m_return = df2[df2["trade_date"]>=one_m_start]        df_1m_turnover = df3[df3["trade_date"]>=one_m_start]        w_return_1m = (df_1m_return["pct_chg"]*df_1m_turnover["turnover_rate"]).sum()/len(df_1m_return)                df4 = pd.DataFrame({"ts_code":codes_list[i],                            "return_1m":return_1m,"return_3m":return_3m,"w_return_1m":w_return_1m,"w_return_3m":w_return_3m},index=[0])        return_factors = return_factors.append(df4)        print("第%d支股票动量反转因子获取成功"%i)    all_factors = all_factors.merge(return_factors)                    #获取波动率因子    vol_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        df2 = df1[df1["trade_date"]>=start]        std_1m = df2["pct_chg"].std()        df3 = df1[df1["trade_date"]>=one_m_start]        std_3m = df3["pct_chg"].std()        df4 = pd.DataFrame({"ts_code":codes_list[i],"std_1m":std_1m,"std_3m":std_3m},index=[0])        vol_factors = vol_factors.append(df4)        print("第%d支股票波动率因子获取成功"%i)    all_factors = all_factors.merge(vol_factors)    #获取beta    beta_factors = pd.DataFrame()    rf = 1.03**(1/360) - 1    hs300 = pro.index_daily(ts_code="399300.SZ",start_date=beta_start,end_date=beta_end)    hs300["rm"] = hs300["pct_chg"]/100 - rf    for i in range(len(codes_list)):        df1 = pro.daily(ts_code=codes_list[i],start_date=beta_start,end_date=beta_end)        df1["rp"] = df1["pct_chg"]/100 - rf        df_model = pd.merge(hs300[["trade_date","rm"]],df1[["trade_date","rp"]],on="trade_date")        df_model.index = pd.to_datetime(df1.trade_date)        df_model.sort_index(inplace=True)        model = sm.OLS(df_model["rp"],sm.add_constant(df_model["rm"]))        result = model.fit()        beta = result.params["rm"]        df2 = pd.DataFrame({"ts_code":codes_list[i],"beta":beta},index=[0])        beta_factors = beta_factors.append(df2)        print("第%d支股票beta因子获取成功"%i)    all_factors = all_factors.merge(beta_factors)    #获取换手率因子    turn_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df1["trade_date"] = df1["trade_date"].astype("int64")        turn_3m = df1["turnover_rate"].sum().mean()        df2 = df1[df1["trade_date"]>=one_m_start]        turn_1m = df2["turnover_rate"].sum().mean()        df3 = pd.DataFrame({"ts_code":codes_list[i],"turn_1m":turn_1m,"turn_3m":turn_3m},index=[0])        turn_factors = turn_factors.append(df3)        print("第%d支股票换手率因子获取成功"%i)        time.sleep(0.3)    all_factors = all_factors.merge(turn_factors)        return all_factors    数据预处理本段的数据预处理显示获取个股所属行业,这一部分需要先在网上下载一份上司公司所属中信一级行业的表格(即代码中的“ industry.xlsx ”)。之后再用merge函数合并进数据表中。之后可以利用所属行业进行行业市值中性化处理,其他预处理步骤包括中位数去极值,缺失值处理,标准化和PCA。这里的PCA主要是为了去除多重共线性的影响,不在于筛选因子。#获取标签def get_tag(data,date):    stocks = data["ts_code"].tolist()    rm = pro.index_monthly(ts_code="399300.SZ",trade_date=date).pct_chg.tolist()    return_list=[]    for i in range(len(stocks)):        r = pro.monthly(ts_code=stocks[i], trade_date=date).pct_chg.tolist()        return_list.append(r[0]-rm[0])        print("第%d支股票超额收益计算完成"%i)        time.sleep(0.5)    data["ex_return"] = return_list    return data#获取行业def get_industry(data):    df1 = pd.read_excel(r"industry.xlsx",dtype="object")    df1 = df1.rename(columns={"code":"ts_code"})    ts_codes = data["ts_code"].tolist()    data["ts_code"] = data["ts_code"].apply(lambda x:x[0:6])    data = data.merge(df1,on="ts_code")    data["ts_code"] = ts_codes    return data#数据预处理#中位数去极值def MAD(data,n):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        Dm = data[indexes[i]].quantile(0.5)        Dm1 = ((data[indexes[i]] - Dm).abs()).quantile(0.5)        max_range = Dm + n*Dm1        min_range = Dm - n*Dm1        data[indexes[i]] = np.clip(data[indexes[i]],min_range,max_range)    return data#缺失值处理def Miss_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        data[indexes[i]] = data.groupby("industry")[indexes[i]].transform(lambda x:x.fillna(x.mean()))    return data#市值行业中性化def Indifference(data):    data2 = data.drop_duplicates(subset=["industry"])    list1 = data2["industry"].tolist()    list2 = data["industry"].tolist()    industry_matrix = pd.DataFrame(columns=list1)    industry_names = industry_matrix.columns.values.tolist()    for each in range(len(industry_names)):        for i in range(len(list2)):            if list2[i] == list1[each]:                list2[i] = 1            else:                list2[i] = 0        industry_matrix[list1[each]] = list2        list2 = data["industry"].tolist()    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        model = sm.OLS(data[indexes[i]],sm.add_constant(industry_matrix))        result = model.fit()        data[indexes[i]] = result.resid    return data#标准化def Standardize(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    data[indexes] = preprocessing.scale(data[indexes])    return data        #主成分分析def PCA_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    pca = PCA(n_components=20)    new_data = pca.fit_transform(data[indexes])    new_data = pd.DataFrame(new_data)    data[indexes] = new_data    return data模型构建到这里之后用于回归模型的数据集就已经构建完成了,利用传统机器学习的步骤,将数据集分为训练集和测试集,训练集为T-2期至T-12期的数据,测试集为T-1期的数据,本模型最终目的是利用T-1期的数据预测T期个股的超额收益率。
  • [交流吐槽] 多元线性回归模型选股应用(α策略)
    内容介绍本文重点在于如何利用python收集各类型因子并进行预处理最终用于构建量化选股模型。工具介绍本代码所需要调用的包如下图所示:import pandas as pdimport tushare as tspro = ts.pro_api()import numpy as npimport timeimport mathimport statsmodels.api as smfrom sklearn import preprocessingfrom sklearn.decomposition import PCAimport os这里需要用到的是python中的pandas和statsmodels模块,分别用于数据处理和做多元回归。另外,还需要获取股票和指数的各项数据,这里所用到的是tushare,tushare拥有丰富的数据内容,如股票、基金等行情数据,公司财务理等基本面数据。通过tushare平台赚取一定的积分可以免费获取平台提供的数据。(个人ID:419382)数据获取本段代码展示了如何通过tushare获取相关数据并清洗成为所需因子,共展示了估值因子,成长因子,财务质量因子,杠杆因子,动量反转因子,波动率因子以及beta的构建。其中beta因子是取个股与指数收益率线性回归的回归系数。def get_all_factors(codes_list,date,start,end,one_m_start,beta_start,beta_end):    #获取估值因子    evaluate_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定交易日的指标        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,trade_date,pe_ttm,pb,ps_ttm,dv_ttm")        evaluate_factors = evaluate_factors.append(df1)        time.sleep(0.4)        print("第%d支股票估值因子获取成功"%i)    #根据指标计算因子    evaluate_factors["EP"] = 1/evaluate_factors["pe_ttm"]     evaluate_factors["BP"] = 1/evaluate_factors["pb"]    evaluate_factors["SP"] = 1/evaluate_factors["ps_ttm"]    evaluate_factors["DP"] = evaluate_factors["dv_ttm"]    evaluate_factors = evaluate_factors[["ts_code","trade_date","EP","BP","SP","DP"]]        #获取成长因子    growth_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.income(ts_code=codes_list[i],end_date=date,                          fields="ts_code,end_date,revenue,n_income")        df1 = df1.drop_duplicates(subset=["end_date"])    #根据财报计算因子        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[[0,4],:]        revenue = df1["revenue"].tolist()        n_income = df1["n_income"].tolist()        sales_G = revenue[0]/revenue[1] - 1        profit_G = n_income[0]/n_income[1] - 1        df2 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df2 = df2.drop_duplicates(subset=["end_date"])        df2["end_date"] = df2["end_date"].astype("int64")        df2 = df2.iloc[[0,4],:]        roe = df2["roe"].tolist()        ROE_G = roe[0]/roe[1] - 1        df3 = pd.DataFrame({"ts_code":codes_list[i],"sales_G":sales_G,"profit_G":profit_G,"ROE_G":ROE_G},index=[20201231])        growth_factors = growth_factors.append(df3)        time.sleep(1.2)        print("第%d支股票成长因子获取成功"%i)    all_factors = evaluate_factors.merge(growth_factors)        #获取财务质量因子    quality_factors = pd.DataFrame()    for i in range(len(codes_list)):    #获取给定日期最近的财报        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","roe","assets_turn"]]        quality_factors = quality_factors.append(df1)        time.sleep(1)        print("第%d支股票财务质量获取成功"%i)    all_factors = all_factors.merge(quality_factors)    #获取杠杆因子    leverage_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.fina_indicator(ts_code=codes_list[i],end_date=date)        df1["end_date"] = df1["end_date"].astype("int64")        df1 = df1.iloc[0,:]        df1 = df1[["ts_code","debt_to_assets"]]        leverage_factors = leverage_factors.append(df1)        time.sleep(0.8)        print("第%d支股票杠杆因子获取成功"%i)    all_facotrs = all_factors.merge(leverage_factors)            #获取市值因子    capital_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],trade_date=date,fields="ts_code,total_mv")        df1["total_mv"] = df1["total_mv"].apply(lambda x:math.log(x))        capital_factors = capital_factors.append(df1)        time.sleep(0.5)        print("第%d支股票市值因子获取成功"%i)    all_factors = all_facotrs.merge(capital_factors)            #获取动量反转因子    return_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], freq='M', adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        close = df1["close"].tolist()        return_1m = df1["pct_chg"].tolist()[0]        return_3m = close[0]/close[3] - 1        df2 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df2["trade_date"] = df2["trade_date"].astype("int64")        df3 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df3["trade_date"] = df3["trade_date"].astype("int64")        df2 = df2[df2["trade_date"]>=start]        w_return_3m = (df2["pct_chg"]*df3["turnover_rate"]).sum()/len(df2)        df_1m_return = df2[df2["trade_date"]>=one_m_start]        df_1m_turnover = df3[df3["trade_date"]>=one_m_start]        w_return_1m = (df_1m_return["pct_chg"]*df_1m_turnover["turnover_rate"]).sum()/len(df_1m_return)                df4 = pd.DataFrame({"ts_code":codes_list[i],                            "return_1m":return_1m,"return_3m":return_3m,"w_return_1m":w_return_1m,"w_return_3m":w_return_3m},index=[0])        return_factors = return_factors.append(df4)        print("第%d支股票动量反转因子获取成功"%i)    all_factors = all_factors.merge(return_factors)                    #获取波动率因子    vol_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = ts.pro_bar(ts_code=codes_list[i], adj='hfq')        df1["trade_date"] = df1["trade_date"].astype("int64")        df2 = df1[df1["trade_date"]>=start]        std_1m = df2["pct_chg"].std()        df3 = df1[df1["trade_date"]>=one_m_start]        std_3m = df3["pct_chg"].std()        df4 = pd.DataFrame({"ts_code":codes_list[i],"std_1m":std_1m,"std_3m":std_3m},index=[0])        vol_factors = vol_factors.append(df4)        print("第%d支股票波动率因子获取成功"%i)    all_factors = all_factors.merge(vol_factors)    #获取beta    beta_factors = pd.DataFrame()    rf = 1.03**(1/360) - 1    hs300 = pro.index_daily(ts_code="399300.SZ",start_date=beta_start,end_date=beta_end)    hs300["rm"] = hs300["pct_chg"]/100 - rf    for i in range(len(codes_list)):        df1 = pro.daily(ts_code=codes_list[i],start_date=beta_start,end_date=beta_end)        df1["rp"] = df1["pct_chg"]/100 - rf        df_model = pd.merge(hs300[["trade_date","rm"]],df1[["trade_date","rp"]],on="trade_date")        df_model.index = pd.to_datetime(df1.trade_date)        df_model.sort_index(inplace=True)        model = sm.OLS(df_model["rp"],sm.add_constant(df_model["rm"]))        result = model.fit()        beta = result.params["rm"]        df2 = pd.DataFrame({"ts_code":codes_list[i],"beta":beta},index=[0])        beta_factors = beta_factors.append(df2)        print("第%d支股票beta因子获取成功"%i)    all_factors = all_factors.merge(beta_factors)    #获取换手率因子    turn_factors = pd.DataFrame()    for i in range(len(codes_list)):        df1 = pro.daily_basic(ts_code=codes_list[i],start_date=start,end_date=end,fields="ts_code,trade_date,turnover_rate")        df1["trade_date"] = df1["trade_date"].astype("int64")        turn_3m = df1["turnover_rate"].sum().mean()        df2 = df1[df1["trade_date"]>=one_m_start]        turn_1m = df2["turnover_rate"].sum().mean()        df3 = pd.DataFrame({"ts_code":codes_list[i],"turn_1m":turn_1m,"turn_3m":turn_3m},index=[0])        turn_factors = turn_factors.append(df3)        print("第%d支股票换手率因子获取成功"%i)        time.sleep(0.3)    all_factors = all_factors.merge(turn_factors)        return all_factors    数据预处理本段的数据预处理显示获取个股所属行业,这一部分需要先在网上下载一份上司公司所属中信一级行业的表格(即代码中的“ industry.xlsx ”)。之后再用merge函数合并进数据表中。之后可以利用所属行业进行行业市值中性化处理,其他预处理步骤包括中位数去极值,缺失值处理,标准化和PCA。这里的PCA主要是为了去除多重共线性的影响,不在于筛选因子。#获取标签def get_tag(data,date):    stocks = data["ts_code"].tolist()    rm = pro.index_monthly(ts_code="399300.SZ",trade_date=date).pct_chg.tolist()    return_list=[]    for i in range(len(stocks)):        r = pro.monthly(ts_code=stocks[i], trade_date=date).pct_chg.tolist()        return_list.append(r[0]-rm[0])        print("第%d支股票超额收益计算完成"%i)        time.sleep(0.5)    data["ex_return"] = return_list    return data#获取行业def get_industry(data):    df1 = pd.read_excel(r"industry.xlsx",dtype="object")    df1 = df1.rename(columns={"code":"ts_code"})    ts_codes = data["ts_code"].tolist()    data["ts_code"] = data["ts_code"].apply(lambda x:x[0:6])    data = data.merge(df1,on="ts_code")    data["ts_code"] = ts_codes    return data#数据预处理#中位数去极值def MAD(data,n):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        Dm = data[indexes[i]].quantile(0.5)        Dm1 = ((data[indexes[i]] - Dm).abs()).quantile(0.5)        max_range = Dm + n*Dm1        min_range = Dm - n*Dm1        data[indexes[i]] = np.clip(data[indexes[i]],min_range,max_range)    return data#缺失值处理def Miss_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        data[indexes[i]] = data.groupby("industry")[indexes[i]].transform(lambda x:x.fillna(x.mean()))    return data#市值行业中性化def Indifference(data):    data2 = data.drop_duplicates(subset=["industry"])    list1 = data2["industry"].tolist()    list2 = data["industry"].tolist()    industry_matrix = pd.DataFrame(columns=list1)    industry_names = industry_matrix.columns.values.tolist()    for each in range(len(industry_names)):        for i in range(len(list2)):            if list2[i] == list1[each]:                list2[i] = 1            else:                list2[i] = 0        industry_matrix[list1[each]] = list2        list2 = data["industry"].tolist()    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    for i in range(len(indexes)):        model = sm.OLS(data[indexes[i]],sm.add_constant(industry_matrix))        result = model.fit()        data[indexes[i]] = result.resid    return data#标准化def Standardize(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    data[indexes] = preprocessing.scale(data[indexes])    return data        #主成分分析def PCA_data(data):    indexes = data.columns.values.tolist()    indexes = indexes[2:len(indexes)-1]    pca = PCA(n_components=20)    new_data = pca.fit_transform(data[indexes])    new_data = pd.DataFrame(new_data)    data[indexes] = new_data    return data模型构建到这里之后用于回归模型的数据集就已经构建完成了,利用传统机器学习的步骤,将数据集分为训练集和测试集,训练集为T-2期至T-12期的数据,测试集为T-1期的数据,本模型最终目的是利用T-1期的数据预测T期个股的超额收益率。
  • [技术干货] Python-机器学习(一)-线性回归[转载]
    原文链接:https://blog.csdn.net/weixin_43212535/article/details/122393250线性回归模型属于经典的统计学模型,该模型的应用场景是根据已知的变量(自变量)来预测某个连续的数值变量(因变量),线性回归通常可以应用在股价预测、营收预测、广告效果预测、销售业绩预测当中。一元线性回归:基本概念:一元线性回归是分析只有一个自变量(自变量x和因变量y)线性相关关系的方法。一个经济指标的数值往往受许多因素影响,若其中只有一个因素是主要的,起决定性作用,则可用一元线性回归进行预测分析。数据集可以表示成{(x1,y1),(x2,y2),…,(xn,yn)}。其中,xi表示自变量x的第i个值,yi表示因变量y的第i个值,n表示数据集的样本量。当模型构建好之后,就可以根据其他自变量x的值,预测因变量y的值,该模型的数学公式可以表示成: python中展示:导入我们需要的包和相关库#引入sklearn库,使用其中的线性回归模块from sklearn import  datasets,linear_model#引入train_test_split来把我们的数据集分为训练集和测试集from sklearn.model_selection import train_test_splitimport numpy as npimport pandas as pdimport matplotlib.pyplot as plt# 创建数据集  比如我们现在有10行2列数据,第一列是身高,第二列是体重,通常做法:将原始数据切分时,将原始数据的80%作为训练数据来训练模型,另外20%作为测试数据,通过测试数据直接判断模型的效果,在模型进入真实环境前不断改进模型;data = np.array([[152,51],[156,53],[160,54],[164,55],                 [168,57],[172,60],[176,62],[180,65],                 [184,69],[188,72]]) # X,y分别存放特征向量和标签,这里边使用reshape的目的是data[:,0]是一个一维的数组,但后边模型调用的时候要求是矩阵的形式X,y = data[:,0].reshape(-1,1),data[:,1]# 训练集和测试集区分开# train_size=0.8的意思就是随机提取80%的数据作为训练数据X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=0.8) # 实现线性回归算法模型regr = linear_model.LinearRegression()# 拟合数据,训练模型regr.fit(X_train,y_train)# score得到的返回结果是决定系数R平方值regr.score(X_train,y_train)决定系数R的平方值 = 1-u/vu = (y的实际值-y的预期值)的平方的求和v = (y的实际值-y的实际值的平均值)的平方的求和--输出结果R的平方值=0.963944147932503font = {'family':"SimHei",'size':20}plt.rc('font',**font)##训练数据plt.scatter(X_train,y_train,color='r')##画拟合线plt.plot(X_train,regr.predict(X_train),color='b')plt.scatter(X_test,y_test,color='black')# 测试数据plt.xlabel('身高')plt.ylabel('体重')plt.show() 下面让我们简单的做一个预测,加入身高是170的人,他的体重是多少那?np.round(regr.predict([[170]]),1)array([59.8]),可以看到170的人,经过我们的预测他的体重是59.8公斤。
  • [新手课堂] 机器学习之简单线性回归
    最广为人知的线性回归模型——将数据拟合成一条直线。直线拟合的模型方程为 y = ax + b,其中 a 是直线斜率,b 是直线截距。看看下面的数据,它们是从斜率为 2、截距为 -5 的直线中抽取的散点:rng = np.random.RandomState(1) x = 10 * rng.rand(50) y = 2 * x - 5 + rng.randn(50) plt.scatter(x, y);可以用 Scikit-Learn 的 LinearRegression 评估器来拟合数据,并获得最佳拟合直线:from sklearn.linear_model import LinearRegression model = LinearRegression(fit_intercept=True) model.fit(x[:, np.newaxis], y) xfit = np.linspace(0, 10, 1000) yfit = model.predict(xfit[:, np.newaxis]) plt.scatter(x, y) plt.plot(xfit, yfit);数据的斜率和截距都在模型的拟合参数中,Scikit-Learn 通常会在参数后面加一条下划线,即 coef_ 和 intercept_:print("Model slope: ", model.coef_[0]) print("Model intercept:", model.intercept_) 输出结果如下所示:Model slope: 2.02720881036 Model intercept: -4.99857708555可以看到,拟合结果与真实值非常接近,这正是我们想要的。然而,LinearRegression 评估器能做的可远不止这些——除了简单的直线拟合,它还可以处理多维度的线性回归模型:y = a 0 + a 1 x 1 + a 2 x 2 + … 里面有多个 x 变量。从几何学的角度看,这个模型是拟合三维空间中的一个平面,或者是为更高维度的数据点拟合一个超平面。虽然这类回归模型的多维特性使得它们很难可视化,但是我们可以用 NumPy 的矩阵乘法运算符创建一些数据,从而演示这类拟合过程:rng = np.random.RandomState(1) X = 10 * rng.rand(100, 3) y = 0.5 + np.dot(X, [1.5, -2., 1.]) model.fit(X, y) print(model.intercept_) print(model.coef_) 输出结果如下所示:0.5 [ 1.5 -2. 1.]
总条数:45 到第
上滑加载中