• [技术干货] 【r语言 python 线性回归】相关性分析中,p<0.05, r=0.29,怎么评价相关性呢
    在统计分析中,相关性系数 ( r ) 和 p 值都提供了关于变量之间关系的重要信息。以下是如何评价和解释你的结果,并考虑该因子对因变量的影响。1. 相关性系数 ( r )**相关性系数 ( r = 0.29 )**:相关系数 ( r ) 的取值范围在 -1 到 1 之间。具体解释如下:0.00–0.10:几乎无相关性0.10–0.30:弱相关性0.30–0.50:中等相关性0.50:强相关性因此,( r = 0.29 ) 表示变量之间存在弱相关性。2. p 值p < 0.05:表示相关性在统计学上显著。这意味着在 95% 的置信水平下,我们可以拒绝无关的原假设,即变量之间确实存在一定程度的相关性。3. 综合评价虽然 p 值表明相关性在统计学上显著,但相关性系数 ( r ) 很低,只说明变量间存在弱相关性。在撰写文章时,你可以根据分析的上下文来决定如何总结这些结果。通常会考虑以下几点:4. 解读和结论在文章中,可以这样总结:明确您的发现:“我们的分析显示,这两个变量之间存在统计显著的相关性(p < 0.05),但相关性系数 ( r = 0.29 ) 表示这种相关性很弱。”讨论相关性的实际意义:“尽管相关性在统计学上显著,但由于相关性系数较低,表明这两个变量之间的关系在实际中可能并不强。”是否忽略该变量:在解释是否忽略该变量时,可以结合领域知识和研究背景。如果仅凭 ( r ) 值判断,弱相关性一般建议谨慎处理,而非完全忽视。你可以进一步探讨变量的实际影响或在多元回归模型中验证其贡献。5. 多元回归分析为了更好地理解该变量对因变量的影响,可以进行多元线性回归分析,在控制其他变量的情况下评估该变量的独立贡献。Python 实现 import pandas as pdimport statsmodels.api as sm# 假设df是你的数据框,X是自变量,y是因变量X = df[['your_variable', 'other_variables']] # 添加其他控制变量y = df['dependent_variable']# 添加常数项(截距)X = sm.add_constant(X)# 拟合回归模型model = sm.OLS(y, X).fit()# 输出模型摘要print(model.summary())R 实现 # 假设df是你的数据框,X是自变量,y是因变量model <- lm(dependent_variable ~ your_variable + other_variables, data=df)# 输出模型摘要summary(model)通过上述多元回归分析,可以评估该变量的系数及其显著性。如果该变量在多元回归中仍然不显著,则可以更合理地考虑忽略它。6. 总结根据 p 值和相关性系数 ( r ),可以得出以下结论:虽然统计上显著(p < 0.05),但相关性较弱(( r = 0.29 ))。在总结中,应强调这种弱相关性,并结合领域知识决定是否忽略该变量。通过多元回归分析进一步验证该变量的独立贡献,有助于做出更全面的判断。
  • [其他] 《深度学习入门》笔记 - 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都是未知数,就是`模型参数`。
  • [其他] 机器学习分类与回归
    1.机器学习的主要任务:一是将实例数据划分到合适的分类中,即分类问题。 而是是回归, 它主要用于预测数值型数据,典型的回归例子:数据拟合曲线。2.监督学习和无监督学习:分类和回归属于监督学习,之所以称之为监督学习,是因为这类算法必须直到预测什么,即目标变量的分类信息。对于无监督学习,此时数据没有类别信息,也不会给定目标值。在无监督学习中,将数据集合分成由类似的对象组成的多个类的过程被成为聚类;将寻找描述数据统计值的过程称之为密度估计。此外,无监督学习还可以减少数据特征的维度,以便我们可以使用二维或者三维图形更加直观地展示数据信息。3.线性回归和非线性回归  线性回归需要一个线性模型。一个线性的模型意味着模型的每一项要么是一个常数,要么是一个常数和一个预测变量的乘积。一个线性等式等于每一项相加的和。等式:Response = constant + parameter * predictor + ... + parameter * predictor  <=>  Y = b o + b1X1 + b2X2 + ... + bkXk在统计学中,如果一个回归方程是线性的,那么它的参数必须是线性的。但是可以转换预测变量加上平方,来使得模型产生曲线,比如 Y = b o + b1X1 + b2X12这时模型仍然是线性的,虽然预测变量带有平方。当然加上log或者反函数也可以。
  • [交流吐槽] 多元线性回归模型选股应用(α策略)
    内容介绍本文重点在于如何利用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公斤。
  • [特性分析] 浅析梯度下降算法
    # MindSpore机器学习系列文章 文章同步于笔者CSDN:https://blog.csdn.net/weixin_54227557/article/details/122307610 # 前言 在上一个章节中,我们已经给大家讲解了什么是线性回归,并且用python几个功能强大的库演示了线性回归的实际效果,但是真正的想弄懂线性回归的原理我们还是得从他的根本出发,一步步推理,结合数学理论,再加手动实现! 当然我这边以简单的一元线性方程为例 ------ # 一、线性回归的第一步 ​ 准备或收集数据集,计算相关系数,我们一切线性关系的寻找都是建立在有价值的数据集基础之上的。 ​ 数据集好理解,那什么是相关系数呢,其实相关系数在我们上一章节中已经演示,他是描述数据与数据直接关联程度的一个概念。我们之前的实现方法也是采用直接库的调用,但其实相关系数的实现原理很简单,我们来一起了解一下。 ## 1、数据读取和相关性分析 相关系数的定义式: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/173229qme7g5qhtfdf7jzv.png) 当然这只是最简单的相关系数表达式,也就是针对两个变量之间联系的计算方法。 那他使用代码怎么实现呢。 ```python import numpy as np #读取数据 data = np.genfromtxt("1.txt",encoding="utf-8") #数据分割 data_x,data_y = data[:,0],data[:,1] x_ave,y_ave = data_x.mean(),data_y.mean() xysum,xsum,ysum,sum = 0,0,0,0 dic = dict(zip(data_x,data_y)) for x,y in dic.items(): x_t,y_t = x-x_ave,y-y_ave xysum,xsum,ysum = xysum+x_t*y_t,xsum+x_t**2,ysum+y_t**2 sum = xysum/((xsum*ysum)**0.5) print(sum**2) 12345678910111213 ``` 可以看到我们的数据散点图肉眼看上去还是很有线性关系的,同时r²的结果也证明了这种关系,说明我们的数据应该还是挺适合最线性规划分析的。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/1732538k6eivas54hircbt.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/173307c9mfdr58seqa6qvs.png) # 二、线性回归理论分析 ## 1.统计学概念 在统计学中,线性回归(Linear Regression)是利用回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种概念。当自变量只有一个的情况称为简单回归,大于一个自变量的情况则叫多元回归。 本章我们举例的便是一个简单回归 ## 2.回归方程构建 因为我们是一个单自变量的简单回归,所以我们的回归方程可以很简单的表示为一个一元一次方程: **y=w\*x+b** 针对这样的一个未知方程,对 w 、b 的确定便是回归的核心任务。 但苦恼的是面对这样一大堆离散的数据点,面对其中任意的某个点,方程的w、b值都是不一样的,我们又如何唯一确定出这样一条最拟合全部数据点的直线呢? 首先,我们现在明确知道的一点就是他最后会产生一条线,那我们索性就先用k和b来暂代最终结果。然后来调整kb的值来试探性的接近我们的最终答案。那么这边就涉及到一个概念了,我们怎么知道试探到什么程度这就是最终答案了呢? 答案就是用:[最小二乘法](https://so.csdn.net/so/search?q=最小二乘法)(当然还有其他方法) ## 3.最小二乘法 **最小二乘法的概念:** 最小二乘法其实是一种在误差估计中广泛应用的数学思想,他表达通过求解涉及的参数(w,b),但这组w,b代入后使计算结果与实际结果的方差最小,也就说明估计相对准确了的思想。 **最小二乘法的实现:** 虽然通过其概念我们能很容易了解他的思想,但这边涉及到一个技术难点便是:怎么去调整参数来求得这个解呢? 因为我们涉及到的数据点很多,这条表达式展开异常的复杂,不可能直接求解,但我们有计算机这个工具,所以我们最简单粗暴的方法就是进行试探,比如:答案是2,我们并不知道,现在估计的是1,我们去与结果比较,小了,那我们就加一点:1+0.5,一比较,发现还是比答案小,那就再:1+0.5,一比较,对了,那答案就被我们试探出来了。 这下思路清晰了,但我们又遇到一个问题: - 怎么知道大了小了 - 怎么去确定这个试探的幅度 这就又引出来一个算法:[梯度下降](https://so.csdn.net/so/search?q=梯度下降)算法 ## 4.梯度下降 **梯度下降的概念** 梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数时,梯度下降(Gradient Descent)是最常采用的方法之一。在求解二乘法的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的[损失函数](https://so.csdn.net/so/search?q=损失函数)和模型参数值。 **梯度下降原理** 举一个非常简单的例子,如求函数 f(x)= x² 的最小值 利用梯度下降的方法解题步骤如下: 1、求梯度,f’(x) = 2x 用于确定我们目前与最终答案的方向关系,观察导数图像即可懂得。 2、向梯度相反的方向移动x来逼近答案 ,如下 x = x-lr*2x,其中, lr为步长。如果步长足够小,则可以保证每一次迭代都在减小(*不会跨过答案,导致在答案左右来回跳动*),但可能导致收敛太慢,如果步长太大,则不能保证收敛。 3、重复步骤2,直到x 的值变化使得 f(x)(注意是f(x)不是f’(x))在两次迭代之间的差值足够小,比如0.00000001(到达极值点),也就是说,直到两次迭代计算出来的f(x) 基本没有变化,则说明f(x)已经达到局部最小值了。 4、此时,输出 x,这个 x就是使得函数f(x)最小时的x 的取值,当这个f(x)是我们的最小二乘法时,那不就能求出其解,而得出最小二乘法的解后,kb的解不也就对应得出了 。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/1733344yfq1t0l3manz0ow.png) ## 5.求解最小二乘法 我们已知的最小二乘法公式为: $minF(x) = ∑ [yi-f(xi,wi,bi)]²$ $(i)’= -2*xi*(yi-wi*xi-bi) / n$ $f’b(x)=((yi-wi*xi-bi)² )’= -2*(yi-wi*xi-bi) / n$ 第二步迭代计算: 定义步长:lr = 0.001 迭代次数:epoch = 3000 第三步梯度更新 $w = w- lr*(-2*xi*(yi-wi*xi-bi)) / n$ $b = b- lr*(-2*(yi-wi*xi-bi)) / n$ 第四步完成计算 完全我们的全部迭代后,得出的w和b就是我们的最终结果了 # 三、线性回归代码实现 ## 1.数据读取和相关性评估 这个模块的工作我们在上面已经完成了,大家可以参考前面所描述的源码。 ## 2.参数设置 ```py #y=kx+b #参数预定义 lr=0.001 b=1 k=0 epochs=3000 #轮次 data_len=float(len(data_x)) 1234567 ``` ## 3.定义损失函数 ```python def error_num(b,k): sum=0 for i in range(0,len(data_x)): sum+=(data_y<i>-(k*data_x+b))**2 return sum/float(len(data_x)) 12345 ``` ## 4.定义梯度下降函数 ```py def Gradient_Descent(b,k,lr,epochs): for i in range(epochs): b_grad=0 k_grad=0 for j in range(0,len(data_x)): b_grad,k_grad=b_grad-(1/data_len)*(data_y[j]-k*data_x[j]-b),k_grad-(1/data_len)*(data_x)*(data_y[j]-k*data_x[j]-b) b,k=b-(lr*b_grad),k-(lr*k_grad) if i%1000 == 0: print("epochs:",i) print('b:',b,'k:',k) print('error:',error_num(b,k)) plt.plot(data_x,data_y,'b') plt.plot(data_x,k*data_x+b,'r') plt.show() return b,k 123456789101112131415 ``` ## 5.进行线性回归 ```py Gradient_Descent(b,k,lr,epochs) 1 ``` ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/173353fb95rbs8ky78xqhx.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/173407oplivqypcjc89uis.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/173418bbe9mi9jexngecvs.png) ## 6.结果分析 至此我们已经完成了线性规划的代码实现,根据最终的结果我们可以发现,最开始我们随便估计的结果与实际趋势相差较大,但随着迭代的进行,直线越来越拟合我们的离散点。 ------ # 总结 在本章节中,我们真正深入的了解了什么是线性回归的原理。分析了线性回归的过程,以及求解的方法——最小二乘法,但面对最小二乘法难以用公式直接求解的问题,我们结合计算机又提出了梯度下降的方法来帮助我们求解最小二乘法,最终实现一个完整的线性回归。
  • [其他] 由线性回归来理解深度学习的理论基础(5)
    多层感知器 现在我们来介绍多层感知器(MLP)。通过添加非线性的激活函数以及使用多层网络的结构,多层感知器延展了单层感知器的功能。在训练中,我们需要用到反向传播和梯度下降的方式来更新权重。多层感知器的构造如图所示:多层感知器的“多层”结构可以从数据当中提取层次性的结构(每一层都可以从上一层当中提取一次特征),从而找到更好地模拟数据规律的方式。因此,具有单层无激活功能(或阶跃激活功能)的神经网络(即多层感知器)等同于线性回归。此外,线性回归可以使用封闭形式解决方案来解决。然而,随着MLP的结构更加复杂,封闭形式的解决方案不再管用,因此必须使用迭代解决方案,即通过逐步改进的方法来改善结果。这样的算法不一定会收敛,梯度下降就是一个经典的例子。MLP(深度学习)是一个高度参数化的模型。对于等式y = mx + c,m和c被称为参数,我们从数据和中推导出参数的值。方程的参数可以看作自由度,线性回归具有相对较少的参数,即具有较小的自由度。然而,更复杂的MLP具有更多的参数,也具有更大的自由度。虽然两者都是参数化模型,但MLP的优化策略(反向传播+梯度下降)比线性回归的优化策略(最小二乘法)复杂得多。从这个方面讲,神经网络可以看作是线性回归的复杂衍生物,多层感知器的高度参数化允许我们构建功能更加复杂的模型。
  • [其他] 由线性回归来理解深度学习的理论基础(4)
    感知器学习 接下来我们看看感知器是如何与线性回归模型产生联系的。        感知器(Perceptrons)是用于二元分类问题的监督学习算法,二元分类器是二类问题的线性分类器。Mark I 感知器是感知器算法的第一个实现,感知器算法由Frank Rosenblatt于1957年在康奈尔航空实验室发明,感知器旨在成为一台机器,而不是一个程序,这台机器专为图像识别而设计:它有一个由400个光电池组成的阵列,随机连接到“神经元”,权重由电位器编码,并且在学习期间通过机器执行权重更新。在美国海军组织的1958年新闻发布会上,Rosenblatt发表了关于感知者的声明,这一声明引起了人工智能社区的激烈争论。根据罗森布拉特的声明,感知器是“电子计算机的胚胎,走路,说话,看,写,复制自己,并感受到它的存在。”单层感知器仅能够学习线性可分离的模式。1969年,一本名为Perceptrons的书表明,感知器网络不可能学习XOR功能。但是,如果我们使用非线性激活函数(而不是梯度函数),则可突破此限制。事实上,通过使用非线性激活函数,我们可以构建比XOR更复杂的函数(即使只有单层),如果我们添加更多隐藏层,则可以拓展处更复杂的功能,即我们接下来要介绍的多层感知器(深度学习)。我们回顾一下:1)感知器是生物神经元的简化模型。2)感知器是用于学习二元分类器的算法:将其输入映射到输出值的函数。3)在神经网络的背景下,感知器是使用Heaviside阶跃函数作为激活函数的人工神经元,感知器算法也称为单层感知器,以区别于多层感知器。4)Perceptron算法具有历史意义,但它为我们提供了一种拉近线性回归和深度学习之间差别的方法。5)单层感知器的学习过程如下所示,每加入一个数据点,感知器便会更新一次线性边界,类似于线性回归中的回归线。下图为感知器的示意图,f为阶跃函数,输出为二进制(0或1),i1-in为输入,Wi为各个输入的权重:
  • [其他] 由线性回归来理解深度学习的理论基础(3)
    广义线性模型 在普通线性回归中,预测变量(x)的变化会导致响应变量(y)的变化,但是,当且仅当响应变量具有正态分布时才成立。在响应变量是正态分布时,有好多问题我们无法处理:1)响应变量总是为正且在很大范围内变化;2)预测变量的变化导致响应变量的几何变换,而不是连续变化(即两者间非线性关系)。广义线性回归是由普通线性回归延伸出的第二个模型,它满足:1)响应变量可以不是正态分布;2)允许响应变量不是随着预测变量线性变化。多项式回归 介绍了多元回归和GLM之后,让我们现在看一下我们可以从普通线性回归推断出的第三个模型——多项式回归。在多项式回归中,自变量x和因变量y之间的关系被表示为x的n次多项式的形式。多项式回归已被用于描述非线性现象,如组织的生长速度,湖泊沉积物中碳同位素的分布,以及疾病流行的进展。
  • [其他] 由线性回归来理解深度学习的理论基础(2)
    多重线性回归 普通线性回归的第一个明显变体是多元线性回归。当只有一个特征时,我们有单变量线性回归,如果有多个特征,我们有多元线性回归。对于多元线性回归,模型可以以一般形式表示为:模型的训练即寻找最佳参数θ,以使模型最贴合数据。预测值与目标值之间的误差最小的直线称为最佳拟合线或回归线,这些误差被称为残差(Residuals)。可以通过从目标值到回归线的垂直线来可视化残差,如下图所示,灰色直线即回归线,紫色点为目标值,黄色垂直距离即残差。我们将整个模型的误差(即损失函数)定义为残差平方和,表示如下:最经典的多元线性回归问题是波士顿房价问题(Boston Housing Dataset)
  • [其他] 由线性回归来理解深度学习的理论基础(1)
    线性回归 为什么从线性回归开始?因为即使在高中阶段,我们也开始接触到了这个概念。首先从“学习”这个概念讲起,在机器学习(监督学习)中,学习的过程即寻找一个数学方程式,从而使得每一个输入和输出都能够通过这个方程一一对应。在最简单的情境下,这个方程是线性的。什么是线性关系?线性关系指的是可以用一条直线表示的两个变量(x和y)之间的关系。许多现象都是线性关系,如双手拉橡皮所使用的力量和橡皮被拉伸的长度,我们可以用线性方程来表示如上关系:在线性关系中,改变自变量(x)的值会导致因变量(y)的值发生改变,因此线性关系可以用来预测诸如销售预估、用户行为分析等实际问题。线性关系如下图所示:线性回归问题意在寻找可以描述一个或多个特征(自变量)与目标值(因变量)之间关系的方程。如上图所示的线性回归问题,我们通常称之为普通线性回归,即最简单的线性回归。现在我们来考虑由简单线性回归引申出的三个问题:多元线性回归广义线性模型多项式回归
  • [技术干货] 纵向联邦学习场景下的逻辑回归(LR)
    原文链接:https://bbs.huaweicloud.com/blogs/271147一、什么是逻辑回归?        回归是描述自变量和因变量之间相互依赖关系的统计分析方法。线性回归作为一种常见的回归方法,常用作线性模型(或线性关系)的拟合。        逻辑回归(logistic regression)虽然也称为回归,却不是一种模型拟合方法,而是一种简单的“二分类”算法。具有实现简单,算法高效等诸多优点。                                           图1.1   二维线性回归                                                    图1.2   三维线性回归1.1 线性回归(linear regression)       图1.1、1.2分别表示二维和三维线性回归模型,图1.1的拟合直接(蓝线)可表示为 y=ax+b,所有数据点(红点)到直线的总欧式距离最短,欧式距离常用作计算目标损失函数,进而求解模型;类似的,图1.2的所有数据点到二维平面的总欧式距离最短。所以线性回归模型通常可以表示为:其中θ表示模型系数。    1.2 逻辑回归(LR)        LR是一种简单的有监督机器学习算法,对输入x,逻辑回归模型可以给出 y<0 or y>0 的概率,进而推断出样本为正样本还是负样本。        LR引入sigmoid函数来推断样本为正样本的概率,输入样本 x 为正样本的概率可以表示为:P(y|x) = g(y),其中 g() 为sigmoid函数,曲线图如图1.3所示,输出区间为0~1:图1.3    sigmoid曲线对于已知模型 θ 和样本 x,y=1的概率可以表示为:所以sigmoid尤其适用于二分类问题,当 g(y) > 0.5 时,表示 P(y=1|x) > 0.5,将其判为正样本,对应 y>0 ;反之,当 g(y) < 0.5 时,表示 P(y=1|x) < 0.5,将其判为负样本,对应 y<0。  1.3 LR损失函数     LR采用对数损失函数,对于训练集x∈S,损失函数可以表示为(参考https://zhuanlan.zhihu.com/p/44591359):     梯度下降算法是LR模型的经典解法之一,模型迭代更新的表达式如下:其中l()为目标损失函数,本质为平均对数损失函数。S'为批处理数据集(大小为batchsize),通过批处理方式引入随机扰动,使得模型权重更加快速逼近最优值。α为学习率,直接影响模型的收敛速度,学习率过大会导致loss左右震荡无法达到极值点,学习率太小会导致loss收敛速度过慢,长时间找不到极值点。    二、纵向联邦学习场景下的LR        关于纵向联邦学习的介绍已经屡见不鲜,市面上也涌现出很多优秀的产品,比如FATE、TICS等。纵向联邦可以实现多用户在不暴露己方数据的前提下,共享数据和特征,训练出精度更高的模型,对于金融和政务等众多行业具有重要意义。图2.1 纵向联邦LR2.1 LR的纵向联邦实现         纵向联邦学习的参与方都是抱着共享数据、不暴露己方数据的目的加入到联邦中,所以任何敏感数据都必须经过加密才能出己方信任域(图2.1,参考https://arxiv.org/pdf/1711.10677.pdf),这就引入了同态加密算法。同态加密为密文计算提供了可行性,同时也一定程度上影响了机器学习算法的性能。常见的同态加密库包括seal、paillier等。         纵向联邦场景下梯度计算公式如下:LR的纵向联邦流程如图2.2所示,host表示只有特征的一方,guest表示包含标签的一方。图 2.2 纵向联邦LR算法实现流程在训练开始之前,作业双方需要交换同态公钥。每轮epoch(迭代)的batch(一轮batchsize的计算为一个batch)循环中,包含calEncryptedU-->calEncryptedGradient-->decryptGradient-->updateLrModel四步,guest和host都需要按此顺序执行一遍(  流程图中只体现了guest作为发起方的执行流程)。A2步骤中梯度加随机噪声的目的是为了防止己方U泄露,造成安全问题。      由于同态加密计算只支持整数、浮点数的加法和乘法,所以将1.3中的模型迭代公式中的指数部分表示成泰勒表达式形式:
  • [执行问题] 使用mindspore写了一个线性回归的算法,跑不出结果,持续运行无法结束
    【功能模块】import mindspore import numpy as np #引入numpy科学计算库 import matplotlib.pyplot as plt #引入绘图库 np.random.seed(123) #随机数生成种子 #from sklearn.model_selection import train_test_split#从sklearn里面引出训练与测试集划分 import mindspore.nn as nn import mindspore.ops as ops from mindspore import Tensor from mindspore import ParameterTuple, Parameter from mindspore import dtype as mstype # 训练数据集 def creat_dataset(): n_x=2*np.random.rand(500,1)#随机生成一个0-2之间的,大小为(500,1)的向量 n_y=5+3*n_x+np.random.randn(500,1)#随机生成一个线性方程的,大小为(500,1)的向量 x = Tensor(n_x, dtype=mindspore.float32) y = Tensor(n_y, dtype=mindspore.float32) return x, y class Net(nn.Cell): def __init__(self, input_dims, output_dims): super(Net, self).__init__() self.matmul = ops.MatMul() self.weight_1 = Parameter(Tensor(np.random.randn(input_dims, 128), dtype=mstype.float32), name='weight_1') self.bias_1 = Parameter(Tensor(np.zeros(128), dtype=mstype.float32), name='bias_1') self.weight_2 = Parameter(Tensor(np.random.randn(128, 64), dtype=mstype.float32), name='weight_2') self.bias_2 = Parameter(Tensor(np.zeros(64), dtype=mstype.float32), name='bias_2') self.weight_3 = Parameter(Tensor(np.random.randn(64, output_dims), dtype=mstype.float32), name='weight_3') self.bias_3 = Parameter(Tensor(np.zeros(output_dims), dtype=mstype.float32), name='bias_3') def construct(self, x): x = self.matmul(x, self.weight_1)+self.bias_1 x = self.matmul(x, self.weight_2)+self.bias_2 x = self.matmul(x, self.weight_3)+self.bias_3 return x class LossNet(nn.Cell): def __init__(self, net): super(LossNet, self).__init__() self.net = net self.pow = ops.Pow() self.mean = ops.ReduceMean() def construct(self, x, y): _x = self.net(x) loss = self.mean(self.pow(_x - y, 2)) return loss class GradNetWrtX(nn.Cell): def __init__(self, net): super(GradNetWrtX, self).__init__() self.net = net self.params = ParameterTuple(net.trainable_params()) self.grad_op = ops.GradOperation(get_by_list=True) def construct(self, x, y): gradient_function = self.grad_op(self.net, self.params) return gradient_function(x, y) def train(epochs, loss_net, x, y, print_flag=False): # 构建加和操作 ass_add = ops.AssignAdd() para_list = loss_net.trainable_params() for epoch in range(epochs): grad_net = GradNetWrtX(loss_net) grad_list = grad_net(x, y) for para, grad in zip(para_list, grad_list): ass_add(para, -0.000001*grad) if print_flag and (epoch%100 == 0): print("epoch: %s, loss: %s"%(epoch, loss_net(x, y))) def main(): epochs = 10000 x, y = creat_dataset() net = Net(x.shape[-1], y.shape[-1]) loss_net = LossNet(net) train(epochs, loss_net, x, y) y_hat = net(x) fig=plt.figure(figsize=(8,6))#确定画布大小 plt.title("Dataset")#标题名 plt.xlabel("First feature")#x轴的标题 plt.ylabel("Second feature")#y轴的标题 plt.scatter(x.asnumpy(), y.asnumpy())#设置为散点图 plt.scatter(x.asnumpy(), y_hat.asnumpy())#设置为散点图 plt.show()#绘制出来 if __name__ == '__main__': """ 设置运行的背景context """ from mindspore import context # 为mindspore设置运行背景context context.set_context(mode=context.GRAPH_MODE, device_target='GPU') import time a = time.time() main() b = time.time() print(b-a)【操作步骤&问题现象】1、运行一直提示警告,运行时间过长,一直无法获得结果警告信息如下:[WARNING] OPTIMIZER(4150,python):2021-07-06-22:53:34.396.781 [mindspore/ccsrc/frontend/optimizer/ad/dfunctor.cc:860] FindPrimalJPair] J operation has no relevant primal call in the same graph. Func graph: 119648_construct_wrapper, J user: 119648_construct_wrapper:construct{[0]: 803, [1]: x, [2]: y, [3]: ValueNode<UMonad> U}[WARNING] OPTIMIZER(4150,python):2021-07-06-22:53:34.540.042 [mindspore/ccsrc/frontend/optimizer/ad/dfunctor.cc:860] FindPrimalJPair] J operation has no relevant primal call in the same graph. Func graph: 119797_construct_wrapper, J user: 119797_construct_wrapper:construct{[0]: 804, [1]: x, [2]: y, [3]: ValueNode<UMonad> U}[WARNING] OPTIMIZER(4150,python):2021-07-06-22:53:34.667.100 [mindspore/ccsrc/frontend/optimizer/ad/dfunctor.cc:860] FindPrimalJPair] J operation has no relevant primal call in the same graph. Func graph: 119946_construct_wrapper, J user: 119946_construct_wrapper:construct{[0]: 805, [1]: x, [2]: y, [3]: ValueNode<UMonad> U}[WARNING] OPTIMIZER(4150,python):2021-07-06-22:53:34.796.065 [mindspore/ccsrc/frontend/optimizer/ad/dfunctor.cc:860] FindPrimalJPair] J operation has no relevant primal call in the same graph. Func graph: 120095_construct_wrapper, J user: 120095_construct_wrapper:construct{[0]: 806, [1]: x, [2]: y, [3]: ValueNode<UMonad> U}[WARNING] OPTIMIZER(4150,python):2021-07-06-22:53:34.920.186 [mindspore/ccsrc/frontend/optimizer/ad/dfunctor.cc:860] FindPrimalJPair] J operation has no relevant primal call in the same graph. Func graph: 120244_construct_wrapper, J user: 120244_construct_wrapper:construct{[0]: 807, [1]: x, [2]: y, [3]: ValueNode<UMonad> U}【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [基础知识] 【MindSpore易点通】机器学习系列:逻辑回归(二)
    小Mi学习,向上积极!逻辑回归的函数表示还有判决边界还记得不,是不是觉得上一节还不得劲儿?!这不,小Mi又来更新啦~4. 代价函数现在我们就要开始讨论如何拟合logistic回归模型的参数,具体来说,我们要定义用来拟合参数的优化目标或者代价函数,以下便是监督学习问题中的logistic回归模型的拟合问题:  假使我们有一个训练集,里面有m个训练样本,依旧和以前一样,每个样本是用n+1维的特征向量表示的,其中第一个特征为1。同时,由于这是一个分类问题,所以训练集中所有的标签y不是0就是1,。而假设函数,参数就是公式中的,我们要解决的问题就是,对于这个给定的训练集,我们如何选择。以前我们建立线性回归模型时,使用的代价函数为:,现在在此基础上稍作修改,将1/2放到求和符号里面:,然后后面的部分直接替换成,也就是说代价函数是1/m乘以这个cost项在训练集范围上的求和: ,为了更加简洁一点,可以直接去掉上标,,代价值就是1/2乘以预测值h和实际观测的y值的差的平方,这部分在线性回归中发挥了很大的作用,但是如果用于logistic回归,就会出现一个问题,会变成参关于参数的非凸函数。由于,这是一个很复杂的非线性函数,如果把这个Sigmoid函数带入,再把这个Cost项带入进原公式,可以画出图像,最后可以发现有很多局部最优解,这样的就可以称之为非凸函数: 这时我们就可以发现,如果在这样的函数上使用梯度下降法,并不能够保证它会收敛到全局最小值,相反地,如果代价函数是一个凸函数,对其使用梯度下降法,会最终收敛到全局最小值,既然这样的话,我们可以换个思路,寻找另一个是凸函数的代价函数不就好了呗。是不是!从而梯度下降法也能运用了,继而全局最小值的问题也会迎刃而解。 因此,我们定义:当y=1时,代价值将等于-log(h(x));而y=0时,则是-log(1-h(x))。这看起来是个非常复杂的函数,但是如果画出这个函数的图像,就很好理解啦,从y=1这个情况开始,代价函数的图像如下图:我们来具体理解下这个函数为什么是这样的,首先画出对数函数log(z)的图像:-log(z)就是沿着z轴翻译一下,然后再选中0~1的部分:因此,全新的代价函数有一些有趣并且很好的性质:首先,我们可以注意到,如果假设函数预测值h(x)=1,并且y刚好等于h(x)时,那么这个代价就为0,这也是我们希望看到的,因为我们正确预测了输出值;同时,当y=1但h(x)不为1时,误差随着h(x)变小而增大。另一种情况,y=0时,代价值函数是什么样子的呢?这个曲线的特点是,当实际的y=0且h(x)也为0时的代价为0,当y=0但h(x)不为0时误差随着h(x)的变大而变大。Python代码实现:xxxxxxxxxx import numpy as np def cost(theta, X, y): theta = np.matrix(theta) X = np.matrix(X) y = np.matrix(y) first = np.multiply(-y, np.log(sigmoid(X* theta.T))) second = np.multiply((1 - y), np.log(1 - sigmoid(X* theta.T))) return np.sum(first - second) / (len(X))在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的参数了。算法为:求导后得到:注:虽然得到的梯度下降算法表面上看上去与线性回归的梯度下降算法一样,但是这里的与线性回归中不同,所以实际上是不一样的。另外,在运行梯度下降算法之前,进行特征缩放依旧是非常必要的。当然 除了梯度下降算法以外,还有一些常被用来求代价函数最小的算法,这些算法更加复杂和优越,而且通常不需要人工选择学习率,通常也比梯度下降算法要更加快速,比如:共轭梯度(Conjugate Gradient),局部优化法(Broyden fletcher goldfarb shann,BFGS)和有限内存局部优化法(LBFGS) 等。5 简化的成本函数和梯度下降在这段视频中,我们将会找出一种稍微简单一点的方法来写代价函数,来替换我们现在用的方法。同时我们还要弄清楚如何运用梯度下降法,来拟合出逻辑回归的参数。因此,后续的话我们就应该知道如何实现一个完整的逻辑回归算法了。逻辑回归的代价函数:我们的整体代价函数是1/m乘以对应不同标签y的各个训练样本,在预测时付出的代价之和,这是我们约定单个样本的代价,另外,我们还需要注意一下,对于分类的问题,在我们的训练集中,甚至不在训练集中的样本,y的值总是等于0或1的,这是由y的数学定义决定的,由于y是0或1,我们就可以一个超简单的方式来写这个代价函数,将两个式子合并成一个等式:与之前的公式其实是等效的,大家可以动动手简单证明一下!从而就可以推导出logistic回归的代价函数:不过这里运用了统计学中的极大似然法,可以快速寻找参数,同时还能满足凸函数的性质(更深一层的原理后续会统统介绍给大家)。根据这个代价函数,为了拟合出参数,该怎么做呢?我们要试图找尽量让取得最小值的参数。如果给我们一个新的样本,具有某些特征x,我们可以用拟合训练样本的参数来输出这样的预测。同时,我们假设的输出,实际上就是y=1的概率,就是输入为x以为参数时y=1的概率,就可以想成,我们的假设就是估计y=1的概率:。因此,接下来需要做的就是弄清楚如何最小化,这样我们才能为训练集拟合出参数。不用猜都能知道,现在提到最小化,肯定是使用梯度下降法,代价函数为:如果我们要最小化这个关于的函数值,可以选用常见的梯度下降法模板:需要不断反复更新每个参数,就是用它自己减去学习率乘以后面的导数项,也可以自己动手试一下,直接算出这个导数项,最终得到的式子为:该式子在i=1 到m上求和,其实就是预测误差乘以 ,将偏导数项放回到原来式子这里,梯度下降算法写作就会变成: 所以,如果有n个特征,也就是说:,那么就需要用这个式子来同时更新所有的值。现在,如果把这个更新规则和我们之前用在线性回归上的进行比较的话,最后可能会惊讶地发现,这个式子正是我们之前用来做线性回归梯度下降的式子!那么,这时候小Mi就有疑问了,线性回归和逻辑回归是同一个算法吗?回答这个问题,我们先观察一下逻辑回归发生了哪些变化。实际上,假设的定义发生了变化。对于线性回归假设函数:而现在逻辑函数假设函数:因此,即使更新参数的规则看起来基本相同,但由于假设的定义发生了变化,所以逻辑函数的梯度下降,跟线性回归的梯度下降实际上是两个完全不同的东西。在先前的视频中,当我们在谈论线性回归的梯度下降法时,我们谈到了如何监控梯度下降法以确保其收敛,同理,通常也把同样的方法用在逻辑回归中,来监测梯度下降,以确保它正常收敛。最后还有一点,我们之前在谈线性回归时讲到的特征缩放,特征缩放可以帮助提高梯度下降的收敛速度,同时也适用于逻辑回归。如果你的特征范围差距很大的话,那么应用特征缩放的方法,同样也可以让逻辑回归中,梯度下降收敛更快。6 高级优化这一章节我们会涉及一些高级优化算法和一些高级的优化概念,利用这些方法,我们就能够使其速度大大提高,而这也将使算法更加适合解决大型的机器学习问题,比如,我们有数目庞大的特征量。 现在我们换个角度来看什么是梯度下降,我们有个代价函数,而我们想要使其最小化,那么我们需要做的是编写代码,当输入参数时,它们会计算出两样东西:以及J等于0、1直到n 时的偏导数项。假设我们已经完成了可以实现这两件事的代码,那么梯度下降所做的就是反复执行这些更新。 另一种考虑梯度下降的思路是:我们需要写出代码来计算和这些偏导数,然后把这些插入到梯度下降中,然后它就可以为我们最小化这个函数。 对于梯度下降来说,实际上并不需要编写代码来计算代价函数,只需要编写代码来计算导数项,但是,如果希望代码还要能够监控这些的收敛性,那么我们就需要自己编写代码来计算代价函数和偏导数项。所以,在写完能够计算这两者的代码之后,我们就可以使用梯度下降。 然而梯度下降并不是我们可以使用的唯一算法,还有其他一些算法,更高级、更复杂。如果我们能用这些方法来计算代价函数和偏导数项两个项的话,那么这些算法就是为我们优化代价函数的不同方法,共轭梯度法 BFGS (变尺度法) 和L-BFGS (限制变尺度法) 就是其中一些更高级的优化算法,它们需要有一种方法来计算 ,以及需要一种方法计算导数项,然后使用比梯度下降更复杂的算法来最小化代价函数。这三种算法有许多优点:一个是使用这其中任何一个算法,通常不需要手动选择学习率 ,所以对于这些算法的一种思路是,给出计算导数项和代价函数的方法,可以认为算法有一个智能的内部循环,而且,事实上,他们确实有一个智能的内部循环,称为线性搜索(line search)算法,它可以自动尝试不同的学习速率 ,并自动选择一个好的学习速率 ,因此它甚至可以为每次迭代选择不同的学习速率,那么就不需要自己选择。这些算法实际上在做更复杂的事情,不仅仅是选择一个好的学习速率,所以它们往往最终比梯度下降收敛得快多了,不过关于它们到底做什么的详细讨论,我们后续再详细讨论啦。我们实际上完全有可能成功使用这些算法,并应用于许多不同的学习问题,而不需要真正理解这些算法的内环间在做什么,如果说这些算法有缺点的话,那么小Mi真的很想吐槽一下它们比梯度下降法复杂多了!特别是 L-BGFS、BFGS这些算法,除非你是数值计算方面的专家。不过值得高兴的是,我们现在很多编程软件都有强大的库可以调用!它们会让算法使用起来更模糊一点,也许稍微有点难调试,不过由于这些算法的运行速度通常远远超过梯度下降。所以当有一个很大的机器学习问题时,小Mi会选择这些高级算法,而不是梯度下降。7 多类别分类:一对多首先上例子:Example one:假如说现在需要一个学习算法能自动地将邮件归类到不同的文件夹里,或者说可以自动地加上标签,那么,也许需要一些不同的文件夹,或者不同的标签来完成这件事,来区分开来自工作的邮件、来自朋友的邮件、来自家人的邮件或者是有关兴趣爱好的邮件,那么,我们就有了这样一个分类问题:其类别有四个,分别用y=1、y=2、y=3、y=4 来代表。Example two:如果一个病人因为鼻塞来到诊所,他可能并没有生病,用y=1这个类别来代表;如果患了感冒,用 y=2来代表;如果得了流感用来y=3代表。Example three:如果我们正在做有关天气的机器学习分类问题,可能想要区分哪些天是晴天、多云、雨天、或者下雪天。上述所有的例子中,y可以取一个很小的数值,一个相对"谨慎"的数值,比如1 到3、1到4或者其它数值,以上说的都是多类分类问题,然而对于之前的二元分类问题,我们的数据图像是这样的:对于一个多类分类问题,我们的数据集或许看起来像这样:用3种不同的符号来代表3个类别,而给出3个类型的数据集,我们又如何得到一个学习算法来进行分类呢?我们现在已经知道如何进行二元分类,可以使用逻辑回归,对于直线或许你也知道,可以将数据集一分为二为正类和负类。用一对多的分类思想,我们可以将其用在多类分类问题上。下面将介绍如何进行一对多的分类工作,有时这个方法也被称为"一对余"方法。有一个训练集,好比上图表示的有3个类别,我们用三角形表示y=1 ,方框表示y=2,叉叉表示 y=3。我们下面要做的就是使用一个训练集,将其分成3个二元分类问题。先从用三角形代表的类别1开始,实际上我们可以创建一个,新的"伪"训练集,类型2和类型3定为负类,类型1设定为正类,创建一个新的训练集,如下图所示的那样,拟合出一个合适的分类器。这里的三角形是正样本,而圆形代表负样本。可以这样想,设置三角形的值为1,圆形的值为0,然后训练一个标准的逻辑回归分类器,这样我们就得到一个正边界。为了能实现这样的转变,我们将多个类中的一个类标记为正向类(y=1),然后将其他所有类都标记为负向类,这个模型记作。接着,类似地第我们选择另一个类标记为正向类(y=2),再将其它类都标记为负向类,将这个模型记作 ,依此类推。 最后我们得到一系列的模型简记为: 其中:。最后,在我们需要做预测时,再将所有的分类机都运行一遍,然后对每一个输入变量,都选择最高可能性的输出变量。总之,我们已经把要做的做完了,现在要做的就是训练这个逻辑回归分类器:, 其中i对应每一个可能的y=i,最后,为了做出预测,我们给出输入一个新的x值,用这个做预测。我们要做的就是在我们三个分类器里面输入x,然后我们选择一个让最大的i,即。现在我们知道了基本挑选分类器的方法,选择出哪一个分类器是可信度最高效果最好的,那么就可认为得到一个正确的分类,无论值是多少,我们都有最高的概率值,我们预测y就是那个值。这就是多类别分类问题,以及一对多的方法,通过这个小方法,也可以将逻辑回归分类器用在多类分类的问题上啦~终于,逻辑回归也带着大家一起学习完啦!这里小Mi不由地要感慨一下,历史总是相似的,经典也是亘古不变的,适用于线性回归的方法说不定也适用于逻辑回归,只是细节有所不同而已。下期我们还将学习新一轮的学习算法,大家做好准备了吗?我们,下期见呦~